First, let's take a look at the action performed by Gamma when GMX's ADL (Automatic Deleveraging) invokes GmxProxy.sol
's afterOrderExecution() callback:
Any collateral & index tokens received from GMX are transferred to the PerpetualVault. And if this ADL has not resulted in the entire position size to be de-leveraged i.e. sizeInUsd > 0
, then afterLiquidationExecution()
is NOT called.
With that in mind, let's now look at a user's withdrawal flow:
User calls withdraw()
. This sets flow = FLOW.WITHDRAW
.
If there's an open position, calls _settle()
which creates a GMX order.
GMX executes the settle order, triggering afterOrderExecution()
. This sets nextAction = NextActionSelector.WITHDRAW_ACTION
.
Keeper calls runNextAction()
which if needed, swaps any indexTokens to collateralTokens.
Calls _withdraw()
which creates a GMX decrease position order.
GMX executes decrease order, triggering afterOrderExecution()
. This sets nextAction = NextActionSelector.FINALIZE
.
Keeper calls runNextAction()
which calls _finalize()
which calls _handleReturn()
to process the withdrawal.
However, _finalize()
and _handleReturn()
rely on contract's collateral token balance to determine how much withdrawn amount is to be credited back to the user. If an ADL inadvertently happens between steps 6 and 7, i.e. Keeper's runNextAction()
gets front-runned coincidentally in the same block (Or Keeper fails to notice the ADL event and calls runNextAction()
anyway), then user receives more than they should:
User will receive both their proportional share from the decrease order AND the ADL tokens
This is incorrect since ADL tokens should be distributed across all position holders. Essentially, other position holders take a loss.
The fix may not be quite that simple. We may need to properly track credited tokens during ADL, perhaps by having ADL tokens flow into a separate accounting bucket.
Another way could be to increment prevCollateralBalance
inside the if (msg.sender == address(adlHandler))
branch when afterOrderExecution()
callback happens.
Likelihood: Low, when ADL with profit happen just before a nextAction.FINALIZE and FLOW.WITHDRAW Impact: High, the withdrawing user receives all the delivery with the tokens.
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.