Ethernaut Level 2 Fallout [Foundry-Hardhat]

Ethernaut Level 2 Fallout [Foundry-Hardhat]

ยท

2 min read

The Ethernaut-Solutions repository contains the solutions using Foundry and Hardhat.

Objectives

  • Claim ownership of the contract

Analysis

A constructor is a special function declared with the constructor keyword, which is executed upon contract creation and is executed only once. The constructor sets the contract's initial state by initializing state variables to their specified value or their default value. Constructor code and the internal functions that are only called in the constructor are not included in the final bytecode.

Before Solidity version 0.4.22, constructors were defined as functions with the same name as the contract. This syntax was deprecated since Solidity version 0.5.0.

pragma solidity 0.4.21;
contract OldWay {
    function OldWay() public { }    // constructor
}

This method introduced a security issue. If the constructor name is misspelled, it becomes a regular function and gets included in the bytecode. It can be called from outside of the contract.

In the newer version of Solidity, the constructor is declared as shown below:

pragma solidity 0.8.17;
contract NewWay {
    constructor() { }
}

Looking at the code for this level, we can see that there is a function with a similar name to that of the contract.

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

As the comment suggests, it is meant to be the constructor. When executed, this function sets the msg.sender as the new owner(We are only interested in the ownership part). Also, notice that the Solidity version used is greater than 0.4.21.

If the Solidity version would have been <=0.4.21 and the function was spelled correctly, it would have been treated as the constructor. As the name of the constructor is misspelled and visibility is public, it is included in the bytecode and can be called from outside the contract. Whoever calls this function will become the owner of the contract.


Exploit

  • Call the Fal1out() function

      await contract.Fal1out()
    

    This will set our address as the owner of the contract.

  • Check the owner

      await contract.owner()
    

You have become the owner of the contract.

Submit the instance.

Level passed!!!๐Ÿ˜„

The Ethernaut-Solutions repository contains the solutions using Foundry and Hardhat.

Solution using Foundry:-

Solution using Hardhat:-

More Levels

Did you find this article valuable?

Support Web3 Vanguard by becoming a sponsor. Any amount is appreciated!

ย