The Rock Paper Scissors game smart contract contains a logic error in the turn counting mechanism within the _determineWinner function. Due to an incorrect comparison operator (< instead of <=), games will always execute one fewer turn than the user-specified value in totalTurns. This results in users not receiving the full number of turns they expect, potentially affecting game outcomes and user experience.
The vulnerability is located in the _determineWinner function at lines 526-545:
The issue is in the condition game.currentTurn < game.totalTurns. When a game is created, currentTurn is initialized to 1. For a game with totalTurns set to n, the game will execute turns with currentTurn values of 1, 2, ..., n-1, and then end. The nth turn is never played because when currentTurn reaches n, the condition n < n evaluates to false.
Let's trace through an example with totalTurns set to 5:
Start: currentTurn = 1
After first turn completion: 1 < 5 is true, increment currentTurn to 2
After second turn completion: 2 < 5 is true, increment currentTurn to 3
After third turn completion: 3 < 5 is true, increment currentTurn to 4
After fourth turn completion: 4 < 5 is true, increment currentTurn to 5
For the fifth turn: 5 < 5 is false, so the game ends without playing the fifth turn
This means a game created with totalTurns = 5 will only play 4 actual turns.
This bug has several impacts:
Reduced Game Length: Users will always get one fewer turn than they specified and expect.
Potential Game Outcome Manipulation: Since the contract requires totalTurns to be odd (to avoid ties), this bug could make some games have an even number of turns, potentially resulting in ties that shouldn't occur.
User Experience Degradation: Players expecting a specific number of turns will find their games shorter than anticipated.
Score Calculation Impact: The final turn being skipped could affect the final score and outcome of close games.
Manual code review
Logic flow analysis
State transition simulation
The fix for this issue is straightforward - change the comparison operator from < to <=:
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.