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

Randomness Vulnerabilities in RapBattle.sol contract

Summary

The code snippet represents a function for conducting battles between players in a game. However, it uses a flawed method to generate randomness, making the outcomes predictable rather than truly random.

function _battle(uint256 _tokenId, uint256 _credBet) internal {
address _defender = defender;
require(defenderBet == _credBet, "RapBattle: Bet amounts do not match");
uint256 defenderRapperSkill = getRapperSkill(defenderTokenId);
uint256 challengerRapperSkill = getRapperSkill(_tokenId);
uint256 totalBattleSkill = defenderRapperSkill + challengerRapperSkill;
uint256 totalPrize = defenderBet + _credBet;
//@audit not randomized - high
@> uint256 random =
uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender))) % totalBattleSkill;
// Reset the defender
defender = address(0);
emit Battle(msg.sender, _tokenId, random < defenderRapperSkill ? _defender : msg.sender);
// If random <= defenderRapperSkill -> defenderRapperSkill wins, otherwise they lose
if (random <= defenderRapperSkill) {
// We give them the money the defender deposited, and the challenger's bet
credToken.transfer(_defender, defenderBet);
credToken.transferFrom(msg.sender, _defender, _credBet);
} else {
// Otherwise, since the challenger never sent us the money, we just give the money in the contract
credToken.transfer(msg.sender, _credBet);
}
totalPrize = 0;
// Return the defender's NFT
oneShotNft.transferFrom(address(this), _defender, defenderTokenId);
}

Vulnerability Details

The vulnerability lies in the method used to generate randomness for determining the outcome of the battle. The code utilizes keccak256 hashing of block data such as block.timestamp, block.prevrandao, and msg.sender to produce a pseudo-random number. However, block data can be manipulated or predicted by miners to some extent, compromising the randomness of the generated number. This makes the outcome of the battle susceptible to manipulation or exploitation by malicious actors.

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

Impact

Using non-truly-random generation undermines the fairness and trustworthiness of the game. Players could exploit this vulnerability to gain unfair advantages, causing financial losses and damaging the game's reputation.

##tool used
manual audit

Recommendations

To address this vulnerability, it's crucial to use a secure and decentralized source of randomness, such as Chainlink VRF. Integrating Chainlink VRF would ensure that battle outcomes are genuinely random, enhancing fairness and trust in the game.

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.