The RapBattle
contract allows users to get their rapper NFT on stage for battle and winner is decided on the basis of rapper's skill which is used to weight their likelihood of randomly winning the battle.
Here, randomness is used to get a random number on the basis of which the winner is decided based on their skills.
But, the implementation to decide the winner for a particular scenario when the random
variable is equal to defenderRapperSkill
is wrong, the winner is set to defender
instead of challenger
.
The vulnerability is present in the RapBattle::_battle
function where the winner deciding mechanism is incorrectly implemented.
The protocol calculate the winner as below:
It uses the sum of skills of both the rappers to calculate the random number by taking a modulo with the sum, therefore the random number lies in the range from 0 to totalBattleSkill - 1
, where totalBattleSkill
being the sum of skills of both the competing rappers.
And finally, to decide the winner if the random number is less than or equal to the defenderRapperSkill
, defender is considered the winner otherwise challenger is considered the winner.
But there is a catch over here, the range of values for which it considers defender
the winner is from 0 to defenderRapperSkill
but challenger
is considered a winner for the values from defenderRapperSkill + 1
to totalBattleSkill - 1
.
For defender: 0 to defenderRapperSkill
which is a span of defenderRapperSkill - 0 + 1
= defenderRapperSkill + 1
For challenger: defenderRapperSkill + 1
to totalBattleSkill - 1
which is a span of totalBattleSkill - 1 - defenderRapperSkill - 1 + 1
= totalBattleSkill - defenderRapperSkill - 1
= challengerRapperSkill - 1
.
We can clearly see that defender is considered a winner for the span of defenderRapperSkill + 1
but for challenger it is challengerRapperSkill - 1
, thus giving advantage to the defender
by considering one extra skill span for their winning.
The correct implementation should be to consider the span for defender as defenderRapperSkill
and challenger as challengerRapperSkill
.
For the case when random
number is equal to defenderRapperSkill
, defender is considered the winner instead of challenger.
Manual Review
Make the necessary changes to consider challenger
as winner when random number is >=
defenderRapperSkill.
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.