Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: high
Invalid

`CRED` Whales Can Submit Excessively Large Bets in `RapBattle:goOnStageOrBattle`, Pricing Others Out, Resulting in DoS

Summary

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.

Vulnerability Details

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.

Impact

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.

Proof of Code

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:

function test_dosByCredWhale() public {
address whale = makeAddr("whale");
vm.startPrank(whale);
for (uint256 i = 0; i < 1000; i++) {
oneShot.mintRapper();
oneShot.approve(address(streets), i);
streets.stake(i);
}
vm.warp(4 days + 1);
for (uint256 i = 0; i < 1000; i++) {
streets.unstake(i);
}
uint256 whaleBalance = cred.balanceOf(whale);
console.log("Whale balance: ", whaleBalance);
cred.approve(address(rapBattle), whaleBalance);
oneShot.approve(address(rapBattle), 0);
rapBattle.goOnStageOrBattle(0, whaleBalance); // nobody will be able to match such a high bet
vm.stopPrank();
}

and test it by executing forge test --mt test_dosByCredWhale.

Output:

Running 1 test for test/OneShotTest.t.sol:RapBattleTest
[PASS] test_dosByCredWhales() (gas: 141504568)
Logs:
Whale balance: 4000
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 213.13ms

Tools Used

Manual review, Foundry.

Recommendations

There are a couple of possible solutions you can consider:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.