Summary
When GMX triggers a callback (afterOrderExecution
) with a large negative priceImpact
, code in PerpetualVault
subtracts priceImpact
from the user deposit. If priceImpact
> deposit net, a raw uint256
underflow reverts repeatedly—locking the vault flow.
GmxProxy
finalizes an order with a priceImpact
value.
PerpetualVault.afterOrderExecution()
does something like amount - feeAmount - uint256(priceImpact)
.
If priceImpact
> amount - feeAmount
, the subtraction underflows.
A user deposit net is 100, but the callback sets priceImpact = 150
.
The code 100 - 150
underflows → revert.
GMX tries again; it reverts again. The vault remains in partial deposit flow.
Infinite Flow Lock: The vault can’t finalize or cancel; each callback reverts.
User Funds Stuck: The user’s deposit is effectively locked as the flow can’t finish.
High volatility or malicious off-chain signals produce an extreme negative price impact. The deposit underflow reverts. The keeper re-tries; no progress is made.
Recommendations
Clamp or Check: Before subtracting, do:
or clamp to zero if it exceeds.
Graceful Fallback: If impact is too large, revert with a clear “priceImpact too high” so the vault can be canceled or re-attempted.
Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.
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.