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

Weak randomness in `ChoosingRam.sol`, allows anyone to choose the randomness that favour's them

Summary

Hashing msg.sender, block.timestamp, block.prevrandao together creates a predictable final number. A predictable number is not a good random number. Malicious users can manipulate these values or know them ahead of time to choose the randomness that gives them a favorable NFT characteristics.

Vulnerability Details

There are a few attack vectors here.

  1. Validators can know ahead of time the block.timestamp and block.difficulty and use that knowledge to predict when / how to participate. See the solidity blog on prevrando here. block.difficulty was recently replaced with prevrandao.

  2. Users can manipulate the msg.sender value to result in their index being the winner.

Example proof of code:

Paste below code in Dessehra.t.sol and run command - forge test --mt test__manipulateTimestamp

code
function test__manipulateTimestamp() public participants {
assertEq(ramNFT.ownerOf(0), player1); //player1 owns the token 0
vm.warp(1728691198 + 1); // executing the transaction exactly at a particular timestamp to get a predictable outcome of 0
vm.startPrank(player1);
uint256 random = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender))) % 2;
vm.stopPrank();
assertEq(random, 0);
assertEq(ramNFT.getCharacteristics(random).ram, player1);
assertEq(ramNFT.getCharacteristics(random).isJitaKrodhah, false); // isJitaKrodhah is false initially
vm.startPrank(player1);
choosingRam.increaseValuesOfParticipants(0, 1); // executed with predictable random value
vm.stopPrank();
assertEq(ramNFT.getCharacteristics(random).isJitaKrodhah, true); // updated the value of isJitaKrodhah to true in favor of caller/miner
}

Using on-chain values as a randomness seed is a well-known attack vector in the blockchain space.

Impact

ChoosingRam::selectRamIfNotSelected and ChoosingRam::increaseValuesOfParticipants can be manipulated easily in a way that miner can submit these call transactions that can benifit him by picking his NFT or characteristics that can make him a winner.

Tools Used

Foundry

Recommendations

Consider using an oracle for your randomness 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::increaseValuesOfParticipants`

Support

FAQs

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