Back to Blog

GMX 安全事件 #4:跨合約重入攻擊繞過四年前的防禦機制

Code Auditing
February 10, 2026
7 min read

2025 年 7 月 9 日,去中心化永續合約平台 GMX 遭遇攻擊 [1, 2],該攻擊針對其部署在 Arbitrum 網路上的 V1 合約,造成約 4,200 萬美元的損失。攻擊者利用跨合約重入漏洞操控了 GLP 價格,隨後利用價格偏差從 GMX V1 的流動性池中抽走底層資產。

背景

GMX V1 [3] 是一個部署在 Arbitrum 上的去中心化永續合約交易平台。它允許使用者以無需許可和非託管的方式,對多種加密資產進行槓桿永續合約交易。GMX V1 採用單一多資產池設計,所有支援資產的流動性都被匯集到一個統一的 Vault(金庫)系統中。

GMX 中的部位管理

GMX 的部位管理是一個兩步走的過程。具體而言,使用者透過與 OrderBookPositionRouter 合約互動來創建增加/減少部位的訂單。接著,授權的 Keeper 帳戶執行使用者的訂單,這會更新 ShortTracker 合約中的全域空頭數據以及 Vault 合約的神經狀態。下圖展示了管理 GMX 部位的兩條執行路徑(訂單簿執行路徑路由執行路徑)。在此次事件中,攻擊者利用了這兩條路徑來操縱全域空頭數據並獲取利潤。

訂單簿執行路徑

路由執行路徑

GMX Vault

GMX 中的 Vault 合約負責管理使用者的部位和資產(例如,結算損益)。為了避免惡意互動,Vault 合約僅在「槓桿視窗」開啟時才可存取(即透過 Timelock.enableLeverage() 函數將 Vault 合約中的 isLeverageEnabled 變數設為 true)。此驗證機制強制要求訂單執行必須遵循固定的路徑(訂單簿執行路徑路由執行路徑)。

GMX Short Tracker

ShortTracker 合約負責在訂單執行期間跟蹤和更新全域空頭數據(例如 globalShortAveragePrice 變數)。根據訂單簿執行路徑路由執行路徑ShortTracker 合約的 updateGlobalShortData() 函數會在執行使用者訂單前被調用,以同步最新的全域空頭數據。此步驟確保使用者部位的損益實現正確。

減少 WETH 部位

與其他訂單不同,透過訂單簿執行路徑減少 WETH 部位將會調用 OrderBook 合約中的 _transferOutETH() 函數,以提取 WETH 代幣並將原生 ETH 代幣轉移給使用者。如果接收者 _receiver 是一個合約,sendValue() 可能會觸發該合約的 fallback() 函數,進而引發潛在的重入漏洞。在此次事件中,攻擊者多次利用此重入漏洞來獲取巨額利潤。

GLP 代幣

GLP(GMX 流動性提供者)代幣代表 Vault 合約中多種資產的統一份額。使用者可以透過鑄造和銷毀 GLP 來提供和贖回資產。

GLP 價格的計算公式如下:

GLPPrice=AUMGLPTotalSupply\text{GLPPrice}= \frac{\text{AUM}}{\text{GLPTotalSupply}}

AUM=i=asset[0]assets(ΔGlobalShort[i]+AUMOther[i])\text{AUM} = \sum^{assets}_{i = asset[0]}(\Delta_{\text{GlobalShort[i]}} + \text{AUM}_{\text{Other[i]}})

ΔGlobalShort[i]=globalShortSize×(AssetMarketPriceglobalShortAveragePrice)globalShortAveragePrice\Delta_{\text{GlobalShort[i]}} = \frac{ \text{globalShortSize} \times (\text{AssetMarketPrice} - \text{globalShortAveragePrice} ) }{ \text{globalShortAveragePrice} }

其中:

  • GLPTotalSupply 代表 GLP 代幣的總供給量。
  • AUM 由以下兩個部分組成:
    • ΔGlobalShort\Delta_{\text{GlobalShort}} 代表所有空頭部位的 uPnL(即未實現損益)。
    • AUMOther\text{AUM}_{\text{Other}} 代表流動性提供者提供的流動性加上所有多頭部位的未實現損益。在利潤實現之前,該項在整個事件中保持幾乎不變。
  • AssetMarketPrice 是底層資產的市場價格(以美元計)。
  • globalShortSize 是所有空頭部位的總和(以美元計)。
  • globalShortAveragePrice 是彙總全域空頭部位的平均開倉價格。

在此次事件中,攻擊者扭曲了 globalShortAveragePrice 以操縱 GLP 價格並提取利潤。

漏洞分析

根本原因是 OrderBook 合約中存在跨合約重入漏洞。如背景中所述,透過訂單簿執行路徑減少 WETH 部位會透過 _transferOutETH() 觸發對接收者的底層 fallback 調用。該函數帶有 nonReentrant 修飾符,但此保護措施僅防止 OrderBook 合約內部的重入,無法防止對 Vault 的跨合約調用。

在正常運作下,VaultincreasePosition() 只能透過 PositionRouterPositionManager 調用,這兩者會在每次部位變動前調用 ShortTracker 以更新 globalShortAveragePrice。攻擊者建立了一個以惡意合約為接收者的訂單,並在 fallback 調用期間,直接在 Vault 上調用 increasePosition(),繞過了 PositionRouter/PositionManager 以及相關的 ShortTracker 更新。透過在不更新 globalShortAveragePrice 的情況下重複開倉和關閉空頭部位,攻擊者逐漸扭曲了該變數。扭曲後的數據推高了 GLP 價格,使攻擊者能夠透過鑄造和贖回 GLP 獲取利潤。

攻擊分析

攻擊者發起了一系列交易來操縱全域空頭數據並實現獲利。具體而言,此事件可分為三個階段:準備階段價格操縱階段利潤實現階段。所有相關交易列於下表:

Tx No. 階段 描述 交易哈希 時間 (UTC)
1 準備 部署攻擊合約 0xa4ece5...8cd4c93f 2025/07/09 12:16:32 PM
2 建立 WETH 多頭增加訂單 0x0b8cd6...e90a4712 2025/07/09 12:22:28 PM
3 執行 WETH 多頭增加訂單 0x28a000...7bf0beef 2025/07/09 12:23:23 PM
4 建立 WETH 多頭減少訂單 0x20abfe...decc49af 2025/07/09 12:24:56 PM
5 價格操縱 1 執行 WETH 多頭減少訂單 0x1f00da...6a4a7353 2025/07/09 12:25:37 PM
6 執行 WBTC 空頭減少訂單 0x222cda…c994464e 2025/07/09 12:25:43 PM
7 價格操縱 2 同交易 5 0xc9a469...221293c2 2025/07/09 12:26:25 PM
8 同交易 6 0x1cbf25...d853943a 2025/07/09 12:26:30 PM
9 價格操縱 3 同交易 5 0xb58415...3b4cfb0b 2025/07/09 12:27:22 PM
10 同交易 6 0x5a37ff...cb59c3b7 2025/07/09 12:27:28 PM
11 價格操縱 4 同交易 5 0xff6fe6...377bf108 2025/07/09 12:28:13 PM
12 同交易 6 0xbd65d6...e0187be6 2025/07/09 12:28:18 PM
13 價格操縱 5 同交易 5 0x105273...19fcdec6 2025/07/09 12:29:12 PM
14 同交易 6 0x0cdbac...84339fcc 2025/07/09 12:29:17 PM
15 利潤實現 實現利潤 0x03182d....a32626ef 2025/07/09 12:30:11 PM
16 退款 向攻擊者留言 0x92a39e...89547380 2025/07/09 02:04:19 PM
17 回應 GMX 協議 0x1d806c...919feac0 2025/07/11 06:29:00 AM
18 回應攻擊者 0x9c4ca9...39fa27fc 2025/07/11 07:42:17 AM
19 退款 0x62b845...99211841 2025/07/11 08:04:34 AM
20 退款 0x255d0a...9321b3 2025/07/11 08:08:27 AM
21 退款 0xceafc3...a6313b22 2025/07/11 10:17:23 AM

準備階段

  1. (Tx 1) 攻擊者部署了攻擊合約,該合約在訂單執行期間作為資產接收者。攻擊合約中包含一個惡意的 fallback() 函數。
  2. (Tx 2) 攻擊者在 OrderBook 合約中為其攻擊合約創建了一個 WETH 多頭增加訂單。
  3. (Tx 3) Keeper 執行了攻擊者的增加訂單,為攻擊合約開啟了一個 WETH 多頭部位。
  4. (Tx 4) 攻擊者在 OrderBook 合約中為其攻擊合約創建了一個 WETH 多頭減少訂單。

操縱階段

  1. (Tx 5) Keeper 透過訂單簿執行路徑執行了攻擊合約的 WETH 多頭減少訂單。該執行路徑調用了 _transferOutETH(),觸發了攻擊合約中的惡意 fallback() 函數。 由於在「槓桿視窗」期間調用了 fallback(),攻擊合約在不更新 globalShortAveragePrice 的情況下,與 Vault 合約直接互動以開啟 WBTC 空頭部位(透過 increasePosition()),隨後創建了一個 WBTC 空頭減少/平倉訂單。
  2. (Tx 6) Keeper 透過路由執行路徑執行了 WBTC 空頭減少訂單。該執行過程還透過 PositionRouter 合約中的 fallback 機制創建了一個 WETH 多頭減少訂單。由於開啟 WBTC 空頭部位時未更新 globalShortAveragePrice,在更新該變數的同時平倉導致 globalShortAveragePrice 出現異常下跌。
  3. (Tx 7-14) 攻擊者重複上述 5-6 步驟 4 次。結果導致 globalShortAveragePrice1.08e35 扭曲至 1.9e33

利潤實現階段

  1. (Tx 15) Keeper 透過訂單簿執行路徑執行了 WETH 多頭減少訂單。由於 OrderBook 合約存在重入漏洞,此執行觸發了攻擊合約中的利潤實現邏輯:
    1. 在 fallback 調用中,攻擊合約首先借入 7,538,567e18 USDC 的閃電貸。
    2. 攻擊合約調用 mintAndStakeGlp(),使用 6,000,000e18 USDC 鑄造 4,129,578e18 GLP。
    3. 攻擊合約調用 Vault.increasePosition(),用剩餘的 1,538,567e18 USDC 開啟 WBTC 空頭部位。由於 WBTC 的全域空頭數據被嚴重扭曲,訂單執行顯著擴大了 AUM,導致 GLP 價格急劇上漲。
    4. 攻擊合約調用 unstakeAndRedeemGlp(),以被放大後的價格將 GLP 贖回為 Vault 合約中的多種資產。
    5. 攻擊合約調用 Vault.decreasePosition() 平掉 WBTC 空頭部位。
    6. 攻擊合約重複上述 8.b-8.e 步驟四次,抽幹了 Vault 合約中的所有資產。
    7. 攻擊合約歸還閃電貸,獲得近 4,200 萬美元利潤。

退款

透過與攻擊者的談判(Tx 16-18),攻擊者最終同意收取 10% 的賞金並歸還剩餘的被盜資產(Tx 19-21)。

總結

此事件是對位於 Arbitrum 上的 GMX V1 進行的多階段攻擊,造成了約 4,200 萬美元的損失。攻擊者濫用了 OrderBook 合約上的重入漏洞,扭曲了 globalShortAveragePrice 變數並操縱了 GLP 價格。透過利用被操縱的價格,攻擊者抽走了大量資產。

關鍵教訓:

  • 跨合約重入: 在單一合約上的 nonReentrant 修飾符並不能防止進入同一系統內其他合約的重入。當外部呼叫在旗標(例如「槓桿視窗」)重置之前發生時,依賴臨時旗標的存取控制機制可能會被繞過。
  • 營運安全性: 攻擊者分三個不同的階段對協議進行了利用,共執行了 15 筆交易。此事件凸顯了即時監控、及時警報和有效緩解策略手冊的關鍵需求。

參考資料

  1. https://x.com/GMX_IO/status/1942955807756165574
  2. https://x.com/GMX_IO/status/1943336664102756471
  3. GMX V1

關於 BlockSec

BlockSec 是全端區塊鏈安全與加密貨幣合規服務提供者。我們構建各類產品與服務,協助客戶執行程式碼審計(包括智慧合約、區塊鏈與錢包)、即時攔截攻擊、分析安全事件、追蹤非法資金,並在協議與平台的完整生命週期中履行反洗錢/反恐融資(AML/CFT)義務。

BlockSec 已在各大頂級會議發表多篇區塊鏈安全論文,披露了多個 DeFi 應用的零日漏洞,攔截了數次攻擊並挽救了超過 2,000 萬美元的資產,累積保護了數十億美元的加密貨幣資產。

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit