DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: low
Invalid

Unused fee never returned to user

Description & Impact

Inside withdraw() Gamma collects execution fee from the user:

depositInfo[depositId].recipient = recipient;
@----> _payExecutionFee(depositId, false);
if (curPositionKey != bytes32(0)) {
nextAction.selector = NextActionSelector.WITHDRAW_ACTION;
_settle(); // Settles any outstanding fees and updates state before processing withdrawal
} else {
MarketPrices memory prices;
_withdraw(depositId, hex'', prices);
}
  • But this fee is never used if curPositionKey != bytes32(0) is false i.e. there's no open position. The control moves to the else clause where _withdraw() is called which internally calls _handleReturn(0, true, false). the presence of false as the third param ensures no refund is issued.

  • Similar behaviour is observed in deposit(). Even if all the fee provided by user is not spent on GMX and the unspent amount is refunded to Gamma, it never makes it way back to the user.

Mitigation

  • Do not ask the user to pay execution fee if curPositionKey == bytes32(0)

  • Incorporate a mechanism to refund unspent GMX fees back to the user at the time of deposit()

Updates

Lead Judging Commences

n0kto Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

invalid_withdraw_positionIsClosed_does_not_refund_fees

No fee needed in _payExecutionFee when position is closed. Make a PoC if you disagree.

Support

FAQs

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