GmxProxy contract's queue state can be manipulated because queue reset logic isn't properly restricted. This allows unauthorized resetting of pending orders, potentially disrupting the order execution flow between PerpetualVault and GMX.
The issue centers around the GmxProxy's queue management. The contract maintains an OrderQueue struct that tracks pending GMX orders and their settlement status. Its requires that queue resets should only happen through valid GMX handlers (orderHandler, liquidationHandler, or adlHandler), but this invariant can be violated.
Think of it like a ticket validation system where only authorized ticket inspectors should be able to clear the queue, but there's a backdoor allowing anyone to reset it. We expects that when pendingOrderCount goes from >0 to 0 (queue reset), the msg.sender must be one of the valid GMX handlers. However, the issue is that while the validCallback modifier checks the caller, the queue deletion happens unconditionally after processing. Why isn't this protected by additional access controls?
If exploited, an attacker could:
Wait for a legitimate order to be queued
Force a queue reset through an unauthorized path
Disrupt the normal order flow between PerpetualVault and GMX
This breaks the core assumption that order execution flow is strictly controlled through authorized GMX handlers.
The GmxProxy contract acts as a critical bridge between the PerpetualVault and GMX's trading infrastructure like an order management system at a brokerage, it needs to ensure every trade request flows through proper channels and gets executed correctly.
When users want to open or close positions through the PerpetualVault, their requests get queued in GmxProxy. Only authorized GMX handlers (orderHandler, liquidationHandler, or adlHandler) should be able to process and clear these queues, similar to how only licensed brokers can execute trades on an exchange.
The queue can be reset (cleared to empty) by paths that bypass the authorized handlers. Here's how: GmxProxy.sol#afterOrderExecution
While the validCallback modifier checks the caller's authorization, the actual queue deletion happens unconditionally after processing. This breaks the core invariant that queue state should only be modified by GMX handlers.
When a vault user opens a position:
PerpetualVault queues the order in GmxProxy
An unauthorized path could clear this queue
The position never gets executed on GMX
User funds remain locked in an incomplete state
The PerpetualVault's entire order flow depends on GmxProxy maintaining strict queue integrity, like a broker ensuring trades only execute through licensed channels. The code assumed the validCallback modifier provided sufficient protection. However, while it checks the caller's authorization, the queue deletion happens unconditionally after processing, breaking the core invariant that only GMX handlers should reset queue state.
The protocol's asynchronous order flow (detailed in PerpetualVault.sol) makes state management tricky. The code was desing to focused on the happy path where orders flow through proper GMX handlers, but overlooked edge cases where queue state could be manipulated mid-flow.
The PerpetualVault system acts like an automated trading desk, where users deposit collateral and the protocol manages leveraged positions on GMX. At its core, the GmxProxy serves as the critical bridge between user intentions and actual GMX trades, maintaining order flow through a carefully managed queue system.
When examining the queue reset vulnerability, imagine a trading desk where order tickets mysteriously vanish before execution. The GmxProxy contract's queue management system, designed to track pending GMX orders and their settlement status, can be manipulated because its reset mechanism lacks proper access controls.
The technical heart of this issue lies in the afterOrderExecution function. While it includes a validCallback modifier to check caller authorization, the queue deletion happens unconditionally afterward. This creates a scenario where the queue state tracking up to 3x leveraged positions worth up to 100,000 USDC can be cleared without proper GMX handler authorization.
The real-world impact becomes clear when considering the protocol's automated trading flow. A user deposits USDC into the vault, expecting it to open a leveraged ETH position. The vault queues this order through GmxProxy, but an attacker exploits the queue reset vulnerability, causing the position to never execute while funds remain locked. This directly breaks the protocol's promise of automated position management and could affect multiple users' deposits simultaneously.
The vulnerability is in the interaction flow between these contracts:
PerpetualVault.sol initiates orders
GmxProxy.sol manages GMX interaction
IGmxProxy.sol defines the interface
IGmxReader.sol provides market data
We need proper queue state encapsulation with explicit handler checks, ensuring that only authorized GMX handlers (orderHandler, liquidationHandler, or adlHandler) can reset the queue state. This maintains the protocol's core invariant of controlled order flow between PerpetualVault and GMX.
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.
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.
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.