Ethernaut Lvl 18 Recovery Walkthrough: How to retrieve lost contract addresses (in 2 ways)

This is a in-depth series around Zeppelin team’s smart contract security puzzles. I’ll give you the direct resources and key concepts you’ll need to solve the puzzles 100% on your own.

Nicole Zhu
Published in
4 min readSep 17, 2018


This levels requires you to retrieve a lost contract address to regain the remaining 0.5 ethers.

It’s a common flub for Solidity developers to lose a newly created contract address. This becomes frustrating, especially if you also lose the transaction receipt and other means of retracing your steps.

Here are two methods for finding the contract address, via raw sender information and Etherscan, respectively.

Method 1: calculate the contract address

Contract addresses are deterministically calculated. From the yellow paper:

The address of the new account is defined as being the rightmost 160 bits of the Keccak hash of the RLP encoding of the structure containing only the sender and the account nonce. Thus we define the resultant address for the new account a ≡ B96..255 KEC RLP (s, σ[s]n − 1) 

An easier way to represent this function is:

address = rightmost_20_bytes(keccak(RLP(sender address, nonce)))


  • sender address: is the contract or wallet address that created this new contract
  • nonce: is the number of transactions sent from the sender address OR, if the sender is a factory contract, the nonce is the number of contract-creations made by this account.
  • RLP: is an encoder on data structure, and is the default to serialize objects in Ethereum.
  • keccak: is a cryptographic primitive that compute the Ethereum-SHA-3 (Keccak-256) hash of any input.

Recreating this Remix

Let’s calculate the address of a new contract created by an existing contract located at 0x890ca422059d877085ce763187ddb12b62ab809d. Let’s assume that this is the first ever contract creation from this address, so the nonce (transaction count) should be 1.

Interesting fact: nonce 0 is always the smart contract’s own creation event

  1. From documentation, the RLP encoding of a 20-byte address is: 0xd6, 0x94 . And for all integers less than 0x7f, its encoding is just its own byte value. So the RLP of 1 is 0x01.
  2. In Remix, compute the following:
address public a = address(keccak256(0xd6, 0x94, YOUR_ADDR, 0x01));

3. This yields 0x048559A2982f50c268B80E14b1A98A1524295016, which is presumably the first address of the new smart contract the existing contract will deploy.

4. To get subsequent contract addresses, simply increment the nonce.

Method 2: use Etherscan

An albeit faster way to derive the new contract address from the creator is with Etherscan.

  1. In Etherscan, look up your current contract by address.
  2. Inside the Internal Txns tab, locate the latest contract creation, and click on the link into the new contract.
  3. The new contract address should now show at the top left hand corner.

Read on to crack this level!

Detailed Walkthrough

  1. Get the address of the contract creator Recovery.sol in the console via instance
  2. Follow Method 1 or 2 above to obtain the new contract address. The nonce used should be 1, as SimpleToken.sol was its first contract creation.
  3. In Remix Injected Web3, retrieve SimpleToken.sol by its address.
  4. Invoke selfdestruct(YOUR_WALLET_ADDR) to withdraw the remaining 0.5 ethers. As we learned in lvl 7, selfdestruct will forward all remaining funds prior to destroying this contract.

Key Security Takeaways

  • Money laundering potential: this blog post elaborates on the potential of using future contract addresses to hide money. Essentially, you can send Ethers to a deterministic address, but the contract there is currently nonexistent. These funds are effectively lost forever until you decide to create a contract at that address and regain ownership.
  • You are not anonymous on Ethereum: Anyone can follow your current transaction traces, as well as monitor your future contract addresses. This transaction pattern can be used to derive your real world identity.