2026-03-09 20:06:27

Amber Group安全专家解析:Dinosaur Eggs(DSG)流动性资金池漏洞

摘要
2020 年夏天, SushiSwap 创始人 Chef Nomi 所发布的 MasterChef 智能合约可能是最早一波 DeFi 狂潮中被重新部署最多次的合约。

2020 年夏天, SushiSwap 创始人 Chef Nomi 所发布的 MasterChef 智能合约可能是最早一波 DeFi 狂潮中被重新部署最多次的合约。很多的 DeFi 项目会略为修改 MasterChef 合约来实现他们流动性挖矿的功能。然而,过去一年多的时间内,有几个项目在修改 Nomi 主厨「食谱」的过程中犯了错误,造成无法挽救的损失 。2021 年 10 月 6 日,我们也发现了一个失误的项目,所幸在还没造成损失之前,该项目就成功修复了漏洞,并且完成升级。

0x00: Dinosaur Eggs

这次事件的主角Dinosaur Eggs 项目的「流动性资金池」(Liquidity Pool)智能合约也是一个「加强版」的 MasterChef 合约,其主要修改的部分是新增了「addtionalRate」功能。这个功能是为了让特定的NFT 持有者在存入「流动性提供者代币」(LP Tokens)时可以获得额外的奖励,最高可达10%,条件是存入LP Tokens 之前必须「销毁」特定的NFT 资产。

DSG

从上面的程序代码片段327-328 行可以看到(_amount*user.addtionalRate) 会被加到user.addtionalAmount 里头,而这个addtionalAmount 会在计算奖励时被加入计算。

0x01: 漏洞细节

漏洞出现在从MasterChef 继承而来的紧急逃生出口— emergencyWithdraw() 函数。这个函数是用来让user 可以在紧急情况把所有存入的LP tokens 一次取出来,不考虑奖励计算。然而,前面提到的user.addtionalAmount 在这个函数里没有被reset,也就是说下一次的harvest() call 会出现user 没有存入任何LP tokens 的状态下仍然可以领取奖励的情况。

从harvest() 函数的第342 行可以看到pendingAmount 的计算是[(user.amount+user.additionalAmount)*pool.accRewardPerShare – user.rewardDebt]。由于之前的emergencyWithdraw() 已经reset 了user.amount 以及user.rewardDebt,pendingAmount 就变成了(user.addtionalAmount*pool.accRewardPerShare)。因此,攻击者可以在没有任何LP tokens 存入的状态下,不停的来回利用harvest() 跟emergencyWithdraw() 把所有的reward tokens 取出。

0x02: 漏洞利用

上面的攻击合约程序代码验证了上述的想法,在prepare() 函数里,我们刻意铸造了一个NFT(第36 行)并且通过第40 行的additionalNft() 函数启动了前面提到的addtionalRate 机制,随后我们deposit() 了一部分LP tokens 到LiquidityPool。为了获得额外的奖励,我们在trigger() 函数里利用回圈多次调用emergencyWithdraw() 与harvest() 函数(第48-51 行)。

从上面的eth-brownie 截图可以看到,我们只用了30 个LP tokens (DsgLP) 就能获取上千的reward tokens (DSG)。在同样的情况如果只是单纯的harvest() 没有刻意emergencyWithdraw(),只有不到一个的DSG 奖励。假设攻击者利用闪电贷款生成大量LP tokens,还能更进一步扩大获利。

0x04: 后续发展

在我们向DSG 团队通报这个漏洞之后,他们很快的确认问题并且展开了修补工作。新版的LiquidityPool 合约部署上线后,DSG 团队通知了用户将资产从旧版取出后迁移到新版,同时也将旧版的流动性挖矿暂停。幸运的是,在完成迁移之前,并没有真正的攻击发生,DSG 团队也根据漏洞赏金计画给了我们$10k 等值的DSG tokens奖励。这部分奖金随后被用来捐助开放文化基金会,支持开源软件发展。

DSG
声明:文章不代表链懂观点及立场,不构成本平台任何投资建议。投资决策需建立在独立思考之上,本文内容仅供参考,风险自担!转载请注明出处!侵权必究!
热门新闻
热门百科
回顶部