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.