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

Execution fees can become permanently stuck in GmxProxy due to silent failure in cancelFlow

Summary and Impact

There's a vulnerability in the PerpetualVault's cancelFlow function where execution fees can become permanently stuck in the GmxProxy contract due to silent failure handling. When a flow is cancelled, the system attempts to refund execution fees to users but wraps this attempt in an empty try-catch block, meaning failures are silently ignored with no logging or recovery mechanism.

This directly impacts one of the protocol's key invariants: "There could be delays in claiming some funding fees. If the user withdraws prior to the ability to claim, then it would be ok not to receive his fair share." While this invariant addresses temporary delays, the current implementation can lead to permanent loss of execution fees, which goes beyond the intended temporary delay scenario described in the documentation.

Vulnerability Details

The issue occurs in the _cancelFlow function:

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 {}
}
// Setting flow to liquidation has no meaning.
// The aim is to run FINAIZE action. (swap indexToken to collateralToken);
flow = FLOW.LIQUIDATION;
nextAction.selector = NextActionSelector.FINALIZE;
}

The empty try-catch block means if the refund fails for any reason (network issues, contract problems, insufficient gas), users permanently lose their execution fees with no recourse. This is particularly concerning because:

  1. The protocol documentation emphasizes fair fee distribution and temporary delays, not permanent loss

  2. Users pay execution fees expecting them to be either used or refunded

  3. The system lacks any mechanism to track or recover stuck fees

  4. There's no event emission to alert users or monitoring systems of failed refunds

Tools Used

  • Manual Review

Recommendations

Implement a fee tracking system

Updates

Lead Judging Commences

n0kto Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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