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

Reentrancy Attack due to weak randomness in `RapBattle.sol::_battle` function

Summary

A malicious attacker can be able to deploy a reentrancy attack and drain the funds in the contract by exploiting the weak randomness in the RapBattle.sol::_battle function.

Vulnerability Details

The Weak Randomness that occurs by hashing msg.sender, block.timestamp, block.pervrando

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

can further be exploited and drain contract funds. In the RapBattle.sol::_battle function if the random number is predicted by a malicious user and they become the winner, the challenger's bet and the money deposited by the defender will be transferred to them else the money from the contract is sent to them. Malicious attackers can reenter this function as a winner to drain any funds that the contract has even if there are no challengers.

// 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);
}

Impact

Any funds held by the contract whether deposited by the defender or any other challenger can be drained ad all funds meant for the rightful winners will be lost.

Tools Used

Manual Review

Recommendations:

  1. The root cause of this attack is weak randomness generated from the hashing of block.timestamp, block.prevrandao, msg.sender. The usual recommendation is to always use oracles like chainlink VRF to generate random numbers off-chain.

  2. Consider adding the nonReentrant modifier from openzeppelin ReentrancyGuard library in the function:

+ import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
.
.
+ contract RapBattle is ReentrancyGuard {
- function _battle(uint256 _tokenId, uint256 _credBet) internal {
+ function _battle(uint256 _tokenId, uint256 _credBet) internal nonReentrant{
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Lack of quality
Vunderthehood Submitter
over 1 year ago
inallhonesty Lead Judge
over 1 year ago
Vunderthehood Submitter
over 1 year ago
inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

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