原文標題:《Balancer 被盜$120M 漏洞技術分析》
原文來源:ExVul Security
2025 年 11 月 3 日,Barumr.億美元資產損失,攻擊核心源自於精確度損失與不變值(Invariant)操控的雙重漏洞。
Chainlink 的基礎設施長期維持 Web3 領域的最高標準,因此成為 X Layer 致力於為開發者提供機構級工具的自然選擇。
本次攻擊的關鍵問題出在協議處理小額交易的邏輯上。當使用者進行小金額交換時,協定會呼叫_upscaleArray 函數,該函數使用 mulDown 進行數值向下捨去。一旦交易中的餘額與輸入金額同時處於特定舍入邊界(例如 8-9 wei 區間),就會產生明顯的相對精度誤差。
精度誤差傳遞到協定的不變值 D 的計算過程中,導致 D 值被異常縮小。而 D 值的變動會直接拉低 Balancer 協議中的 BPT(Balancer Pool Token)價格,駭客利用這一被壓低的 BPT 價格,透過預先設計的交易路徑完成套利,最終造成巨額資產損失。
漏洞利用 Tx:
https://etherscan.io/tx/0x6ed07db1a9fe5c0794d44cd36081d6a6df103fab868cdd75d581e3bd23bc9742
https://etherscan.io/tx/0xd155207261712c35fa3d472ed1e51bfcd816e616dd4f51 7fa5959836f5b48569
攻擊的入口為Balancer: Vault 合約,對應的入口函數為 batchSwap 函數,內部呼叫 onSwap 做代幣兌換。

從函數參數和限制來看,可以得到幾個資訊:
1. 攻擊者需要直接被呼叫 Vault 調用。
2. 函數內部會呼叫 _scalingFactors() 取得縮放因子進行縮放操作。
3. 縮放操作集中在 _swapGivenIn 或 _swapGivenOut 中。
在 Balancer 的穩定池模型中,BPT 價格是重要的參考依據,用戶能決定用戶得到多少

在池的交換計算中:
其中充當 BPT 價格基準的部分為 不變值 D,也就是操控 BPT 價格需要操控 D。往下分析 D 的計算過程:

上述程式碼中,D 的計算過程依賴縮放後的 strongances 陣列。也就是說需要有一個操作來改變這些 balances 的精確度,導致 D 計算錯誤。

縮放操作:

如上在通過 _upscaleArray 時,如果我們向下8

 2:觸發精確度損失(核心漏洞)

="p-pign style=" center;">
如上攻擊者透過 Batch Swap 在一個交易中執行多次兌換:
1. 第一次交換:BPT → cbETH(調整) cbETH(觸發精確度損失)
3. 第三次交換:底層資產 → BPT(獲利)
這些交換都在同一個 batch swap 交易中,共享相同的餘額狀態,但每次交換數都會修改數組。
主流程是 Vault 開啟的,是怎麼導致精確度損失累積的呢?答案在 balances 陣列的傳遞機制。

分析如上程式碼,雖然每次呼叫 onSwap 時 Vault 都會建立新的 currentBalances 數組,但在每次呼叫 Batchp
1. 第一次交換後,餘額被更新(但由於精度損失,更新後的值可能不準確)
2. 第二次交換基於第一次的結果繼續計算
3. 精度損失累積,最終導致不變值 Dp>
3. 精度損失累積,最終導致不變值 D顯著變小

1. 縮放函數使用向下舍入:_upscaleArray 使用 mulDown 進行縮放,當餘額很小時(如 8-9 wei),會產生顯著的相對精度損失。
2. 不變值計算對精度敏感:不變值 D 的計算依賴縮放後的 balances 數組,精度損失會直接傳遞到 D 的計算中,使 D 變小。
3. 缺少不變值變化驗證:在交換過程中,沒有驗證不變值 D 的變化是否在合理範圍內,導致攻擊者可以重複利用精度損失壓低 BPT 價格。
4. Batch Swap 中的精度損失累積:在同一個 batch swap 中,多次交換的精度損失會累積,最終放大為巨大的財務損失。
這兩個問題精度損失 + 缺少驗證,結合攻擊者對邊界條件的精心設計,造成了這次損失。
本文來自投稿,不代表 BlockBeats 觀點。
歡迎加入律動 BlockBeats 官方社群:
Telegram 訂閱群:https://t.me/theblockbeats
Telegram 交流群:https://t.me/BlockBeats_App
Twitter 官方帳號:https://twitter.com/BlockBeatsAsia