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

Winner could be determined by Validator

Vulnerability Details

The randomness of some variables winnerIndex, rarity could be subject of exploitation, as they are calculated by the state of the blockchain, making it possible for an actor to calculate all the possible outcomes, and call selectWinner() in a determined time to win the raffle. In this case the Validator can know the result of this line:

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

What it could do the Validator when running the code is to run the line above

Impact

High / Medium - Validator could create a series of transactions to guarantee a specific winner

Exploit

uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp, block.difficulty))) % players.length;

This is the line which determines the winnerIndex (the index inside the players array), since the Paris upgrade block.difficulty doesn't work as before, It doesn't get the hashrate of the network, as now Ethereum is PoS. Now block.difficulty is an alias for block.prevrandao (A random number determined in a previous block in the beacon chain).

More info can be found here https://eips.ethereum.org/EIPS/eip-4399.

It's possible for a Validator to run the snippet above adding 1 to the length of the players (in case if he wants to add a address), or try for different timestamps with prevrandao of the previous block and try different timestamps until it gets the desired index. In case of wanting to add an address it will call the enterRaffle() and then execute the code of selectWinner(), this must be withing the same block when adding the transactions to Ethereum to know the value of block.prevrandao.

Although this is unlikely to happen, because of the mechanism of Ethereum with PoS, which selects a node at based on the ammount of Ether staked, a big part of the Network of nodes will need to be aware of this contract and actively search to exploit it. The randomness of the protocol could be better, but is no reason to alarm.

Recommendations

Use a service which ensures a random number who cannot be determined by the state of the blockchain or an Actor at the moment of execution, I recommend to implement the service VRF, developed by Chainlink, a service that provides of a random number.

Updates

Lead Judging Commences

Hamiltonite Lead Judge almost 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.