Ethernaut Lvl 2 Fallout Walkthrough: how simple developer errors become big mistakes

This is a in-depth series around Zeppelin team’s smart contract security puzzles. I’ll give you the direct resources and key concepts you’ll need to solve the puzzles 100% on your own.

Nicole Zhu
2 min readAug 18, 2018

This simple level challenges you to claim ownership of a contract by exploiting a simple developer typo.

The Walkthrough

Notice fallout() is misspelled asfal1out(), causing the constructor function to become a public function that you can call anytime.

// Simply invoke this function with nominal ether
function Fal1out() public payable {
owner = msg.sender;
allocations[owner] = msg.value;

Querying contract.owner() in your console now shows you as the contract owner!

Real examples of such simple human errors

This seemingly trivial level illustrates how simple errors like typos, have historically resulted in serious problems:

The Rubixi Bug

In the Rubixi incidence, the developer changed the contract’s name from Dynamic Pyramid to Rubixi. However, he forgot to rename his constructor function from DynamicPyramid() to Rubixi().

Adversaries were then able to call the now publicly invokable DynamicPyramid() function to gain control of the contract and transfer its ethers out.

The Hackergold Bug

In the Hackergold incidence, the developer used the assignment operator: =+ instead of the intended+= as follows:

// do the actual transfer
balances[from] -= value;
balances[to] =+ value;

The bug is that when you specify balances[to] =+ value; you are actually saying: balances[to] = (positive 1) * value. Thus, anyone is able to arbitrarily reset someone else’s account balance within the contract scope!