The createGameWithEth()
function in the contract initializes a game's joinDeadline
using block.timestamp + joinTimeout
. However, the joinTimeout
variable is unbounded and lacks input validation. This opens up the potential for abuse, such as games that never expire or games with deadlines far into the future, leading to storage bloat or denial-of-service conditions in game lifecycle management.
Function:
function createGameWithEth(uint256 _totalTurns, uint256 _timeoutInterval) external payable returns (uint256)
its found in the following line:
The value of joinTimeout
is used without any constraints or range checks. If this variable is:
Publicly modifiable
Unintentionally initialized to a very high value (e.g., type(uint256).max
)
…it would allow a game to set a joinDeadline
that is years .
This creates a logic flaw, especially if other parts of the contract rely on the joinDeadline
to:
Allow or reject players from joining
Refund bets after a timeout
Clean up abandoned games
Without time-based expiry, such games may linger indefinitely, consuming contract storage and resources.
Storage Bloat: Attackers could spam the contract with games that remain active forever, leading to unnecessary storage consumption and increased gas for legitimate users.
Economic Lock-in: Funds placed in such games may become inaccessible if no timeout ever occurs.
Manual code review
Validate the joinTimeout
value: Add an upper and lower bound to ensure reasonable deadline values:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.