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

PerpetualVault::_cancelFlow refunds fee to the last depositor in Withdraw flow

Summary

https://github.com/CodeHawks-Contests/2025-02-gamma/blob/84b9da452fc84762378481fa39b4087b10bab5e0/contracts/PerpetualVault.sol#L1220-L1236

In case PerpetualVault::cancelFlow needs to be invoked, if the current flow is FLOW.WITHDRAW, the refunded fees will be transferred to the last depositor of this vault instead of the user withdrawing the funds.

Vulnerability Details

PerpetualVault::cancelFlow invokes _cancelFlow which in case of the flow being FLOW.WITHDRAW, it will refund the fees to depositInfo[counter].owner instead of to the user who initiated the withdraw function.

Impact

The user who initiated the withdraw function will not receive the fees back

Tools Used

Manual review

Recommendations

function _cancelFlow() internal {
if (flow == FLOW.DEPOSIT) {
uint256 depositId = counter;
collateralToken.safeTransfer(depositInfo[depositId].owner, depositInfo[depositId].amount);
totalDepositAmount = totalDepositAmount - depositInfo[depositId].amount;
EnumerableSet.remove(userDeposits[depositInfo[depositId].owner], depositId);
try IGmxProxy(gmxProxy).refundExecutionFee(
depositInfo[counter].owner,
depositInfo[counter].executionFee
) {} catch {}
delete depositInfo[depositId];
} else if (flow == FLOW.WITHDRAW) {
-- try IGmxProxy(gmxProxy).refundExecutionFee(depositInfo[counter].owner, depositInfo[counter].executionFee) {} catch {}
++ try IGmxProxy(gmxProxy).refundExecutionFee(depositInfo[flowData].owner, depositInfo[flowData].executionFee) {} catch {}
}
Updates

Lead Judging Commences

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

finding_counter_invalid_during_cancelFlow_after_withdrawing

Likelihood: Low, contract has to call cancelFlow after a withdraw, and the settle action is already executed by GMX. 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.