慢雾:Cellframe 被黑简析

    据慢雾安全团队情报,2023年6月1日,Cellframe遭到闪电贷攻击,CellframeERC20v2价格下跌41.2%。慢雾安全团队第一时间介入分析,并将结果分享如下:相关信息攻击者地址:0x2525c811EcF22Fc5fcdE03c67112D34E97DA6079攻击者合约地址:0x1e2a251b29e84e1d6d762c78a9db5113f5ce7c48攻击交易:0x943c2a5f89bc0c17f3fe1520ec6215ed8c6b897ce7f22f1b207fea3f79ae09a6攻击者添加LP(OLD)交易:0xe2d496ccc3c5fd65a55048391662b8d40ddb5952dc26c715c702ba3929158cb9前置信息此次攻击中出现多个新旧合约,我们将使用LpMigration合约中新旧合约的参数名作为本次攻击分析中的合约名。addressOLD_CELL:0xf3E1449DDB6b218dA2C9463D4594CEccC8934346addressLP_OLD:0x06155034f71811fe0D6568eA8bdF6EC12d04Bed2addressCELL:0xd98438889Ae7364c7E2A3540547Fad042FB24642addressLP_NEW:0x1c15f4E3fd885a34660829aE692918b4b9C1803d具体细节分析1.通过DODO的DPPOracle闪电贷1000个BNB。2.通过PancakeSwapV3闪电贷50万枚CELL。

    3.攻击者在PancakeSwapV2LP_NEW池子中,将闪电贷来的50万枚CELLToken全部swap为50枚BNB。这时,LP_NEW池中仅剩8枚BNB,而CELL有55万枚。4.紧接着,攻击者在另外一个PancakeSwapV2池子LP_OLD池中,将900枚BNBswap为OLD_CELL。此时LP_OLD中的BNB数量为902枚,OLD_CELL仅有7枚。

    5.在攻击者将BNB兑换成OLD_CELL后,我们发现攻击者直接调用LpMigration合约的migrate函数进行LP迁移。奇怪的是,在我们刚刚的分析里,攻击者并没有获取LPToken的操作,那么这些LPToken又是从哪里来的呢?6.于是回到攻击合约,通过攻击合约的前一笔交易可以发现,攻击者在交易中向LP_OLD池子添加流动性,获取LP(OLD)Token。7.攻击者对LP_OLD池的LP(OLD)进行连续migrate操作,细节如下:先调用migrateLP函数移除LP(OLD)的流动性,并将代币返还给用户。

    由于池子LP_OLD中的BNB代币很多,在移除流动性时,计算所获得的BNB数量会增加,OLD_CELL减少。随后,在LP_NEW池中,getReserves获取到BNB和CELL的数量。由于之前的swap操作,LP_NEW池中的BNB数量少,CELL数量多,所以计算出来的resoult值会偏大,使得新计算出的CELL的token1值也偏大。8.然而,原本LpMigration合约中又是存在CELL代币的,所以攻击者添加流动性所用的token1代币CELL都来自LpMigration合约。

    随后将计算出的结果添加流动性到ROUTER_V2池中。(PS:这也是为什么在攻击发生后,Cellframe:Deployer会通过withdrawCELL()函数将合约中的CELL代币全部取出)9.也就是说,攻击者利用LP_OLD池中BNB多,OLD_CELL少,通过移除流动性获取到更多的BNB。而在LP_NEW池中BNB少,CELL多的情况下,以少量的BNB和CELL就可以添加流动性。攻击者通过多次migrate操作获利。10.最后,攻击者将LP_NEW的流动性移除,将OLD_CELL在LP_OLD池中兑换为BNB,并在一个新的CELL-BUSD池中先兑换成BUSD再兑换成BNB,偿还FlashLoan,获利245.522826177178247245BNB。总结此次攻击的核心在于利用流动性迁移计算,攻击者操纵两个不同池子中的流动性致其不平衡,进而套利。