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做代幣兌換。

從函數參數和限制來看,可以得到幾個信息:
攻擊者需要通過 Vault 調用這個函數,無法直接調用。
函數內部會調用 _scalingFactors() 獲取縮放因子進行縮放操作。
縮放操作集中在 _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 中:
第一次交換後,餘額被更新(但由於精度損失,更新後的值可能不準確)
第二次交換基於第一次的結果繼續計算
精度損失累積,最終導致不變值 D 顯著變小
關鍵問題:

雖然 Vault 每次傳入新陣列,但:
- 如果餘額很小(8-9 wei),縮放時精度損失大
- 在 Batch Swap 中,後續交換基於已損失精度的餘額繼續計算
- 沒有驗證不變值 D 的變化是否在合理範圍內
總結
Balancer 的這次攻擊,總結為下面幾個原因:
縮放函數使用向下舍入 :_upscaleArray 使用mulDown進行縮放,當餘額很小時(如 8-9 wei),會產生顯著的相對精度損失。
不變值計算對精度敏感 :不變值 D 的計算依賴縮放後的 balances 陣列,精度損失會直接傳遞到 D 的計算中,使 D 變小。
缺少不變值變化驗證 :在交換過程中,沒有驗證不變值 D 的變化是否在合理範圍內,導致攻擊者可以反復利用精度損失壓低 BPT 價格。
Batch Swap 中的精度損失累積 :在同一個 batch swap 中,多次交換的精度損失會累積,最終放大為巨大的財務損失。
這兩個問題精度損失 + 缺少驗證,結合攻擊者對邊界條件的精心設計,造成了這次損失。














