# Creating an order of type MarketIncrease opens an attack vector where attacker can execute txs with stale prices by inputting a very extense swapPath

GMX MarketIncrease orders with an extremely long swapPath can exhaust block gas in the callback, letting attacker delay execution and fill at stale prices.

- Payout: Contest reward
- Severity: high
- Program: Gmx
- Credited: stopthecap
- Disclosed: 2022-09-22
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-02-gmx-judging/issues/54
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-02-gmx%3AH-21
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:dos vuln:oracle-manipulation

**Target:** GMX Synthetics OrderUtils.createOrder / order execution
**Root cause:** createOrder does not cap swapPath length, so a MarketIncrease order can consume nearly the whole block gas limit during execution; the callback contract can then be made to revert until the attacker chooses to let it succeed, deferring execution to a later block while the order still fills at the originally acceptable price.
**Steps:**
1. Deploy attack contract implementing callback that can toggle gas usage via `flipSwitch()`.
2. Build `swapPath` of ~63 alternating market tokens (ethUsdMarket/ethUsdSpotOnlyMarket) to approach block gas limit.
3. Call `createOrder` with `orderType: MarketIncrease`, `callbackContract: attackContract`, `callbackGasLimit: 1900000`, `sizeDeltaUsd: 200k`, `acceptablePrice: 5001e12`, collateral 50k USDC.
4. Keeper `executeOrder` reverts due to gas exhaustion in callback.
5. Mine ~50 blocks while price moves; call `attackContract.flipSwitch()` to reduce gas usage.
6. Keeper re-executes order at old acceptable price; attacker opens 4x long at stale price.
7. Close position via MarketDecrease at current (higher) price, extracting ~100k USDC profit.
**How found:** Researcher read createOrder and noticed swapPath length is unbounded (only validated via getEnabledMarkets), then reasoned that a long path plus a gas-heavy callback could push execution past block.gasLimit, allowing the attacker to control execution timing.
**Exploitation:** Attacker creates a MarketIncrease order whose swapPath nearly fills the block gas limit and whose callback contract intentionally reverts on execution. The order stays pending across blocks; when the attacker wants, they flip the callback to succeed and the keeper executes the order at the stale acceptablePrice, opening a leveraged position at an outdated price, then closes it at the current price for risk-free profit.
**Insight:** When an order/queue system validates inputs but not their size, check whether a large-but-valid input can push execution near block gas limits and let a callback contract control success/failure to defer execution — deferred execution against a fixed acceptablePrice is a stale-price oracle.
