cancelRegistration
in ThePredicter contract has a reentrancy vulnerability bug because it updates the user's status after sending ether. An attacker can exploit this by re-entering the function call and draining the contract before their status is updated.You find the bug on
The following exploit contract will take advantage of the reentrancy vulnerability in the cancelRegistration
function to drain funds from ThePredicter
:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ThePredicter.sol";
contract Exploit {````ThePredicter public thePredicter;````address public owner;
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "forge-std/Test.sol";
import "../src/ThePredicter.sol";
import "../src/Exploit.sol";
contract ThePredicterTest is Test {
ThePredicter public thePredicter;
Exploit public exploit;
address public owner = address(1);
uint256 public entranceFee = 0.04 ether;
}
Impact: Users who have registered and paid the entrance fee can have their funds stolen by an attacker. This undermines trust in the contract and its security.
Manual Review
Foundry
To fix the vulnerability, update the state before making any external calls: following CEI
function cancelRegistration() public {
if (playersStatus[msg.sender] == Status.Pending) {
playersStatus[msg.sender] = Status.Canceled;
(bool success, ) = msg.sender.call{value: entranceFee}("");
require(success, "Failed to withdraw");
return;
}
revert ThePredicter__NotEligibleForWithdraw();
}
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.