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

Weak source of randomness makes winner selection vulnerable to attack

Summary

Chain attributes, such as block.timestamp and block.timestamp can be predicted or manipulated, and should thus never be used for random number generation. The block.timestamp is used twice in the PuppyRaffle::selectWinner() function, first to select the winner and again to select the winner's NFT.

Vulnerability Details

The PuppyRaffle::selectWinner() function decides the winnerIndex and NFT rarity based on pseudorandom numbers generated from deterministic information that can be either manipulated or predicted.

  • PuppyRaffle::L128: uint256 winnerIndex = uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp, block.difficulty))) % players.length;

  • PuppyRaffle::L139: uint256 rarity = uint256(keccak256(abi.encodePacked(msg.sender, block.difficulty))) % 100;

The Chainlink team have researched and discussed the problems associated with using data form a deterministic blockchain at: https://chain.link/vrf

The two key points are:

Onchain solutions that rely on biasable inputs like blockhashes are at severe risk of being exploited.

You and your users take severe risks of being financially impacted by insecure and biasable RNG techniques.

Impact

This will allow a malicious actor to potentially steal the winnings and the rarity of the NFT when the PuppyRaffle::selectWinner() is invoked.

Tools Used

Manual Review and Foundry

Recommendations

The contract should be updated to use an oracle solution such as Chainlink VRF.

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!