Eggstravaganza

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

Predictable On-Chain Random Number Generation in `EggHuntGame:searchForEgg()`

Vulnerability Details:

The function searchForEgg() uses a predictable method for random number generation:

uint256 random = uint256(
keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender, eggCounter))
) % 100;
  • block.timestamp and block.prevrandao are publicly visible and can be manipulated by miners

  • An attacker could front-run transactions when they see favorable conditions

  • The seed components are predictable, allowing players only to search when they know they'll win

Impact:

Risk Level: Critical
Attackers can predict or manipulate the outcome of egg searches, allowing them to game the system and unfairly accumulate eggs.

Exploit Scenarios

  1. Miner Manipulation Attack

    • Miners can influence block.timestamp and block.prevrandao to generate favorable outcomes for themselves or collude with players.

    • If a miner sees a pending searchForEgg() transaction, they can reorder transactions to ensure their attempts succeed.

  2. Front-Running Attack

    • An attacker monitors the mempool for searchForEgg() calls.

    • If a legitimate player’s transaction is about to succeed (due to predictable randomness), the attacker front-runs it with their transaction, ensuring they get the egg instead.

  3. Statistical Prediction Attack

    • Since eggCounter is public, and block.timestamp/block.prevrandao are guessable, an attacker can compute the likely random outcome before submitting a transaction.

    • They only send transactions when they know they will win, reducing wasted gas fees.

Recommendations:

  • Players submit a hashed commitment of their guess using a commit-reveal scheme, then reveal it later.

    Implementation:

    1. Player commits keccak256(secret + address).

    2. After a delay, they reveal the secret.

    3. The contract verifies and generates randomness from the revealed data.

  • Oracle-based randomness (Chainlink VRF). Chainlink Verifiable Random Function (VRF) provides cryptographically secure randomness.

  • If on-chain randomness is required, consider using a future block hash with a delay

    Implementation:

uint256 random = uint256(blockhash(block.number - 1)) % 100;
Updates

Lead Judging Commences

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

Insecure Randomness

Insecure methods to generate pseudo-random numbers

Support

FAQs

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