GmxProxy
Summary:
The GmxProxy contract uses a single global OrderQueue variable to store the active order’s request key and settlement flag. When a new order is created via createOrder or settle, the request key is stored by simply writing to this global queue. Later, in callback functions like afterOrderExecution and afterOrderCancellation, the entire queue is deleted. This design assumes that only one order is active at a time. If the associated PerpetualVault (or its trusted caller) inadvertently initiates a second order before the callback for the first order is received, the global queue is overwritten. As a result, the callback for the earlier order will use the wrong—or missing—request key, causing misprocessing of order results, such as incorrect fee accounting or state updates.
Where the Issue Is:
The vulnerability is in the GmxProxy contract’s use of a single global OrderQueue variable:
In both the createOrder and settle functions, the new order’s request key is stored as follows:
Later, when processing order callbacks in afterOrderExecution and afterOrderCancellation, the code simply clears the queue (using delete queue), without verifying that the callback corresponds to the correct order.
Root Cause:
The core issue stems from using a single, global state variable (queue) to store order information. This design enforces a one‑order‑at‑a‑time invariant. However, if two orders are submitted in rapid succession (for example, due to a coding error or inadvertent vault behavior), the second order’s request key overwrites the first. Consequently, when GMX sends a callback for the earlier order, the stored request key does not match, leading to misprocessing of order results.
Proof-of-Concept:
VulnerableGmxProxy.sol
VulnerableGmxProxyTest.t.sol
Run the Tests:
From the project root, run:
Impact:
State Inconsistency: Order callbacks will process mismatched data, leading to incorrect fee distribution, collateral adjustments, or share minting.
Financial Risk: Incorrect processing of orders can result in misallocated funds, causing loss or dilution of depositor balances.
Invariant Violation: The intended one‑order‑at‑a‑time invariant is broken, undermining the protocol’s assumption of sequential, isolated order processing.
Remediation:
Support Multiple Concurrent Orders:
Replace the single global OrderQueue with a mapping or an array keyed by the unique request key. This ensures that each order’s state is tracked independently.
Example:
Then, in the callback functions, reference the order using its unique request key.
Enforce Strict Sequential Order Submission:
If concurrent orders are not intended, add strict checks in the vault or proxy to ensure that a new order cannot be initiated until the callback for the previous order is processed.
Severity:
High – The flaw directly affects the core order processing logic, leading to potential misallocation of funds and breaches in state consistency, which can have significant financial repercussions.
Tools Used:
manual.
There is no real proof, concrete root cause, specific impact, or enough details in those submissions. Examples include: "It could happen" without specifying when, "If this impossible case happens," "Unexpected behavior," etc. Make a Proof of Concept (PoC) using external functions and realistic parameters. Do not test only the internal function where you think you found something.
Order is proceed one by one and requestKey is only used to cancelOrder. I didn’t see any real scenario where it will cause a problem. Flow and gmxLock will prevent that to happen.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.