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

Missing Event Emission for Failed Execution Fee Refunds in PerpetualVault Leads to Potential Loss of Information

Summary:

The PerpetualVault contract defines an event ExecutionFeeRefundFailed, intended to be emitted when a refund of excess execution fees fails. However, this event is never emitted in the contract's code, meaning that information about failed refund attempts is lost. This can hinder debugging and monitoring of the contract's operation.

Vulnerability Details:

The ExecutionFeeRefundFailed event is declared but never emitted. The functions _finalize, _cancelFlow, _handleReturn, and _mint all contain try-catch blocks around attempts to refund excess execution fees using IGmxProxy(gmxProxy).refundExecutionFee(). While the catch blocks prevent the transaction from reverting, they do not provide any mechanism to signal that the refund failed.

Affected Functions:

The following code snippet (from _mint, but the issue is identical in the other functions) illustrates the lack of event emission:

function _mint(uint256 depositId, uint256 amount, bool refundFee, MarketPrices memory prices) internal {
// ... other code ...
if (refundFee) {
uint256 usedFee = callbackGasLimit * tx.gasprice;
if (depositInfo[counter].executionFee > usedFee) {
try IGmxProxy(gmxProxy).refundExecutionFee(depositInfo[counter].owner, depositInfo[counter].executionFee - usedFee) {} catch {} // No event emitted here
}
}
// ... other code ...
}

Even if refundExecutionFee throws an exception, the catch block simply swallows the error without emitting the ExecutionFeeRefundFailed event.

Impact

The lack of emitted ExecutionFeeRefundFailed events makes it difficult to track and diagnose instances where execution fee refunds fail. This can lead to:

  • Potential for undetected issues: If refunds fail consistently for a specific reason, the lack of events makes it harder to identify and address the underlying cause. While the transactions don't revert, the funds are still lost to the user and the vault may have to compensate.

  • Difficulty in debugging: If users report discrepancies in their balances, it will be harder to determine if the issue is related to failed refunds.

Recommended Mitigation:

Modify the try-catch blocks in _finalize, _cancelFlow, _handleReturn, and _mint to emit the ExecutionFeeRefundFailed event when a refund attempt fails.
For example, the corrected _mint function should look like this:

function _mint(uint256 depositId, uint256 amount, bool refundFee, MarketPrices memory prices) internal {
// ... other code ...
if (refundFee) {
uint256 usedFee = callbackGasLimit * tx.gasprice;
uint256 refundAmount = depositInfo[counter].executionFee - usedFee;
if (depositInfo[counter].executionFee > usedFee) {
try IGmxProxy(gmxProxy).refundExecutionFee(depositInfo[counter].owner, refundAmount) {}
- catch {} // No event emitted here
+ catch (bytes memory reason) {
+ emit ExecutionFeeRefundFailed(depositInfo[counter].owner, refundAmound); // Event emitted here
+ }
}
}
// ... other code ...
}

Similar changes should be made to the other functions mentioned above. This will provide a comprehensive record of refund failures and aid in debugging and monitoring.

Updates

Lead Judging Commences

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

Informational or Gas

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

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

Informational or Gas

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Appeal created

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

Informational or Gas

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Support

FAQs

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