# Limit orders can be used to get a free look into the future

GMX limit orders can be repeatedly updated by ±1 wei to delay execution, letting users peek at future oracle prices and exit only when favorable.

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

**Target:** GMX Synthetics limit/stop-loss decrease and swap order execution (DecreaseOrderUtils, SwapOrderUtils, ExchangeRouter.updateOrder)
**Root cause:** Limit order execution requires oracle min block numbers greater than orderUpdatedAtBlock, but updateOrder() can reset orderUpdatedAtBlock with no delay or fee, so a user can keep pushing execution forward while observing future signed prices.
**Steps:**
1. Submit a limit decrease/swap order at block N.
2. Observe the next signed oracle price covering block N+1 (or up to N+5) before the keeper can execute.
3. If unfavorable, call `ExchangeRouter.updateOrder()` changing amount by ±1 wei, resetting orderUpdatedAtBlock to current block.
4. Repeat each block until a favorable future price appears, then let the keeper execute at that price.
**How found:** Code review of validateOracleBlockNumbers comparing minOracleBlockNumbers against orderUpdatedAtBlock, combined with noticing updateOrder() touches orderUpdatedAtBlock with no delay or fee, and reasoning about the oracle's block-range signing gap.
**Exploitation:** Attacker with a pending exit order watches the archived signed oracle prices for the next block range; when the future price is favorable they stop updating and let the keeper execute, otherwise they bump the order by 1 wei to reset orderUpdatedAtBlock and delay execution. Gas cost is outweighed by favorable price on large positions.
**Escalation:** Automated service could perform the update loop on behalf of users, scaling the advantage across many positions.
**Insight:** When execution validity is gated on a mutable 'last updated' timestamp, check whether the user can reset that timestamp cheaply and repeatedly; any gap between signed price ranges and block production becomes a free option.
