The RockPaperScissors
game contract contains a critical security vulnerability in both the joinGameWithEth()
and joinGameWithToken()
functions. Neither function validates whether game.playerB
has already been set, allowing multiple players to join the same game and overwrite the previous playerB value. This results in the original joining player losing their staked ETH or tokens without any possibility of playing the game or recovering their funds.
Both functions for joining games only check that the game is in the "Created" state, but fail to validate whether another player has already joined the game as playerB
. When a player joins a game, they commit their stake (either ETH or tokens), but if another player calls the same function afterward, they will overwrite the playerB address value without any validation.
The original playerB loses access to the game and their stake remains locked in the contract with no mechanism to recover it, while the latest player to call the function becomes the new playerB.
Proof of Concept:
The impact of this vulnerability is High due to loss of funds and ease of execution:
Any player who joins a game can have their position locked forever by another player.
This vulnerability can be exploited repeatedly on the same game, causing multiple players to lose their stakes.
This fundamentally breaks the game and creates a significant financial risk for any participant.
The vulnerability can be weaponized by malicious users to undermine the whole system to become not viable anymore.
Foundry
Add a validation check in both functions to ensure playerB has not already been set.
Game state remains Created after a player joins
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.