Mystery Box

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

`Reward`s added through `MysteryBox::addReward` function by the owner are never used.

Summary Rewards added through MysteryBox::addReward function by the owner are never used.

Vulnerability Details addReward function can be used by the owner of the protocol to add rewards to the rewardPool that are available for winning through buying and opening a box. But due to hardcoding of the rewards associated with each interval of randomValue inside openBox function, these new rewards being added are never utilised.

function addReward(string memory _name, uint256 _value) public {
require(msg.sender == owner, "Only owner can add rewards");
@> rewardPool.push(Reward(_name, _value));
}
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;
}

Impact A player might have a look at the rewardPool and have a picture of what the kind of rewards he might recieve and play the game.But he can only receive the rewards hardcoded in the openBox function. This makes the protocol a malciious one creating a misallignment between what players' might think they will win and what they actually can win by playing the protocol.

Tools Used

Simple code inspection as explained above proves the vulenrability.

Recommendations

Rather than hardcoding the rewards corresponding to each inteval of randomvalue, following process of concept can be sued to mitigate this vulnerability.

  1. Once a randomValue is calculated, the value 100 can be divided into number of intervals, that is equal to the length of rewardPool array.

  2. Whichever interval the calculated randomValue falls in, the reward associated with that index must be awarded to the player.

the above conept can be applied in the openBox function as follows.

function openBox() public {
require(boxesOwned[msg.sender] > 0, "No boxes to open");
+ uint256 rewardPoolLength = rewardPool.length;
+ require(rewardPoolLength > 0, "Reward pool is empty");
// Generate randomValue between 0 and 99
uint256 randomValue = uint256(keccak256(abi.encodePacked(block.timestamp, msg.sender))) % 100;
// Calculate interval size based on rewardPool length
+ uint256 intervalSize = 100 / rewardPoolLength;
// Determine which interval the randomValue falls into
+ uint256 rewardIndex = randomValue / intervalSize;
// Handle edge case where randomValue is exactly 99 (due to modulus operation)
+ if (rewardIndex >= rewardPoolLength) {
+ rewardIndex = rewardPoolLength - 1;
+ }
// Award the corresponding reward
+ rewardsOwned[msg.sender].push(rewardPool[rewardIndex]);
- 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));
- }
// Reduce the number of boxes owned by the user
boxesOwned[msg.sender] -= 1;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
11 months ago

Appeal created

inallhonesty Lead Judge 11 months 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.