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

Inadequate Balance Check in goOnStageOrBattle Function

Summary

The goOnStageOrBattle function in the contract lacks a balance check for the challenger when there is already a defender in place. This omission allows challengers to participate in battles without verifying if they have sufficient funds to cover the bet.

Vulnerability Details

In the goOnStageOrBattle function, the logic for handling cases where a defender is already present does not include a check to ensure that the challenger has an adequate balance to cover the bet. Without this check, challengers can initiate battles without having the necessary funds, potentially leading to unfair or inconsistent behavior.

function testPoc(uint256 randomBlock) public twoSkilledRappers {
uint256 initialUserBalance = cred.balanceOf(user);
uint256 initialChallengerBalance = cred.balanceOf(challenger);
console.log("initial balance of user:", initialUserBalance);
console.log("initial balance of challenger:",initialChallengerBalance);
vm.startPrank(user);
oneShot.approve(address(rapBattle), 0);
cred.approve(address(rapBattle), 3);
rapBattle.goOnStageOrBattle(0, 3);
vm.stopPrank();
vm.startPrank(challenger);
oneShot.approve(address(rapBattle), 1);
cred.approve(address(rapBattle), 3);
cred.transfer(address(user), 2);
uint256 ChallengerBalance2 = cred.balanceOf(challenger);
console.log("new balance of challenger:", ChallengerBalance2);
// Change the block number to get different RNG
vm.roll(randomBlock);
vm.recordLogs();
rapBattle.goOnStageOrBattle(1, 3);
vm.stopPrank();
// Retrieve the winner from the logs
Vm.Log[] memory entries = vm.getRecordedLogs();
address winner = address(uint160(uint256(entries[0].topics[2])));
uint256 newchallengerbalance = cred.balanceOf(challenger);
console.log("final balance of challenger", newchallengerbalance);
uint256 newuserbalance = cred.balanceOf(user);
console.log("final balance of user", newuserbalance);
}

Impact

Allowing challengers to bet without risking their credToken creates an imbalance in the gameplay dynamics. This scenario incentivizes users to participate in battles without any real consequence or risk.Defenders can lose their bet to challengers who have not staked any actual tokens.

Tools Used

Manual Review

Recommendations

To address this issue, it is recommended to implement a balance check for the challenger before allowing them to proceed with the battle

function goOnStageOrBattle(uint256 _tokenId, uint256 _credBet) external {
if (defender == address(0)) {
defender = msg.sender;
defenderBet = _credBet;
defenderTokenId = _tokenId;
emit OnStage(msg.sender, _tokenId, _credBet);
oneShotNft.transferFrom(msg.sender, address(this), _tokenId);
credToken.transferFrom(msg.sender, address(this), _credBet);
} else {
// credToken.transferFrom(msg.sender, address(this), _credBet);
+ require(credToken.balanceOf(msg.sender) >= _credBet, "Insufficient balance for bet");
_battle(_tokenId, _credBet);
}
}
Updates

Lead Judging Commences

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

missing check for sufficient `_credBet_` approval

Support

FAQs

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