Christmas Dinner

First Flight #31
Beginner FriendlyFoundrySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

H-2 ETH permanently locked in contract

Summary

The contract accepts ETH through the receive() function but provides no mechanism to withdraw it, resulting in permanently locked ETH.

Vulnerability Details

The contract includes a receive() function that accepts ETH:

receive() external payable {
etherBalance[msg.sender] += msg.value;
emit NewSignup(msg.sender, msg.value, true);
}

However, the withdraw() function only handles ERC20 tokens, leaving ETH trapped in the contract with no withdrawal mechanism.

Impact

  • Critical: ETH contributions are permanently locked

  • Users lose access to their ETH deposits

  • No emergency withdrawal mechanism exists

  • Contract accumulates unusable ETH

Tools Used

  • Foundry for testing and verification

  • Manual code review

  • Test demonstrating locked ETH:

function test_etherLock() public {
// User sends ETH
vm.deal(user1, 1 ether);
vm.prank(user1);
(bool success,) = address(dinner).call{value: 1 ether}("");
require(success, "ETH transfer failed");
// Verify ETH is locked
vm.prank(host);
dinner.withdraw();
assertEq(address(dinner).balance, 1 ether);
assertEq(host.balance, 0);
}

Recommendations

  1. Add ETH withdrawal functionality:

function withdrawEth() external onlyHost {
require(block.timestamp > deadline, "Cannot withdraw before deadline");
(bool success, ) = host.call{value: address(this).balance}("");
require(success, "ETH transfer failed");
}
Updates

Lead Judging Commences

0xtimefliez Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

withdraw function lacks functionality to send ether

Support

FAQs

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