The function claimAllRewards()
in the MysteryBox contract is vulnerable to a re-entrancy attack. Specifically, the function updates the contract’s state deleting rewardsOwned[msg.sender]
after an external call is made to transfer funds to the user using payable(msg.sender).call
. This creates an opportunity for a malicious contract to re-enter the function before the state is updated, allowing the attacker to drain the contract's funds.
The following scenario demonstrates how an attacker can exploit this vulnerability:
The attacker’s contract initiates a call to claimAllRewards().
The external call to payable(msg.sender).call{value: totalValue}
is made before the contract updates its state using delete rewardsOwned[msg.sender]
.
The attacker’s contract re-enters claimAllRewards()
before the state is updated and claims rewards again in the same transaction.
This cycle repeats, allowing the attacker to withdraw more funds than they are entitled to, draining the contract of its funds.
A malicious contract might look like this:
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.