我们监测到一起针对 BNB Smart Chain 链上项目 H2O 攻击事件,此次攻击共造成 22,000 USD 的损失。
<!--StartFragment-->
2025年3月14日,我们监测到一起针对 BNB Smart Chain 链上项目 H2O 攻击事件,攻击hash为:
https\://bscscan.com/tx/0x729c502a7dfd5332a9bdbcacec97137899ecc82c17d0797b9686a7f9f6005cb7
https\://bscscan.com/tx/0x994abe7906a4a955c103071221e5eaa734a30dccdcdaac63496ece2b698a0fc3
被攻击的项目为 H2O ,攻击共造成 22,000 USD 的损失。
<!--EndFragment-->
<!--StartFragment-->
在第一次攻击中,攻击者首先从 PancakeSwapV3 Pool 中利用 flashloan 贷了 100,000 USDT 作为攻击的初始资金。
<!--EndFragment-->
<!--StartFragment-->
随后,用贷来的初始资金在 USDT-H2O 的 PancakeSwap Pair 中兑换了 66,439,209 H2O。
<!--EndFragment-->
<!--StartFragment-->
攻击者随后频繁将 H2O 转给 PancakeSwap Pair USDT-H2O ,然后使得 Pair 中 USDT reserve 和H2O reserve 不平衡,随后利用 skim 平衡 Pair 中的 reserve0 和 reserve1 来实施攻击。H2O 的漏洞出现在 transfer 函数中,我们可以看到 transfer 函数的具体实现。
<!--EndFragment-->
<!--StartFragment-->
问题具体出现在函数中,当 from 为 PancakeSwap Pair 时,调用 _calulate 函数。由于攻击者利用 Pair 的 Reserve0 和 Reserve1 不平衡,调用 skim 给自身 transfer ,所以该 transfer 的 sender 为 Pair address 。接下来,我们看一下该函数的具体实现。
<!--EndFragment-->
<!--StartFragment-->
这个函数的逻辑很简单根据合约自身持有的 H2O 代币余额动态设定奖励费率(1%-5%,余额越少费率越低),通过链上随机数向用户按比例分发 H2 或 O2 代币;当用户持有至少 10 H2 和 5 O2时,可销毁 2:1 比例的代币(模拟化学反应 2H₂+O₂→2H₂O ),兑换合约中的 H2O 代币,实际兑换量受合约余额限制。
合约生成链上随机数的逻辑如下:
<!--EndFragment-->
<!--StartFragment-->
根据 blocktime , blocknumber 和 msg.sender 的 keccak256 来计算。在第一次攻击中,由于攻击者没有 H2 Token 和 O2 Token ,所以在此次攻击中获得了 169,731,921 O2 Token 。接下来,只要攻击者使得 getRandomOnchain()%2 == 1 即可完成攻击,随后攻击者又进行了三次尝试,但是前两次 getRandomOnchain()%2 均为0,导致攻击失败,第四次才真正完成攻击。
<!--EndFragment-->
<!--StartFragment-->
在第四次攻击时,攻击者首先从 PancakeSwapV3 Pool 中利用 flashloan 贷了 100,000 USDT 作为攻击的初始资金,
<!--EndFragment-->
<!--StartFragment-->
随后,用贷来的初始资金在 USDT-H2O 的 PancakeSwap Pair 中兑换了 66,439,209 H2O。
<!--EndFragment-->
<!--StartFragment-->
攻击者随后频繁将 H2O 转给 PancakeSwap Pair USDT-H2O ,然后使得 Pair 中 USDT reserve 和 H2O reserve 不平衡,随后利用 skim 平衡 Pair 中的 reserve0 和 reserve1 来实施攻击。
<!--EndFragment-->
<!--StartFragment-->
根据我们上述的分析可知,此次攻击中 getRandomOnchain()%2 为1,所以 H2O 会 mint H2Token 。又因为攻击者利用第一次攻击时,getRandomOnchain()%2 为 0,所以获得 mint 的大量 O2 Token 。所以,H2O burn 了 H2 和 O2 后将自身的 H2O 转给攻击者。
最后,攻击者用凭空的来的 H2O 兑换了 122,820 USDT 。归还完 100,000 USDT 的 flashloan 和 50 USDT 的利息,最终获利 22,770 USDT 。
<!--EndFragment-->
<!--StartFragment-->
本次漏洞成因主要是因为 H20 Token 合约设计从 PancakeSwap Pair 上买入的经济模型时,在修改 ERC20 transfer 函数没有考虑到 skim 也可以达到相同目的,导致攻击者利用 skim 凭空获得大量激励。建议项目方在设计经济模型、价格计算机制和代码运行逻辑时要多方验证,合约上线前审计时尽量选择多个审计公司交叉审计。
<!--EndFragment-->
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!