{"content":{"title":"DFX Finance攻击事件分析","body":"### 攻击背景\r\n\r\n攻击者地址：0x14c19962e4a899f29b3dd9ff52ebfb5e4cb9a067\r\n\r\n攻击合约地址：0x6cfa86a352339e766ff1ca119c8c40824f41f22d\r\n\r\n攻击tx：0x390def749b71f516d8bf4329a4cb07bb3568a3627c25e607556621182a17f1f9\r\n\r\n通过blocksec的phalcon工具来分析攻击的tx\r\n\r\n[https://phalcon.blocksec.com/tx/eth/0x390def749b71f516d8bf4329a4cb07bb3568a3627c25e607556621182a17f1f9](https://phalcon.blocksec.com/tx/eth/0x390def749b71f516d8bf4329a4cb07bb3568a3627c25e607556621182a17f1f9)\r\n\r\n### 攻击分析\r\n\r\n1.调用xdr-usdc的viewDeposit方法，根据viewDeposit方法的注释我们可以知道该方法的作用是，存入200 000USDC，可以获得246 249个LP token，这么多LP token分别由 2 325 581 395 XIDR和 100 000USDC组成。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/vQ0qwgUJ639b513b92e10.png)\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/XfMv3eWn639b51470ef29.png)\r\n\r\n2.从uniswap借出100000 USDC\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/p2xGZDZb639b517ea41a6.png)\r\n\r\n3.从uniswap借出2 325 581 395 XIDR\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/qQy2YvRo639b518f25e76.png)\r\n\r\n4.调用dfx的xidr-usdc的flash函数，借出99500 USDC和2 313 953 488 XIDR\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/koWT85JQ639b519cd2af8.png)\r\n\r\n5.调用deposit函数，会将2 325 581 395 XIDR和 100 000USDC转到LP token合约地址中添加流动性，然后收到300886个LP token。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/eI8xpWLz639b51ac24823.png)\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/bYHw4wM1639b51b90cd8c.png)\r\n\r\n6.归还11 627 906 XIDR 和500 USDC，攻击完成。为什么攻击者借出了2 325 581 395 XIDR和 100 000USDC 却只用归还11 627 906 XIDR 和500 USDC呢？\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/n4KVG7Wn639b51cb1fb33.png)\r\n\r\n查看下xidr-usdc的flash函数\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/oO5rZif5639b51d96bb66.png)\r\n\r\n这里判断闪电贷还款的逻辑是，只要还款后池子中的token余额 大于等于 借款前池子中token余额加上fee。在第4步中攻击者借出了99500 USDC和2 313 953 488 XIDR，但是在第5步中攻击者通过添加流动性将2 325 581 395 XIDR和 100 000USDC添加到池子中，就使得当前池子中的token数量接近借款前的token数量，那么攻击者只需要再还很少一部分即可满足还款条件。\r\n\r\n7.完成还款后，攻击者调用withdraw方法撤销流动性，获得99 908 USDC和2 284 065 638XIDR。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/i6DR6FdQ639b51eec90ad.png)\r\n\r\n8.还款从uniswap借出的USDC和XIDR，攻击结束。本次攻击一共获利99 908 USDC和2 284 065 638XIDR。攻击者可以重复上述操作，直到池子被掏空。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/sEj6q7yg639b51fc5289f.png)\r\n\r\n\r\nuniswap为什么不存在这个问题呢？\r\n\r\n通过查看uniswap的mint函数可以知道，如果将借出的代币添加流动性，那么amount0和amount1将会为0，也就不会获得流动性代币。\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/ofbutZHz639ff0452b1e8.png)\r\n### 总结\r\n\r\n这次攻击的核心是dfx的pair合约闪电贷借出的代币可以成功添加流动性并获得流动性代币，且dfx的pair合约的flash方法是通过借款前和还款后池子中token的数量来判断是否还款。攻击者就通过flash后调用deposit方法添加流动性的方式来使池子中token的数量满足还款要求（相当于通过添加流动性的方式还了闪电贷），然后完成还款后再通过withdraw方法撤销流动性将之前添加流动性的token取出。"},"author":{"user":"https://learnblockchain.cn/people/11441","address":null},"history":"QmYKM3Q5B4bJdemFz2uGeJUvwV4rjrSXV7qz9WTjcm6x9S","timestamp":1671426147,"version":1}