# Malicious revert reasons with faked lengths can disrupt order execution

GMX's ErrorUtils.getRevertMessage abi.decodes attacker-controlled revert bytes with a faked huge string length, causing out-of-gas and blocking order execution/liquidation.

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

**Target:** GMX Synthetics order callback error parsing (ErrorUtils.getRevertMessage)
**Root cause:** getRevertMessage abi.decodes a memory bytes revert reason as a string without bounding the declared length against actual data length; a short payload with a huge length word causes the decoder to read far past the buffer and exhaust gas.
**Steps:**
1. Register a callback contract for order events (e.g. afterOrderExecution) that reverts with crafted bytes.
2. Craft revert data: selector `0x08c379a0`, offset `0x20`, length word set to a huge value (e.g. `100000000000`), followed by a few bytes of string.
3. Trigger the order operation so GMX calls the callback under try/catch with limited gas.
4. GMX catches the revert and calls `getRevertMessage(result)` which `abi.decode`s the string, reading past the buffer until out-of-gas.
5. The OOG in the outer frame reverts the whole order operation, blocking liquidation/ADL/cancellation.
**How found:** Code review of ErrorUtils.getRevertMessage: noticed abi.decode on a memory bytes variable allows reads past the end (zero-padded), and that the length word is attacker-controlled; hypothesized a short payload with a huge length word would OOG the decoder, then confirmed with a Foundry PoC.
**Exploitation:** Attacker sets a malicious callback on their position/order; when GMX attempts liquidation, ADL, order execution or cancellation, the callback reverts with a faked-length Error(string). The subsequent abi.decode in getRevertMessage runs out of gas, reverting the entire order-processing transaction, so the attacker's position cannot be liquidated or their resting orders cannot be cancelled/executed.
**Escalation:** Applied across multiple callbacks (afterOrderExecution, cancellation callbacks) to freeze orders, bypass pauses via resting orders, and prevent cancellation when normal execution reverts.
**Insight:** When a contract abi.decodes attacker-supplied revert/return bytes from memory, the declared length is trusted and reads past the buffer return zeros rather than reverting — a tiny payload with a huge length word becomes a gas bomb. Audit every try/catch that decodes user callback revert data.
