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

Wrong way to generate a random number during battle

Summary

Wrong way to generate a random number during battle. The result is not a random number!

Vulnerability Details

The following formula is used to generate the random number during the battle:

uint256 random =
uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender))) % totalBattleSkill;

Neither block.timestamp nor block.prevrandao nor msg.sender are random numbers and that is why the whole formula does not generate truly random number.

Impact

This way of choosing the battle winner can be manipulated by the challenger to win the battle. They have to enter the challenge in specific block timestamp to win the battle. See the test below.

Tools Used

Use this test in your test file. This test repeats at some defined timestamp. The two rappers have the same skills so it should be 50% chance of winning for each rapper. It is not! The challenger always wins.

function testChallengerAlwaysWinsfuzz(uint256 n) public twoSkilledRappers {
//the winner is challenger
uint256 challengerCredStart = cred.balanceOf(challenger);
uint256 userBet = 4;
vm.startPrank(user);
oneShot.approve(address(rapBattle), 0);
cred.approve(address(rapBattle), userBet);
rapBattle.goOnStageOrBattle(0, userBet);
vm.stopPrank();
vm.startPrank(challenger);
oneShot.mintRapper();
oneShot.approve(address(rapBattle), 1);
rapBattle.goOnStageOrBattle(1, userBet);
uint256 challengerCredEnd = cred.balanceOf(challenger);
assert(challengerCredEnd == challengerCredStart + userBet);
}

Recommendations

For secure and unbiased random number generation use oracles like chainlink vrf (https://docs.chain.link/vrf)

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.