11月3號,Balancer V2協議及其fork項目在多條鏈上遭受攻擊,導致超過$120M的嚴重損失。 BlockSec在第一時間預警[1],並給予初步分析結論[2]。這是一起高度複雜的攻擊事件。我們的初步分析表明,根本原因在於攻擊者操縱了不變量(invariant),從而扭曲了BPT(Balancer Pool Token ) -- 也就是Balancer Pool的LP token -- 價格的計算,使其能夠通過一次batchSwap 操作在某個穩定池(stable pool)中獲利。
背景知識
1. 縮放(scaling)與取整(rounding)
為統一不同代幣的小數位,Balancer 合約會:
- upscale:把餘額與金額放大到統一內部精確度再做計算;
- downscale:把結果縮回原生精確度,並進行有方向的取整(例如輸入端通常向上取整,確保池子不少收;輸出路徑常有向下截斷)。
結論:同一筆交易內,不同環節所採用的取整方向不對稱,在極小步重複執行時,會產生系統性微小偏差。
2. D 與BPT 價格
遭受此攻擊影響的是Balancer V2協定的Composable Stable Pool[3]以及fork的協定。 Stable Pool 用於那些預期可以保持接近1:1 兌換比例(或在已知匯率下進行兌換的資產),允許在不產生顯著價格衝擊的情況下進行大額兌換,從而大幅提升相似資產或相關資產之間的資金利用效率。
- 此pool採用Stable Math(基於Curve 的StableSwap 模型),不變式D 代表池子的「虛擬總價值」。
- BPT (Pool的LP Token) 價格近似為:

從上述公式可以看出若能讓D在帳面上變小(即使資金實際上未流失),就能讓BPT 價格更便宜。 BTP 代表的是Pool的份額,用於計算撤出流動性的時候能獲得多少Pool中Reserve,因此如果攻擊者能獲得更多的BPT,最後在撤出流動性的時候就能獲利。
攻擊分析
以Arbitrum 上的攻擊交易為例,batchSwap 操作可分為三個階段:
第一階段: 攻擊者將BPT 兌換為底層資產,以精確調整其中一種代幣(cbETH)的餘額至四捨五入邊界的臨界點(數量= 9)。這一步驟為下一階段的精度損失(precision loss)創造了條件。
第二階段:攻擊者使用精心建構的數量(= 8),在另一個底層資產(wstETH)與cbETH 之間進行交換。由於在縮放代幣數量時進行了向下取整(rounding down),計算得到的Δx 略小(從8.918 變為8),從而導致Δy 被低估,並使不變量D(來自Curve 的StableSwap 模型)變小。由於BPT 價格= D / totalSupply,BPT 價格被人為壓低。

第三階段: 攻擊者將底層資產反向兌換回BPT,在恢復池內平衡的同時,利用被壓低的BPT 價格獲利-- 獲得更多的BPT Token.
最後,攻擊者利用另一個獲利交易進行流動性撤回,從而利用多獲得的BPT獲得Pool中其他底層資產(cbETH和wstETH)從而獲利
攻擊交易:
https://app.blocksec.com/explorer/tx/arbitrum/0x7da32ebc615d0f29a24cacf9d18254bea3a2c730084c690ee40238b1d8b55773
獲利交易:
https://app.blocksec.com/explorer/tx/arbitrum/0x4e5be713d986bcf4afb2ba7362525622acf9c95310bd77cd5911e7ef12d871a9
Reference:
[1]https://x.com/Phalcon_xyz/status/1985262010347696312
[2]https://x.com/Phalcon_xyz/status/1985302779263643915
[3]https://docs-v2.balancer.fi/concepts/pools/composable-stable.html
