Mystery Box

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

[H-4] Re-Entrancy Vulnerability in claimSingleReward Function

Summary

The claimSingleReward 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: value}("")) before updating the contract’s state by deleting the specific reward (delete rewardsOwned[msg.sender][_index]). This sequence allows malicious actors to re-enter the claimSingleReward function during the Ether transfer, potentially enabling them to repeatedly claim the same reward or drain the contract’s funds.

Impact

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

1. Financial Drain: Attackers can repeatedly invoke the claimSingleReward function before the specific reward is deleted, allowing them to withdraw the same reward multiple times. This can rapidly deplete the contract’s Ether reserves.

2. User Trust Erosion: Legitimate 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 claimSingleReward(uint256 _index) public {
require(_index < rewardsOwned[msg.sender].length, "Invalid index"); // Corrected comparison operator
uint256 value = rewardsOwned[msg.sender][_index].value;
require(value > 0, "No reward to claim");
// Effects: Update state before external interactions
delete rewardsOwned[msg.sender][_index];
// Interaction: Transfer Ether after state update
(bool success, ) = payable(msg.sender).call{value: value}("");
require(success, "Transfer failed");
}
Updates

Appeal created

inallhonesty Lead Judge 12 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.