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

Organizer can know which will be the selected ram

Summary

In the function 'selectRamIfNotSelected' in the contract 'ChoosingRam', the organizer can know which will be the selected ram before calling the function.

Vulnerability Details

In the function 'selectRamIfNotSelected' in the contract 'ChoosingRam', the organizer can know which will be the selected ram before calling the function because of a bad randomness, in fact a random value is generated by encoding the values: 'block.timestamp' and 'block.prevrandao'.

##PoC

function test_selectRamIfNotSelected_badRandomness(uint256 timestamp) public {
vm.startPrank(address(this));
ramNft.setChoosingRamContract(address(choosingRam));
vm.stopPrank();
address casualAddress1 = address(123);
vm.startPrank(casualAddress1);
ramNft.mintRamNFT(casualAddress1);
vm.stopPrank();
address casualAddress2 = address(124);
vm.startPrank(casualAddress2);
ramNft.mintRamNFT(casualAddress2);
vm.stopPrank();
address casualAddress3 = address(125);
vm.startPrank(casualAddress3);
ramNft.mintRamNFT(casualAddress3);
vm.stopPrank();
address casualAddress4 = address(126);
vm.startPrank(casualAddress4);
ramNft.mintRamNFT(casualAddress4);
vm.stopPrank();
vm.startPrank(address(this));
timestamp = bound(timestamp, 1728691200, 1728777600);
vm.warp(timestamp);
assertEq(choosingRam.selectedRam(), 0x0000000000000000000000000000000000000000);
choosingRam.selectRamIfNotSelected();
//Organizer can know in an anticipate way which will be the selectedRam address
address selectedRam = choosingRam.selectedRam();
assertNotEq(selectedRam, 0x0000000000000000000000000000000000000000);
uint256 random = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao))) % ramNft.tokenCounter();
if(random == 0){
assertEq(selectedRam, address(123));
}
if(random == 1){
assertEq(selectedRam, address(124));
}
if(random == 2){
assertEq(selectedRam, address(125));
}
if(random == 3){
assertEq(selectedRam, address(126));
}
}

Impact

Organizer will have the advantage to know which will be the selected ram, so there is an high centralization risk.

Tools Used

Manual Review

Recommendations

Do not encode block.timestamp and block.prevrandao, simply use 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.

Support

FAQs

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