17.Recovery — Ethernaut
To understand how contract addresses are calculated to be deployed
Challenge
Problem details: Recovery
Solution
Our goal in this challenge is to recover or remove the ether from the lost contract address. We have something to consider:
- The
SimepleToken
contract is deployed fromRecovery
contract, so the addresses ofSimepleToken
instances could be calculated because of the deterministic property in EVM. The contract address to be deployed is calculated bykeccak256(rlp_encode(account, nonce))
whereaccount
is the address that will deploy,nonce
is the nonce of that address. - The lost contract address is the first token contract, so the
nonce
is 1 for that transaction - There is a function
destroy(address payable _to)
that can be used to transfer ether from the contract instance because that function useselfdestruct
So, the solution for this challenge is straightforward that : calculate the lost contract address and then execute functiondestroy(address payable _to)
on that contract address
Here is my script calculating the lost contract address with my level instance address 0x845a30000e5e891950EFe68E777b8269E40a14dB. I got my result : 0x762af2fdc341d577bfc546a569c4c457b2d5be35
const ethers = require("ethers");const addr = "0x845a30000e5e891950EFe68E777b8269E40a14dB";const nonce = "0x01";const rlpEncoded = ethers.utils.RLP.encode([addr, nonce]);const contractAddress = ethers.utils.keccak256(rlpEncoded);console.log(`0x${contractAddress.slice(26)}`);
Let’s execute function destroy(address payable _to)
on that address without using fully ABI of SimpleToken
- Encode function data
const iface = new ethers.utils.Interface(["function destroy(address payable _to) public",]);console.log(iface.encodeFunctionData("destroy", ["0x7e31BBf761C360cDf9887133E650c4f5989b4A16", // my public key]));
2. Using Ethernaut console to execute function by this
3. Send transaction and then get the ether recovered
Submit level instance and the challenge completed!