A CRED
whale (an entity with a large amount of the CRED
token) can either accidentally or intentionally cause a Denial of Service (DoS) scenario in the RapBattle
contract by submitting such a large bet that nobody else (or only the wealthiest individuals) can (or want) to match.
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 submit as a bet.
Since there is no upper limit to the bet amount, a CRED
whale can either accidentally or intentionally submit such a large bet that nobody else (or only the wealthiest individuals) can (or want) to match. Since there are no options and mechanisms for:
defender users (in this case the whale) to go off the stage (pull back from the battle),
lowering a submitted bet,
dropping defender users (in this case the whale) from the stage if they do not find a challenger for a pre-defined amount of time,
this effectively results in a DoS scenario so that other users are essentially prevented from participating in battles, given that they cannot meet an excessively high bet.
An entitiy can become a CRED
whale multiple ways:
by buying CRED
from other users,
by minting and staking (then unstaking, re-staking, etc.) a lot of rapper NFTs,
by winning a lot of rap battles with significant bet amounts.
First, the general accessibility of the RapBattle
contract is compromised in a way that only the wealthiest players can participate in a battle, others are priced out.
Eventually, a single whale can create a DoS-like scenario where no one else can match an excessively high bet (that is, at least for a significant amount of time) and, hence, RapBattle::goOnStageOrBattle
will be rendered unusbable.
The following piece of code demonstrates how a user can acquire a large CRED
balance by buying and staking lots of rapper NFTs.
Insert this test in OneShotTest.t.sol
:
and test it by executing forge test --mt test_dosByCredWhale
.
Output:
Manual review, Foundry.
There are a couple of possible solutions you can consider:
Introduce maximum bet limits: Establish a cap on the amount of CRED
that can be wagered in any single battle. This limit could be a static value determined by the platform or dynamically adjusted based on the average bet sizes over a certain period.
Bet matching system: Implement a matching system that pairs users based on their wager sizes. This could involve creating different "leagues" or "tiers" of battles, where users are matched with opponents who have placed similar bet amounts, ensuring that all players, regardless of their cred holdings, have the opportunity to participate in battles.
Tiered participation fees: For users placing higher bets, introduce scaled participation fees, where the fee percentage increases with the size of the bet. This approach could discourage the placement of excessively large bets for the sole purpose of excluding others from participation.
Dynamic bet adjustment mechanism: Consider a system where, if a bet remains unmatched for a certain period, it is automatically reduced to a more reasonable amount based on recent average bet sizes. This ensures that battles remain active and accessible to a broader range of players.
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.