Rock Paper Scissors

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

Timeout Exploitation and Griefing Vulnerabilities in Rock Paper Scissors Game

Summary

The Rock Paper Scissors game implementation lacks sufficient penalties and protections against timeout abuse and griefing behavior. Players can strategically manipulate timeouts and reveals to gain unfair advantages or grief opponents.

Vulnerability Details

Vulnerability 1: Strategic Timeout Exploitation

function timeoutReveal(uint256 gameId) external {
Game storage game = games[gameId];
require(game.state == GameState.Committed, "Game not in reveal phase");
require(block.timestamp > game.revealDeadline, "Reveal phase not timed out yet");
// Winning player gets full pot minus fee
if (playerARevealed && !playerBRevealed) {
_finishGame(gameId, game.playerA); // Player A wins
}
// ... similar for Player B
}

Attack Scenario:

  1. Player A and B both commit moves

  2. Player A reveals their move

  3. Player B sees they would lose, intentionally doesn't reveal

  4. Game times out, both players get refunded

  5. No penalty for B's griefing behavior

Vulnerability 2: Reveal Phase Manipulation

function reveal(uint256 gameId, uint8 move, bytes32 salt) external {
Game storage game = games[gameId];
bytes32 commitment = keccak256(abi.encodePacked(move, salt));
if (msg.sender == game.playerA) {
require(commitment == game.commitmentA, "Invalid move/salt");
game.moveA = move;
}
// ... similar for Player B
}

Attack Scenario:

  1. Player A reveals first

  2. Player B waits until near timeout

  3. B can decide whether to reveal or timeout based on A's move

  4. No incentive for timely reveals

Vulnerability 3: Multi-Game Griefing

function createGame() external payable {
// No limit on concurrent games
// No tracking of timeout history
games[gameId] = Game({
playerA: msg.sender,
bet: msg.value,
state: GameState.Created
});
}

Attack Scenario:

  1. Malicious player creates multiple games

  2. Times out or griefs consistently

  3. No reputation system or penalties

  4. Wastes gas and time of honest players

Impact

  • Players can avoid losses through timeout manipulation

  • No incentive for timely play

  • Potential DOS through mass game creation

  • Poor player experience

  • Reduced protocol adoption

Tools Used

Recommendations

  • Implement Timeout Penalties:

struct Player {
uint256 timeoutCount;
uint256 lastTimeout;
uint256 penaltyBalance;
}
function handleTimeout(address player) internal {
players[player].timeoutCount++;
uint256 penalty = calculatePenalty(players[player].timeoutCount);
players[player].penaltyBalance += penalty;
// Deduct from refund amount
}
  • Add Anti-Griefing Mechanisms:

struct GameLimits {
uint256 maxConcurrentGames;
uint256 minTimeBetweenGames;
uint256 requiredStake;
}
function createGame() external payable {
require(getPlayerActiveGames(msg.sender) < limits.maxConcurrentGames);
require(block.timestamp - lastGameTime[msg.sender] > limits.minTimeBetweenGames);
require(msg.value >= limits.requiredStake);
}
  • Implement Progressive Reveal Requirements:

struct RevealPhase {
uint256 baseTime;
uint256 maxExtension;
uint256 revealBond;
}
function reveal(uint256 gameId, uint8 move, bytes32 salt) external payable {
require(msg.value >= currentRevealBond(), "Insufficient reveal bond");
// Bond returned on timely reveal
// Bond partially slashed on timeout
}
  • Add Economic Incentives:

struct Rewards {
uint256 earlyRevealBonus;
uint256 consistentPlayBonus;
uint256 reputationMultiplier;
}
function calculatePayout(address winner, uint256 gameId) internal returns (uint256) {
uint256 basePayout = games[gameId].totalPot;
uint256 bonus = calculateTimelyPlayBonus(winner, gameId);
return basePayout + bonus;
}

Additional Considerations

  1. Reputation System:

  • Track player history

  • Adjust requirements based on reputation

  • Implement progressive penalties

  1. Time Management:

  • Dynamic timeout periods

  • Grace periods for network issues

  • Sliding scale penalties

  1. Economic Balance:

  • Carefully tune penalty amounts

  • Ensure rewards cover gas costs

  • Consider protocol revenue impact

  1. Implementation Requirements:

  • Extensive testing of timeout scenarios

  • Clear documentation of penalties

  • User interface warnings

  • Emergency pause functionality

The vulnerabilities should be addressed before mainnet deployment to ensure fair gameplay and protocol sustainability.

Updates

Appeal created

m3dython Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

Invalid TimeoutReveal Logic Error

timeoutReveal function incorrectly allows execution and game cancellation even when only one player has committed

Support

FAQs

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