Rock Paper Scissors

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

High Gas Denial of Service (DoS) via Unbounded _totalTurns in createGameWithEth

Summary

The createGameWithEth function in RockPaperScissors.sol lacks an upper bound check on the _totalTurns parameter, allowing any user to create a game with an extremely high number of turns. This leads to a Denial of Service (DoS) as subsequent game phases (e.g., committing or revealing moves) will become computationally infeasible due to extreme gas consumption. This could render the game unusable or permanently stalled.

Vulnerability Details

Function Affected: createGameWithEth
Line: 92 – 116
Code Location:

function createGameWithEth(uint256 _totalTurns, uint256 _timeoutInterval) external payable returns (uint256)

There are checks ensuring _totalTurns > 0 and that it is odd, but no upper bound is enforced, which allows an attacker to pass extremely high values (e.g., 2**256 - 1). This causes:

  • Gas-intensive storage growth (due to _totalTurns being stored and incremented during gameplay)

  • Unresolvable games (e.g., committing or revealing millions of turns)

  • Risk of failing transactions and locked funds

Impact

High gas costs for all game participants

  • Failure to resolve game rounds due to gas limits being exceeded

  • Unplayable game sessions, blocking users from recovering ETH or completing the game

  • Potential loss of user trust in the platform

Proof of Concept (PoC)

contract MaliciousUser {
RockPaperScissors public gameContract;
constructor(address _gameContract) {
gameContract = RockPaperScissors(_gameContract);
}
function exploit() external payable {
uint256 maliciousTurns = 2**256 - 1;
uint256 timeout = 5 minutes;
gameContract.createGameWithEth{value: msg.value}(maliciousTurns, timeout);
}
}

Tools Used

  • Remix IDE

  • Manual Code Review

  • Custom Exploit Contract

Recommendations

Add an upper bound check for _totalTurns to limit the number of turns per game to a reasonable amount, for example:

require(_totalTurns <= 101, "Too many turns");

Alternatively, use a configurable max limit that can be adjusted by an admin if needed:

uint256 public maxAllowedTurns = 101;
require(_totalTurns <= maxAllowedTurns, "Too many turns");
Updates

Appeal created

m3dython Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
m3dython Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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