Bot logic relies heavily on REVM simulations to detect sandwichable transactions. The simulations are done by injecting a modified router contract called LilRouter.sol
into a new EVM instance. Once injected, a concurrent binary search is performed to find an optimal input amount that results in the highest revenue. After sandwich calculations, the bot performs a salmonella check. If the sandwich is salmonella free, the bot then calculates gas bribes and sends the bundle to the Flashbots relay.
Performing EVM simulations in this way allows the bot to detect sandwichable opportunities against any tx that introduces slippage.
- At startup, index all pools from a specific factory by parsing the
PairCreated
event. And fetch all token dust stored on addy. - Read and decode tx from mempool.
- Send tx to
trace_call
to obtainstateDiff
. - Check if
statediff
contains keys that equal to indexed pool addresses. - For each pool that tx touches:
- Find the optimal amount in for a sandwich attack by performing a concurrent binary search.
- Check for salmonella by checking if tx uses unconventional opcodes.
- If profitable after gas calculations, send the bundle to relays.
-
This repo requires you to run an Erigon archive node. The bot relies on the
newPendingTransactionsWithBody
subscription rpc endpoint which is a Erigon specific method. The node needs to be synced in archive mode to index all pools. -
Install Rust if you haven't already.
-
Fill in the searcher address in Huff contract and deploy either straight onchain or via create2 using a metamorphic like factory.
If you are using create2, you can easily mine for an address containing 7 zero bytes, saving 84 gas of calldata every time the contract address is used as an argument. read more.
- Copy
.env.example
into.env
and fill out values.
cp .env.example .env
WSS_RPC=ws://localhost:8545
SEARCHER_PRIVATE_KEY=0000000000000000000000000000000000000000000000000000000000000001
FLASHBOTS_AUTH_KEY=0000000000000000000000000000000000000000000000000000000000000002
SANDWICH_CONTRACT=0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa
SANDWICH_INCEPTION_BLOCK=...
- Run the integration tests
cargo test -p strategy --release --features debug
- Run the bot in
debug mode
Test bot's sandwich finding functionality without a deployed or funded contract (no bundles will be sent)
cargo run --release --features debug
- Running the bot
cargo run --release
Warning
By taking this codebase into production, you are doing so at your own risk under the MIT license.
This repo explores only basic and simple multi V2 and V3 sandwiches, however, sandwiches come in many flavors and require some modifications to the codebase to capture them:
- Stable coin pair sandwiches.
- Sandwiches involving pairs that have a transfer limit, an example. Transfer limit can be found using a method similar to Fej:Leuros's implementation.
- Multi-meat sandwiches that target more than one pool. example: frontrun, meat1, meat2, backrun.
- Token -> Weth sandwiches by using a 'flashswap' between two pools. Normally we can only sandwich Weth -> Token swaps as the bot has Weth inventory, however you can use another pool's reserves as inventory to sandwich swaps in the other direction. example.
- Longtail sandwiches to target TOKEN->(WETH or STABLE) swaps by pre buying and holding token.
- Sandwiches that include a user's token approval tx + swap tx in one bundle.
- Sandwiches that include a user's pending tx/s + swap tx in one bundle if swap tx nonce is higher than pending tx.