Skip to content

Fallout

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import 'openzeppelin-contracts-06/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];
  }
}

Goal

Withdraw the ETH from the vulnerable smart contract

Exploit

In order to drain the contract from it's funds, we need to be able to call the collectAllocations() function.

From the code we can see that the collectAllocations() function, has onlyOwner modifier attached to it, which means that only the account that has created this smart is able to call this function.

So, the next step would be to check if somehow we can modify/change the owner of the contract.

If we take a look at the Fal1out() function, we can see that inside this function the owner is set to be msg.sender.

The reason we can exploit this function is actually a typo. The Fal1out() function is meant to be the contract's constructor, but since the name of the contract (Fallout) differ from the constructor function name, the Fal1out() function is publicly accessible, meaning anyone can call it.

This kind of exploit can't happen with newer versions of Solidity, since there is a special keyword for the contract's constructor.

To exploit the contract we need to:

  1. call Fal1out() function with some value, this function will set our account as the owner of the contract
  2. call the collectAllocations() function, since we are the new owner of the contract, all the balance from the Fallout contract will be transferred to our account