Mystery Box

First Flight #25
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

All low findings

[L-1] Lack of Event Emissions in MysteryBox

Description
The MysteryBox contract does not emit any events, which limits transparency and usability for users and external interfaces. Without event logging, users cannot track important contract actions such as:

  1. Who wins rewards from opening a mystery box.

  2. Changes to the price of mystery boxes by the owner.

  3. The remaining balance or rewards after claiming a single reward.

Impact
The lack of emitted events reduces the transparency of the contract’s operations. Users and off-chain systems cannot easily monitor or verify key actions like reward distribution, price changes, or balances.

Recommendation
Add event emissions for key actions, such as setting the box price, claiming rewards, and opening mystery boxes. This would improve the user experience by providing clear on-chain logs of important events.

[L-2] Missing Minimum Box Price Check in MysteryBox#buyBox()

Description
The setBoxPrice() function currently allows the owner to set the box price to any value, including 0. This could allow users to purchase mystery boxes for free, resulting in unintended behavior or exploitation.

Impact
Without a minimum price check, users could potentially exploit the contract by purchasing boxes at zero cost, leading to financial loss for the contract owner and undermining the intended value of the mystery box system.

Recommendation
Add a check in the setBoxPrice() function to ensure the price of a mystery box is always greater than zero.

function setBoxPrice(uint256 _price) public {
require(msg.sender == owner, "Only owner can set price");
+ require(_price > 0, "Box price must be greater than zero");
boxPrice = _price;
}

By implementing this fix, the contract will prevent the owner from setting an invalid box price and ensure users always pay for the boxes.

[L-3] Missing Checks-Effects-Interactions (CEI) Pattern

Description
The MysteryBox contract does not follow the Checks-Effects-Interactions (CEI) pattern in several functions. The CEI pattern is a best practice in Solidity, as it helps prevent reentrancy attacks by updating state before external calls. Failure to implement CEI can leave the contract vulnerable to exploits.

The following functions are missing CEI checks:

  • claimAllRewards()

  • claimSingleReward()

  • withdrawFunds()

  • openBox()

Recommendation
Ensure that state changes are made before making any external calls. This can be achieved by following the CEI pattern:

  1. Checks: Validate conditions (e.g., ownership or balance checks).

  2. Effects: Update the contract’s internal state.

  3. Interactions: Interact with external contracts or make transfers.

Here’s an example for fixing the claimAllRewards() function:

function claimAllRewards() public {
uint256 totalValue = 0;
for (uint256 i = 0; i < rewardsOwned[msg.sender].length; i++) {
totalValue += rewardsOwned[msg.sender][i].value;
}
require(totalValue > 0, "No rewards to claim");
// Update state before external interaction
+ delete rewardsOwned[msg.sender];
(bool success,) = payable(msg.sender).call{value: totalValue}("");
require(success, "Transfer failed");
- delete rewardsOwned[msg.sender];
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago

Appeal created

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

`claimAllRewards` reentrancy

`claimSingleReward` reentrancy

Support

FAQs

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

Give us feedback!