• Stars
    star
    112
  • Rank 312,240 (Top 7 %)
  • Language
    TypeScript
  • Created over 2 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

simulates MEV activity from an array of unique searchers; used for testing infra

mev-flood

A collection of tools to simulate MEV activity on EVM-based networks.

the cli

Quickly set up an environment and start sending swaps with the cli.

easy setup (docker)

pull from dockerhub:

docker pull flashbots/mev-flood

# re-tag for convenience
docker tag flashbots/mev-flood mevflood

alernatively, build from source:

git clone https://github.com/flashbots/mev-flood
cd mev-flood/
docker build -t mevflood:latest .

run the CLI with docker:

# see available commands
docker run mevflood --help

### assumes an Ethereum node is running on your machine at localhost:8545

# deploy smart contracts & save deployment to file (./deployments/local.json on localhost)
docker run -v ${PWD}:/app/cli/deployments mevflood init -r http://host.docker.internal:8545 -s local.json

# start sending swaps using the deployment file created in the last step
docker run --init -v ${PWD}:/app/cli/deployments mevflood spam -r http://host.docker.internal:8545 -l local.json

# press Ctrl+C to quit

| If host.docker.internal doesn't work, try 172.17.0.1 (docker's default host proxy)

See the send swaps section for more details on sending random swaps with mev-flood.

build/run locally

First, we need to initialize the environment and build our library:

cd core/
yarn install
# required for build:
yarn script.createWallets
yarn build
cd ..

Next, build the CLI:

cd cli/
yarn install
yarn build

cli usage

deploy smart contracts

./bin/run init

Run init with the --help flag to see all available overrides:

./bin/run init --help
ENV: undefined
Deploy smart contracts and provision liquidity on UniV2 pairs.

USAGE
  $ mevflood init [-r <value>] [-k <value>] [-u <value>] [-a <value>] [-s <value>]

FLAGS
  -a, --wethMintAmount=<value>  [default: 1000] Integer amount of WETH to mint for the owner account.
  -k, --privateKey=<value>      [default: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80] Private key used to send
                                transactions and deploy contracts.
  -r, --rpcUrl=<value>          [default: http://localhost:8545] HTTP JSON-RPC endpoint.
  -s, --saveFile=<value>        Save the deployment details to a file.
  -u, --userKey=<value>         [default: 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d] Private key for the user
                                wallet used to send transactions

DESCRIPTION
  Deploy smart contracts and provision liquidity on UniV2 pairs.

send swaps

Next, send random swaps with the spam command:

./bin/run spam --help
ENV: undefined
Send a constant stream of UniV2 swaps.

USAGE
  $ mevflood spam [-r <value>] [-k <value>] [-u <value>] [-t <value>] [-p <value>] [-l <value>]

FLAGS
  -k, --privateKey=<value>        [default: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80] Private key used to
                                  send transactions and deploy contracts.
  -l, --loadFile=<value>          Load the deployment details from a file.
  -p, --secondsPerBundle=<value>  [default: 12] Seconds to wait before sending another bundle.
  -r, --rpcUrl=<value>            [default: http://localhost:8545] HTTP JSON-RPC endpoint.
  -t, --txsPerBundle=<value>      [default: 2] Number of transactions to include in each bundle.
  -u, --userKey=<value>           [default: 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d] Private key for the
                                  user wallet used to send transactions

DESCRIPTION
  Send a constant stream of UniV2 swaps.

Note: you must use the -s flag in the init command to save your deployment to a file, then use that file for the spam command by specifying the -l flag:

./bin/run init -s deployment.json
# ...
./bin/run spam -l deployment.json

the library

This project's primary export is MevFlood, a library (in core/) that can delpoy a UniswapV2 environment and automate swap traffic & backruns.

import MevFlood from "mev-flood"

const adminWallet = new Wallet("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
const provider = new providers.JsonRpcProvider("http://localhost:8545")

const flood = new MevFlood(adminWallet, provider)

Fund Wallets

This script sends the specified amount to each wallet from the admin account.

const userWallet = new Wallet("0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d")
await flood.fundWallets([userWallet], 5) // send 5 ETH to userWallet

Deployments

MevFlood interacts with a class LiquidDeployment which is a wrapper for interacting with contracts. A LiquidDeployment must be initialized in the MevFlood instance for most features to work.

Create a New Liquid deployment

This will deploy all contracts of a full Uniswap V2 system:

// LiquidDeployment is stored internally in `flood` upon completion
const liquid = await flood.liquid()

// send deployment via one of the callbacks
// await liquid.deployToFlashbots()
await liquid.deployToMempool()

You can also specify options to modify what the liquid script does or doesn't do.

type LiquidParams = {
  shouldApproveTokens?: boolean,
  shouldDeploy?: boolean,
  shouldBootstrapLiquidity?: boolean,
  shouldMintTokens?: boolean,
  wethMintAmountAdmin?: number,
  wethMintAmountUser?: number,
  numPairs?: number,
}

For example, we can use liquid to mint more WETH into a user's account:

await (await flood.liquid({
  shouldDeploy: false,
  shouldBootstrapLiquidity: false,
  wethMintAmountAdmin: 0,
  wethMintAmountUser: 13.37, // mint 13.37 WETH using user's ETH balance
}, userWallet))
.deployToMempool()

We can also send deployments to Flashbots instead of the mempool. We just have to initialize the Flashbots provider first:

// account used to sign payloads to Flashbots, should not contain any ETH
const flashbotsSigner = new Wallet("0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a")
await liquid.initFlashbots(flashbotsSigner)
await (await flood.liquid({}, userWallet)).deployToFlashbots()

Load & Save Deployment

Deployments can be saved to disk so that you can use the same environment continually.

Save:

await liquid.saveDeployment("deployment.json")

Load:

const flood = new MevFlood(adminWallet, provider).withDeploymentFile("deployment.json")

You can also use the raw LiquidDeployment object to instantiate an MevFlood instance:

const liquid = await flood.liquid()
...
// assume `flood` is now out of scope
const flood = new MevFlood(adminWallet, provider, liquid.deployment)

Alternatively, you can hot-swap deployments:

await flood.withDeployment(liquid.deployment).deployToMempool()

swaps

MevFlood can facilitate the sending of UniV2 swaps from an array of specified accounts.

const swaps = await flood.generateSwaps({}, [userWallet])
await swaps.sendToMempool()

Swaps have many options that enable you to test your strategy with certainty, or conversely, increase entropy (your choice!):

type SwapOptions = {
    minUSD?: number,
    maxUSD?: number,
    swapOnA?: boolean,
    daiIndex?: number, // useful if you deployed >1 DAI tokens in the deploy step (using the `numPairs` option)
    swapWethForDai?: boolean,
}

Example:

const swaps = await flood.generateSwaps({
  minUSD: 5000,
  maxUSD: 5000,
  swapOnA: true,
  swapWethForDai: true,
}, [userWallet])
await swaps.sendToMempool()

backruns

MevFlood contains an arbitrage engine that will attempt to create a transaction that arbitrages tokens from a user's trade by backrunning.

// most likely you want to send backruns to Flashbots
await flood.initFlashbots(flashbotsSigner)

provider.on('pending', async pendingTx => {
  const backrun = await flood.backrun(pendingTx)

  // `sendToFlashbots` throws an error if `initFlashbots` hasn't been called on the MevFlood instance
  await backrun.sendToFlashbots()
})

The backrun tx is sent from the adminWallet account used to instantiate MevFlood.

Backruns have some optionality to give you more control when you need it:

type BackrunOptions = {
    minProfit?: BigNumber,
    maxProfit?: BigNumber,
    userPairReserves?: Reserves, // pre-trade reserves of pair that user swaps on; used to calculate optimal arb
    nonce?: number, // override nonce used for backrun tx
}
provider.on('pending', async pendingTx => {
  const backrun = await flood.backrun(pendingTx, {
    minProfit: 0.05, // minimum 0.05 ETH estimated profit to execute
  })
  await backrun.sendToFlashbots()
})

the game

This repository originally started here. This is a game that simulates MEV-like activity, but it's not very applicable to the real world.

Note: MevFlood does not currently export any of this functionality.

Call bid, placing a bet by setting value, and send the highest bid (which may be in addition to others' bids in the block) before calling claim. The winner (the person who called bid with the highest value this round), upon calling claim gets the entire balance of the contract, at which point highest_bid (also the minimum to land a new bid) resets (to 1 gwei). claim will also only pay out if you placed the most recent bid.

system details

mev-flood system diagram

mev-flood is a multi-daemon project, and is designed to be run in parallel with other instances, each using the same source code but different params.

features

  • 100 test accounts to send from (excluding accounts set in .env)
  • claim does not revert when called by a non-winner (on purpose, to add technical complexity to the game)

Daemons

  • dumb-search: blindly sends bid (constant value) & claim txs on every block
    • helpful for stress-testing on testnet (don't run on mainnet!)
    • mostly fails and wastes money on bids (for others to take)
    • sends to FB builder, may also send to mempool (pending how/what we want to test)
  • smart-search: finds winning bid amount and uses a smart contract that atomically executes bid+claim to win the pool
    • if only one instance is run, it's practically guaranteed to win every round
    • if more than one instance is run, they will generate competing bids, and all txs that don't make a profit will revert
  • fake-search sends a uniswap v2 swap that will always revert
    • helpful for early testing (not stress-testing)
    • mainnet-friendly (use an account with no funds for ADMIN_PRIVATE_KEY)
    • this sends a single-transaction bundle to Flashbots from the admin wallet (env: ADMIN_PRIVATE_KEY)
  • swapd generates a random swap for each wallet in the specified array, for every new block
  • arbd watches the mempool for transactions and tries to backrun them

Scripts

  • cancelPrivateTx: cancel a private transaction sent to the bundle API given txHash
  • createTestBundle: prints a test bundle without sending or signing it (txs are signed)
  • createWallets: creates new wallets.json file populated w/ 100 wallets
  • fundWallets: send 0.1 ETH to each wallet in wallets.json from admin wallet (ADMIN_PRIVATE_KEY)
  • getBundleStats: get bundle stats for a given bundleHash
  • sendPrivateTx: send a private transaction to the bundle API
  • getConflictingBundle: quick-and-dirty interface to call getConflictingBundle from the cli; needs refactoring
  • getUserStats: get user stats for admin wallet (ADMIN_PRIVATE_KEY)
  • liquid: bootstrap a new uniswap v2 environment with tokens and pairs
  • sendPrivateTx: send a simple private tx to Flashbots
  • sendProtectTx: send a simple tx to Flashbots Protect RPC
  • testSimpleBundle: simulate & optionally send a bundle with simple transactions to Flashbots

Scripts with optional params are explained with the help flag:

yarn script.sendProtectTx --help
yarn script.sendPrivateTx --help
yarn script.cancelPrivateTx --help

game setup

yarn install

# pick your poison:
cp .env.example .env.goerli
cp .env.example .env.sepolia
cp .env.example .env.mainnet

vim .env.goerli
vim .env.sepolia
vim .env.mainnet

Set preferred environment:

export NODE_ENV=sepolia

Generate test accounts:

mkdir src/output
yarn script.createWallets

Fund all 100 test accounts with ETH:

⚠️ careful, this sends 50 ETH to each account by default.

yarn script.fundWallets

# send 1 ETH to each wallet
yarn script.fundWallets -e 1

run

Run dumb-search simulator with 5 accounts (careful, it currently sends without checking for profit):

yarn dumb-dev 0 5

Note: 5 is the exclusive end index, meaning that arguments (0 5) will use wallets[0, 1, 2, 3, 4].

Run smart-search simulator.

yarn smart-dev

Run fake-search simulator.

yarn fake-dev

help

Daemons that have params/options include the help flag:

yarn dumb-dev --help
yarn smart-dev --help

production builds

yarn build
yarn dumb-search $i $j
yarn smart-search $i $j
yarn fake-search

mempool testing

You might need to use the mempool to test your transactions' validity before trying to use the bundle API.

Add the mempool flag -m or --mempool before the wallet index/indices.

yarn dumb-dev --mempool 13 21
yarn smart-dev -m 21

stress-test example

Run 49 dumb searchers and 2 smart searchers (a relatively realistic case):

# terminal 1 (49 test wallets)
yarn dumb-dev 0 49

# terminal 2 (49 test wallets)
yarn dumb-dev 49 98

# terminal 3 (2 test wallets)
yarn smart-dev 98 100

Generate random orderflow on univ2 environment

# if you haven't already, deploy univ2 environment
yarn script.liquid

# if you haven't already, fund your wallets
yarn script.fundWallets

# generate orderflow w/ 10 wallets, send txs to mempool
yarn swapd --mempool 10 20

# (in another terminal) backrun orderflow (in mempool) generated by swapd using wallet #21 to sign the backrun tx
# sends the backrun bundle to Flashbots
yarn arbd 21

Note: if you didn't run yarn build you can run yarn swapd-dev instead of yarn swapd. Same goes for arbd.

In addition to deploying the contracts to the environment specified by NODE_ENV, this script will create a file at src/output/uniBootstrap.json containing all the details of the deployment, including pre-calculated contract addresses and a list of all signed transactions.

other features

Get bundle stats:

yarn script.getBundleStats 0x40d83aebb63f61730eb6309e1a806624cf6d52ff666d1b13d5ced535397f9a46 0x7088e9
# alternatively you can use int block number
yarn script.getBundleStats 0x40d83aebb63f61730eb6309e1a806624cf6d52ff666d1b13d5ced535397f9a46 7375081

Send private tx:

# send a lottery tx
yarn script.sendPrivateTx

# send a reverting univ2 swap
yarn script.sendPrivateTx dummy

Cancel private tx:

yarn script.cancelPrivateTx 0xca79f3114de50a77e42dd595c0ba4e786d3ddf782c62075ec067fe32329e3ea2

Print a test bundle (sends ETH from test wallet to itself):

yarn script.createTestBundle

Send tx to Protect:

yarn script.sendProtectTx

# send uniswapV2 router tx to Protect (works on any chain)
yarn script.sendProtectTx dummy

# send lottery contract tx to Protect with fast mode
yarn script.sendProtectTx fast

# send uniswapV2 router tx to Protect w/ fast mode
yarn script.sendProtectTx fast dummy
# or
yarn script.sendProtectTx dummy fast

More Repositories

1

pm

Everything there is to know about Flashbots
2,482
star
2

simple-arbitrage

Example arbitrage bot using Flashbots
TypeScript
1,963
star
3

mev-boost

MEV-Boost allows Ethereum validators to source high-MEV blocks from a competitive builder marketplace
Go
1,172
star
4

mev-research

Project management for MEV Research
884
star
5

mev-inspect-py

🔎 an MEV inspector for Ethereum 🔎
Python
819
star
6

mev-job-board

Need a bot?
727
star
7

ethers-provider-flashbots-bundle

Flashbots provider for ethers.js
TypeScript
548
star
8

mev-inspect-rs

Discover historic Miner Extractable Value (MEV) opportunities
Rust
548
star
9

mev-boost-relay

MEV-Boost Relay for Ethereum proposer/builder separation (PBS)
Go
417
star
10

builder

Flashbots MEV-Boost Block Builder
Go
409
star
11

web3-flashbots

Web3.py plugin for using Flashbots' bundle APIs
Python
405
star
12

searcher-sponsored-tx

TypeScript
360
star
13

simple-blind-arbitrage

Solidity
343
star
14

searcher-minter

Solidity
229
star
15

mempool-dumpster

Dump all the mempool transactions 🗑️ ♻️ (in Parquet + CSV)
Go
206
star
16

flashbots-docs

TypeScript
190
star
17

suave-geth

Go
188
star
18

rpc-endpoint

Flashbots RPC endpoint, to be used with wallets (eg. MetaMask)
Go
180
star
19

mev-share

Protocol for orderflow auctions
129
star
20

mev-share-client-ts

Client library for Flashbots MEV-share Matchmaker.
TypeScript
116
star
21

hindsight

Retroactively estimate Uniswap-ish MEV on Flashbots MEV-Share by simulating backrun-arbitrages.
Rust
116
star
22

mev-relay-js

JavaScript
105
star
23

mev-geth-demo

JavaScript
98
star
24

boost-geth-builder

Example builder
Go
93
star
25

mev-share-node

Go
88
star
26

geth-sgx-gramine

Geth-in-SGX provides an example of running go-ethereum in SGX
C
68
star
27

relayscan

Ethereum MEV-Boost Relay Monitoring
Go
67
star
28

eth2-research

Assessing the nature and impact of MEV in eth2.
Jupyter Notebook
66
star
29

mpc-backrun

Proof-of-concept code for backrunning private transactions using MPC.
Python
63
star
30

mev-explore-public

Public repo of MEV-Explore for the community to jam on the dashboard
59
star
31

suapp-examples

SUAVE Application Examples
Go
54
star
32

simple-limit-order-bot

TypeScript
53
star
33

raytracing

Eth2-MEV project with liquid staking (Flashbots-Lido-Nethermind)
Go
52
star
34

builder-playground

Local end-to-end environment for Ethereum L1 block building
Go
51
star
35

reorg-monitor

Ethereum Reorg Monitoring
Go
44
star
36

block-validation-geth

To be deprecated in favor of https://github.com/flashbots/builder
Go
44
star
37

suave-std

Collection of helpful smart contracts to build Suapps
Solidity
43
star
38

rollup-boost

Sidecar to Enable Rollup Extensions
Rust
42
star
39

go-boost-utils

Eth2 builder API types and signing for Golang
Go
41
star
40

suave-specs

☀️ SUAVE Alpha Protocol Specifications
35
star
41

prysm

Our custom Prysm fork for boost relay and builder CL. Sends payload attributes for block building on every slot to trigger building.
Go
34
star
42

sync-proxy

Proxy from consensus client to block builders
Go
33
star
43

go-template

Template for Go projects
Go
33
star
44

suave-viem

Typescript client library to interact with SUAVE.
TypeScript
32
star
45

dowg

Decentralized Orderflow Working Group
31
star
46

suave-andromeda-revm

Andromeda revm execution service
Rust
29
star
47

relay-specs

MEV-Boost Relay API Specs
HTML
28
star
48

prio-load-balancer

Priority JSON-RPC load balancer (with retries, good logging, and other goodies like SGX/SEV attestation support)
Go
27
star
49

mev-proxy

JavaScript
18
star
50

contender

Generate high-volume state contention on EVM-like networks.
Rust
18
star
51

andromeda-sirrah-contracts

forge development env for SUAVE key management
Solidity
18
star
52

flashbots-repository-template

Template to bootstrap and configure new projects maintained by the Flashbots collective
17
star
53

mev-blocks

JavaScript
17
star
54

flashbots-dashboard

TypeScript
17
star
55

flashbots-writings-website

MDX
15
star
56

EIP-712-swap-PoC

Solidity
11
star
57

go-utils

Various reusable Go utilities and modules
Go
11
star
58

eth-sparse-mpt

Caching sparse Merkle Patricia Trie for reth.
Rust
7
star
59

flashbots-airflow-workflows

Python
6
star
60

curve-based-bundle-pricing

Jupyter Notebook
6
star
61

dealer-smart-contract

Integral DEX smart contract
TypeScript
6
star
62

flashbots-data-transparency

Collection, analysis and presentation of Flashbots data.
JavaScript
6
star
63

suave-docs

TypeScript
6
star
64

gramine-andromeda-revm

Python
5
star
65

mev-inspect-logs

Log-based MEV inspections
JavaScript
5
star
66

aleth

C++
5
star
67

research-mev-eip1559

Jupyter Notebook
4
star
68

web3-data-tools

Data tools for Web3
Jupyter Notebook
3
star
69

node-healthchecker

Composite health (sync status) checker for blockchain nodes
Go
3
star
70

yocto-manifests

Repo Manifests for the Yocto Project Build System for reproducible TEE builds
Makefile
3
star
71

builder-olympics-website

HTML
2
star
72

suave-toolchain

JavaScript
2
star
73

protect-explorer

A dashboard designed to illuminate the savings Protect users are enjoying.
TypeScript
2
star
74

prometheus-sns-lambda-slack

Receive prometheus alerts via AWS SNS and publish then to slack channel
Go
2
star
75

flashbots-toolchain

GitHub action to install Flashbots tools
JavaScript
2
star
76

nginx-static-response

nginx image that returns a fixed status code
Dockerfile
1
star
77

yocto-scripts

Shell
1
star
78

rbuilder-relay-measurement

A script to pull data for a specific block number and builder public key from the relay and compare them against those from the builder logs
Python
1
star
79

revm

Revm suited for suave needs
Rust
1
star
80

kube-sidecar-injector

Sidecar injector for k8s
Go
1
star
81

eth-faucet

Faucet for ethereum based chains
Go
1
star