In the RockPaperScissors
contract, there's a vulnerability that allows a malicious actor to replace the legitimate PlayerB
after they've joined a game but before any moves are committed. This occurs because the game remains in GameState.Created
status after PlayerB joins, and the join functions (joinGameWithEth
and joinGameWithToken
) only check the game state but not whether playerB is already set.
PlayerA creates a game using createGameWithEth()
or createGameWithToken()
functions
A legitimate PlayerB joins using the appropriate join function, which sets game.playerB
to their address
Before either player calls commitMove()
(which would change the game state to GameState.Committed
), an attacker calls the same join function
Since the game is still in GameState.Created
status and there's no check to verify if playerB is already set, the attacker successfully replaces the legitimate PlayerB
The original PlayerB has now lost their position in the game and any ETH or token they transferred
This vulnerability allows malicious actors to:
Disrupt gameplay by continuously replacing legitimate players
Create denial of service conditions for legitimate players trying to join games
Causes the legitimate PlayerB to lose their ETH or token without being able to play
Add a check in both join functions to verify that playerB has not been set
joinGameWithEth function lacks a check to verify the game was created with ETH
joinGameWithEth function lacks a check to verify the game was created with ETH
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.