Mystery Box

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

Reentrancy vulnerability in function `claimAllRewards` and `claimSingleReward`

Summary

It is possible for reentrancy attack in functions claimAllRewards and claimSingleReward.

Vulnerability Details

The contract uses a low-level .call function to transfer Ether, which forwards all remaining gas to the recipient (msg.sender). After transferring Ether, the state update (delete rewardsOwned[msg.sender];) happens. This leaves the contract vulnerable to a reentrancy attack, where the recipient could call the contract again (reenter) before the state is updated, potentially claiming rewards multiple times.

Impact

If msg.sender is a contract, it could use the Ether received to call claimAllRewards() or claimSingleReward again before the delete rewardsOwned[msg.sender]; the statement is executed, allowing them to claim rewards multiple times.

An attacker could repeatedly call the function before the rewards are deleted, draining the contract's balance.

Tools Used

Manual review.

Recommendations

If msg.sender is a contract, it could use the Ether received to call claimAllRewards() again before the delete rewardsOwned[msg.sender]; a statement is executed, allowing them to claim rewards multiple times. Also, use reentrancy guards like OpenZeppelin's nonReentrant modifier to prevent reentrancy attacks.

For example, that is how you could fix it:

function claimAllRewards() public nonReentrant {
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");
// State change before external call
delete rewardsOwned[msg.sender];
// External call to send Ether
(bool success,) = payable(msg.sender).call{value: totalValue}("");
require(success, "Transfer failed");
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago

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!