Level 1 Noob Hacker
Ethernaut 01 Fallback
0 / 100 EXP 100 EXP to Junior Hacker
0%

Challenge 1 / Ethernaut

Fallback

Goal

  1. Claim ownership of the contract.
  2. Reduce the contract balance to zero.

Your task

Read Fallback.sol, then complete Exploit.s.sol.

Starting facts

Start: owner = deployer. Contract balance = 0.001 ether. Player balance = 1 ether.

:~/targets/ethernaut-fallback$
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Fallback {
    mapping(address => uint256) public contributions;
    address public owner;

    constructor() {
        owner = msg.sender;
        contributions[msg.sender] = 1000 * (1 ether);
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "caller is not the owner");
        _;
    }

    function contribute() public payable {
        require(msg.value < 0.001 ether);
        contributions[msg.sender] += msg.value;
        if (contributions[msg.sender] > contributions[owner]) {
            owner = msg.sender;
        }
    }

    function getContribution() public view returns (uint256) {
        return contributions[msg.sender];
    }

    function withdraw() public onlyOwner {
        payable(owner).transfer(address(this).balance);
    }

    receive() external payable {
        require(msg.value > 0 && contributions[msg.sender] > 0);
        owner = msg.sender;
    }
}
How this CTF works Execution environment and verification

Is this a real smart contract execution environment?

Yes. Each submission is compiled and run through a sandboxed Foundry verifier on the server. The verifier checks the final contract state against the challenge conditions and returns a pass/fail result.

What does the Foundry verifier check?

It compiles your exploit script in an isolated sandbox, deploys the target contract, runs your exploit, then asserts the challenge condition — for example, that you became the owner or drained the balance.