Rock Paper Scissors

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

Unrestricted Timeout Value

Summary

While this vulnerability requires victims to participate without properly checking timeout values or an attacker to use a second/alt account, it still represents a legitimate risk. The severity is medium because it could potentially be used in a targeted manner to lock funds for unreasonable periods or as part of a market manipulation strategy for the RPSW token. The primary risk is not to sophisticated users who carefully check game parameters, but to casual players who might miss this detail or malicious actor locking tokens as part of market manipulation strategy so that the price of token moves due the decreased demand

Vulnerability Details

There's no upper bound check for the _timeoutInterval in createGameWithEth and createGameWithToken:

function createGameWithEth(uint256 _totalTurns, uint256 _timeoutInterval) external payable {
require(_timeoutInterval >= 5 minutes, "Reveal timeout must be at least 5 minutes");
// No maximum limit check
}

Impact

While setting an extremely long timeout would lock the attacker's own funds, there are several malicious scenarios:

  1. Strategic Token Supply Manipulation: An attacker could:

    • Create multiple token games with extremely long timeouts

    • Effectively remove tokens from circulation

    • Potentially influence token price on external DEXes if enough supply is locked

  2. Griefing Uninformed Players: An attacker could:

    • Create attractive high-value games with extreme timeouts

    • Specifically target inexperienced players who may not understand timeout implications

    • Lock opponent funds for years once they join

  3. Protocol Reputation Damage:

    • Mass creation of "permanent" games clutters the game list

    • Players with locked funds may blame the protocol design

    • Could lead to decreased trust in the platform

PoC

// 1. Create a game with a 100-year timeout
uint256 HUNDRED_YEARS = 60 * 60 * 24 * 365 * 100;
game.createGameWithToken(3, HUNDRED_YEARS);
// 2. Innocent player joins, attracted by potential rewards
// 3. Both commit moves, but neither reveals
// 4. Funds remain locked for 100 years

Tools Used

Manual code review

Recommendations

Add an upper bound for the timeout interval:

require(_timeoutInterval >= 5 minutes, "Reveal timeout must be at least 5 minutes");
require(_timeoutInterval <= 7 days, "Reveal timeout cannot exceed 7 days");
Updates

Appeal created

m3dython Lead Judge 2 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Informational

Code suggestions or observations that do not pose a direct security risk.

Support

FAQs

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