2025 年 11 月 3 日,曾被業內普遍認為 “久經考驗” 的協議 Balancer V2,遭遇了超 1.28 億美元的資產被盜。對許多人來説,這是一場意外;但對讀過我10 月 16 日發佈的 Balancer AMM 架構分析的讀者而言,這卻是一次令人恐慌的印證。
https://www.zealynx.io/blogs/balancer-protocol-architecture
攻擊者並未發現某個複雜到極致的新漏洞,而是利用了我們早已指出的一個架構缺陷。
這並非算法層面的漏洞,而是一個更隱蔽、更 “精妙” 的問題:協議層的邏輯缺陷,它利用了存在漏洞的狀態機,讓協議對自身狀態產生了誤判。
接下來,我們將拆解攻擊路徑、漏洞原理,以及為何任何理解 V2 架構核心風險的人,本應能預見這場危機。
核心總結
- 事件經過: Balancer V2 金庫操作中存在授權缺陷或狀態完整性漏洞,導致其內部賬本被篡改。
- 影響範圍: 主網及分叉項目共計約 1.28 億美元資產被盜。
- 根本原因: 金庫多調用操作期間,狀態控制機制不完善,攻擊者藉此突破了金庫與資金池的信任邊界。
- 受影響對象: Balancer V2 及其分叉項目。
- 未受影響對象: Balancer V3—— 其原子記賬模型可防範此類漏洞攻擊。
- 核心教訓: 審計需針對跨合約信任邊界及隱式狀態轉換進行測試。
架構背景:單例金庫與 “信任邊界”
要理解這次漏洞利用,必須先搞懂 Balancer V2 的架構。它的核心設計基於兩個概念:
- 單例金庫(Vault.sol):一個單獨的大型合約,託管着所有 Balancer V2 資金池(Pool)的資產,相當於 “銀行” 的角色。
- 外部資金池合約(如 LinearPool.sol): 獨立的外部合約,僅包含業務邏輯(即 AMM 算法),自身不持有任何資產。
當你執行兑換(swap)操作時,金庫會先接收你的代幣,然後向對應的資金池合約發起外部回調(如onSwap函數)。本質上是在問:“我收到了 100 枚 WETH,應該返還多少枚 osETH?” 資金池完成計算後,會將結果返回給金庫。
這就形成了一個關鍵的信任邊界:持有資產的金庫,必須信任僅含邏輯的資金池。這 1.28 億美元資產的安全,完全依賴於這套回調機制的可靠性。
另一個關鍵設計是 “內部用户餘額” 系統。為節省 Gas 費,金庫不會在每一步操作中都執行 ERC-20 轉賬,而是通過一個內部的mapping(address => uint256)
賬本更新餘額。攻擊者的最終目標,並非直接盜取代幣,而是讓這個賬本寫入一條虛假的餘額記錄。
根本原因:狀態機漏洞
早期報告推測漏洞是通過資金池onSwap 函數調用initialize() 引發的重入,但鏈上證據顯示,漏洞更可能是利用了金庫用户餘額流程中的授權缺陷或內部餘額不一致問題。不過,核心架構問題 —— 金庫與資金池邏輯間脆弱的信任邊界 —— 並未改變。
核心漏洞很可能是金庫在處理多調用(multi-call)操作時,存在授權缺陷或狀態完整性問題。
攻擊者似乎瞄準了金庫內部餘額管理系統中可能存在的授權漏洞,可能在金庫與資金池的回調交互過程中,利用了跨合約重入或權限提升的漏洞。
架構層面的缺陷在於:開發者可能為正常操作流程設置了完善的訪問控制,但未能預見覆雜的多調用場景 —— 在這類場景中,特權操作可能會在執行過程中被非法調用。
這一漏洞表明,系統中存在未被妥善保護的 “隱式狀態”:
- 狀態 A:閒置(等待外部調用)
- 狀態 B:執行中(處於多調用操作的執行過程中)
關鍵操作在狀態 A 下受到保護,但在狀態 B 的複雜狀態切換過程中,卻可能處於暴露狀態。
攻擊鏈:如何 “欺騙” 金庫
攻擊者的執行過程堪稱 “完美”。以下是推測的分步邏輯鏈:
準備階段
攻擊者通過金庫發起了一系列多調用操作,可能利用了金庫與資金池合約間複雜的交互模式。
觸發漏洞
在多調用序列執行過程中,攻擊者很可能觸發了一種 “狀態不一致”—— 通過不完整的授權校驗,操縱金庫的內部餘額管理系統。
權限提升
由於缺失狀態驗證,一條特權邏輯路徑在操作中途被非法調用。這意味着,攻擊者在複雜的回調序列中,利用了金庫與資金池之間的信任邊界。
狀態篡改(致命一步)
授權漏洞讓攻擊者得以操縱金庫的內部餘額追蹤系統。
該漏洞可能允許攻擊者通過特權操作,指令金庫將自己的內部用户餘額設置為一個極高的虛假數值(例如 6500 枚 WETH)。
而金庫由於授權校驗被繞過,會乖乖更新內部賬本:
internalBalances[攻擊者地址] = 6500e18 (即 6500 枚 WETH 對應的最小單位數值)。
收尾階段
惡意操作序列順利完成,金庫的內部狀態被永久篡改,但表面上看,整個執行過程完全正常。
常規提取
在另一筆看似無異常的獨立交易中,攻擊者調用了標準的exitPool (退出資金池)或提取函數。
資產轉移
金庫檢查了已被篡改的賬本,確認攻擊者擁有 6500 枚 WETH 的 “餘額”,隨後便盡職盡責地將真實的 WETH 從合約中轉移到攻擊者的錢包。
這次攻擊並非 “盜竊”,而是 “欺詐”—— 攻擊者先騙金庫開出一張虛假的存款憑證,再讓金庫用真實資產兑現這張憑證。
“分叉炸彈”:為何 Berachain 暫停了整條 L1 鏈
對研究人員而言,漏洞的影響範圍往往比漏洞本身更可怕。這個漏洞存在於 Balancer V2 的核心代碼庫中,這意味着所有分叉(fork)了 V2 代碼的協議,都面臨同樣的風險。
- Beets Finance: 被盜走數百萬美元資產。
- Berachain: 情況更為特殊。Berachain 的原生去中心化交易所 BEX,正是 Balancer V2 的分叉版本。這個漏洞不僅存在於鏈上的某個應用,更存在於其 L1 區塊鏈 DeFi 生態的底層基礎設施中。
因此,Berachain 被迫採取了最極端的措施:暫停整條 Layer 1 區塊鏈。這是唯一能阻止攻擊者盜取 BEX 資產、並讓驗證者有時間通過緊急硬分叉修復應用層漏洞的方法。這一事件也成為 “應用層風險升級為共識層故障” 的典型案例。
為何 Balancer V3 安然無恙
V3 的 “原子化 BPT 與代幣記賬模型” 恰好填補了這個漏洞。
由於所有內部狀態變更都在金庫內部以原子化方式完成(得益於瞬時記賬和統一的 BPT 管理),資金池無法在操作執行過程中通過重入篡改金庫餘額。
這種設計升級,印證了 Balancer 在架構上的改進價值 —— 也凸顯出審計工作不僅要檢查 “函數級邏輯”,更要審視 “系統級狀態完整性”。
“早有預警”:數週前已指出該風險
儘管這次漏洞利用的具體機制具有新意,但本不應令人意外。它所利用的架構缺陷,正是我在10 月 16 日 Balancer AMM 架構分析中強調的風險點。
任何讀過該分析的審計人員或開發者,都應高度警惕這類漏洞。以下是攻擊發生前數週就已準確指出的內容:
- 風險區域: V2 的回調機制。該分析明確指出了 V2 架構回調系統中的漏洞風險。儘管當時重點討論的是已知的重入路徑,但核心缺陷完全一致 —— 回調過程中金庫與資金池合約間脆弱的信任邊界。
- 跨合約信任假設的缺陷。 該分析的核心觀點是,V2 設計存在危險的跨合約信任假設。而這次漏洞利用,正是這一觀點的 “完美例證”:金庫(資產管理者)在複雜操作中信任了資金池邏輯,攻擊者則利用這一信任篡改了金庫的內部狀態。
- V2 與 V3 的安全差異。 分析中已明確指出,V3 架構是解決該問題的方案 —— 其原子化的代幣與 BPT 管理機制,能緩解這類狀態篡改風險。事後分析也證實了這一點:V3 資金池完全未受影響。
這是一個發人深省的教訓:安全分析的目標不僅是發現已知漏洞,更要識別架構層面的缺陷。V2 的回調模型本就是已知的薄弱環節,而 11 月 3 日,攻擊者只是從我們早已指出的 “未上鎖的門” 走了進去。
審計視角的核心啓示
這次漏洞事件為所有 Solidity 開發者和審計人員提供了三個關鍵教訓:
- 授權校驗必須 “上下文感知”。 此次漏洞可能表明,為正常操作流程設計的訪問控制,在複雜多調用場景中可能失效。關鍵函數不僅要驗證 “誰在調用”,還要驗證 “何時調用” 以及 “在何種條件下調用”。
- 顯式狀態機優於隱式假設。 該漏洞表明,系統中存在未被妥善保護的隱式狀態。這類漏洞可通過 “顯式狀態管理” 避免 —— 確保所有特權操作都會校驗當前系統狀態。
- 分叉審計過的代碼,仍需承擔風險。 Beets 和 Berachain 團隊都分叉了 “久經考驗” 的代碼,但這一事件提醒我們:分叉並非安全捷徑。你會 100% 繼承原協議中潛在的漏洞,因此對分叉代碼進行獨立審計,是必不可少的步驟。
原文:https://www.zealynx.io/blogs/balancer-v2-128m
作者:@ZealynxSecurity
(OpenBuild 翻譯整理,原文有刪減)