2025年7月9日、分散型パーペチュアルプラットフォームであるGMXは、Arbitrumネットワーク上のV1コントラクトを標的としたエクスプロイト(約4200万ドルの損失)が発生しました [1, 2]。攻撃者はクロスコントラクトのリエントランシー脆弱性を悪用してGLP価格を操作し、その歪んだ価格を用いてGMX V1の流動性プールから基盤資産を不正に引き出しました。
背景
GMX V1 [3]は、Arbitrum上に展開された分散型パーペチュアル取引プラットフォームです。ユーザーは、レバレッジをかけた複数の暗号資産のパーペチュアルコントラクトを、パーミッションレスかつノンカストディアルな方法で取引できます。GMX V1は、単一のマルチアセットプール設計を採用しており、サポートされているすべての資産の流動性が単一のVaultシステムに集約されています。
GMXにおけるポジション管理
GMXのポジション管理は2段階のプロセスです。具体的には、ユーザーはOrderBookまたはPositionRouterコントラクトと対話することで、増減注文を作成します。その後、認証されたキーパーアカウントがユーザーの注文を実行し、ShortTrackerコントラクトのグローバルショートデータとVaultコントラクトの対応する状態が更新されます。以下の2つの図は、GMXでポジションを管理するための2つの実行パス(orderbook-executionおよびrouter-executionパス)を示しています。このインシデントでは、攻撃者は両方のパスを使用してグローバルショートデータを操作し、利益を実現しました。
Orderbook-executionパス
Router-executionパス
GMX Vault
GMXのVaultコントラクトは、ユーザーのポジションと資産(例:損益の確定)の管理を担当します。悪意のあるインタラクションを回避するため、Vaultコントラクトは「レバレッジウィンドウ」が開いている場合(つまり、Vaultコントラクトの変数isLeverageEnabledがTimelock.enableLeverage()関数を介してtrueに設定されている場合)のみアクセス可能です。この検証により、注文実行は固定パス(orderbook-executionおよびrouter-execution)に従う必要があります。
GMX Short Tracker
ShortTrackerコントラクトは、注文実行中にグローバルショートデータ(例:変数globalShortAveragePrice)の追跡と更新を担当します。orderbook-executionおよびrouter-executionパスによると、ShortTrackerコントラクトのupdateGlobalShortData()関数は、最新のグローバルショートデータを同期するために、ユーザーの注文を実行する前に呼び出されます。このステップにより、ユーザーのポジションの正確な損益実現が保証されます。
WETHポジションの減少
他の注文とは異なり、orderbook-executionパスを介してWETHポジションを減少させると、OrderBookコントラクトの_transferOutETH()関数が呼び出され、WETHトークンが引き出され、ネイティブETHトークンがユーザーに転送されます。受信者_receiverがコントラクトである場合、sendValue()はコントラクトのfallback()関数をトリガーする可能性があり、潜在的なリエントランシー脆弱性を導入します。このインシデントでは、攻撃者はこのリエントランシー脆弱性を繰り返し悪用して、多額の利益を引き出しました。
GLPトークン
GLP(GMX Liquidity Provider)トークンは、Vaultコントラクト内のさまざまな資産の統合されたシェアを表します。ユーザーは、GLPをミントおよびバーンすることによって資産を提供および償還できます。
GLP価格は、次の式で計算できます。
ここで:
GLPTotalSupplyはGLPトークンの総供給量を示します。AUMは次の2つのコンポーネントで構成されます。- は、すべてのショートポジションのuPnL(つまり、未実現損益)を表します。
- は、LPの提供流動性プラス、すべてのロングポジションの未実現uPnLを表します。この項は、利益実現前はインシデント全体を通してほぼ一定でした。
AssetMarketPriceは、基盤資産の市場価格(USD建て)です。globalShortSizeは、すべてのショートポジションの合計(USD建て)です。globalShortAveragePriceは、集約されたグローバルショートポジションの平均エントリー価格です。
このインシデントでは、攻撃者はglobalShortAveragePriceを操作してGLP価格を操作し、利益を引き出しました。
脆弱性分析
根本原因は、OrderBookコントラクトのクロスコントラクトリエントランシー脆弱性です。背景で説明したように、orderbook-executionパスを介してWETHポジションを減少させると、_transferOutETH()を介して受信者への低レベルのフォールバックコールがトリガーされます。この関数にはnonReentrant修飾子がありますが、このガードはOrderBookコントラクト自体のリエントランシーを防ぐだけで、Vaultへのクロスコントラクトコールは防ぎません。
通常の操作では、VaultのincreasePosition()はPositionRouterおよびPositionManagerを介してのみ呼び出すことができ、これらは各ポジション変更の前にShortTrackerを呼び出してglobalShortAveragePriceを更新します。攻撃者は、攻撃コントラクトを受信者として注文を作成し、フォールバックコールの間に、PositionRouter/PositionManagerおよび関連するShortTrackerの更新をバイパスして、直接VaultのincreasePosition()を呼び出しました。globalShortAveragePriceを更新せずにショートポジションを繰り返し開閉することにより、攻撃者は徐々に変数を歪めました。歪んだ値はGLP価格を膨張させ、攻撃者がGLPをミントおよび償還することによって利益を引き出すことを可能にしました。
攻撃分析
攻撃者は、グローバルショートデータを操作し、利益を実現する一連のトランザクションを開始しました。具体的には、このインシデントは「準備」「価格操作」「利益実現」の3つのフェーズに分けることができます。関連するトランザクションは次の表にリストされています。
| Tx No. | フェーズ | 説明 | トランザクション | 時間 (UTC) |
|---|---|---|---|---|
| 1 | 準備 | 攻撃コントラクトをデプロイ | 0xa4ece5...8cd4c93f | 2025年7月9日 12:16:32 |
| 2 | WETHロングポジション増加注文を作成 | 0x0b8cd6...e90a4712 | 2025年7月9日 12:22:28 | |
| 3 | WETHロングポジション増加注文を実行 | 0x28a000...7bf0beef | 2025年7月9日 12:23:23 | |
| 4 | WETHロングポジション減少注文を作成 | 0x20abfe...decc49af | 2025年7月9日 12:24:56 | |
| 5 | 価格操作 1 | WETHロングポジション減少注文を実行 | 0x1f00da...6a4a7353 | 2025年7月9日 12:25:37 |
| 6 | WBTCショートポジション減少注文を実行 | 0x222cda…c994464e | 2025年7月9日 12:25:43 | |
| 7 | 価格操作 2 | Tx 5 と同じ | 0xc9a469...221293c2 | 2025年7月9日 12:26:25 |
| 8 | Tx 6 と同じ | 0x1cbf25...d853943a | 2025年7月9日 12:26:30 | |
| 9 | 価格操作 3 | Tx 5 と同じ | 0xb58415...3b4cfb0b | 2025年7月9日 12:27:22 |
| 10 | Tx 6 と同じ | 0x5a37ff...cb59c3b7 | 2025年7月9日 12:27:28 | |
| 11 | 価格操作 4 | Tx 5 と同じ | 0xff6fe6...377bf108 | 2025年7月9日 12:28:13 |
| 12 | Tx 6 と同じ | 0xbd65d6...e0187be6 | 2025年7月9日 12:28:18 | |
| 13 | 価格操作 5 | Tx 5 と同じ | 0x105273...19fcdec6 | 2025年7月9日 12:29:12 |
| 14 | Tx 6 と同じ | 0x0cdbac...84339fcc | 2025年7月9日 12:29:17 | |
| 15 | 利益実現 | 利益を実現 | 0x03182d....a32626ef | 2025年7月9日 12:30:11 |
| 16 | 返金 | 攻撃者にメッセージ | 0x92a39e...89547380 | 2025年7月9日 14:04:19 |
| 17 | GMXプロトコルへの応答 | 0x1d806c...919feac0 | 2025年7月11日 06:29:00 | |
| 18 | 攻撃者への応答 | 0x9c4ca9...39fa27fc | 2025年7月11日 07:42:17 | |
| 19 | 返金 | 0x62b845...99211841 | 2025年7月11日 08:04:34 | |
| 20 | 返金 | 0x255d0a...9321b3 | 2025年7月11日 08:08:27 | |
| 21 | 返金 | 0xceafc3...a6313b22 | 2025年7月11日 10:17:23 |
準備フェーズ
-
(Tx 1) 攻撃者は、注文実行中に資産受信者として使用される攻撃コントラクトをデプロイしました。攻撃コントラクトには悪意のある
fallback()関数が含まれていました。 -
(Tx 2) 攻撃者は、
OrderBookコントラクトで、攻撃コントラクト向けのWETHロングポジション増加注文を作成しました。
-
(Tx 3) キーパーが(ステップ2で作成された)攻撃者の増加注文を実行し、攻撃コントラクトのWETHロングポジションを開設しました。(Tx 3)。
-
(Tx 4) 攻撃者は、
OrderBookコントラクトで、攻撃コントラクト向けのWETHロングポジション減少注文を作成しました。
操作フェーズ
-
(Tx 5) キーパーが、orderbook-executionパスを介して、攻撃コントラクトの減少WETHロング注文(ステップ4で作成)を実行しました。この実行により、攻撃コントラクトの悪意のある
fallback()関数がトリガーされました。fallback()は「レバレッジウィンドウ」中に呼び出されたため、攻撃コントラクトはVaultコントラクトと直接対話してWBTCショートポジションを(increasePosition()を介して)開設し、その前にglobalShortAveragePriceを更新しませんでした。その後、WBTCショートポジションの減少/クローズ注文を作成しました。
-
(Tx 6) キーパーが、router-executionパスを介して、WBTCショートポジション減少注文(ステップ5で作成)を実行しました。この実行により、
PositionRouterコントラクトのフォールバックメカニズムを介して、減少WETHロング注文も作成されました。WBTCショートポジションは
globalShortAveragePriceを更新せずに開設されたため、この変数を更新しながらポジションをクローズすると、globalShortAveragePriceの予期せぬ低下が発生しました。
-
(Tx 7-14) 攻撃者はステップ5-6を4回繰り返しました。その結果、
globalShortAveragePriceは1.08e35から1.9e33に歪みました。
利益実現フェーズ
-
(Tx 15) キーパーが、orderbook-executionパスを介して、減少WETHロング注文(Tx 14で作成)を実行しました。この実行により、
OrderBookコントラクトのリエントランシー脆弱性のため、攻撃コントラクトの利益実現ロジックがトリガーされました。
-
フォールバック呼び出し中に、攻撃コントラクトはまず7,538,567e18 USDCのフラッシュローンを借りました。
-
攻撃コントラクトは
mintAndStakeGlp()を呼び出し、6,000,000e18 USDCを使用して4,129,578e18 GLPをミントしました。 -
攻撃コントラクトは
Vault.increasePosition()を呼び出し、残りの1,538,567e18 USDCでWBTCショートポジションを開設しました。WBTCのグローバルショートデータが極端に歪んでいたため、注文実行はAUMを大幅に増幅させ、GLP価格を急上昇させました。 -
攻撃コントラクトは
unstakeAndRedeemGlp()を呼び出し、Vaultコントラクト内の複数の資産の増幅された価格でGLPを償還しました。 -
攻撃コントラクトは
Vault.decreasePosition()を呼び出し、WBTCショートポジションをクローズしました。 -
攻撃コントラクトはステップ8.b-8.eを4回繰り返し、
Vaultコントラクト内のすべての資産を吸い上げました。 -
攻撃コントラクトはフラッシュローンを返済し、約4200万ドルの利益を得ました。
-
返金
攻撃者との交渉(Tx 16-18)を経て、攻撃者は最終的に10%のバウンティを受け入れ、残りの盗まれた資産を返却しました(Tx 19-21)。
まとめ
このインシデントは、Arbitrum上のGMX V1に対する多段階エクスプロイトであり、推定4200万ドルの損失につながりました。攻撃者はOrderBookコントラクトのリエントランシー脆弱性を悪用してglobalShortAveragePrice変数を歪め、GLP価格をインフレさせました。操作された価格を利用して、攻撃者は相当量の資産を不正に引き出しました。
主な教訓:
- クロスコントラクトリエントランシー: 単一コントラクト上の
nonReentrant修飾子は、同じシステム内の他のコントラクトへのリエントランシーを防ぐものではありません。一時的なフラグ(例:「レバレッジウィンドウ」)に依存するアクセス制御メカニズムは、フラグがリセットされる前に外部コールが発生した場合にバイパスされる可能性があります。 - 運用セキュリティ: この攻撃者は、3つの別個のフェーズでプロトコルを悪用し、合計15件のトランザクションを実行しました。このインシデントは、リアルタイム監視、迅速なアラート、および効果的な緩和プレイブックの極めて重要な必要性を強調しています。
参照
- https://x.com/GMX_IO/status/1942955807756165574
- https://x.com/GMX_IO/status/1943336664102756471
- GMX V1
BlockSecについて
BlockSecは、フルスタックのブロックチェーンセキュリティおよび暗号コンプライアンスプロバイダーです。当社は、コード監査(スマートコントラクト、ブロックチェーン、ウォレットを含む)、リアルタイムでの攻撃傍受、インシデント分析、不正資金追跡、およびAML/CFT義務の遵守を、プロトコルおよびプラットフォームのライフサイクル全体にわたって支援する製品とサービスを構築しています。
BlockSecは、著名なカンファレンスで複数のブロックチェーンセキュリティ論文を発表し、DeFiアプリケーションのゼロデイ攻撃を複数報告し、複数回ハッキングを阻止して2000万ドル以上を救済し、数十億ドルの暗号資産を確保しました。
-
公式ウェブサイト: https://blocksec.com/
-
公式Twitterアカウント: https://twitter.com/BlockSecTeam



