Skip to content

Recovery

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

contract Recovery {

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

  }
}

contract SimpleToken {

  string public name;
  mapping (address => uint) public balances;

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

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

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

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

Goal

Recover (or remove) the 0.001 ether from the lost contract address (the Simple Token contract)

Exploit

This CTF requires onchain transaction debugging. After we deploy the contract we can search for the transaction that created the insance of SimpleCoin (the one transaction that sends 0.001 ether).

After we find the address of the contract, we can use Remix to load the SimpleCoin contract at the given address and call the destroy(_to) function, with our address as argument for _to parameter.

Inside destroy(), selfdestruct() function will be called on the contract, and send the 0.001 ether to our account.