Forking is such an important topic that I put it right after Accounts and Smart Contracts in the Blockchain Basics series.
My forking tool of choice is Anvil, part of the Foundry toolkit.
I have covered using Anvil to simulate bundles before, and I recommend reviewing Local Bundle Simulation where I developed the initial version of AnvilFork
, which has since been merged into the degenbot repo.
I had two main drivers for building AnvilFork
:
Performance — For rapid testing, latency is a killer. Having a locally-available tool I wanted a locally-available, high performance tool for testing multi-transaction bundles.
Availability — I wanted to stop relying on external services like Flashbots Relay and Tenderly for transaction simulation.
AnvilFork
does both. I have used it exclusively for both testing and active simulation on live bots, and I continue to make improvements.
But one issue kept dogging me — the gas usage values weren’t right! Users in Discord reported similar findings.
I have discovered the fix, though to be honest I don’t fully understand the cause. EVM opcodes and their gas use are deterministic, so there should be no difference between a transaction executed by geth, reth, Anvil, Hardhat, or some other EVM execution engine.
But we have to assume some variance in the accuracy of our tools, so let’s continue marching forward. In this post we will launch a fork, execute a series of transactions using two methods, then compare their gas use and accuracy against the canonical chain.
Replaying A Bundle
To begin, take this multi-TX sandwich bundle that I saw on Etherscan:
TX 1: Target Swap