An attacker who does not have a rapper tokenId minted to him/her can enter a rap battle as a challenger using someone else's tokenId, or a random, non-existent tokenId as well. If he/she wins, he/she gets the defender's credibility token bet. However, if the defender wins, the transaction reverts because the attacker never approved any credibility tokens to the contract (the attacker doesn't have any credibility tokens to begin with).
The RapBattle::goOnStageOrBattle
function doesn't check if the rapper tokenId is valid, nor does it check the ownership of the tokenId. This can lead to the following exploits:
Exisiting rappers (users of the protocol), can enter as challengers with someone else's rapper tokenId with maxed out stats to maximize their chance of winning (rapper skill is a factor in determining the random winner).
An attacker who doesn't assume a role in the protocol (doesn't have a rapper Nft minted to him/her), can enter a rap battle and win credibility tokens. This is made possible because the RapBattle::goOnStageOrBattle
function doesn't require the challenger to transfer his/her rapper tokenId, nor his/her credibility token bet to the RapBattle contract. Thus, if the defender wins, the transaction reverts as the RapBattle::_battle
function fails to transfer credibility token bet from challenger to the defender (the challenger never approved the credibility token bet to the contract).
Additionally, it is also possible to enter a rap battle as a challenger using a non-existent rapper tokenId. However, attackers will prefer the second option (the option above).
Defender enters the rap battle by approving his/her rapper tokenId and credibility token bet to the RapBattle contract. The RapBattle contract transfers the tokenId and credibility token bet to itself.
The challenger (attacker) without his/her own rapper tokenId enters the battle with someone else's tokenId (with maxed out stats). Also, the challenger doesn't approve any credibility tokens to the RapBattle contract.
If the defender wins, the transaction reverts because the contract failed to transfer tokens from challenger to the defender.
If the challenger wins, he/she gets the credibility token bet placed by the defender.
Add the following function to the test contract in your Foundry test file:
The fuzz test ran with randomized time and block difficulty for 272 times with seed "0x1", indicating that the attacker was able to successfully win those battles. The transaction reverted when the defender won.
Attackers who do not assume any role in the protocol (they don't have a rapper tokenId minted to them) can enter rap battles and win defender's credibility token bet. Also, anyone can use anyone's rapper tokenId for battle (if they enter as challenegrs). This is a serious disruption of what the protocol intends to achieve. Only users with rapper tokenIds should be able to go and battle.
Foundry, VSCodium.
In RapBattle::goOnStageOrBattle
function, check if the rapper tokenId is owned by the msg.sender.
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.