Rock Paper Scissors

First Flight #38
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: medium
Valid

Lack of Emergency Function to Recover Stuck ETH Sent by Mistake

Description:

The contract includes a receive() function, allowing it to accept ETH transfers. However, it lacks an admin or emergency function to withdraw ETH that could be accidentally sent to the contract address outside the intended game logic.

While protocol fees can be withdrawn via withdrawFees(), any ETH sent directly (or residual ETH due to unexpected situations) would remain permanently locked.

Impact

  • ETH mistakenly sent to the contract cannot be recovered.

  • Funds could accumulate over time due to user errors.

  • Operational inefficiency and potential future need for contract migration to recover assets.

Tools Used

Manual Review and Foundry

Recommendations

Implement an admin-only rescueETH() function to recover accidentally sent ETH, while ensuring protocol fees remain protected:

+ function rescueETH(uint256 _amount) external {
+ require(msg.sender == adminAddress, "Only admin can rescue ETH");
+ uint256 ethBalance = address(this).balance;
+ uint256 ethDisponible = ethBalance - accumulatedFees;
+ require(_amount <= ethDisponible, "Insufficient balance");
+ (bool success, ) = adminAddress.call{value: _amount}("");
+ require(success, "Transfer failed");
+ }

This allows recovery of stuck ETH without affecting accumulatedFees. Use only for exceptional cases.

Updates

Appeal created

m3dython Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Orphaned ETH due to Unrestricted receive() or Canceled Game

ETH sent directly to the contract via the receive function or after a canceled game becomes permanently locked

Support

FAQs

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