Ethernaut - Lvl 2: Fallout
Tags: ethereum, solidity, security, tutorial
Published: 2023-05-30 01:15:23

###### _Requirements: basic understanding of constructors in Solidity._

## The challenge 📄

Claim ownership of the following contract:

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

import 'openzeppelin-contracts-06/math/SafeMath.sol';

contract Fallout {
  
  using SafeMath for uint256;
  mapping (address => uint) allocations;
  address payable public owner;


  /* constructor */
  function Fal1out() public payable {
    owner = msg.sender;
    allocations[owner] = msg.value;
  }

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

  function allocate() public payable {
    allocations[msg.sender] = allocations[msg.sender].add(msg.value);
  }

  function sendAllocation(address payable allocator) public {
    require(allocations[allocator] > 0);
    allocator.transfer(allocations[allocator]);
  }

  function collectAllocations() public onlyOwner {
    msg.sender.transfer(address(this).balance);
  }

  function allocatorBalance(address allocator) public view returns (uint) {
    return allocations[allocator];
  }
}
```

### Studying `Fallout.sol` 👩‍🏫👨‍🏫

Similarly to the contract from the previous challenge, `Fallout.sol` is a fundraiser. People are allowed pledge and unpledge ether whenever they want and the owner of the contract can withdraw funds.

This contract uses a version of Solidity `< v0.8.x`. This means the contract is prone to underflow and overflow. To protect the arithmetic operations the contract implements the `SafeMath` library from OpenZeppelin and attaches the functions from this library to the `uint256` type.

State Variables:
- `allocations`: keeps track of the amount deposited by each allocator.
- `owner`: `address` of the current owner of the contract. This `address` is marked as `payable` enabling the account to receive ether from the contract.

Functions:
- `Fal1out`: the `constructor` of the contract. Set `msg.sender` as `owner` and the `msg.value` send during deployment as the `allocation` for the deployer.
- `allocate`: method used to deposit ether in the contrac.
- `sendAllocation`: method allocators can use to withdraw their allocation.
- `collectAllocation`: callable method by the `owner` to withdaw the entire balance in the contract.
- `allocatorBalance`: reads the amount deposited by `allocator`.  

## Hacking `Fallout.sol` 💣💣

This challenge was a little tricky for me because after inspecting the contract, the `Fal1out` function with the `/* constructor */` comment looked weird to me.

When I started learning Solidity, the language was well beyond `v0.8.x` and I did not know the syntax to declare a `constructor` in older versions, specifically before `v0.4.22`.

From the Solidity docs:

> _Prior to version 0.4.22, constructors were defined as functions with the same name as the contract. This syntax was deprecated and is not allowed anymore in version 0.5.0._

`Fal1out` was intended to be the `constructor` of the contract but due a typo while writing it, the function is never called automatically because it's not recognized as a constructor and so the contract is not initialized at creation time. 

`Fal1out` ended up being compiled as a `public` function accessible by any EOA to call it and claim the ownership of the contract and to gain access to the balance in the contract.

After that brief explanation, it should be straightforward claiming the ownership of `Fallout`.

In your dev tools call the `Fal1out` method:
```solidity
await contract.Fal1out()
```

After the transaction is mined, verify you own the contract:
```solidity
await contract.owner() // should return your address
```

## Conclusion ⚡️

Creating a more robust syntax to declare a `constructor` is one on the many changes implemented by the core devs to make Solidity a more robust and safe language.

Despite the effort of the core devs, typos can still lead to lose of funds or unusable code, we should always try our best on reading our code before deploying it.

## Further reading 🧟‍♀️🧟

- Solidity docs: [Constructors](https://docs.soliditylang.org/en/latest/contracts.html#constructors) 
- [SWC-118](https://swcregistry.io/docs/SWC-118)