GivingThanks

First Flight #28
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: medium
Invalid

ETH Can Be Permanently Locked in Contract

Summary

The GivingThanks contract lacks withdrawal mechanisms, which can result in ETH being permanently locked in the contract if sent through direct transfers or failed transactions.

Vulnerability Details

The contract:

  • Has no withdraw function

  • No fallback/receive functions

  • No emergency ETH recovery mechanism

  • Lacks admin functions to rescue stuck funds

contract GivingThanks {
// No withdraw mechanism
// No fallback function
// No emergency functions
}

Impact

  • ETH can be permanently locked in contract

  • No way to recover mistakenly sent funds

  • Admin/owner cannot rescue funds

  • Potential loss of user funds through failed transactions

  • Force-sent ETH via selfdestruct remains trapped

Tools Used

  • Manual code review

  • Foundry testing framework

  • Custom test demonstrating stuck ETH:

function testLockedEthInContract() public {
vm.deal(address(charityContract), 1 ether);
assertEq(address(charityContract).balance, 1 ether);
vm.prank(admin);
(bool success,) = address(charityContract).call{value: 0}("");
assertFalse(success);
assertEq(address(charityContract).balance, 1 ether);
}

Recommendations

  1. Add withdraw function with access control:

function withdrawStuckEth() external onlyOwner {
(bool success,) = msg.sender.call{value: address(this).balance}("");
require(success, "Transfer failed");
emit WithdrawnStuckEth(msg.sender, address(this).balance);
}
event WithdrawnStuckEth(address indexed to, uint256 amount);
  1. Add receive function to handle direct transfers:

receive() external payable {
emit ReceivedEth(msg.sender, msg.value);
}
Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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