Ethernaut level #2 - Fallout
Tags: ethernaut, solidity
Published: 2023-11-10 18:12:03

Continue with Ethernaut. So, level #2 is a [Fallout](https://ethernaut.openzeppelin.com/level/0x676e57FdBbd8e5fE1A7A3f4Bb1296dAC880aa639) challenge. Let's check it out. 

## Requirements
The following smart contract is provided: 
```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];
  }
}
```

The goal is to claim ownership of the contract. 

## Solution
Line #2 already gives us some hints:
```solidity
pragma solidity ^0.6.0;
```
An outdated Solidity version is used. Also, a short story on the task page gives us another hint - the solution may be related to constructor. 

What is a constructor? It's an optional function which is executed during contract creation and is called only once. This concept is common for the majority of programming languages. Constructor has its own advantages and use cases, but we don't need to focus on them now. Let's check some examples on how constructor is called in Solidity `0.6.0`. 

A quick review of example smart contract in Solidity `0.6.0` [documentation](https://docs.soliditylang.org/en/v0.6.0/contracts.html) shows us that a method with name `constructor()` is used for constructor instead of a contract name. In fact, _contract name as constructor_ was deprecated in Solidity `0.4.22`, see the official [release announcement](https://soliditylang.org/blog/2018/04/17/solidity-0.4.22-release-announcement/). 

So, `Fal1out()` can't be a constructor under the given pragma. Moreover, this won't work even in Solidity < `0.4.21`, because there is a typo. It must be called `Fallout()` instead of `Fal1out()`. 

Now it's clear that there is nothing special about `Fal1out()` and unlike the constructor it can be called as many times as we want. 

Let's see current contract owner: 
```javascript
await contract.owner()
``` 
That's not our address. Time to fix this and pwn the contract. `Fal1out()` is an ideal candidate to give us the ownership. It's a payable function, so send `1 wei` to it: 
```javascript
contract.Fal1out.sendTransaction({value: 1})
```
Good moment to check the owner once again: 
```javascript
await contract.owner()
```
Voilà. We've gained access to control of the contract. 

## Summary
The challenge shows that it's important to understand how special functions like constructors are defined. The definitions can change even between the versions of the same programming language. It is also necessary to pay attention to their correct spelling.

---
If you like this article, feel free to subscribe to my social media accounts:

https://dev.to/wallebach
https://twitter.com/just_buidl