The RockPaperScissors::createGameWithEth
and RockPaperScissors::createGameWithToken
functions allows users to specify the number of game turns using the _totalTurns parameter.
Although the function validates that _totalTurns is greater than zero and an odd number, it does not
enforce an upper limit on the number of turns.
Internally, the game uses uint8 types to store player scores (scoreA and scoreB). A uint8 has a maxi‑
mum value of 255. If a game is configured to allow more than 255 turns, and one player wins over 255
rounds, the scoreX++ operation will cause an overflow and trigger a revert due to built‑in overflow
checks in Solidity versions ≥ 0.8.
This creates a scenario where malicious users can exploit the absence of an upper bound to manipu‑
late or break the game logic
Proof of Concept:
Create a game with totalTurns set to a value greater than 255.
Join the game using a second account.
Simulate gameplay where playerA wins every round, incrementing scoreA until it exceeds the uint8 limit.
If exploited, this issue can:
- Cause score variables to overflow and trigger transaction reverts mid-game.
- Prevent games from finishing correctly, leading to denial of service for both players.
- Lock up ETH bets indefinitely if _determineWinner cannot complete due to score overflow.
This vulnerability may be used to grief opponents or disrupt the contract's availability by repeatedly creating or participating in games with abnormally high turn counts.
Foundry
Introduce a Maximum Turn Limit: Add a validation check to cap the number of game turns to a reasonable maximum that cannot exceed the capacity of uint8 (i.e., 255):
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.