Ethernaut Level 1: Fallback Tutorial
Tags: solidity, smartcontract, blockchain, security
Published: 2022-01-19 12:24:37


In this article, I will walk you through how to solve the first task of the Ethernaut game. 

The aim of the task is to :

-  claim ownership of the contract
-  reduce balance of the contract to 0

Let's start with the analysis of the contract that we need to hack. 


```
  function contribute() public payable {
    require(msg.value < 0.001 ether);
    contributions[msg.sender] += msg.value;
    if(contributions[msg.sender] > contributions[owner]) {
      owner = msg.sender;
    }
  }
```

Looking at the constructor we can see that contribution of the owner was set to 1000 ethers. This means that if we want to take ownership of the contract we need to call the `contribute` function until we reach a balance higher than 1000 ethers. 

Considering that we cannot send more than 0.001 ether in one call it will take a lot of time.

```

  constructor() public {
    owner = msg.sender;
    contributions[msg.sender] = 1000 * (1 ether);
  }

```

Another way to take ownership of the contract is to use the `receive` fallback function. The fallback function is executed if none of the other functions match the function identifier or no data was provided with the function call. 

Note that only one unnamed function can be assigned to a contract and it is executed whenever the contract receives plain ether without any data. To receive ether and add it to the total balance of the contract, the fallback function must be marked `payable`.

```
  receive() external payable {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }
```

As you can see, to take the ownership we need to meet to conditions: `msg.value > 0 && contributions[msg.sender] > 0`

After that, we can call `withdraw` function to claim all funds.

```
function withdraw() public onlyOwner {
    owner.transfer(address(this).balance);
  }
```

Before let's check who is the owner of the contract.


![ethernaut level 1 initial address](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yms7cgkvs72ec5516kob.jpg)

As you can see the owner's address is different than player's address.

Now we can send some amount of ether to the contract. Note, you cannot send more than 0.001 ether.


![Ethernaut level 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ufcpv4cjtttq6w6q0fu.jpg)

To send the transaction you need to confirm your operation in MetaMask and pay some small gas. Once the transaction will be executed you should see confirmation as above.

We can also verify that we contributed to the contract.

![ethernaut level 1 tutorial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b0i8syo8bqvrvyjf0t57.jpg)
 
Without going into details the `length:3` is the confirmation. So now we need to fulfill the second condition of the fallback function. To do that we need to call the function and send some value.


![ethernaut level 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n5jh5v72uc9ogpn1itb7.jpg)

Since this is a fallback function we used the specific function `sendTransaction`

After that, we can check the contract owner. As you can see now the ownership was assigned to the player's address. So we claimed the ownership!


![ethernaut level 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yvffs5zhpukstzwt1fc0.jpg)

Now we can withdraw ethers. Before we will check the current balance.


![ethernaut level 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w25fhthz34c6dl85d8f7.jpg)

Let's call the `withdraw` function to get all ethers.


![ethernaut fallback](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gs0qb4esaxx2ptto7qqj.jpg)

When you check the contract balance you will see that it is 0. So we achieved the second goal.


![ethernaut level 1 fallback](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6h46t03fz3k5nhgo5yxm.jpg)