GMX provide a functionality to manually cancel an order after certain period if it is not executed. However, the gas refund for canceled orders is sent to the PerpetualVault contract (because it is set as cancellationReceiver when creating orders in GmxProxy) , where it gets stuck and cannot be used. If the indexToken is ETH, the refund is “distributed” among depositors instead.
Taking a look into OrderHandler::cancelOrder() which handles logic regarding order cancellation we see that it internally uses OrderUtils::cancelOrder().
There we see that executionFeeReceiver is set to order's cancellationReceiver.
Cancellation receiver for orders is always set to PerpetualVault in GmxProxy:
Going further in the code, we see that GasUtils::payExecutionFee() is used to handle the actual transfer of tokens to the refundReceiver which is incorrectly PerpetualVault in our case.
Stuck tokens in PerpetualVault.
Inability to refund gas execution fees to depositors.
Manual review
Since it is important for PerpetualVault to be cancellation receiver for other parts of the protocol, I suggest having a function to transfer tokens from PerpetualVault to GmxProxy where native token can be used for actual gas refunds.
Likelihood: Low/Medium, during cancellation with a refund. Impact: High, refund and ETH are stuck in the perpVault.
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.