Mystery Box

First Flight #25
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Invalid

H-4 Loss of user rewards when a user claims all rewards before opening others.

Summary

Inadvertent Loss of Unopened Rewards(boxes) in claimAllRewards() Function

Vulnerability Details

Type: Logic Error
Affected Function: claimAllRewards()
Description: The function aggregates the total value of rewards, transferring it to the user and deleting all rewards in the rewardsOwned array. This includes unopened rewards, which are inadvertently lost if the user forgets to open them first.

Impact

Users may lose valuable unopened rewards if they claim all rewards without opening their boxes first, leading to a total loss of funds.

Tools Used

Unit tests

POC

User 2 should receive 1.5 ether (His total balance should be 2.2 ether), but instead gets 1 ether, and his rewardsOwned mapping gets deleted.
Add this to your test suite.

function testPlayerCanClaimRewards() public {
//
vm.startPrank(user1);
mysteryBox.buyBox{value: 0.1 ether}();
uint r = mysteryBox.openBox();
console2.log("REWARD:", r);
mysteryBox.claimSingleReward(0);
//
vm.startPrank(user1);
mysteryBox.buyBox{value: 0.1 ether}();
uint a = mysteryBox.openBox();
console2.log("REWARD:", a);
mysteryBox.claimSingleReward(1);
MysteryBox.Reward[] memory aa = mysteryBox.getRewards(user1);
//
vm.startPrank(user2);
mysteryBox.buyBox{value: 0.1 ether}(); //silver reward 1
uint b = mysteryBox.openBox();
console2.log("REWARD:", b);
//
mysteryBox.buyBox{value: 0.1 ether}(); //silver reward 2
uint c = mysteryBox.openBox();
console2.log("REWARD:", c);
mysteryBox.buyBox{value: 0.1 ether}();//silver reward 3. not opened
mysteryBox.claimAllRewards();
MysteryBox.Reward[] memory rew = mysteryBox.getRewards(user2);
//
vm.startPrank(user3);
mysteryBox.buyBox{value: 0.1 ether}();
uint w = mysteryBox.openBox();
console2.log("REWARD:", w);
mysteryBox.claimSingleReward(0);
//
vm.startPrank(user3);
mysteryBox.buyBox{value: 0.1 ether}();
uint t = mysteryBox.openBox();
console2.log("REWARD:", t);
mysteryBox.claimSingleReward(1);
//
vm.startPrank(user4);
mysteryBox.buyBox{value: 0.1 ether}();
uint y = mysteryBox.openBox();
console2.log("REWARD:", y);
mysteryBox.claimSingleReward(0);
//
vm.startPrank(user4);
mysteryBox.buyBox{value: 0.1 ether}();
uint f = mysteryBox.openBox();
console2.log("REWARD:", f);
mysteryBox.claimSingleReward(1);
// assertEq(mysteryBox.getBalance(), 19.9 ether);
assertEq(user3.balance, 0.8 ether);
>>> assertEq(user2.balance, 1.7 ether);
assertEq(user1.balance, 0.8 ether);
assertEq(rew.length, 0);
assertEq(aa.length, 2);
} ```
## Recommendations
Invoke `openBox()` Automatically: Modify the `buyBox()` function to automatically call the `openBox()` function after purchasing a box. This ensures that users immediately open their rewards upon buying, reducing the likelihood of forgetting to do so later.
Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago

Appeal created

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!