The joinGameWithEth
function allows multiple players to join the same game as "Player B", overwriting the previous Player. This results in stolen game slots and permanently locked funds for the overwritten players, as there is no mechanism to withdraw their funds once overwritten.
The vulnerability exists in both joinGameWithEth
and joinGameWithToken
functions. When a second player joins a game, the contract correctly updates the playerB
address but fails to update the game state from GameState.Created
to another state which will disable joining the game once it has started and both players complete.
Since the game remains in the Created
state after a player joins, other players can call the join functions again with the same game ID. This overwrites the previous playerB
address with the new joiner's address, effectively stealing the game slot and locking the previous player's funds in the contract.
Vulnerable Code:
The same issue exists in joinGameWithToken
function.
Financial Loss: Players who are overwritten lose their bet amount, which becomes permanently locked in the contract.
Denial of Service: The legitimate second player is denied participation in the game they joined.
Manual code review
Foundry for test case development and verification
A test case was developed that demonstrates the vulnerability:
There two ways to solve this issue.
Update Game State: After a player joins a game update the state and add a check to prevent others joining once this state is active
Check Player B Empty: Add a check to ensure playerB
is empty before allowing a join:
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.