Because _doDexSwap()
accepts arbitrary aggregator call data and never checks the actual output beyond computing outputAmount
, the protocol is fully exposed to slippage exploits or malicious aggregator calls that yield near-zero tokens for the vault. Implementing a minimum-output or slippage check on-chain is crucial to protect users from catastrophic losses.
Unexpected market event can effectively drain user deposits or cause severe losses during DEX swaps, all without triggering a revert.
FIX -> Accept a minOutput
parameter in _doDexSwap()
or metadata
then enforce:
This ensures that if the aggregator returns fewer tokens than minOutput
, the vault reverts and does not accept the trade.
RootCause & Where It Happens
Take a close look at _doDexSwap()
:
Notice that the function:
Accepts a prepared callData
and to
address from an off-chain script (the “metadata”).
Calls ParaSwapUtils.swap(to, callData);
without any local checks on how many tokens actually came back.
Computes outputAmount
only by the difference in the contract’s token balance before and after the swap.
No code ensures outputAmount
is at least X
or “less than some slippage threshold.” Consequently:
A malicious or misconfigured off-chain aggregator call could yield close to 0 tokens in return, effectively draining the user’s or vault’s input tokens.
The vault never reverts or even checks that the swap was “fair.”
Attack / Exploit Scenario
User or Keeper calls a vault action that triggers _runSwap()
, which in turn calls _doDexSwap()
.
The off-chain aggregator data is set up maliciously, or the aggregator front-runs the trade in some fashion to produce a near-zero output.
_doDexSwap()
just sees outputAmount = (finalBalance - initialBalance)
, which might be extremely low (or even 0).
The vault then proceeds with the rest of the flow, treating that near-zero output as valid—no revert or slippage protection kicks in.
This can be particularly damaging when large amounts of collateral are swapped via Paraswap, and the vault receives little or nothing in return. Honest users who deposit expecting a normal DEX rate can be heavily impacted.
Severity
High if the vault expects normal market trades with only moderate slippage.
->This can cause direct, catastrophic user or vault losses if a malicious aggregator route or a significant front-running scenario occurs.
The vault provides no fallback or revert condition if the output is grossly less than expected.
Implement Slippage Checks On-Chain
Accept a minOutput
parameter in _doDexSwap()
or metadata
, then enforce:
This ensures that if the aggregator returns fewer tokens than minOutput
, the vault reverts and does not accept the trade.
Slippage and deadline are handled externally. Paraswap implementation used by the current code (behind the proxy): https://etherscan.io/address/0xdffd706ee98953d3d25a3b8440e34e3a2c9beb2c GMX code: https://github.com/gmx-io/gmx-synthetics/blob/caf3dd8b51ad9ad27b0a399f668e3016fd2c14df/contracts/order/OrderUtils.sol#L150C15-L150C33
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.