Eggstravaganza

First Flight #37
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: low
Invalid

Unbounded Game Duration in EggHuntGame::startGame Enables Potential Game State Manipulation

Summary

The EggHuntGame::startGame function only implements a minimum duration check (MIN_GAME_DURATION) but lacks a maximum duration limit. This allows the game owner to set arbitrarily long game durations, potentially leading to unintended game states and timestamp overflow risks.

Vulnerability Details

https://github.com/CodeHawks-Contests/2025-04-eggstravaganza/blob/f83ed7dff700c4319bdfd0dff796f74db5be4538/src/EggHuntGame.sol#L41-L48

Current implementation in EggHuntGame::startGame:

function startGame(uint256 duration) external onlyOwner {
require(!gameActive, "Game already active");
require(duration >= MIN_GAME_DURATION, "Duration too short");
startTime = block.timestamp;
endTime = block.timestamp + duration; // No upper bound check
gameActive = true;
emit GameStarted(startTime, endTime);
}

The vulnerability allows:

  1. Setting extremely long game durations (up to type(uint256).max)

  2. Creating games that could run for years or decades

  3. Potential timestamp overflow if block.timestamp + duration exceeds type(uint256).max

Example exploitation:

function testExcessiveDuration() public {
// Set maximum possible duration
game.startGame(type(uint256).max);
// Game will run for ~10^77 years
assertEq(game.endTime(), block.timestamp + type(uint256).max);
// Game remains active indefinitely
vm.warp(block.timestamp + 100 years);
assertEq(game.getGameStatus(), "Game is active");
}

Impact

  • Games could remain active indefinitely

  • Difficulty in managing game states

  • Potential timestamp overflow risks

  • Confusion for players about game duration

  • Possible interference with future game iterations

Tools Used

Recommendations

. Implement a maximum duration limit:

contract EggHuntGame is Ownable {
uint256 public constant MIN_GAME_DURATION = 60;
uint256 public constant MAX_GAME_DURATION = 30 days;
function startGame(uint256 duration) external onlyOwner {
require(!gameActive, "Game already active");
require(duration >= MIN_GAME_DURATION, "Duration too short");
require(duration <= MAX_GAME_DURATION, "Duration too long");
// Additional safety check for timestamp overflow
require(
block.timestamp + duration >= block.timestamp,
"Duration overflow"
);
startTime = block.timestamp;
endTime = block.timestamp + duration;
gameActive = true;
emit GameStarted(startTime, endTime);
}
}
  1. Additional recommendations:

    • Add ability to extend/reduce game duration within bounds

    • Implement game phases for longer tournaments

    • Add emergency game end functionality

    • Consider using OpenZeppelin's SafeMath for timestamp calculations

    • Add events for duration modifications

Updates

Lead Judging Commences

m3dython Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

Trusted Owner

Owner is trusted and is not expected to interact in ways that would compromise security

Support

FAQs

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