Description:
The Perpetual Vault Protocol uses an all-or-nothing execution for GMX swaps via GmxProxy.createOrder, with no partial fills. If a swap fails (e.g., due to slippage), afterOrderCancellation sets nextAction = SWAP_ACTION, prompting the Protocol Keeper (not GMX Keeper) to retry via runNextAction. Without a retry limit, an attacker can craft a swap with an unachievable minOutputAmount (e.g., 1000 USDC to 1 WETH at $2000/WETH), causing GMX to cancel it repeatedly and the Keeper to retry indefinitely. This leverages the absence of partial fills and the "retry until success" design.
Impact:
Denial of Service: The _gmxLock remains true during retries, fully blocking vault actions (e.g., deposits, withdrawals, signal changes) until the swap succeeds or is canceled. Unlike Paraswap’s nonReentrant delay, this halts all operations.
Gas Consumption: Each retry (~100k gas, ~$50 at 25 gwei, $2000/ETH) consumes Protocol Keeper ETH, though mitigated by the Known Issues assumption of "more than enough gas" (e.g., 1 ETH ≈ 10,000 retries).
Fund Accessibility: Funds stay in the vault or GMX orderVault, locked but not lost during retries.
Severity: Medium—significant disruption with full lockout, recoverable via manual cancelOrder, and gas impact softened by funding assumptions.
Proof of Concept:
Setup: Attacker has 1000 USDC, vault deployed with GMX integration.
Malicious Deposit: Attacker calls vault.deposit(1000e6) with 0.01 ETH execution fee, triggering a GMX swap.
Craft Swap: run submits swapData with minOutputAmount = 1e18 (1 WETH), unachievable for 1000 USDC ($1000 vs. $2000).
GmxProxy.createOrder submits order.
GMX Keeper cancels due to slippage.
Retry Loop:
afterOrderCancellation sets nextAction = SWAP_ACTION.
Protocol Keeper calls runNextAction, resubmitting the failing swap.
_gmxLock = true, blocking new actions (e.g., deposit reverts with "GmxLock").
Outcome: Keeper retries indefinitely (~$50/retry), locking vault until cancelOrder is called.
Recommended Mitigation:
Add a retry limit to cap GMX swap attempts, preventing indefinite loops:
Fix:
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.