Beatland Festival

First Flight #44
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: high
Likelihood: medium
Invalid

[Critical] FestivalPass: ETH Withdrawal Lacks Reentrancy Protection

Root + Impact

Description

  • The withdraw(address target) function allows the contract owner to withdraw all ETH from the contract to a specified address.

    Explain the specific issue:

    The function uses payable(target).transfer(address(this).balance); to send ETH. While transfer forwards only 2300 gas and is generally considered safe, it is now discouraged due to gas cost changes and may break with certain recipient contracts. More importantly, the function does not use a reentrancy guard, and if the withdrawal logic is ever changed to use call (for flexibility or to support contracts as recipients), it would become vulnerable to reentrancy attacks.

// FestivalPass.sol
function withdraw(address target) external onlyOwner {
@> payable(target).transfer(address(this).balance);
}

Risk

Likelihood:

  • Reason 1: This will occur whenever the owner withdraws ETH to a contract address that may have a fallback or receive function.

  • Reason 2: If the withdrawal logic is ever updated to use call instead of transfer, the lack of a reentrancy guard will become critical.

Impact:

  • Impact 1: Potential loss of all ETH in the contract if reentrancy is possible.

  • Impact 2: Withdrawal may fail if the recipient is a contract with a complex fallback/receive function.

Proof of Concept

// If transfer is replaced with call, a malicious contract could reenter withdraw()

Recommended Mitigation

- payable(target).transfer(address(this).balance);
+ // Add OpenZeppelin's ReentrancyGuard and use nonReentrant modifier
+ // Consider using (bool sent, ) = target.call{value: address(this).balance}("");
+ // require(sent, "ETH transfer failed");
Updates

Lead Judging Commences

inallhonesty Lead Judge 25 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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