Back to Blog

#4 GMX Incident: Cross-Contract Reentrancy Bypasses a Four-Year-Old Guard

Code Auditing
February 10, 2026

On July 9, 2025, the decentralized perpetual platform GMX experienced an exploit [1, 2] targeting their V1 contract on the Arbitrum network, resulting in a loss of approximately $42 million. The attacker exploited a cross-contract reentrancy vulnerability to manipulate the GLP price, then used the distorted price to siphon underlying assets from GMX V1's liquidity pools.

Background

GMX V1 [3] is a decentralized perpetuals trading platform deployed on Arbitrum. It allows users to trade perpetual contracts on multiple crypto assets with leverage in a permissionless and non-custodial manner. GMX V1 follows a single multi-asset pool design, where liquidity for all supported assets is aggregated into a unified Vault system.

Position Management in GMX

The position management in GMX is a two-step process. Specifically, users create increase/decrease orders via interacting with the contracts OrderBook or PositionRouter. Then, the authorized keeper account executes users' orders, which updates the global short data in the contract ShortTracker and the corresponding state of the contract Vault. The following two figures demonstrate the two execution paths (the orderbook-execution and router-execution paths) for managing positions in GMX. In this incident, the attacker used both paths to manipulate the global short data and realize profits.

The Orderbook-execution Path

The Router-execution Path

GMX Vault

The contract Vault in GMX is responsible for managing users' positions and assets (e.g., finalizing the profit and loss). To avoid malicious interactions, the contract Vault is only accessible when the "leverage window" is opened (i.e., the variable isLeverageEnabled in the contract Vault is set to true via the function Timelock.enableLeverage()). This validation enforces that order execution must follow the fixed paths (orderbook-execution and router-execution).

GMX Short Tracker

The contract ShortTracker is responsible for tracking and updating the global short data (e.g., the variable globalShortAveragePrice) during the order execution. According to the orderbook-execution and router-execution paths, the function updateGlobalShortData() of the contract ShortTracker is invoked before executing users' orders to sync the latest global short data. This step ensures correct profit and loss realization for users' positions.

Decreasing WETH Position

Different from other orders, decreasing the WETH position via the orderbook-execution path will invoke the function _transferOutETH() in the contract OrderBook to withdraw WETH tokens and transfer the native ETH tokens to users. If the recipient _receiver is a contract, sendValue() could trigger the contract's fallback() function, introducing a potential reentrancy vulnerability. In this incident, the attacker repeatedly exploited this reentrancy vulnerability to extract significant profits.

GLP Token

The GLP (GMX Liquidity Provider) token represents the unified shares for various assets in the contract Vault. Users are allowed to provide and redeem assets by minting and burning GLPs.

The GLP price could be calculated in the following equations:

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} }

Where:

  • GLPTotalSupply represents the total supply of the GLP tokens.
  • AUM consists of the following two components.
    • ΔGlobalShort\Delta_{\text{GlobalShort}} represents the uPnL (i.e., unrealized Profit and Loss) of all short positions.
    • AUMOther\text{AUM}_{\text{Other}} represents the provided liquidity of the LP plus the unrealized uPnL of all long positions. This term remained nearly unchanged throughout the incident prior to profit realization.
  • AssetMarketPrice is the market price (in USD) of the underlying asset.
  • globalShortSize is the sum (in USD) of all short positions.
  • globalShortAveragePrice is the average entry price of the aggregated global short position.

In this incident, the attacker skewed globalShortAveragePrice to manipulate the GLP price and extract profits.

Vulnerability Analysis

The root cause is a cross-contract reentrancy vulnerability in the contract OrderBook. As described in Background, decreasing WETH positions via the orderbook-execution path triggers a low-level fallback call to the receiver through _transferOutETH(). The function carries a nonReentrant modifier, but this guard only prevents reentrancy within the OrderBook contract itself, not cross-contract calls to the Vault.

Under normal operation, the Vault's increasePosition() can only be called through PositionRouter and PositionManager, which invoke ShortTracker to update globalShortAveragePrice before each position change. The attacker created orders with a malicious contract as the receiver, and during the fallback call, directly called increasePosition() on the Vault, bypassing PositionRouter/PositionManager and the associated ShortTracker update. By repeatedly opening and closing short positions without updating globalShortAveragePrice, the attacker progressively skewed the variable. The distorted value inflated the GLP price, allowing the attacker to extract profits by minting and redeeming GLPs.

Attack Analysis

The attacker launched a series of transactions manipulating the global short data and realizing the profit. Specifically, this incident could be divided into three phases: Preparation, Price Manipulation, and Profit Realization. All related transactions are listed in the following table.

Tx No. Phase Description Transaction Time (UTC)
1 Preparation Deploy the attack contract 0xa4ece5...8cd4c93f Jul-09-2025 12:16:32 PM
2 Create an increase WETH-long order 0x0b8cd6...e90a4712 Jul-09-2025 12:22:28 PM
3 Execute the increase WETH-long order 0x28a000...7bf0beef Jul-09-2025 12:23:23 PM
4 Create a decrease WETH-long order 0x20abfe...decc49af Jul-09-2025 12:24:56 PM
5 Price Manipulation 1 Execute the decrease WETH-long order 0x1f00da...6a4a7353 Jul-09-2025 12:25:37 PM
6 Execute the decrease WBTC-short order 0x222cda…c994464e Jul-09-2025 12:25:43 PM
7 Price Manipulation 2 Same as tx 5 0xc9a469...221293c2 Jul-09-2025 12:26:25 PM
8 Same as tx 6 0x1cbf25...d853943a Jul-09-2025 12:26:30 PM
9 Price Manipulation 3 Same as tx 5 0xb58415...3b4cfb0b Jul-09-2025 12:27:22 PM
10 Same as tx 6 0x5a37ff...cb59c3b7 Jul-09-2025 12:27:28 PM
11 Price Manipulation 4 Same as tx 5 0xff6fe6...377bf108 Jul-09-2025 12:28:13 PM
12 Same as tx 6 0xbd65d6...e0187be6 Jul-09-2025 12:28:18 PM
13 Price Manipulation 5 Same as tx 5 0x105273...19fcdec6 Jul-09-2025 12:29:12 PM
14 Same as tx 6 0x0cdbac...84339fcc Jul-09-2025 12:29:17 PM
15 Profit Realization Realize profits 0x03182d....a32626ef Jul-09-2025 12:30:11 PM
16 Refunding Message the attacker 0x92a39e...89547380 Jul-09-2025 02:04:19 PM
17 Response to the GMX protocol 0x1d806c...919feac0 Jul-11-2025 06:29:00 AM
18 Response to the attacker 0x9c4ca9...39fa27fc Jul-11-2025 07:42:17 AM
19 Refund 0x62b845...99211841 Jul-11-2025 08:04:34 AM
20 Refund 0x255d0a...9321b3 Jul-11-2025 08:08:27 AM
21 Refund 0xceafc3...a6313b22 Jul-11-2025 10:17:23 AM

Preparation Phase

  1. (Tx 1) The attacker deployed the attack contract, which is used as the asset receiver during the order execution. The attack contract contained a malicious fallback() function.

  2. (Tx 2) The attacker created an increase WETH-long order for the attack contract in the contract OrderBook.

  3. (Tx 3) A Keeper executed the attacker's increase order (created in step 2), which opened a WETH-long position for the attack contract. (Tx 3).

  4. (Tx 4) The attacker created a decrease WETH-long order for the attack contract in the contract OrderBook.

Manipulation Phase

  1. (Tx 5) A Keeper executed the attack contract's decrease WETH-long order (created in step 4) via the orderbook-execution path. The execution path invoked _transferOutETH(), triggering the malicious fallback() function in the attack contract.

    Since fallback() was invoked during the "leverage window", the attack contract directly interacted with the contract Vault to open a WBTC-short position (via increasePosition()) without updating globalShortAveragePrice, and subsequently created a decrease/close WBTC-short order.

  2. (Tx 6) A Keeper executed the decrease WBTC-short order (created in step 5) via the router-execution path. The execution also created a decrease WETH-long order via the fallback mechanism in the contract PositionRouter.

    Since the WBTC-short position was opened without updating globalShortAveragePrice, closing the position while updating the variable caused an unexpected drop in globalShortAveragePrice.

  3. (Tx 7-14) The attacker repeated steps 5-6 four times. As a result, globalShortAveragePrice was skewed from 1.08e35 to 1.9e33.

Profit Realization Phase

  1. (Tx 15) A Keeper executed the decrease WETH-long order (created in Tx 14) via the orderbook-execution path. This execution triggered the profit realization logic in the attack contract due to the reentrancy vulnerability in the contract OrderBook.

    1. In the fallback invocation, the attack contract first borrowed a flash loan of 7,538,567e18 USDC.

    2. The attack contract invoked mintAndStakeGlp() to mint 4,129,578e18 GLPs using 6,000,000e18 USDC.

    3. The attack contract invoked Vault.increasePosition() to open a WBTC-short position with the remaining 1,538,567e18 USDC. Because WBTC's global short data was extremely skewed, the order execution significantly amplified AUM, sharply increasing the GLP price.

    4. The attack contract invoked unstakeAndRedeemGlp() to redeem GLPs at the amplified price for multiple assets in the contract Vault.

    5. The attack contract invoked Vault.decreasePosition() to close the WBTC-short position.

    6. The attack contract repeated steps 8.b-8.e four times to drain all assets in the contract Vault.

    7. The attack contract repaid the flash loan with a profit of nearly $42 million.

Refunding

Through negotiations with the attacker (Tx 16-18), the attacker ultimately accepted a 10% bounty and returned the remaining stolen assets (Tx 19-21).

Summary

This incident involved a multi-phase exploit against GMX V1 on Arbitrum, resulting in an estimated loss of $42 million. The attacker abused a reentrancy vulnerability on the contract OrderBook to skew the variable globalShortAveragePrice, inflating the GLP price. By leveraging the manipulated price, the attacker siphoned a significant amount of assets.

Key lessons:

  • Cross-contract reentrancy: A nonReentrant modifier on a single contract does not prevent reentrancy into other contracts within the same system. Access control mechanisms that rely on a temporary flag (e.g., the "leverage window") can be bypassed when an external call occurs before the flag is reset.
  • Operational Security: This attacker exploited the protocol in three distinct phases, executing a total of 15 transactions. This incident underscores the critical need for real-time monitoring, prompt alerts, and effective mitigation playbooks.

Reference

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

About BlockSec

BlockSec is a full-stack blockchain security and crypto compliance provider. We build products and services that help customers to perform code audit (including smart contracts, blockchain and wallets), intercept attacks in real time, analyze incidents, trace illicit funds, and meet AML/CFT obligations, across the full lifecycle of protocols and platforms.

BlockSec has published multiple blockchain security papers in prestigious conferences, reported several zero-day attacks of DeFi applications, blocked multiple hacks to rescue more than 20 million dollars, and secured billions of cryptocurrencies.

Sign up for the latest updates
Tether Freezes $6.76M USDT Linked to Iran's IRGC & Houthi Forces: Why On-Chain Compliance is Now a Geopolitical Battlefield
Security Insights

Tether Freezes $6.76M USDT Linked to Iran's IRGC & Houthi Forces: Why On-Chain Compliance is Now a Geopolitical Battlefield

Looking ahead, targeted freezing events like this $6.76M USDT action will only become more common. On-chain data analysis is improving. Stablecoin issuers are also working closely with regulators. As a result, hidden illicit financial networks will be exposed.

Weekly Web3 Security Incident Roundup | Mar 2 – Mar 8, 2026
Security Insights

Weekly Web3 Security Incident Roundup | Mar 2 – Mar 8, 2026

During the week of March 2 to March 8, 2026, seven blockchain security incidents were reported with total losses of ~$3.25M. The incidents occurred across Base, BNB Chain, and Ethereum, exposing critical vulnerabilities in smart contract business logic, token deflationary mechanics, and asset price manipulation. The primary causes included a double-minting logic flaw during full token deposits that allowed an attacker to exponentially inflate their balances through repeated burn-and-mint cycles, a price manipulation vulnerability in an AMM-based lending market where artificially inflated vault shares created divergent price anchors to incorrectly force healthy positions into liquidation, and a flawed access control implementation relying on trivially spoofed contract interfaces that enabled attackers to bypass authorization to batch-mint and dump arbitrary tokens.

Weekly Web3 Security Incident Roundup | Feb 23 – Mar 1, 2026
Security Insights

Weekly Web3 Security Incident Roundup | Feb 23 – Mar 1, 2026

During the week of February 23 to March 1, 2026, seven blockchain security incidents were reported with total losses of ~$13M. The incidents affected multiple protocols, exposing critical weaknesses in oracle design/configuration, cryptographic verification, and core business logic. The primary drivers included oracle manipulation/misconfiguration that led to the largest loss at YieldBloxDAO (~$10M), a crypto-proof verification flaw that enabled the FOOMCASH (~$2.26M) exploit, and additional token design and logic errors impacting Ploutos, LAXO, STO, HedgePay, and an unknown contract, underscoring the need for rigorous audits and continuous monitoring across all protocol layers.