Balancer 被盜 $120M 漏洞技術分析
2025 年 11 月 3 日,Balancer 協議在 Arbitrum、Ethereum 等多條公鏈遭受黑客攻擊,造成 1.2 億美元資產損失,攻擊核心源於精度損失與不變值(Invariant)操控的雙重漏洞。
本次攻擊的關鍵問題出在協議處理小額交易的邏輯上。 當用戶進行小金額交換時,協議會調用_upscaleArray函數,該函數使用muLDOwn進行數值向下舍入。 一旦交易中的餘額與輸入金額同時處於特定舍入邊界(例如 8-9 wei 區間),就會產生明顯的相對精度誤差。
精度誤差傳遞到協議的不變值 D 的計算過程中,導致 D 值被異常縮小。 而 D 值的變動會直接拉低 Balancer 協議中的 BPT(Balancer Pool Token)價格,黑客利用這一被壓低的 BPT 價格,通過預先設計的交易路徑完成套利,最終造成巨額資產損失。
漏洞利用Tx:
https://ETHerscan.io/tx/0x6ed07db1a9fe5c0794d44cd36081d6a6df103fab868cdd75d581e3bd23bc9742
資產轉移Tx:
https://etherscan.io/tx/0xd155207261712c35fa3d472ed1e51bfcd816e616dd4f517fa5959836f5b48569
技術分析攻擊入口
攻擊的入口為 Balancer: Vault 合約,對應的入口函數為batchSWap函數,內部調用onSwap做代幣兌換。
從函數參數和限制來看,可以得到幾個信息:
1. 攻擊者需要通過 Vault 調用這個函數,無法直接調用。
2. 函數內部會調用 _scalingFactors() 獲取縮放因子進行縮放操作。
3. 縮放操作集中在 _swapGivenIn 或 _swapGivenOut 中。
攻擊模式分析
BPT Price 的計算機制:
在 Balancer 的穩定池模型中,BPT 價格是重要的參考依據,能決定用戶得到多少 BPT 和每個 BPT 得到多少資產。
其中 D = 不變值(InvARiant),來自 Curve 的 StableSwap 模型
在池的交換計算中:
其中充當 BPT 價格基準的部分為 不變值 D,也就是操控 BPT 價格需要操控 D。 以下分析 D 的計算過程:
上述代碼中,D 的計算過程依賴縮放後的 balances 數組。 也就是說需要有一個操作來改變這些 balances 的精度,導致 D 計算錯誤。
精度損失的根源:
縮放操作:
如上在通過 _upscaleArray 時,如果餘額很小(如 8-9 wei),mulDown 的向下舍入會導致顯著的精度損失。
攻擊流程詳解
這些交換都在同一個batchSwap交易中,共享相同的餘額狀態,但每次交換都會調用_upscaleArray修改 balances 數組。
Callback 機制的缺失
主流程是 Vault 開啟的,是怎麼導致精度損失累積的呢? 答案在 balances 數組的傳遞機制中。
分析如上代碼,雖然在每次調用onSwap時 Vault 都會創建新的currentBalances數組,但在 Batch Swap 中:
1. 第一次交換後,餘額被更新(但由於精度損失,更新後的值可能不准確)
2. 第二次交換基於第一次的結果繼續計算
3. 精度損失累積,最終導致不變值 D 顯著變小
關鍵問題:
雖然 Vault 每次傳入新數組,但:
1. 如果餘額很小(8-9 wei),縮放時精度損失大
2. 在 Batch Swap 中,後續交換基於已損失精度的餘額繼續計算
3. 沒有驗證不變值 D 的變化是否在合理範圍內
Balancer 的這次攻擊,總結為下面幾個原因:
1.:_upscaleArray 使用mulDown進行縮放,當餘額很小時(如 8-9 wei),會產生顯著的相對精度損失。
2.:不變值 D 的計算依賴縮放後的 balances 數組,精度損失會直接傳遞到 D 的計算中,使 D 變小。
3. 缺少不變值變化驗證:在交換過程中,沒有驗證不變值 D 的變化是否在合理範圍內,導致攻擊者可以反複利用精度損失壓低 BPT 價格。
4. Batch Swap 中的精度損失累積:在同一個 batch swap 中,多次交換的精度損失會累積,最終放大為巨大的財務損失。
這兩個問題精度損失 缺少驗證,結合攻擊者對邊界條件的精心設計,造成了這次損失。