Eggstravaganza

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

Predictable randomness in searchForEgg function

Summary

Miners can manipulate block.prevrandao and block.timestamp to influence the egg searching mechanism, potentially allowing specific addresses to win the raffle unfairly.

function searchForEgg() external {
require(gameActive, "Game not active");
require(block.timestamp >= startTime, "Game not started yet");
require(block.timestamp <= endTime, "Game ended");
// Pseudo-random number generation (for demonstration purposes only)
uint256 random = uint256(
@> keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender, eggCounter))
) % 100;
if (random < eggFindThreshold) {
eggCounter++;
eggsFound[msg.sender] += 1;
eggNFT.mintEgg(msg.sender, eggCounter);
emit EggFound(msg.sender, eggCounter, eggsFound[msg.sender]);
}
}

Vulnerability Details

The function uses block.timestamp and block.prevrandao as sources of randomness, which can be manipulated by miners within certain bounds. In Proof-of-Stake Ethereum, validators can influence PREVRANDAO by choosing whether to propose a block, giving them some control over the outcome. Similarly, block.timestamp can be set with some flexibility. This allows miners to potentially control the random value generation, especially when they can predict the other inputs (msg.sender and eggCounter).

Impact

Miners or validators can manipulate the randomness to favor specific addresses, allowing them to mint valuable NFTs unfairly.

Tools Used

Manual

Recommendations

Change randon generate method (can use chainlink VRF, etc...)

- // Pseudo-random number generation (for demonstration purposes only)
- uint256 random = uint256(
- keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender, eggCounter))
- ) % 100;
+ // Use a verifiable random function like Chainlink VRF
+ bytes32 requestId = CHAINLINK_VRF_COORDINATOR.requestRandomWords(
+ keyHash,
+ subscriptionId,
+ requestConfirmations,
+ callbackGasLimit,
+ 1
+ );
+
+ // Store user request for fulfillment
+ randomRequests[requestId] = msg.sender;
Updates

Lead Judging Commences

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

Give us feedback!