Eggstravaganza

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

Game Status Inconsistency in EggHuntGame Contract

Summary

The EggHuntGame contract contains a logical inconsistency in its getGameStatus() function that can lead to contradictory game state reporting. The function can return "Game time elapsed" even when the internal gameActive flag is still set to true. This inconsistency creates a state where the game appears to be simultaneously active and ended, potentially confusing users and causing unexpected behavior in dependent contract functions and frontend interfaces.

Vulnerability Details

The vulnerable function is found in the EggHuntGame contract:

function getGameStatus() external view returns (string memory) {
if (gameActive) {
if (block.timestamp < startTime) {
return "Game not started yet";
} else if (block.timestamp >= startTime && block.timestamp <= endTime) {
return "Game is active";
} else {
return "Game time elapsed";
}
} else {
return "Game is not active";
}
}

The issue arises when block.timestamp exceeds endTime but gameActive is still true. In this scenario, the function returns "Game time elapsed" despite the game still being marked as active in the contract state. This creates a misalignment between the reported status and the actual state that controls contract behavior.

The core problem is that the contract does not automatically set gameActive = false when the time elapses, relying instead on a manual call to the endGame() function by the contract owner.

POC

function testGameStatusInconsistency() public {
// 1. Start the game with a short duration (120 seconds)
vm.prank(owner);
game.startGame(120);
// 2. Verify game is active
assertEq(game.gameActive(), true);
assertEq(game.getGameStatus(), "Game is active");
// 3. Warp time to after endTime
vm.warp(block.timestamp + 150);
// 4. Check status - this shows the inconsistency
assertEq(game.gameActive(), true); // Game is still marked as active
assertEq(game.getGameStatus(), "Game time elapsed"); // But status says elapsed
// 5. Try to search for an egg after time is elapsed but game is still "active"
vm.prank(alice);
vm.expectRevert("Game ended"); // The searchForEgg function will revert
game.searchForEgg();
}

Impact

This status inconsistency has several negative impacts:

  1. User Confusion: Players may receive conflicting information about whether the game is active or not, leading to confusion and potential frustration.

  2. Frontend Discrepancies: UIs relying on the getGameStatus() function may display incorrect information or enter an undefined state, causing poor user experience.

  3. Operational Delays: If the owner does not call endGame() promptly, the contract remains in an inconsistent state where it reports the game has ended but still has gameActive = true.

Tools Used

Manual code review

Recommendations

Add Automatic Game End: Modify the contract to automatically update the gameActive state when the end time is reached:

function searchForEgg() external {
// Check if game time has elapsed and update state if needed
if (gameActive && block.timestamp > endTime) {
gameActive = false;
emit GameEnded(block.timestamp);
}
require(gameActive, "Game not active");
require(block.timestamp >= startTime, "Game not started yet");
require(block.timestamp <= endTime, "Game ended");
// Rest of the function remains the same
// ...
}
function getGameStatus() external view returns (string memory) {
// Update the game status function to be consistent with the logic above
if (!gameActive) {
return "Game is not active";
} else if (block.timestamp < startTime) {
return "Game not started yet";
} else if (block.timestamp > endTime) {
return "Game time elapsed"; // This will never be reached with the auto-end logic
} else {
return "Game is active";
}
}
Updates

Lead Judging Commences

m3dython Lead Judge 4 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.