5月20日,CertiK安全技术团队发现币安智能链DeFi收益聚合器PancakeBunny遭到闪电贷攻击,发生代币闪崩事件。
此次事件共损失114,631枚BNB和697,245枚BUNNY,按当时价格计算约合约4200万美元。?
经CertiK安全团队调查得出,由于该协议是使用PancakeSwapAMM来进行资产价格计算的,因此黑客恶意利用了闪电贷来操纵AMM池的价格,并利用Bunny在铸造代币的时候计算上的问题成功完成攻击。
攻击是如何发生的?
本次攻击,攻击者总共进行了8笔闪电贷。其中7笔闪电贷来自PancakeSwap流动性池的BNB,另外一笔则来自ForTubeBank的USDT。
技术细节分析
在文中,CertiK安全专家添加了地址标签,使代币的流向更加清晰。
攻击者的地址:https://bscscan.com/address/0xa0acc61547f6bd066f7c9663c17a312b6ad7e187
以太坊互操作性网络Connext完成1200万美元融资:基于以太坊的互操作性网络Connext完成1200万美元融资,ConsenSysMesh和1kx共同领投,CoinbaseVentures、OkExVentures、eGirlCapital和Hashed等参投。这笔资金将有助于发展团队、建立Connext的生态系统并扩展网络。(the block)[2021/7/13 0:49:16]
攻击者使用的合约地址:https://bscscan.com/address/0xcc598232a75fb1b361510bce4ca39d7bc39cf498
交易一:?
https://bscscan.com/tx/0x88fcffc3256faac76cde4bbd0df6ea3603b1438a5a0409b2e2b91e7c2ba3371a
在第一笔交易中,攻击者完成了两件事:
①将BNB转换成"USDT-BNBFLIP"。
XT交易所将于7月7日上线USDC:据官方消息,XT交易所现已开放USDC/USDT充提功能。其交易功能将于7月7日17:00(UTC+8)开启。
USD Coin(USDC)是一个完全可抵押的对标美元的稳定币,它提供详细的财务和运营透明度,并在美国货币流通法的框架内运行,而且跟多家银行机构和审计团队合作。这是Centre的第一个稳定币开源项目。
XT是一家社交化交易平台。[2021/7/7 0:33:40]
②将"USDT-BNBFLIP"存入BUNNY的池子。
攻击者将FLIP存入资金池,这样当其在后期调用VaultFlipToFlip合约中的Withdraw()或getReward()函数时,资金池将铸造BUNNY代币。
①"Zap"所做的是将所提供的代币的一半换成一对中的另一个代币,并将两个代币提供给相应的PancakeSwap池。这也可以通过BUNNY的Dapp前端来完成。
②将USDT-BNBFLIP存入池中。
Gate.io杠杆ETF速报:XTZ3L以20.60%涨幅领涨ETF:据Gate.io杠杆ETF官方数据,截至今日17:00时,XTZ3L以20.60%涨幅领涨ETF,ETH3L(+13.59%)、BSV3L(+7.57%)涨幅紧随其后。BSV3S24小时成交量达$118.39万美元。Gate.io杠杆ETF产品在永续合约市场对冲管理,平台收取每日0.3%管理费来弥补开销成本,用户只需简单买币卖币即可参与杠杆。以上观点不构成投资建议,请注意风险。[2020/4/19]
交易二:?
https://bscscan.com/tx/0x897c2de73dd55d7701e1b69ffb3a17b0f4801ced88b0c75fe1551c5fcce6a979
在完成第一笔交易将"USDT-BNBFLIP"存入BUNNY资金池之后,攻击者进行了第二笔交易,这也是大多数人最关注的交易。
接下来把第二笔交易中的发生的所有代币的转移分解成多个部分:
①攻击者从7个不同的PancakeSwap流动性池中利用闪电贷共借了232万BNB,从ForTube用闪电贷款借了296万USDT。
然后攻击者向"USDT-BNB''池提供了7700枚BNB和296万USDT的流动性,获得了14.4万LP代币。
②攻击者将从闪电贷中获得的232万BNB在PancakeSwapV1池中换取了383万USDT。
由于V1池的BNB和USDT储备远少于V2池,V1池的价格更容易被操纵,在将BNB换成USDT后,BNB价格急剧下降。
③上文提到攻击者在"交易一?"中把"USDT-BNBFLIP"存到BUNNY池,现在攻击者可以调用"getReward()"函数来铸造BUNNY。
在调用"VaultFlipToFlip"合约中的"getReward()"函数时产生了大量代币转移记录,如截图所示。
上图中这个函数发生的细节如下:
?BUNNYMinterV2从USDT-BNBv2池中取出流动性——从池中取出296万USDT和7744枚BNB。
?将USDT换成BNB。在ZapBSC合约中使用的是V1PancakeSwapRouter而不是V2。
由于V1池的价格已经被操纵,攻击者能够将296万USDT换成231万BNB。
然后,一半的BNB被换成BUNNY,另一半的BNB和换来的BUNNY被添加到BNB-BUNNY池中。
现在,大量的BNB被加入到BNB-BUNNY池中,这增加了BNB(reserve0)的数量。
当之后计算要铸造的BUNNY数量时,这将被用来操纵"valueInBNB"变量。
ZapBSC合约地址https://bscscan.com/address/0xf4c17e321a8c566d21cf8a9f090ef38f727913d5#code
?把标记?中移除流动性获得的7700BNB交换一半到BUNNY,并将另一半BNB与BUNNY配对,以提供"BNB-BUNNY"池中的流动性。
注意标记?、?和?发生在"BUNNYMinterV2"合约的"mintForV2"函数中的"_zapAssetsToBUNNYBNB"函数调用。
BunnyMinterV2合约地址:https://bscscan.com/address/0x819eea71d3f93bb604816f1797d4828c90219b5d#code
?从标记?和?产生的所有LP代币都被送到PancakeSwap的BUNNY池中,这是BunnyMinterV2合约中"mintForV2"函数中的这行代码所执行的结果:
"IBEP20(BUNNY_BNB).safeTransfer(BUNNY_POOL,bunnyBNBAmount);"?
如标记?所示,该合约继续执行,铸造了700万的BUNNY。
那么,是什么原因导致合约铸造了这么多的BUNNY?呢?
在bunnyMinterV2合约中,要铸造的BUNNY数量与"valueInBNB"变量有关,该变量是通过`priceCalculator.valueOfAsset(BUNNY_BNB,bunnyBNBAmount)`函数计算得出的。
在函数`valueOfAsset`中,valueInBNB的计算方法是:`valueInBNB=amount.mul(reserve0).mul(2).div(IPancakePair(asset).totalSupply())`
因为在BNB-BUNNY池中有大量的BNB,变量"reserve0"是一个非常大的值,使"valueInBNB"变得很大,所以它最终会增加铸造的BUNNY数量。
④在收到700万的BUNNY后,攻击者在PancakeSwapBNB-BUNNYV1池和V2池中将BUNNY换成BNB。
⑤最后,攻击者向ForTube和PancakeSwap的7个流动性池偿还闪电贷,并将69.7万枚BUNNY和11.4万枚BNB转移到攻击者的地址。
这种攻击奏效的原因之一是"ZapBSC"合约使用PancakeSwapV1流动性池,通过V1PancakeSwapRouter进行代币交换。
很多DeFi项目无法从PancakeSwapV1过渡到V2,因为它们在合约中把PancakeSwapRouter和池子的地址写死为V1的地址。
由于V1流动性池已经被放弃,它们的池子中代币的储备量很低,这使得攻击者更容易操纵其中的代币价格。
写在最后
当前的加密世界中,这样的闪电贷攻击和恶意价格操纵必然不会是最后一次。
CertiK建议DeFi项目将其PancakeSwap集成从V1迁移到V2。
同时也可使用时间加权平均价格来避免价格异常波动所带来的损失,以此防范黑客利用闪电贷攻击价格预言机。
迄今为止,CertiK已进行了超过700次的审计,保护了超过300亿美元的数字资产与软件系统免受安全损失。
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。