# Ethernaut - Fallback Writeup

By [abbudi](https://paragraph.com/@abbudi) · 2023-06-25

---

Fallback is the first of the Ethernaut challenges. It is fairly simple, requiring only basic Solidity knowledge, mainly about fallback functions.

**Clear conditions:**

*   Become the owner of the contract.
    
*   Empty all ether from the contract.
    

Let’s first run through the code…

![Fallback Contract](https://storage.googleapis.com/papyrus_images/bdc71c00b54749e4ad8aecf1171b48d0b94e897cf0cb7db1239afbfac3b7e10f.png)

Fallback Contract

First, notice the two variables:

**contributions**: A mapping keeping track of how much **wei** an address contributed.

**owner:** A single address that can withdraw funds from the contract.

The constructor then sets up the scenario for this challenge, the owner of the contract is now Ethernaut who has **1000 ether** in contributions.

Looking at the rest of the code, two functions stand out in particular.

### contribute()

This function will revert if we contribute an amount over **0.001 ether**, and we can only become the owner of the contract if we donate **1000 ether** through this function.

So let’s look for another way.

### receive()

If you are unfamiliar with what **receive()** is, it is basically the **fallback** function of this contract. What this means is that if you send a transaction to this contract with empty **calldata**, the transaction will end up triggering the **receive()** function instead.

> **calldata:** Raw hexadecimal bytes sent with a transaction that specifies which external contract function you want to call, along with what parameters.

With the basics out of the way, we notice that the receive function requires us to send some amount of money (obviously), and have some amount of a contribution.

If we fulfill both of these requirements, we can be assigned as the owner of the contract.

We can then use our ownership to empty the ether in the contract by calling **withdraw()**.

### The attack

Now we know we first need a contribution to become the owner of the contract, let’s write a Python3 script named "**fallback.py**” that will:

1.  **Contribute 1 wei.**
    
2.  **Send a transaction with no calldata.**
    
3.  **Call the withdraw() function, emptying the contract.**
    

### Imports

![](https://storage.googleapis.com/papyrus_images/5d0d50febeac280dc70c71287eb089f34b0b9d7dc19255a7000efccb1df5420d.png)

We will only need these four modules for this challenge. Make sure to **load\_dotenv()** before doing anything else, because we will need to import some variables from env soon.

**web3** to interact with the Sepolia network.

**solcx** to compile the Ethernaut contract and get the **ABI** needed to interact with the contract.

**dotenv** & **os** to read environment variables.

![](https://storage.googleapis.com/papyrus_images/ac9b21d0a0427d1dad389dc900f38e52e0c847024e5fd37d0e1881a9e51916ac.png)

You can then load your **private key**, **address**, and **provider** like so.

### Function -- read\_contract\_return\_abi()

This function will read “**fallback.sol**“ that exists in the same directory as our python script. In the file, we can copy the Fallback contract’s source code from Ethernaut.

![](https://storage.googleapis.com/papyrus_images/e6a2ba24882ee0c4633f83bd78499899c62115b93df8f83fc6f906af501cdc57.png)

The function above first opens “**fallback.sol**“, installs **solidity 0.8.0** and compiles the contract using the source code.

Then, we get the **ABI**, which will allow us to encode/decode function calls. Without it, we wouldn’t be able to interact with the contract.

Finally, we return the contract object, which gives us an easy interface to encode function calls when interacting with the contract on Sepolia.

### Function -- sign\_and\_send\_transaction()

![](https://storage.googleapis.com/papyrus_images/767f3735b5b33ec68430bb9a07547369b438eb72d5ed0a8791f050a2f9e5dbec.png)

This function will allow us to sign the transactions we’ll need to exploit the contract.

We sign the transaction we want to send using our private key and store it in **signed\_tx**, then get the receipt using the **transaction hash**, which allows us to look at details of our transactions, like if the transaction failed or not.

### Attack

![Main function with instructions on how to attack the contract.](https://storage.googleapis.com/papyrus_images/d2b6ed881004b79ed3da36b9ee55d320165362468e8cefbbfd766f15caa4d00d.png)

Main function with instructions on how to attack the contract.

We’ll now work on our main function, where we can now exploit the contract.

![Getting the contract ABI.](https://storage.googleapis.com/papyrus_images/6c6056913342eda7592b18ec72b9a8cd315ee607b767842f63e141879aa62d5a.png)

Getting the contract ABI.

At the top of the main function is where we specify the **gas** and **gas price** we’ll use to send all of our transactions. **web3.py** does have modules to estimate how much gas a future transaction will use. But, I found that my transactions usually ran out of gas, so I’m using **50,000 gas** at **5 gwei**.

![](https://storage.googleapis.com/papyrus_images/84dd55bcca5b8df42168291a8aaa5f0eabd218e43abb013568145bd885ad3463.png)

Then we contribute to the contract, and save the receipt to analyze our transaction.

![Checking our contribution amount.](https://storage.googleapis.com/papyrus_images/02ee5954611c47a759937751fb217f7810830cad2407bc92cdbef3e357cd78ba.png)

Checking our contribution amount.

Now we’ll check how much we contributed by calling **contributions()** with our address and save it in **contribution**. This is to make sure we actually contributed some amount to the contract.

![Logic if we contributed successfully.](https://storage.googleapis.com/papyrus_images/4cb62fdab96fd8062a73f31b322d0e5cda81ef723e56f55e2bb1e4fe5b86c9f5.png)

Logic if we contributed successfully.

If we contributed successfully, we send the transaction with no calldata, then attempt to withdraw. The script will print a success message if the withdrawal worked, and the program will exit. Then submit your instance on Ethernaut and you’re done!

If you want to see the full code for this challenge, you can find it here:

[https://github.com/imam-abbudi/ethernaut-web3py-solutions/blob/main/fallback/fallback.py](https://github.com/imam-abbudi/ethernaut-web3py-solutions/blob/main/fallback/fallback.py)

---

*Originally published on [abbudi](https://paragraph.com/@abbudi/ethernaut-fallback-writeup)*
