hackerdao攻击事件分析

  • Drac
  • 更新于 2022-12-14 02:38
  • 阅读 1954

hackerDao项目遭受价格操控攻击

skim函数

// force balances to match reserves
    function skim(address to) external lock {
        address _token0 = token0; // gas savings
        address _token1 = token1; // gas savings
        _safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0));
        _safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1));
    }

该函数的作用是提取lp合约地址中多余的代币转到指定的地址

sync函数

function sync() external lock {
        _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1);
    }
// update reserves and, on the first call per block, price accumulators
    function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private {
        require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'Pancake: OVERFLOW');
        uint32 blockTimestamp = uint32(block.timestamp % 2**32);
        uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired
        if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {
            // * never overflows, and + overflow is desired
            price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed;
            price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;
        }
        reserve0 = uint112(balance0);
        reserve1 = uint112(balance1);
        blockTimestampLast = blockTimestamp;
        emit Sync(reserve0, reserve1);
    }

该函数的作用是更新reserve为balance的值。

攻击者地址:0xcfc591db031b760961fe8943a183741ed7cd1f82

恶意合约地址:0x24cb6980995aeb7d5a9204e04b17dcd1e99a4694

攻击tx:0x04673c95054247588bb8380dbc7d361f08f8f0baa319366f48ad46e51d08422d

通过blocksec的phalcon工具来分析攻击的tx

https://phalcon.blocksec.com/tx/bsc/0x04673c95054247588bb8380dbc7d361f08f8f0baa319366f48ad46e51d08422d

攻击者通过部署恶意合约通过如下步骤完成套利攻击:

1.从dodo闪电贷借出2500wbnb。

image.png

2.在pancake中将其中1995个换成hackerdao,一共换取了10315个hackerdao,在swap前wbnb-hakcerdao地址的hackerdao的余额为11335

image.png

我们实际收到了9077个hackerdao,我们分析交易流程可以发现,412个被发送到了address(1),825个被发送到了0x465开头的地址。

image.png

然后看了下transfer方法,发现如果不在白名单中,转账有个fee,如果是收款地址为uniswapV2Pair(经过查询是hackerdao-usdt的lp合约地址)的话,那么fee由发送方出。

image.png

image.png

在bscscan上得到fee为12%,那么fee一共需要1237个hackerdao。

image.png

继续查看代码,发现fee分成了2个部分,4%发送到address(1)销毁,8%发送到0x465开头的poolAddress地址

image.png

image.png

3.将9077个hackerdao转账给hackerdao-wbnb的lp合约,转帐扣除fee后到账7988个

image.png

4.调用hackerdao-wbnb的lp合约的skim函数,将多余的7988个hackerdao转出到hackerdao-usdt的lp合约地址,因为目标地址是hackerdao-usdt的lp地址,因此调用skim函数所扣的fee是原本lp合约中的hackerdao余额,到账后还是7988个。

image.png

hackerdao-wbnb中的hackerdao减少,wbnb的数量不变,那么单个hackerdao的价格相当于上升了。

5.继续调用hackerdao-usdt的lp合约的skim函数,将多余的7988个hackerdao转回攻击者的恶意合约地址。扣除fee后实际收到7029个。

image.png

6.调用hackerdao-wbnb的lp合约的sync函数更新一下reserve,hackerdao的价格更新为上升后的。

image.png

7.然后调用pancake的swapExactTokensForTokensSupportingFeeOnTransferTokens,将全部hackerdao换成wbnb,一共换取了2170个wbnb,之前一共花费了1995个wbnb,因此这次攻击获利175个wbnb。

image.png

8.归还借来的2500个wbnb,提取获利的175个wbnb,攻击结束。

image.png

点赞 0
收藏 3
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Drac
Drac
江湖只有他的大名,没有他的介绍。