Eggstravaganza

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

[H-1] Bad random in `searchForEgg()`

Summary

Variable random in searchForEgg() function not enough random.

Vulnerability Details

searchForEgg() function source code:

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]);
}
}

The current implementation relies on easily predictable values (block.timestamp, block.prevrandao, msg.sender, eggCounter), all of which can be known in advance. This allows a malicious actor to time their transaction, calling searchForEgg() at the optimal moment to guarantee the comparison on line 9 passes (in the code above).

Impact

This implementation of randomness allows an malicious actor to always win or have a high chance of winning in searchForEgg().

Tools Used

Manual code review.

Recommendations

Fix:

  • Use ChainlinkVRF for important random values.


Hardening:

  • Use more random values, for example:

uint256 random = uint256(
keccak256(abi.encodePacked(block.prevrandao, blockhash(block.number - 1), msg.sender, address(this).balance, eggCOunter))
) % 100;
Updates

Lead Judging Commences

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