Mystery Box

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

Weak randomness in `MysteryBox::openBox` function allows users to influence or predict the `randomValue`, selecting the highest value reward

Summary

Hashing msg.sender and block.timestamp together creates a predictable find number. A predictable number is not a good random number. Malicious users can manipulate these values or know them ahead of time to choose the highest value in the mystery box.

function openBox() public {
require(boxesOwned[msg.sender] > 0, "No boxes to open");
@> 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

Any user can influence the selection of the rewards getting the most valuable reward in the mystery box.

Vulnerability Details

  1. Validators can know ahaed of time the block.timestamp and use that to predict when/how to participate.

  2. Users can mine/manipulate their msg.sender value to result in their address being used to generate the winner.

  3. Users can revert their openBox transaction if they don't like the reward.

Tools Used

Manual code review and slither

Recommendations

Consider using a cryptographically provable random number generator such as Chainlink VRF

Updates

Appeal created

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

Weak Randomness

Support

FAQs

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

Give us feedback!