Description
The MysteryBox.sol#openBox() function allows users to open their mystery boxes and receive rewards based on the following probabilities:
75% chance of getting "Coal"
20% chance of getting a "Bronze Coin"
4% chance of getting a "Silver Coin"
1% chance of getting a "Gold Coin"
When a user opens a box, the number of boxes they own is reduced by 1. However, if a user wins a high-value reward (such as a Gold Coin) and tries to claim it through MysteryBox.sol#claimAllRewards(), the contract may not have enough balance to cover the payout. Given that each box costs only 0.1 ETH, it would take thousands of box purchases to accumulate enough ETH to pay out a single Gold Coin reward (1 ETH). As a result, the contract will revert the transaction, leaving the user unable to claim their prize.
Impact
If a user wins a large number of Bronze Coins or a high-value Gold Coin, they will not be able to claim their rewards due to insufficient contract funds. Every attempt to claim the rewards will revert until the contract has enough balance, leading to frustration and loss of trust in the platform.
Several users buy boxes, contributing a total of 0.50 ETH to the contract.
A new user wins a Gold Coin (worth 1 ETH).
The user attempts to withdraw their reward using claimAllRewards().
The transaction reverts because the contract only holds 0.50 ETH and cannot cover the 1 ETH reward.
Recommendation
To mitigate this issue:
Increase Box Price: Adjust the price of the mystery boxes to ensure the contract can cover potential high-value rewards.
Limit High-Value Rewards: Restrict the issuance of high-value rewards unless the contract has sufficient balances.
Implement a Reserve Mechanism: Set aside a portion of every box purchase to build a reserve that can cover large rewards.
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.