TwentyOne

First Flight #29
Beginner FriendlyGameFiFoundrySolidity
100 EXP
View results
Submission Details
Severity: medium
Valid

Logic in startGame allows users to send more than 1 ETH

Summary

The startGame function in the TwentyOne contract allows users to send more than 1 ETH to participate in the game, despite the requirement that players must deposit exactly 1 ETH to play. This behavior violates the stated game rules, creates ambiguity about how excess ETH is handled, and could lead to user confusion or disputes.

Vulnerability Details

In the startGame function, the following line checks whether the user sends at least 1 ETH:

require(msg.value >= 1 ether, "not enough ether sent");

This allows users to send more than 1 ETH, which is inconsistent with the stated rules of the game, where a player must send exactly 1 ETH to start a game.

Game Requirement:

  • A player must deposit exactly 1 ETH to play.

Current Implementation Issue:

  • Users can send any amount greater than or equal to 1 ETH, but only 1 ETH is used for the game.

  • The excess ETH remains in the contract’s balance without clear documentation or purpose, which can lead to:

    • Ambiguity for users about the handling of excess ETH.

    • Potential disputes over the fairness of the game.


Example Scenario

Initial Setup:

  • A user decides to participate in the game.

Execution:

  • The user mistakenly sends 2 ETH to the startGame function instead of 1 ETH.

Outcome:

  • The game starts successfully because the require condition is satisfied.

  • However, the extra 1 ETH is left in the contract’s balance, creating ambiguity about its purpose and fairness.

Impact

  • Violation of Game Rules:

  • Allowing users to send more than 1 ETH contradicts the stated rules, which require exactly 1 ETH to participate.

  • User Confusion and Disputes:

    • Players may mistakenly believe that sending more ETH increases their chances of winning or influences the game, leading to dissatisfaction and disputes.

  • Unintended Ether Management:

    • Excess ETH left in the contract balance is not accounted for in the game logic, creating potential discrepancies in contract funds and payouts.

Tools Used

Manual Review

Recommendations

  1. Restrict ETH to Exactly 1 ETH:
    Modify the require statement in the startGame function to enforce the exact amount of 1 ETH:

    require(msg.value == 1 ether, "You must send exactly 1 ETH to play");
  2. Refund Excess ETH (Optional):
    If flexibility is desired, allow users to send more than 1 ETH and refund the excess:

    require(msg.value >= 1 ether, "You must send at least 1 ETH to play");
    uint256 excess = msg.value - 1 ether; if (excess > 0) {
    payable(msg.sender).transfer(excess);
  3. Improve Error Messaging:
    Provide clear feedback to users who send an incorrect amount of ETH:

    require(msg.value == 1 ether, "Send exactly 1 ETH to play. Excess or insufficient ETH is not accepted.");
Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Insufficient balance for payouts / Lack of Contract Balance Check Before Starting Game

Support

FAQs

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