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

Unsecured ETH Management Leading to Potential ETH Withdrawal Failures

Summary:

The withdrawEth function in the GmxProxy contract employs Solidity’s transfer() function to send ETH to the contract owner. However, transfer() imposes a gas limit of 2,300 gas, which may be insufficient if the owner is a smart contract with a non-trivial receive() or fallback() function. This limitation can cause withdrawals to fail unexpectedly, making it difficult for contract owners to retrieve their ETH.

Vulnerability Details:

Location:

  • withdrawEth function in GmxProxy.sol

Code Snippet:

function withdrawEth() external onlyOwner returns (uint256) {
uint256 balance = address(this).balance;
payable(msg.sender).transfer(balance);
return balance;
}

Issue:

  • The function uses transfer(balance), which only forwards 2,300 gas to the recipient.

  • If msg.sender is a smart contract, its fallback function may require more gas to execute.

  • If gas runs out, the transfer silently fails, leaving ETH stuck in the contract.

Root Cause:

  • Solidity’s transfer() enforces a hard gas limit of 2,300, making it unsafe for sending ETH to contract addresses that require more gas for execution.

  • This can lead to unexpected failures when the owner is a smart contract with a complex receive() function.

Impact:

  • ETH withdrawal can fail unexpectedly if the recipient is a contract.

  • The contract owner may be unable to retrieve funds if their wallet is a multisig or a smart contract.

  • While the ETH is not permanently lost, the owner may need to deploy an upgrade or use workarounds, leading to operational inefficiencies.

Tools Used:

  • Manual Code Review

  • **Slither

  • **Foundry

Mitigation:

Replace:

payable(msg.sender).transfer(balance);

With:

(bool success, ) = payable(msg.sender).call{value: balance}("");
require(success, "ETH Transfer failed");

Why this my proposed Fix Works:

Forwards all available gas to the recipient, preventing unexpected failures.
Ensures proper error handling via require(success, ...), preventing silent failures.
**More compatible with multisig wallets

The withdrawEth function in GmxProxy is vulnerable to ETH withdrawal failures due to the use of transfer(). While this does not result in fund loss, it can cause operational disruptions. Replacing transfer() with .call{value: amount}("") mitigates this issue by allowing more gas flexibility and proper error handling. Implementing this fix ensures a more reliable and secure ETH withdrawal mechanism.

Updates

Lead Judging Commences

n0kto Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
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 5 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
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.