Eggstravaganza

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

Centralization Risk: Owner-Only Game Control Functions

Summary

The EggHuntGame contract has several functions, including startGame(), that are restricted to the contract owner. This creates a centralization risk where the owner has exclusive control over critical game functionality.

Vulnerability Details

The startGame() function uses the onlyOwner modifier:

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;
gameActive = true;
emit GameStarted(startTime, endTime);
}

This restricts the ability to start the game exclusively to the contract owner. Similar restrictions exist on other admin functions like endGame() and setEggFindThreshold().

Impact

Medium impact (centralization vulnerability). While this design choice is intentional for administrative purposes, it introduces several risks:

  1. Single point of failure - if the owner key is compromised, game operation could be disrupted

  2. Trust requirement - users must trust the owner not to manipulate game conditions unfairly

  3. Censorship risk - owner could selectively prevent certain games from starting

  4. Key loss risk - if owner keys are lost, the game could become permanently inoperable

Tools Used

Manual code review

Recommendations

  1. Consider implementing one or more of these mitigations:

  2. Time-lock mechanism: Add a delay between owner-initiated actions and their execution to allow users to react to potentially malicious actions.

  3. Multi-signature governance: Replace the single owner with a multi-signature scheme requiring multiple approvals for administrative actions.

  4. DAO or community governance: Transition control to a decentralized autonomous organization where token holders vote on key decisions.

  5. Automated scheduling: Implement an automated game schedule that doesn't rely on owner intervention for regular operations.

// Example time-lock implementation
mapping(bytes32 => uint256) public pendingActions;
uint256 public constant TIME_LOCK_DELAY = 2 days;
function proposeStartGame(uint256 duration) external onlyOwner {
bytes32 actionId = keccak256(abi.encodePacked("startGame", duration));
pendingActions[actionId] = block.timestamp + TIME_LOCK_DELAY;
emit GameStartProposed(duration, pendingActions[actionId]);
}
function executeStartGame(uint256 duration) external onlyOwner {
bytes32 actionId = keccak256(abi.encodePacked("startGame", duration));
require(pendingActions[actionId] > 0, "Action not proposed");
require(block.timestamp >= pendingActions[actionId], "Time lock not expired");
// Current startGame logic here
// ...
delete pendingActions[actionId];
}
Updates

Lead Judging Commences

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