Mystery Box

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

Bad source of randomness

Summary

A high-severity vulnerability was discovered in the (MysteryBox) smart contract, where the openBox function gives a reward depending on a value that is calculated using the block.timestamp a source that is not random. This issue allows an attacker to open a box knowing this number and getting the desired reward.

Vulnerability Details

Using block.number orblock.timestamp as a source of randomness is commonly advised against, as the outcome can be manipulated by calling contracts.

uint256 randomValue = uint256(keccak256(abi.encodePacked(block.timestamp, msg.sender))) % 100;

Impact

This vulnerability allows a user to get the reward desired. A malicious actor could take advantage of this getting several rewards and extracting all the Etherum stored in the contract.

PoC

function testGetGoldCoin() public {
vm.deal(user1, 0.1 ether);
vm.startPrank(user1);
mysteryBox.buyBox{value: 0.1 ether}();
uint256 randomValue = 0;
while (randomValue != 99) {
// increase timestamp until the value is 99
vm.warp(block.timestamp + 1);
randomValue =
uint256(keccak256(abi.encodePacked(block.timestamp, user1))) %
100;
if (randomValue == 99) {
// open the box when the value is 99 (Gold Coin)
mysteryBox.openBox();
}
}
console.logUint(randomValue);
assertEq(mysteryBox.getRewards()[0].name, "Gold Coin");
}

Tools Used

Manual Analysis

  • Foundry: Smart contract testing and simulation framework

Recommendations

Consider using a decentralized oracle for the generation of random numbers, such as Chainlinks 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.