# GMX v1 Exploit — July 2025

## 1. What happened

On **9 July 2025**, an attacker drained approximately **$42 million** in tokens from the **GLP liquidity pool** on GMX v1, deployed on **Arbitrum**. Roughly $9.6M was bridged to Ethereum. [1][2]

Two days later, GMX announced the incident was a **coordinated vulnerability disclosure**: the entity behind the attack returned ~$40M to the GMX multisig and retained ~$5M as a white-hat bounty. [1][2]

## 2. Root cause

The root cause was a **cross-contract reentrancy vulnerability** in the `executeDecreaseOrder()` function of GMX v1's orderbook contract. When a keeper bot called this function to execute a decrease-order, the contract refunded gas costs to the account that opened the position. If that account was a smart contract, the refund callback handed execution control to the attacker's contract mid-transaction. During reentrancy, the attacker called `increasePosition()` directly on the **Vault contract**, bypassing `PositionRouter` and `PositionManager` — the intermediary contracts that normally calculate and update the global average short price. This allowed the attacker to open a large short that drove BTC's global average short price from ~$109,505 down to ~$1,913, distorting the GLP price. The vulnerability was introduced in a **2022 fix for a separate $1M bug bounty** paid to Collider VC; PeckShield confirmed the bug was "introduced in the fix for the $1M bounty issue." Post-audit code changes to `executeDecreaseOrder` and vault logic were **never re-audited**. [1][2]

## 3. Pattern

**Reentrancy (cross-contract, callback-based).** The vulnerable shape:

```
function executeDecreaseOrder(address _account, ...) external {
    // ... decrease logic ...
    // refund gas to _account — if _account is a contract, control transfers here
    (bool success, ) = _account.call{value: gasRefund}("");
    // state updates after the external call are vulnerable to reentry
}
```

The attacker's contract received execution control during the gas-refund callback while `executeDecreaseOrder` was still unresolved. It then called `increasePosition()` on the Vault directly, skipping the `PositionRouter`/`PositionManager` path that computes and updates the global average short price. This reentrancy distorted a shared global accumulator (`globalShortAveragePrices`), which fed into AUM → GLP pricing, letting the attacker mint GLP cheap and redeem it dear. [1][2]

## 4. The check that would have caught it

1. **Reentrancy guard on order execution.** Apply `nonReentrant` (OpenZeppelin's `ReentrancyGuard`) to `executeDecreaseOrder` and every order-execution path that makes external calls before finalising state. A unit test should deploy a mock attacker contract as the account, call `executeDecreaseOrder`, attempt reentry into Vault from the callback, and assert the reentrant call reverts.

2. **Invariant: global average price must be consistent after every external call.** A fuzz/invariant test (e.g. with Foundry) that opens random positions from EOA and contract accounts, executes decrease-orders, and checks that `globalShortAveragePrice` never deviates by more than a few basis points from the oracle-reported market price at any point during execution. The invariant would have caught the $109K → $1.9K collapse. [1][2]

## 5. Sources

1. rekt.news — "GMX — Rekt" leaderboard entry and article. https://rekt.news/gmx-rekt/ (accessed 2025-07-09 timeframe; leaderboard confirms $42M, 9 July 2025, Arbitrum)

2. QuillAudits — "How GMX V1 Lost $42 Million to a Reentrancy Attack?" https://quillaudits.com/blog/hack-analysis/how-gmx-lost-42m (published 7 Sep 2026; confirms $42M, reentrancy via `executeDecreaseOrder`, attack flow, whitehat return)

*Note: GMX's official post-mortem is hosted on Notion (https://gmxio.notion.site/GMX-v1-Exploit-Post-Mortem-186af3d74056803e909ed1a6a7ae35aa) but could not be accessed — it requires authentication. BlockSec, SlowMist, CertiK, Halborn, and Verichains analyses were searched for but either returned 404, 403, or redirected to unrelated pages at the time of research. The two sources above agree on all material facts: $42M, 9 July 2025, Arbitrum, cross-contract reentrancy in `executeDecreaseOrder`, global-short-average-price manipulation, and whitehat resolution with ~$5M bounty.*
