Mystery Box

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

Wrong random value calculation , random value is deterministic

The openBox function in the MysteryBox contract uses a deterministic method to generate random numbers, which can be exploited by malicious actors to predict and manipulate the outcomes of mystery box openings.

Problem

  1. Predictable Inputs: The random number generation relies on block.timestamp and msg.sender. Both of these values can be known or influenced by miners or users.
    Deterministic Output: Given the same inputs, the keccak256 function will always produce the same output. This means that if an attacker can predict or control the inputs, they can determine the outcome.
    Limited Range: The modulo operation % 100 limits the output to a range of 0-99, which is appropriate for the probability distribution but doesn't mitigate the underlying predictability issue.

  2. Miner Manipulation: Miners can influence the block.timestamp to some degree, potentially allowing them to affect the outcomes of box openings.

  3. Front-Running Vulnerability: Attackers can observe pending transactions and front-run them with their own transactions using the same block.timestamp, potentially stealing favorable outcomes.

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;
}
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!