{"content":{"title":"AES攻击事件分析","body":"和[hackerdao攻击事件](https://learnblockchain.cn/article/5186)相似\r\n\r\n## skim函数\r\n\r\n```solidity\r\n// force balances to match reserves\r\n    function skim(address to) external lock {\r\n        address _token0 = token0; // gas savings\r\n        address _token1 = token1; // gas savings\r\n        _safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0));\r\n        _safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1));\r\n    }\r\n```\r\n\r\n该函数的作用是提取lp合约地址中多余的代币转到指定的地址\r\n\r\n## sync函数\r\n\r\n```solidity\r\nfunction sync() external lock {\r\n        _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1);\r\n    }\r\n```\r\n\r\n```solidity\r\n// update reserves and, on the first call per block, price accumulators\r\n    function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private {\r\n        require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'Pancake: OVERFLOW');\r\n        uint32 blockTimestamp = uint32(block.timestamp % 2**32);\r\n        uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired\r\n        if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {\r\n            // * never overflows, and + overflow is desired\r\n            price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed;\r\n            price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;\r\n        }\r\n        reserve0 = uint112(balance0);\r\n        reserve1 = uint112(balance1);\r\n        blockTimestampLast = blockTimestamp;\r\n        emit Sync(reserve0, reserve1);\r\n    }\r\n```\r\n\r\n该函数的作用是更新reserve为balance的值。\r\n\r\n攻击者地址：0x286e09932b8d096cba3423d12965042736b8f850\r\n\r\n恶意合约地址：0x3cdfbee6ec194e5258d2f9557e2e41015fc8b6e8\r\n\r\n攻击tx：0xca4d0d24aa448329b7d4eb81be653224a59e7b081fc7a1c9aad59c5a38d0ae19\r\n\r\n通过blocksec的phalcon工具来分析攻击的tx：\r\nhttps://phalcon.blocksec.com/tx/bsc/0xca4d0d24aa448329b7d4eb81be653224a59e7b081fc7a1c9aad59c5a38d0ae19\r\n\r\n## 攻击者通过部署恶意合约通过如下步骤完成套利攻击：\r\n\r\n1.从dodo通过闪电贷借出836944 USDT\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/9Bz86Dsq6398c79655592.png)\r\n\r\n2.将其中的100000 USDT换成了AES，按照价格可以兑换2421667 AES，但是其中有72650发送到了address(0)，最终获得2179500 AES。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/tE0OEECP6398c7ac17dae.png)\r\n\r\n我们查看一下transfer方法\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/FxtNN7Xa6398c7c017e58.png)\r\n\r\n一共有四种情况：\r\n\r\n（1）如果from是代币合约地址，to是uniswapV2Pair（经过查询是AES-USDT），那么调用super._transfer函数转帐。super.方法名 是调用最近的父合约的方法。查看父合约的_transfer方法后，发现就是一个普通的转帐，没有任何其他费用。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/oVcizKzO6398c7d4e2436.png)\r\n\r\n（2）如果发起转帐的地址在automatedMarketMakerPairs数组中，那么调用buyTokenAndFees函数：\r\n\r\n转帐数量的3%为burnAmount 从from地址的余额中扣除，这部分通过父函数的_burn方法发送到address(0)销毁。\r\n\r\n转帐数量的1%添加到swapFeeTotal这个状态变量中。\r\n\r\n转帐数量的10%为feeAmount 从转帐数量中扣除。\r\n\r\n最终接收方收到的数量为转帐数量的90%，发送方的AES余额减少转帐数量的3%。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/VsRaFQ1f6398c7f7cc0b6.png)\r\n\r\n（3）如果接收转帐的地址在automatedMarketMakerPairs数组中，那么调用sellTokenAndFees函数：\r\n\r\n转帐数量的3%从转帐数量中扣除。\r\n\r\n转帐数量的1%添加到swapFeeTotal这个状态变量中。\r\n\r\n转帐数量的3%为burnAmount 从from地址的余额中扣除，这部分通过父函数的_burn方法发送到address(0)销毁。\r\n\r\n最终接收方收到转帐数量的97%\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/GyTFchB16398c8095c903.png)\r\n\r\n（4）除上面3种情况外的其他情况，都直接调用父函数的_transfer方法，不需要额外的手续费等。\r\n\r\n100000 USDT换成了AES这个过程中，AES的from地址为AES-USDT的地址（0x40ed17221b3b2d8455f4f1a05cac6b77c5f707e3），该地址在automatedMarketMakerPairs数组中，因此转帐过程是上述第（2）种情况\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/Zf43W4jz6398c8252dd1e.png)\r\n\r\n3.攻击者将兑换得到的其中1089750个AES发送到AES-USDT地址，触发transferr中的第三种情况，AES-USDT地址收到1057057个AES。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/UuZI6mOa6398c83850cb6.png)\r\n\r\n4.攻击者调用skim方法，to地址设为AES-USDT地址，因为from地址为AES-USDT地址，在automatedMarketMakerPairs数组中，因此触发transfer方法中的第（2）种情况，在这种情况下AES-USDT地址的AES代币会被销毁转帐数量的3%。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/9DbXrKK36398c852f0513.png)\r\n\r\n5.攻击者又多次调用了skim方法，to地址设置为AES-USDT地址，导致AES-USDT地址的AES代币数量逐渐减少。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/Z2q4pnrs6398c862d9248.png)\r\n\r\n6.攻击者调用distributeFee方法，将AES-USDT地址的swapFeeTotal转出pair合约，该方法直接调用的父合约的_transfer方法，因此不存在额外的手续费。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/oRRXM0PG6398c89b48583.png)\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/kqLaM1Tk6398c8a836e64.png)\r\n\r\n7.攻击者调用sync方法来更新reserve的值，AES-USDT地址的AES只剩20246个了，因此每个AES代币的价格都提高了很多。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/IGuS1ues6398c8bb57e3b.png)\r\n\r\n8.攻击者将139794个AES兑换为161608 USDT，购买AES花费100000 USDT，卖出AES获得161608 USDT，获利61608 USDT。\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/riM8rpfs6398c8cb1b0c0.png)\r\n\r\n9.将闪电贷借来的USDT归还，攻击结束。\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/12/dHxxVm6R6398c8de0e13b.png)"},"author":{"user":"https://learnblockchain.cn/people/11441","address":null},"history":"QmRRr16tN7tnm4PtXwGbS6zNoADTvWQ44gkSKE8xMtXSpr","timestamp":1671014621,"version":1}