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

Execution Fee Drain via Unprotected Refunds

Summary

The _payExecutionFee function sends ETH to GmxProxy without validating the msg.value. This allows an attacker to send an inflated execution fee (more ETH than required) and potentially manipulate the contract's state. The _payExecutionFee function does not check if the msg.value is reasonable or matches the required execution fee.

https://github.com/CodeHawks-Contests/2025-02-gamma/blob/84b9da452fc84762378481fa39b4087b10bab5e0/contracts/GmxProxy.sol#L341-L344

The refundExecutionFee function allows arbitrary address recipients without proper checks. This means an attacker can specify a malicious recipient address to drain ETH from the GmxProxy contract.

Vulnerability Details

Exploit Scenario

Step 1: Attacker Deposits with Inflated Execution Fee

  • The attacker calls the deposit function in PerpetualVault.sol and sends an inflated execution fee (e.g., 10 ETH instead of the required 0.1 ETH).

  • The _payExecutionFee function in PerpetualVault.sol does not validate the msg.value, so it accepts the inflated fee and transfers the ETH to GmxProxy.

Step 2: Attacker Calls refundExecutionFee with Malicious Recipient

  • The attacker calls the refundExecutionFee function in GmxProxy.sol and specifies a malicious recipient address (e.g., their own wallet).

  • The refundExecutionFee function does not validate the recipient address or the amount being refunded, so it transfers the ETH to the attacker's address.

Step 3: ETH is Drained from GmxProxy

  • The attacker repeats this process multiple times, draining all ETH from the GmxProxy contract.

  • As a result, the protocol loses its ability to execute orders, as it no longer has ETH to pay for gas fees.

The _payExecutionFee function does not check if the msg.value is reasonable or matches the required execution fee. This allows an attacker to send an inflated amount of ETH, which can later be exploited.

The refundExecutionFee function does not validate the recipient address. This allows an attacker to specify their own address and drain ETH from the contract.

Impact

  • It allows an attacker to drain all ETH from the GmxProxy contract.

  • It disrupts the protocol's ability to execute orders, which is a critical function.

  • It can be exploited repeatedly with minimal cost to the attacker.

Tools Used

manual code review

Recommendations

  • Restrict the refundExecutionFee function to only allow the PerpetualVault contract to call it.

  • Validate the recipient address to ensure it is a legitimate user.

  • Ensure that the msg.value matches the required execution fee. Revert if the amount is too high or too low.

Updates

Lead Judging Commences

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

Suppositions

There is no real proof, concrete root cause, specific impact, or enough details in those submissions. Examples include: "It could happen" without specifying when, "If this impossible case happens," "Unexpected behavior," etc. Make a Proof of Concept (PoC) using external functions and realistic parameters. Do not test only the internal function where you think you found something.

Support

FAQs

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