Eggstravaganza

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

Inconsistent game state management creates contract state ambiguity

Summary

The EggHuntGame contract has conflicting mechanisms for determining if the game is active, creating a state where the game can be simultaneously expired by time but still active by flag.

Vulnerability Details

The contract maintains two separate mechanisms for determining if the game is active:

## EggHuntGame.sol
function searchForEgg() external {
require(gameActive, "Game not active");
require(block.timestamp >= startTime, "Game not started yet");
require(block.timestamp <= endTime, "Game ended");
// ... rest of function
}
function endGame() external onlyOwner {
require(gameActive, "Game not active");
gameActive = false;
emit GameEnded(block.timestamp);
}

The issue is that gameActive remains true even after endTime has passed until someone explicitly calls endGame(). This creates a discrepancy between the time-based check and the state flag.

Impact

  • The contract exists in an ambiguous state where time-based checks and state-based checks contradict each other

  • Players can continue to call searchForEgg() after the intended end time but before endGame() is called

  • The game state does not automatically transition when time expires, requiring manual intervention

  • Creates confusion about when the game is actually over

  • Undermines the deterministic nature of the contract

  • Secondary effects include potential front-running and selective ending by the owner

Tools Used

  • Manual code review

Recommendations

Implement automatic game state management based on time:

+ function isGameActive() public view returns (bool) {
+ return gameActive && block.timestamp >= startTime && block.timestamp <= endTime;
+ }
function searchForEgg() external {
- require(gameActive, "Game not active");
- require(block.timestamp >= startTime, "Game not started yet");
- require(block.timestamp <= endTime, "Game ended");
+ require(isGameActive(), "Game not active or outside game timeframe");
// ... rest of function
}
+ function checkGameStatus() public {
+ if (gameActive && block.timestamp > endTime) {
+ gameActive = false;
+ emit GameEnded(block.timestamp);
+ }
+ }
Updates

Lead Judging Commences

m3dython Lead Judge 8 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Incomplete end game handling

Incorrect values reported when a game is ended early

Support

FAQs

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

Give us feedback!