The cancelRegistration
function is vulnerable to a reentrancy attack due to an external call made before updating the contract's state. This allows a malicious actor to re-enter the function and exploit it.
The function checks if the caller's status is Pending
.
It sends Ether to the caller using a low-level call (msg.sender.call{value: entranceFee}("")
).
The caller's status is updated to Canceled
after the call.Vulnerability Details
Line 3 of the cancelRegistration
function as highlighted below shows how an attcker can re-enter the function more than once.
In the current implementation of cancelRegistration
:
The function checks if the caller's status is Pending
.
If true, it sends Ether to the caller via a low-level call (msg.sender.call{value: entranceFee}("")
).
It then updates the caller's status to Canceled
.
The issue here is that the call to msg.sender
can be exploited by a malicious contract to re-enter the cancelRegistration
function before the state is updated, leading to potential multiple withdrawals or other unintended behaviors.
Attackers contract
Proof Of code
The impact of this vulnerability is that an attcker can perform a complete sweep of total funds in the predicter contract.
Foundry
To mitigate the reentrancy vulnerability in the cancelRegistration
function, the contract should follow the Checks-Effects-Interactions (CEI) pattern. This pattern ensures that state changes occur before any external calls, thus preventing reentrancy attacks
Here is the revised cancelRegistration
function following the CEI pattern:
Explanation
Check: Verify if the caller's status is Pending
.
Effect: Update the state to Canceled
before making the external call.
Interaction: Transfer Ether to the caller using a low-level call and check for success.
By following this pattern, the contract ensures that the state change occurs before any external interaction, thereby eliminating the reentrancy risk.
Use Reentrancy Guards: Implement a reentrancy guard (e.g., OpenZeppelin’s ReentrancyGuard
) to prevent reentrant calls entirely.
Reentrancy of ThePredicter::cancelRegistration allows a maliciour user to drain all funds.
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.