The contract allows players to send more than 1 ether to start the game, which violates the game’s intended betting logic. Players are supposed to bet exactly 1 ether and win 2 ether if they succeed. However, if a player sends more than 1 ether, they only win the hardcoded 2 ether, losing the excess ether sent. This inconsistency is due to the lack of a strict check on msg.value
in the startGame()
function.
The startGame()
function does not enforce a condition that ensures the player sends exactly 1 ether. The function logic accepts any amount greater than or equal to 1 ether. This behavior is evident in the following code snippet:
As a result, players can start the game with more than 1 ether, but the endGame()
function is hardcoded to transfer only 2 ether as winnings. This leads to a situation where the player loses the excess amount they sent.
The issue was replicated with the following test case:
Output:
From the logs, we see:
The user started with 10 ether and ended with 9 ether after winning, losing the excess 1 ether they sent to start the game.
The contract balance shows the excess 1 ether added to it.
The issue stems from the startGame()
function accepting msg.value >= 1 ether
instead of enforcing msg.value == 1 ether
.
Relevant function snippets:
startGame()
Accepts any value greater than or equal to 1 ether.
Does not refund or enforce exact ether for starting the game.
endGame()
Transfers a hardcoded 2 ether as winnings regardless of the initial msg.value
.
Financial Loss for Player:
Players can lose any excess ether sent beyond 1 ether when starting the game.
In the test case, the player sent 3 ether and lost 1 ether even after winning the game.
Inconsistent Game Logic:
The betting logic contradicts the intended behavior of betting 1 ether and winning 2 ether.
Unfair Advantage to Contract:
Excess ether sent by players is retained in the contract, leading to unintended financial gains for the contract.
Forge (Foundry): Used to run and validate test cases.
EVM Error Logs: Inspected transaction traces and logs to confirm unexpected ether retention.
Manual Code Review: Identified the lack of msg.value
validation in startGame()
.
Enforce Exact Betting Amount in startGame()
: Update the startGame()
function to ensure players can only bet exactly 1 ether. This can be done as follows:
Revert for Incorrect Ether Amounts: Any transaction sending more or less than 1 ether should revert with an appropriate error message.
Test New Logic: Write additional test cases to confirm the contract reverts if msg.value
is not exactly 1 ether.
Documentation Update: Clearly document the betting rules for players, emphasizing the requirement to send exactly 1 ether.
By implementing these changes, the game will maintain fairness and align with its intended logic, avoiding unintended ether loss for players.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.