Mystery Box

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

Adding a new reward is useless as the logic to calculate the reward in openBox() function is pre-deterministic

Description: Adding a new reward by using MysteryBox::addReward function does not update the reward calculation logic. The logic in MysteryBox::openBox function is pre-determined and does not scale dynamically with the addition if a new reward.

Impact: As one of the core functionalities of the owner/admin is the ability of add new rewards, the contract logic, in its current state, is set up in a way which does not scale in accordance to the new rewards being added.

The highlighted lines in the code snippet of MysteryBox::openBox below show the static logic to calculate the reward based on pre-determined logic.

function openBox() public {
require(boxesOwned[msg.sender] > 0, "No boxes to open");
// Generate a random number between 0 and 99
uint256 randomValue = uint256(
keccak256(abi.encodePacked(block.timestamp, msg.sender))
) % 100;
// Determine the reward based on probability
! if (randomValue < 75) {
// 75% chance to get Coal (0-74)
rewardsOwned[msg.sender].push(Reward("Coal", 0 ether));
! } else if (randomValue < 95) {
// 20% chance to get Bronze Coin (75-94)
rewardsOwned[msg.sender].push(Reward("Bronze Coin", 0.1 ether));
! } else if (randomValue < 99) {
// 4% chance to get Silver Coin (95-98)
rewardsOwned[msg.sender].push(Reward("Silver Coin", 0.5 ether));
! } else {
// 1% chance to get Gold Coin (99)
rewardsOwned[msg.sender].push(Reward("Gold Coin", 1 ether));
}
boxesOwned[msg.sender] -= 1;
}

Proof of Concept:

  1. Owner/admin adds a new reward, say, Platinum which is supposed to be the rarest of all, by using MysteryBox::addReward function.

  2. User/Player purchases a new mystery box by calling MysteryBox::buyBox.

  3. User/Player proceeds to open the box and calls MysteryBox::openBox function. But he will have 0% chance of winning the Platinum reward since the MysteryBox::openBox does not have any logic to dynamically scale with the addition of the Platinum reward in step 1.

Recommended Mitigation: There are a few things to consider in order to get the intended behavior.

  1. Create a new array to store weightage of each reward.

  2. Update the weightage of the rewards to accomodate the new reward which is added by the owner.

  3. in MysteryBox::openBox function, instead of the static logic, have a dynamic logic which can adjust in accordance to the new reward and its weightage.

Updates

Appeal created

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

addReward won't have any effect on openBox

Support

FAQs

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

Give us feedback!