Eggstravaganza

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

Centralised Control Over Egg Discovery Probability

Summary

The setEggFindThreshold function allows the contract owner to arbitrarily modify the egg discovery chance at any time during an active game. This creates an unfair environment where the owner could manipulate success probabilities to benefit specific players or themselves.

Vulnerability Details

Affected Code:

// EggHuntGame.sol
function setEggFindThreshold(uint256 newThreshold) external onlyOwner {
require(newThreshold <= 100, "Threshold must be <= 100");
eggFindThreshold = newThreshold;
}

Exploitation Scenario:

  1. Game is active with default 20% success chance

  2. Owner monitors pending transactions in mempool

  3. When detecting a transaction from favoured address:

    • Frontruns transaction by increasing threshold to 100%

  4. Targeted player gets guaranteed egg mint

  5. Threshold reset to original value afterward

Technical Impact:

  • Complete control over success probabilities:

    • Can set to 0% to block all discoveries

    • Can set to 100% for guaranteed mints

  • No time restrictions or governance delays

  • Changes apply immediately to all subsequent transactions

Impact

Severity: Medium

  • Direct Financial Impact: Enables selective favouritism for NFT minting

  • Protocol Credibility Risk: Undermines game fairness perception

  • Manipulation Potential: Owner could extract value by selling guaranteed mints

Likelihood: Medium

  • Requires malicious/compromised owner

  • Easy to execute with basic blockchain monitoring tools

Tools Used

Manual review

Recommendations

  1. Immutable Threshold After Game Start:

function setEggFindThreshold(uint256 newThreshold) external onlyOwner {
require(!gameActive, "Cannot change during active game");
require(newThreshold <= 100, "Threshold must be <= 100");
eggFindThreshold = newThreshold;
}
  1. Time-Locked Changes:

uint256 public thresholdChangeDelay = 86400; // 24h
uint256 public pendingThreshold;
uint256 public thresholdChangeTime;
function proposeThreshold(uint256 newThreshold) external onlyOwner {
pendingThreshold = newThreshold;
thresholdChangeTime = block.timestamp + thresholdChangeDelay;
}
function applyThreshold() external {
require(block.timestamp >= thresholdChangeTime, "Delay not passed");
eggFindThreshold = pendingThreshold;
}
  1. Transparency Measure:

event ThresholdChanged(uint256 newThreshold, uint256 changeTime);
// Add to any threshold modification function
emit ThresholdChanged(newThreshold, block.timestamp);
Updates

Lead Judging Commences

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