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

Weak randomness in `ChoosingRam:selectRamIfNotSelected` allows organizer to be the winner.

Summary

The current implementation of randomness in the ChoosingRam:selectRamIfNotSelected function uses a combination of block.timestamp and block.prevrandao hashed together and then applies modulo tokenCounter to determine a random number. This method is predictable, allowing a malicious organizer to potentially manipulate the outcome or predict the result ahead of time. As the organizer may have influence over or foreknowledge of these block values, they can exploit this to ensure a specific participant, including themselves, wins.

Vulnerability Details

The current random number generation method in ChoosingRam:selectRamIfNotSelected is:

uint256 randomIndex = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao))) % tokenCounter;

This approach is weak because:

  1. block.timestamp can be influenced by the validator within certain bounds.

  2. block.prevrandao is accessible and predictable for validators.

  3. The tokenCounter can be manipulated through continued NFT minting with the RamNFT:mintRamNFT method after the event has closed.

These factors combined allow an organizer to predict or manipulate the outcome, especially when they have knowledge of or control over block parameters.

The organizer if a validator or working with one can know ahead of time the block.timestamp and block.prevrandao and use that knowledge to predict when to select the winner. See the solidity blog on prevrando here. block.difficulty was recently replaced with prevrandao. Although the hashed result of these two values then applies modulo tokenCounter, the organizer can still manipulate the tokenCounter value to result in their index being the winner because the 'RamNFT:mintRamNFT` function is not restricted after the event has ended.

Impact

If the organizer or an accomplice is a participant, they can manipulate the randomness to select themselves as the winner, leading to unfair outcomes and potential financial loss for other participants. This predictability undermines trust in the event's fairness.

Tools Used

  • Manual Review

Recommendations

Start by preventing the minting of NFTs using the RamNFT:mintRamNFT method once the event has ended. Consider using an oracle for your randomness like Chainlink VRF. It is capable of providing a secure and verifiable source of randomness on-chain for a number found within a range.

Updates

Lead Judging Commences

bube Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Weak randomness in `ChoosingRam::selectRamIfNotSelected`

The organizer is trusted, but the function `ChoosingRam::selectRamIfNotSelected` uses a way to generate a random number that is not completely random.

passandscore Submitter
about 1 year ago
bube Lead Judge
about 1 year ago
bube Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Weak randomness in `ChoosingRam::selectRamIfNotSelected`

The organizer is trusted, but the function `ChoosingRam::selectRamIfNotSelected` uses a way to generate a random number that is not completely random.

Support

FAQs

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