Eggstravaganza

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

Weak Randomness in searchForEgg() function

Summary

The Egg minting is based on a random number that should be lower than a certain threshold (default 20)

/// @notice Participants call this function to search for an egg.
/// A pseudo-random number is generated and, if below the threshold, an egg is found.
function searchForEgg() external {
...
// 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]);
}
}

https://ethereum.stackexchange.com/questions/158525/can-prevrandao-be-written-as-a-random-number-on-chain

https://medium.com/@alexbabits/why-block-prevrandao-is-a-useless-dangerous-trap-and-how-to-fix-it-5367ed3c6dfc

Vulnerability Details

All the used elements for generating a random number are known

uint256 random = uint256(
keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender, eggCounter))
) % 100;

I can create a list of future random numbers:

function testWeakRandomness() public {
uint256 random = 0;
uint256 eggCounter = 0;
uint256 eggFindThreshold = 20; // we can get it's actual value, as it's declared to public
for ( uint256 i = 0 ; i < 100 ; i++ ){
random = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender, eggCounter))) % 100;
if (random <= eggFindThreshold) {
eggCounter++;
}
vm.warp(block.timestamp + 1);
console2.log(random);
}
}

Impact

The Random Number is predictable and I can generate a list of future random numbers and know when the egg will be minted

Tools Used

Solidity, Foundry, Manual Code Review

Recommendations

Switch to an external Randomness Service (ex: Chainlink VRF - https://docs.chain.link/vrf)

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.