Both the claimAllRewards and claimSingleReward functions are vulnerable to reentrancy attacks due to the lack of the Checks-Effects-Interactions pattern. This can allow a malicious actor to repeatedly call one of these functions before state changes are fully applied, potentially draining the contract's funds.
Both functions transfer ETH to the user before updating the state of the contract (before deleting or modifying the rewardsOwned array). This violates the Checks-Effects-Interactions pattern, which is crucial to preventing reentrancy attacks.
A malicious user could craft a contract that calls claimAllRewards or claimSingleReward. Once the call to a malicious contract is made, before the delete operation is executed, the attacker’s fallback function would make another call to the same reward function in MysteryBox.sol, continuing to claim funds. This process would continue until the contract is drained.
The contract’s entire balance could be drained by an attacker.
If exploited, this attack could lead to a complete loss of all funds stored in the contract.
Manual review, Visual Studio Code (VSCode)
To mitigate this vulnerability, the contract should adopt the Checks-Effects-Interactions pattern, ensuring that all state changes occur before making external calls. Specifically, the rewardsOwned array should be cleared before transferring any funds. You may also want to use the ReentrancyGuard modifier from OpenZeppelin’s library to prevent reentrant calls to the contract.
Proposed Fix for claimAllRewards:
Proposed Fix for claimSingleReward:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.