// 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);
}
}
이 문제는 generateToken
함수를 통하여 SimpleToken instance를 생성하는데 주소를 어디에도 저장하지 않고, 해당 instance에 0.001 ether를 보내는데 이 0.001ether를 0으로 만들면 풀리는 문제이다.
먼저 이더리움에서는 주소를 생성할 때 따르는 규칙이 존재한다. address와 nonce를 통하여 생성을 하고 keccak256(address, nonce)
와 같은 규칙으로 생성된다고 한다.
필자는 etherscan을 통하여 생성된 instance를 추적하여 주소를 찾았고 destroy(address)
를 호출하여 문제를 해결하였다.