DFX Finance攻击事件分析
攻击者地址:0x14c19962e4a899f29b3dd9ff52ebfb5e4cb9a067
攻击合约地址:0x6cfa86a352339e766ff1ca119c8c40824f41f22d
攻击tx:0x390def749b71f516d8bf4329a4cb07bb3568a3627c25e607556621182a17f1f9
通过blocksec的phalcon工具来分析攻击的tx
1.调用xdr-usdc的viewDeposit方法,根据viewDeposit方法的注释我们可以知道该方法的作用是,存入200 000USDC,可以获得246 249个LP token,这么多LP token分别由 2 325 581 395 XIDR和 100 000USDC组成。
2.从uniswap借出100000 USDC
3.从uniswap借出2 325 581 395 XIDR
4.调用dfx的xidr-usdc的flash函数,借出99500 USDC和2 313 953 488 XIDR
5.调用deposit函数,会将2 325 581 395 XIDR和 100 000USDC转到LP token合约地址中添加流动性,然后收到300886个LP token。
6.归还11 627 906 XIDR 和500 USDC,攻击完成。为什么攻击者借出了2 325 581 395 XIDR和 100 000USDC 却只用归还11 627 906 XIDR 和500 USDC呢?
查看下xidr-usdc的flash函数
这里判断闪电贷还款的逻辑是,只要还款后池子中的token余额 大于等于 借款前池子中token余额加上fee。在第4步中攻击者借出了99500 USDC和2 313 953 488 XIDR,但是在第5步中攻击者通过添加流动性将2 325 581 395 XIDR和 100 000USDC添加到池子中,就使得当前池子中的token数量接近借款前的token数量,那么攻击者只需要再还很少一部分即可满足还款条件。
7.完成还款后,攻击者调用withdraw方法撤销流动性,获得99 908 USDC和2 284 065 638XIDR。
8.还款从uniswap借出的USDC和XIDR,攻击结束。本次攻击一共获利99 908 USDC和2 284 065 638XIDR。攻击者可以重复上述操作,直到池子被掏空。
uniswap为什么不存在这个问题呢?
通过查看uniswap的mint函数可以知道,如果将借出的代币添加流动性,那么amount0和amount1将会为0,也就不会获得流动性代币。
这次攻击的核心是dfx的pair合约闪电贷借出的代币可以成功添加流动性并获得流动性代币,且dfx的pair合约的flash方法是通过借款前和还款后池子中token的数量来判断是否还款。攻击者就通过flash后调用deposit方法添加流动性的方式来使池子中token的数量满足还款要求(相当于通过添加流动性的方式还了闪电贷),然后完成还款后再通过withdraw方法撤销流动性将之前添加流动性的token取出。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!