Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: high
Valid

Bad PRNG for winnerIndex

Summary

The PRNG used to calculate winnerIndex is not strong enough.

Vulnerability Details

winnerIndex is calculated as such:
uint256 winnerIndex = uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp, block.difficulty))) % players.length;

  • msg.sender, block.timestamp, and block.difficulty are all public information.

  • players.length can be influenced by an attacker by entering or refunding a raffle.

  • Under these conditions: the attacker could craft a large number of raffle entries. Once the block.timestamp reaches the condition to call selectWinner(), the attacker can find the set of players.length values that would make winnerIndex the same as one of his entries computationally. Then he just needs to either add more entries or remove entries to adjust to the correct value of players.length he needs.

  • Not necessary, but he can also monitor the mempool and frontrun any attempts by third party to call selectWinner to be more precise in his attack.

Impact

Attacker can predict the next values for the PRNG and place himself as the winning index.

Tools Used

Manual Review.

Recommendations

Use Chainlink's PRNG which is unpredictable.

Updates

Lead Judging Commences

Hamiltonite Lead Judge about 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

weak-randomness

Root cause: bad RNG Impact: manipulate winner

Support

FAQs

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

Give us feedback!