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:
Where:
GLPTotalSupplyrepresents the total supply of the GLP tokens.AUMconsists of the following two components.- represents the uPnL (i.e., unrealized Profit and Loss) of all short positions.
- 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.
AssetMarketPriceis the market price (in USD) of the underlying asset.globalShortSizeis the sum (in USD) of all short positions.globalShortAveragePriceis 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
-
(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. -
(Tx 2) The attacker created an increase WETH-long order for the attack contract in the contract
OrderBook.
-
(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).
-
(Tx 4) The attacker created a decrease WETH-long order for the attack contract in the contract
OrderBook.
Manipulation Phase
-
(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 maliciousfallback()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 (viaincreasePosition()) without updatingglobalShortAveragePrice, and subsequently created a decrease/close WBTC-short order.
-
(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 inglobalShortAveragePrice.
-
(Tx 7-14) The attacker repeated steps 5-6 four times. As a result,
globalShortAveragePricewas skewed from 1.08e35 to 1.9e33.
Profit Realization Phase
-
(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.
-
In the fallback invocation, the attack contract first borrowed a flash loan of 7,538,567e18 USDC.
-
The attack contract invoked
mintAndStakeGlp()to mint 4,129,578e18 GLPs using 6,000,000e18 USDC. -
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. -
The attack contract invoked
unstakeAndRedeemGlp()to redeem GLPs at the amplified price for multiple assets in the contractVault. -
The attack contract invoked
Vault.decreasePosition()to close the WBTC-short position. -
The attack contract repeated steps 8.b-8.e four times to drain all assets in the contract
Vault. -
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
nonReentrantmodifier 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
- https://x.com/GMX_IO/status/1942955807756165574
- https://x.com/GMX_IO/status/1943336664102756471
- 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.
-
Official website: https://blocksec.com/
-
Official Twitter account: https://twitter.com/BlockSecTeam



