When a user enters a battle as a challenger (2nd player on stage), RapBattle::goOnStageOrBattle
does not check whether the challenger actually has the CRED
balance to cover the bet. Conseqently, challengers can battle without risking any CRED
tokens.
To participate in a battle, users need to call RapBattle::goOnStageOrBattle
and as arguments to this function, they need to provide
(1) the ID of one of their rapper NFTs and
(2) the amount of CRED
tokens they intend to wager.
However,goOnStageOrBattle
does not check whether the challenger actually has the CRED
balance to cover the wager amount.
The challenger can cheat the system and is in an unfair advantage. Having a zero balance of CRED
, the challenger does not actually risk any funds when entering a battle, hence cannot lose. Since the defender has no option to withdraw from the battle once entered on the stage, the challenger can keep the defender "hostage" and keep battling it until chance turns to the challenger's favor so that the challenger wins.
Consider the following scenario:
Defender calls RapBattle::goOnStageOrBattle
, and submits (1) the ID of one of its (not staked) rapper NFTs and (2) some amount of its CRED
balance as a bet.
Defender's NFT and amount of CRED
tokens submitted to the battle are transferred to RapBattle
.
Challenger calls RapBattle::goOnStageOrBattle
, but submits the ID of one of its (not staked) rapper NFTs, and submits the same bet amount as the defender without actually having any balance of CRED
.
Assuming that the defender wins the battle, the challenger cannot pay up since it has a zero balance of CRED
. The transaction (where the challenger entered the battle) reverts. Defender's NFT and bet is stuck in the RapBattle
contract.
Challenger enters the battle again, the same way as in point 3.
Assuming that this time the challenger wins the battle, the defender's bet amount is transferred to the challenger.
Defender's NFT is finally transferred back to the defender.
Insert the following piece of code in OneShotTest.t.sol
:
and test it by executing forge test --mt test_challengerCanBattleWithoutHavingAnNftOrCredTokens
.
Output:
Manual review, Foundry.
Before starting the battle, check that the challenger has enough CRED
balance to cover the bet:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.