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

Bad Randomness in `ChoosingRam::increaseValuesOfParticipants` and `ChoosingRam::selectRamIfNotSelected` functions

Summary

The ChoosingRam::increaseValuesOfParticipants function and ChoosingRam::selectRamIfNotSelected get the uint256 random by abi encoding and hashing the block.timestamp , block.prevrandao , msg.sender and other similar global variables which is just "pseudo randomness" and not true randomness i.e. miners and validators can predict the random number generated since everything here is done on-chain.

Vulnerability Details

The Randomness logic used in the functions below are predictable

  1. ChoosingRam::increaseValuesOfParticipants

    function increaseValuesOfParticipants(uint256 tokenIdOfChallenger, uint256 tokenIdOfAnyPerticipent)
    public
    RamIsNotSelected
    {
    if (tokenIdOfChallenger > ramNFT.tokenCounter()) {
    revert ChoosingRam__InvalidTokenIdOfChallenger();
    }
    if (tokenIdOfAnyPerticipent > ramNFT.tokenCounter()) {
    revert ChoosingRam__InvalidTokenIdOfPerticipent();
    }
    if (ramNFT.getCharacteristics(tokenIdOfChallenger).ram != msg.sender) {
    revert ChoosingRam__CallerIsNotChallenger();
    }
    if (block.timestamp > 1728691200) {
    revert ChoosingRam__TimeToBeLikeRamFinish();
    }
    @> uint256 random = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender))) % 2;
    ...
    ..
    .
    }
  2. ChoosingRam::selectRamIfNotSelected

    function selectRamIfNotSelected() public RamIsNotSelected OnlyOrganiser {
    if (block.timestamp < 1728691200) {
    revert ChoosingRam__TimeToBeLikeRamIsNotFinish();
    }
    if (block.timestamp > 1728777600) {
    revert ChoosingRam__EventIsFinished();
    }
    @> uint256 random = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao))) % ramNFT.tokenCounter();
    selectedRam = ramNFT.getCharacteristics(random).ram;
    isRamSelected = true;
    }

Impact

Values generated using Bad Randomness or Weak Randomness can be predicted and can be used to favour the malicious user i.e one can set all characteristics to true and become selected ram

Tools Used

  1. Manual Review

  2. Foundry

Recommendations

Use a cryptographically provable random number generator like Chainlink VRF

Updates

Lead Judging Commences

bube Lead Judge over 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.

codexbugmenot Submitter
over 1 year ago
bube Lead Judge
over 1 year ago
bube Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Weak randomness in `ChoosingRam::increaseValuesOfParticipants`

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.