11月3日,BalancerV2的池子在多条链上被攻击,造成了1.2亿美元的损失。我来分析下攻击原理
11月3日,Balancer V2的池子在多条链上被攻击,造成了1.2亿美元的损失。我来分析下攻击原理 攻击交易: https://app.blocksec.com/explorer/tx/eth/0x6ed07db1a9fe5c0794d44cd36081d6a6df103fab868cdd75d581e3bd23bc9742 被害合约地址: https://etherscan.io/address/0xba12222222228d8ba445958a75a0704d566bf2c8
区块链的世界没有小数点。所以如果除法结果带有小数点,要么被向上取整,要么被向下取整。 例如A用户向商家B购买一个币,如果最终成交价是3.5 U,A要么给B 3U,要么给B 4U。这个取整的方向由合约代码设定。一般都是往利好商家(项目方)的方向取整。 另外,如果结算是10000.13,向下取整为10000,也还能接受,因为损失仅为 0.13/10000 但是,如果结算是10.9,向下取整为10,这个损失就很大:0.9/10 这次攻击就利用了上述特征。
本次攻击覆盖了balancer上面多个链,多个池子,我们以ETH链的 osETH-wETH-BPT 池子为例子看一下具体发生了什么 osETH/wETH-BPT 的相关信息如下:
所有的攻击都是在一次batchSwap里搞定的,在这次调用里,黑客构造了多笔swaps
攻击者通过 batchSwap 用 osETH/wETH-BPT 多次换出 WETH 和 osETH 代币,大幅降低 Pool 中的流动性。
攻击者只能够每次兑换大约 99% 的代币余额,就是为了留有空间给 fee 的计算。最终只能通过多次兑换来不断减少 balance 的值,直到 6700。
此时 Pool 中的流动性已经被大量移除,黑客在这个基础上利用精度丢失问题操控了 WETH 和 osETH 兑换 osETH/wETH-BPT 的比例。 在 Phase2 中反复进行以下操作:
为什么兑换出的值是17:
进入到 _swapGivenOut() 函数中时,会通过 _upscale 对 osETH 的值进行缩放(因为他是 rebasing token),计算其对应的 ETH 数量。
由于 osETH 的 ScalingFactor 为 1058109553424427048,当 amountOut 为 17 时能够计算得到最大的精度丢失值。
也就是兑换 amountOut 为价值 17.98 ETH的 osETH,只需要按照 17 的数量来提供 WETH。每次进行这个操作都会多获取到池子中的 0.98 个 osETH,使得 invariant 的值不断缩小。
在经过 Phase2 对 Pool 代币余额的操纵后,osETH/wETH-BPT 代币的数量不变, WETH 和 osETH 的数量大幅减少。这导致了同样的 WETH 和 osETH 数量能够兑换出更多的 osETH/wETH-BPT 代币。 黑客在 Phase3 中用高价的 WETH 和 osETH 逐步兑换出 osETH/wETH-BPT,恢复在 Phase1 中被移除流动性。同时保留了剩余的 WETH 和 osETH 代币,完成获利。 最终获利:
本文很多内容借鉴这篇文章,写的很好:https://www.cnblogs.com/ACaiGarden/p/19235024
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!