# 1.0 Fallback [CTF][Blockchain Security]

Ethernaut is a series of fun challenges that teach you how to hack smart contracts on the Ethereum platform. One of the challenges is called "Fallback." In this challenge, you will need to use your coding skills to exploit a vulnerability in a contract to take control of it and change its behavior.

---

To beat this challenge, you will need to:

1. Claim ownership of the contract
    
2. Reduce its balance to 0
    

If you're a beginner, don't worry! You'll learn a lot as you go. Just make sure to try the [challenge](https://ethernaut.openzeppelin.com/level/1) and then come back to the walkthrough for guidance.

---

Now, let's analyze the code to see how we can achieve these goals:

## Code Analysis

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

contract Fallback {
    // ...
}
```

These are basic things for all the smart contracts we look into.

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

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

contract Fallback {

  mapping(address => uint) public contributions;
  address public owner;

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

  // ...
}
```

The contract has a few state variables, including a `mapping` called `contributions` and an `address` called `owner`  
  
The `constructor` function sets the `owner` to the deployer's address and adds the deployer's address to the `contributions` `mapping` with a value of 1000 ETH. It sets the owner's address 🤔 but but but... we can't call a constructor as

> `constructor` is a special function that is invoked only once at the time of deployment

```solidity
  modifier onlyOwner {
        require(
            msg.sender == owner,
            "caller is not the owner"
        );
        _;
    }
```

There is also a `modifier` called `onlyOwner` which restricts access to certain functions to the `owner` only.

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

The `contribute` function is `payable` (meaning it can receive ETH) and publicly accessible. It updates the amount that a contributor has contributed and if the contributor's contribution is greater than the `owner`'s a contribution, sets the `owner` to the contributor.

However, there is a restriction on the amount that can be contributed (it must be less than 0.001 ETH).  
  
So there might be fewer chances of exploiting it as numerous transactions are needed to be performed to achieve our goal.

```solidity
  function getContribution() public view returns (uint) {
    return contributions[msg.sender];
  }
```

The `getContribution` function is a `view` (meaning it does not change the blockchain state) and publicly accessible. It simply returns the contribution amount for the `msg.sender` . This acts like a utility function to check the contribution amount.

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

The `withdraw` function is publicly accessible, but can only be called by the `owner`. It allows the `owner` to transfer the entire contract balance to their own address.

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

Finally, there is a `receive` function (also known as a fallback function) which can be called by external contracts and is `payable`. It requires the `msg.value` to be greater than 0 and the `contributions` of the `msg.sender` to be greater than 0. If these conditions are met, it sets the `owner` to the `msg.sender`.

> Fallback functions are called when a contract receives ETH without any other function being specified.

---

There are a few things to note about this code. 📝

First, the logic in the `receive` function is questionable – it only requires the `msg.value` to be greater than 0 and the `contributions` of the `msg.sender` to be greater than 0, which may make it easier to exploit.  

Additionally, the `contribute` function has a low limit on the amount that can be contributed, which may make it difficult to achieve our goal of claiming ownership of the contract.

---

With these points in mind, let's think about how we can exploit this contract to achieve our goals. One possibility is to try and call the `receive` function with a `msg.value` that is greater than 0 and a `contributions` value that is also greater than 0. This may allow us to claim ownership of the contract.

Once we have ownership, we can call the `withdraw` function to transfer the contract balance to our address, reducing the balance to 0.

Remember, if you get stuck or need help, don't hesitate to come back to this walkthrough for guidance. In the next blog post, we go through the actual challenge hands-on. Good luck! ✨
