Fallout Ethernaut Challenge
Introduction
The Ethernaut is a Web3/Solidity based wargame inspired by overthewire.org,
and played in the Ethereum Virtual Machine.
Each level is a smart contract that needs to be 'hacked'.
The goal of this challenge is analyze the code and to claim ownership of the contract to complete the level.
We will see how to do that by interacting with a contract's ABI (Application Binary Interface).
The Challenge
The first thing we can do is to get a new istance of the smart contract. It is important to know that when we press the Get New Istance button, we are not the principal of the contract. Openzeppelin will deploy the contract and thus is the owner of the contract.

Analyze The Code
Now Let's jump to analyze the code and try to understand it.
After that, we can see that a Solidity library called SafeMath.sol has been imported .Every smart contract start with the pragma directive that specify the version of the compiler that will execute the code.
In the following code, the SafeMath.sol library is used for the state variable for unisgned integer(uint256).
Open Zeppelin provides a whole set of smart contract libraries like SafeMath that allow us to safely perform mathematical operations in smart contracts.
If we look at it, there is a function that is used as constructor of the contract (very bad :( ). The constructor is executed only once and the person who uses the contract becomes the owner of the contract.
-
On the contract is this mapping called
allocations
with a certain amount of ether.
In Solidity there is a data structure called mapping that is a kind of hash map or dictionary. In our scenario this mapping contribution rappreset a "database" of addresses of how much ether/token each address has. - Smart Contracts start with the keyword contract, in this scenario the name is
Fallout
. - There is a public variable --> owner, which is of type address and is specified when the constructor is called.
The address that get insert on the public variable is the msg.sender. - msg is a global variable in your solidity code and represents the transaction. The sender value of the msg object is the actual sender of the transaction that deployed the contract.
-
There is a modifier function called
onlyOwner
that says that whoever sends a transaction must also be the owner. -
There are several functions such as
allocate
,sendAllocation
andcollectAllocations
that manage the transfer and allocation of address balances.
The Vulnerability
If we read the code, we see the constructor function, seems that to has the same name as the contract (very bad practise) but is not.
The constructor is named Fal1out
with a 1 instead of an l.
So Fallout
is misspelled Fal1out
, which causes the constructor function to become a public function that you can call at any time.
Bug:
If we check with the dev console, we can see that the contructor function is accessible through the ABI of the smart contracts.
This is absolutely wrong, as the constructor should not be public and executable through the ABI. (Typo error of the function contructor.)
Since is a typo the constructor is a public function and anyone can call it and become the owner of the contract bacause inside
the function owner == msg.sender
is set , where msg.sender is the one that performs the transaction
Since the constructor is a publicly accessible function, the vulnerability is that whoever performs a transaction and calls this function become the owner of the contract.
How can we become the owner of the contract?
As we can see, at the moment we are not the owner of the contract.
To become the owner we can use the dev console, use the ABI of the smart contract
and call the function Fal1out()
, which assigns the owner to msg.sender.

After the transaction has been mined, we can see by calling the await contract.owner()
function again that the address is now our account address.

Conslusion
KEY TAKEAWAY FROM CHALLENGE:
Always use the constructor()
function when defining a constructor in your contract.
The constructor is a function that gets executed only once when your contract is first deployed.
DO NOT declare a constructor function using the same name as your contract.
