Rock Paper Scissors

First Flight #38
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

PlayerB can join with 0 ether in a game which is created using Token, breaking the rule of game joining

Summary

If player A created a game with Winning Token, player B can join that game using 0 ether in short without staking any asset.

Vulnerability Details

The RockPaperScissors::joinGameWithEth function is not checking if the game.bet is zero or not. so, If player A has started the game with Winning token then player B can join this game by calling RockPaperScissors::joinGameWithEth function without sending any ETh or Token. ideally it should check if the game requires Winning token or ETH for participation using bet variable.

Impact

Player B can join without staking his asset (ETH or Winning Token)

Tools Used

  • foundry test

    Add this following test case in RockPaperScissorsTest.t.sol test suit:

function testCreateGameWithTokenAndJoinWithEth() public {
vm.startPrank(playerA);
// Approve token transfer
token.approve(address(game), 1);
// Create a game with token
vm.expectEmit(true, true, false, true);
emit GameCreated(0, playerA, 0, TOTAL_TURNS);
gameId = game.createGameWithToken(TOTAL_TURNS, TIMEOUT);
vm.stopPrank();
vm.prank(playerB);
game.joinGameWithEth{value: 0 ether}(gameId);
(address storedPlayerA, address storedPlayerB,,,,,,,,,,,,,,) = game.games(gameId);
assertEq(storedPlayerA, playerA);
assertEq(storedPlayerB, playerB);
}

Recommendations

Add the following check to RockPaperScissors::joinGameWithEth function:

function joinGameWithEth(uint256 _gameId) external payable {
Game storage game = games[_gameId];
require(game.state == GameState.Created, "Game not open to join");
require(game.playerA != msg.sender, "Cannot join your own game");
require(block.timestamp <= game.joinDeadline, "Join deadline passed");
@> require(game.bet != 0, "This game requires Winning token bet");
require(msg.value == game.bet, "Bet amount must match creator's bet");
game.playerB = msg.sender;
emit PlayerJoined(_gameId, msg.sender);
}

Or we should calculate ETH equivalent of winning token

Updates

Appeal created

m3dython Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Game Staking Inconsistency

joinGameWithEth function lacks a check to verify the game was created with ETH

m3dython Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Game Staking Inconsistency

joinGameWithEth function lacks a check to verify the game was created with ETH

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.