Solidity Constructors — Ethernaut Level 2

Kevan Mordan
DraftKings Engineering
3 min readNov 4, 2022

Constructors in Solidity are very similar to other object- oriented programming (OOP) languages. Constructors are typically used to declare an object’s base state whenever a new instance of a class is instantiated. The concept is similar in Solidity but the object, in this case, is the smart contract itself and only invoked upon contract deployment.

Constructor Details

Prior to Solidity 0.4.22, a constructor was declared with a function that has the same name as the contract name. This is very similar to a standard constructor pattern in other OOPs where the function name is equivalent to the class name. Since Solidity 0.4.22, constructor is a reserved keyword to declare which function is the constructor. The constructor function can take arguments and can be payable. The Solidity compiler will generate a default constructor if it is omitted.

Constructor Keyword

The contract’s deployed bytecode will not include the constructor code. Because it is only used during the initial deployment, there is no need to take precious storage for something that will never be used.

Internal and Abstract Constructors

Prior to Solidity 0.7.0, constructors were marked as either public or internal. Contracts with internal constructors couldn’t be deployed and internal constructors were intended to be inherited as part of another contract. Solidity 0.7.0 changed the syntax to a more standard OOP nomenclature with abstract replacing internal constructors.

Inheriting Constuctors

The Problem

The only condition to meet to beat the level is to claim ownership of the contract. Start reviewing the contract’s state, upon creation, by looking at the constructor

Fal1out Constructor

The Solidity version declared here is 0.6.0, prior to the constructor keyword change indicating that the constructor here is the function with the same name as the contract: Fallout. There is a problem though, the function that is labeled with the constructor comments is Fal1out, not Fallout. The compiler will not treat this as a constructor and will instead add a default constructor at compile time. However, the Fal1out function is still a perfectly valid Solidity function.

The result is that the contract will be deployed with a base constructor and the Fal1out function will be a callable function on the deployed contract. Simply calling the Fal1out function will assign ownership to the sender.

This level may be a bit of a relic of the past, but it’s an important part of Solidity’s history and of the underlying security implications. The Rubixi contract is the most famous example of a constructor naming snafu, where the developer renamed the contract Dynamic Pyramid to Rubixi but forgot to update the constructor function name. This allowed anyone to claim ownership of the contract and withdraw Eth.

The next problem, Ethernaut Level 3, will focus on the blocks that build the blockchain.

It is simple to copy and paste the contract code into Remix, compile it, and use the level instance address to call functions. Just call Fal1out and you have beat the level.

--

--