Rock Paper Scissors

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

Missing game type check leads to free game entry

Summary

Due to insufficient validation between game types (Token vs ETH) and the use of game.bet = 0 for token games, an attacker can bypass the token requirement by calling joinGameWithEth() on a token-based game, allowing them to join without providing either tokens or ETH.

Vulnerability Details

In the RockPaperScissors contract, games can be created in two modes:

  1. Token-based games where players must provide winning tokens

  2. ETH-based games where players must provide ETH as bets

The vulnerability exists because:

  1. Token games set game.bet = 0 during creation

  2. The joinGameWithEth() function only validates that the sent ETH matches game.bet

  3. There is no explicit game type validation

Example Attack Flow:

// Player A creates token game
function createGameWithToken() {
// Transfers 1 token from Player A
game.bet = 0; // Sets bet to 0
}
// Player B exploits by joining with ETH function
function joinGameWithEth() {
require(msg.value == game.bet); // Passes because bet is 0
// No token required
// Joins game for free
}

Impact

Some users can join games for free. This breaks game economics and fairness and damages trust in the game protocol.

Tools Used

Foundry

Recommendations

Add Game Type Enumeration

enum GameType {
ETH,
TOKEN
}
struct Game {
// ... existing fields ...
GameType gameType;
}

Set Game Type During Creation

function createGameWithToken(...) {
// ...
game.gameType = GameType.TOKEN;
}
function createGameWithEth(...) {
// ...
game.gameType = GameType.ETH;
}

Validate Game Type During Join

function joinGameWithToken(uint256 _gameId) external {
Game storage game = games[_gameId];
require(game.gameType == GameType.TOKEN, "Must use token to join token game");
// ... rest of function
}
function joinGameWithEth(uint256 _gameId) external payable {
Game storage game = games[_gameId];
require(game.gameType == GameType.ETH, "Must use ETH to join ETH game");
// ... rest of function
}
Updates

Appeal created

m3dython Lead Judge 7 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.