Skip to content

0xhammadghazi/Foundry-X-Ethernaut

Repository files navigation

Ethernaut CTF solutions using foundry

My solutions of Ethernaut CTFs.

How to play

Install Foundry

curl -L https://foundry.paradigm.xyz | bash

Update Foundry

foundryup

Clone repo, install dependencies and build

git clone https://github.com/hammadghazi/Foundry-X-Ethernaut.git
forge install
forge build

Run all challenges

forge test -vv

Run a specific challenge

# example forge test --match-contract TestCoinFlip
forge test --match-contract NAME_OF_THE_TEST

Create your own solutions

Create a new test CHALLENGE.t.sol in the test/ directory and inherit from BaseTest.sol.

BaseTest.sol will automate all these things:

  1. The constructor will set up some basic parameters like the number of users to create, how many ethers give them (5 ether) as initial balance and the labels for each user (for better debugging with forge)
  2. Set up the Ethernaut contract
  3. Register the level that you have specified in your CHALLENGE.t.sol constructor
  4. Run the test automatically calling two callbacks inside your CHALLENGE.t.sol contract
    • setupLevel is the function you must override and implement all the logic needed to set up the challenge. Usually is always the same (call createLevelInstance and initialize the level variable)
    • exploitLevel is the function you must override and implement all the logic to solve the challenge
  5. Run automatically the checkSuccess function that will check if the solution you have provided has solved the challenge

Here's an example of a test

// SPDX-License-Identifier: Unlicense
pragma solidity >=0.6.0;
pragma experimental ABIEncoderV2;

import './utils/BaseTest.sol';
import 'src/levels/CHALLENGE.sol';
import 'src/levels/CHALLENGEFactory.sol';

import '@openzeppelin/contracts/math/SafeMath.sol';

contract TestCHALLENGE is BaseTest {
  CoinFlip private level;

  constructor() public {
    // SETUP LEVEL FACTORY
    levelFactory = new CHALLENGEFactory();
  }

  function setUp() public override {
    // Call the BaseTest setUp() function that will also create testsing accounts
    super.setUp();
  }

  function testRunLevel() public {
    runLevel();
  }

  function setupLevel() internal override {
    /** CODE YOUR SETUP HERE */

    levelAddress = payable(this.createLevelInstance(true));
    level = CHALLENGE(levelAddress);
  }

  function exploitLevel() internal override {
    /** CODE YOUR EXPLOIT HERE */

    vm.startPrank(player);

    // SOLVE THE CHALLENGE!

    vm.stopPrank();
  }
}

What you need to do is to

  1. Replace CHALLENGE with the name of the Ethernaut challenge you are solving
  2. Modify setupLevel if needed
  3. Implement the logic to solve the challenge inside exploitLevel between startPrank and stopPrank
  4. Run the test!

Acknowledgement

Note

  • Alien Codex is not part of this repository.
  • Motorbike challenge test case can't be validated because of the way foundry test works.
  • MagicNumber is not part of this repository.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published