DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: high
Valid

PerpetualVault::_handleReturn will always return fees to the latest depositor

Summary

https://github.com/CodeHawks-Contests/2025-02-gamma/blob/84b9da452fc84762378481fa39b4087b10bab5e0/contracts/PerpetualVault.sol#L1129-L1150
PerpetualVault::_handleReturn is the last step during a withdrawal flow. In this function, fees are refunded to the user who invoked the withdrawal if applicable.

Vulnerability Details

If the user performing the withdrawal is applicable for a refund, instead of being transferred to this user, the refund will be transferred to the latest depositor of this vault.
As can be seen, the refund is done to depositInfo[counter].owner instead of depositInfo[depositId].owner.
Also, in case the latest depositor has an executionFee < usedFee (what the if above checks is depositInfo[depositId].executionFee > usedFee instead), it will underflow and revert so not letting the user to withdraw the funds.

Impact

The user withdrawing funds will not get fees refunded and/or might get the withdraw function reverted.

Tools Used

Manual review

Recommendations

if (refundFee) {
uint256 usedFee = callbackGasLimit * tx.gasprice;
if (depositInfo[depositId].executionFee > usedFee) {
-- try IGmxProxy(gmxProxy).refundExecutionFee(depositInfo[counter].owner, depositInfo[counter].executionFee - usedFee) {} catch {}
++ try IGmxProxy(gmxProxy).refundExecutionFee(depositInfo[depositId].owner, depositInfo[depositId].executionFee - usedFee) {} catch {}
}
}
Updates

Lead Judging Commences

n0kto Lead Judge 8 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_counter_invalid_during_handleReturn

Likelihood: Medium/High, when withdraw on a 1x vault. Impact: High, the fees will be distributed to the last depositor and not the withdrawer.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.