When a position is fully liquidated on GMX, the contract updates curPositionKey to 0 in PerpetualVault::afterLiquidationExecution() but fails to properly flag the position as closed. This state inconsistency creates a situation where the contract continues to treat the position as active on GMX when it has actually been liquidated.
The root cause lies in the callback handling logic where the position closure state is not properly synchronized with GMX's liquidation events. This leads to two significant issues:
Users are forced to pay unnecessary execution fees during withdrawals because the contract believes there is an active GMX position
They also pay an execution fee for a deposit transaction that could have been executed almost immediately without needing to involve GMX.
The position gets liquidated on GMX, triggering the callback function
The callback sets curPositionKey to 0 but doesn't update the position's closed status
A user attempts to deposit/withdraw funds.
The contract incorrectly determines that there is an active GMX position
The user is charged an execution fee.
The position state should be properly updated when handling GMX liquidation callbacks. Implement a comprehensive state management system that correctly tracks and updates the positionIsClosed status.
"// keep the positionIsClosed value so that let the keeper be able to create an order again with the liquidated fund" Liquidation can send some remaining tokens. No real impact here.
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.