Mystery Box

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

[H-3] Re-Entrancy Vulnerability in claimAllRewards Function

Description

The claimAllRewards function within the MysteryBox contract is susceptible to re-entrancy attacks due to its violation of the Checks-Effects-Interactions (CEI) pattern. Specifically, the function performs an external call to transfer Ether to the user (payable(msg.sender).call{value: totalValue}("")) before updating the contract’s state by deleting the user’s rewards (delete rewardsOwned[msg.sender]). This sequence allows malicious actors to re-enter the claimAllRewards function during the Ether transfer, potentially enabling them to drain the contract’s funds or manipulate the reward distribution process.

Impact

A successful re-entrancy attack on the claimAllRewards function can have severe consequences, including:

1. Financial Drain: Attackers can repeatedly invoke the claimAllRewards function before the user’s rewards are cleared, allowing them to withdraw more funds than intended. This can rapidly deplete the contract’s Ether reserves.

2. User Trust Erosion: Users expecting to claim their rewards may find the contract unable to fulfill their claims if funds are drained, leading to frustration and loss of trust in the contract’s reliability.

3. Contract Sustainability Risks: Continuous exploitation can render the contract non-functional, undermining its purpose and the ecosystem it supports.

4. Reputational Damage: Security vulnerabilities can tarnish the contract’s reputation, deterring current and potential users from participating.

Tools Used

• **Manual Code Review: **Analyzing the smart contract’s source code to identify the sequence of state changes and external calls that facilitate the vulnerability.

Recommendations

Adhere to the Checks-Effects-Interactions (CEI) Pattern:

• Ensure that all state changes (effects) occur before any external calls (interactions). This prevents attackers from manipulating the state during external interactions.

Example Implementation:

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");
// Effects: Update state before external interactions
delete rewardsOwned[msg.sender];
// Interaction: Transfer Ether after state update
(bool success, ) = payable(msg.sender).call{value: totalValue}("");
require(success, "Transfer failed");
}
Updates

Appeal created

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

`claimAllRewards` reentrancy

Support

FAQs

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