{"id":20433900,"url":"https://github.com/flashbots/mev-flood","last_synced_at":"2026-01-19T23:33:01.550Z","repository":{"id":53519203,"uuid":"521446647","full_name":"flashbots/mev-flood","owner":"flashbots","description":"simulates MEV activity from an array of unique searchers; used for testing infra","archived":false,"fork":false,"pushed_at":"2024-08-31T18:13:53.000Z","size":1319,"stargazers_count":124,"open_issues_count":13,"forks_count":25,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-11-15T00:05:39.205Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flashbots.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-04T23:46:09.000Z","updated_at":"2025-07-29T14:42:32.000Z","dependencies_parsed_at":"2023-02-19T13:30:33.407Z","dependency_job_id":"5579c2f9-4657-4125-b42c-c1e11d9d6c22","html_url":"https://github.com/flashbots/mev-flood","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/flashbots/mev-flood","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flashbots%2Fmev-flood","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flashbots%2Fmev-flood/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flashbots%2Fmev-flood/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flashbots%2Fmev-flood/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flashbots","download_url":"https://codeload.github.com/flashbots/mev-flood/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flashbots%2Fmev-flood/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28589970,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T20:45:59.482Z","status":"ssl_error","status_checked_at":"2026-01-19T20:45:41.500Z","response_time":67,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T08:22:17.831Z","updated_at":"2026-01-19T23:33:01.528Z","avatar_url":"https://github.com/flashbots.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mev-flood\n\nA collection of tools to simulate MEV activity on EVM-based networks.\n\n## the cli\n\nQuickly set up an environment and start sending swaps with the cli.\n\n### easy setup (docker)\n\n**pull from [dockerhub](https://hub.docker.com/r/flashbots/mev-flood):**\n\n```sh\ndocker pull flashbots/mev-flood\n\n# re-tag for convenience\ndocker tag flashbots/mev-flood mevflood\n```\n\n**alernatively, build from source**:\n\n```sh\ngit clone https://github.com/flashbots/mev-flood\ncd mev-flood/\ndocker build -t mevflood:latest .\n```\n\n**run the CLI with docker:**\n\n```sh\n# see available commands\ndocker run mevflood --help\n\n### assumes an Ethereum node is running on your machine at localhost:8545\n\n# deploy smart contracts \u0026 save deployment to file (./deployments/local.json on localhost)\ndocker run -v ${PWD}:/app/cli/deployments mevflood init -r http://host.docker.internal:8545 -s local.json\n\n# start sending swaps using the deployment file created in the last step\ndocker run --init -v ${PWD}:/app/cli/deployments mevflood spam -r http://host.docker.internal:8545 -l local.json\n\n# press Ctrl+C to quit\n```\n\n| _If `host.docker.internal` doesn't work, try `172.17.0.1` (docker's default host proxy)_\n\nSee the [send swaps](#send-swaps) section for more details on sending random swaps with mev-flood.\n\n### build/run locally\n\nFirst, we need to initialize the environment and build our library:\n\n```sh\ncd core/\nyarn install\n# required for build:\nyarn script.createWallets\nyarn build\ncd ..\n```\n\nNext, build the CLI:\n\n```sh\ncd cli/\nyarn install\nyarn build\n```\n\n### cli usage\n\n#### deploy smart contracts\n\n```sh\n./bin/run init\n```\n\nRun `init` with the `--help` flag to see all available overrides:\n\n```sh\n./bin/run init --help\nENV: undefined\nDeploy smart contracts and provision liquidity on UniV2 pairs.\n\nUSAGE\n  $ mevflood init [-r \u003cvalue\u003e] [-k \u003cvalue\u003e] [-u \u003cvalue\u003e] [-a \u003cvalue\u003e] [-s \u003cvalue\u003e]\n\nFLAGS\n  -a, --wethMintAmount=\u003cvalue\u003e  [default: 1000] Integer amount of WETH to mint for the owner account.\n  -k, --privateKey=\u003cvalue\u003e      [default: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80] Private key used to send\n                                transactions and deploy contracts.\n  -r, --rpcUrl=\u003cvalue\u003e          [default: http://localhost:8545] HTTP JSON-RPC endpoint.\n  -s, --saveFile=\u003cvalue\u003e        Save the deployment details to a file.\n  -u, --userKey=\u003cvalue\u003e         [default: 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d] Private key for the user\n                                wallet used to send transactions\n\nDESCRIPTION\n  Deploy smart contracts and provision liquidity on UniV2 pairs.\n```\n\n#### send swaps\n\n_Next, send random swaps with the `spam` command:_\n\n```sh\n./bin/run spam --help\nENV: undefined\nSend a constant stream of UniV2 swaps.\n\nUSAGE\n  $ mevflood spam [-r \u003cvalue\u003e] [-k \u003cvalue\u003e] [-u \u003cvalue\u003e] [-t \u003cvalue\u003e] [-p \u003cvalue\u003e] [-l \u003cvalue\u003e]\n\nFLAGS\n  -k, --privateKey=\u003cvalue\u003e        [default: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80] Private key used to\n                                  send transactions and deploy contracts.\n  -l, --loadFile=\u003cvalue\u003e          Load the deployment details from a file.\n  -p, --secondsPerBundle=\u003cvalue\u003e  [default: 12] Seconds to wait before sending another bundle.\n  -r, --rpcUrl=\u003cvalue\u003e            [default: http://localhost:8545] HTTP JSON-RPC endpoint.\n  -t, --txsPerBundle=\u003cvalue\u003e      [default: 2] Number of transactions to include in each bundle.\n  -u, --userKey=\u003cvalue\u003e           [default: 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d] Private key for the\n                                  user wallet used to send transactions\n\nDESCRIPTION\n  Send a constant stream of UniV2 swaps.\n```\n\nNote: 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:\n\n```sh\n./bin/run init -s deployment.json\n# ...\n./bin/run spam -l deployment.json\n```\n\n## the library\n\nThis project's primary export is `MevFlood`, a library (in `core/`) that can delpoy a UniswapV2 environment and automate swap traffic \u0026 backruns.\n\n```typescript\nimport MevFlood from \"mev-flood\"\n\nconst adminWallet = new Wallet(\"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80\")\nconst provider = new providers.JsonRpcProvider(\"http://localhost:8545\")\n\nconst flood = new MevFlood(adminWallet, provider)\n```\n\n### Fund Wallets\n\nThis script sends the specified amount to each wallet from the admin account.\n\n```typescript\nconst userWallet = new Wallet(\"0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d\")\nawait flood.fundWallets([userWallet], 5) // send 5 ETH to userWallet\n```\n\n### Deployments\n\n`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.\n\n#### Create a New Liquid deployment\n\nThis will deploy all contracts of a full Uniswap V2 system:\n\n```typescript\n// LiquidDeployment is stored internally in `flood` upon completion\nconst liquid = await flood.liquid()\n\n// send deployment via one of the callbacks\n// await liquid.deployToFlashbots()\nawait liquid.deployToMempool()\n```\n\nYou can also specify options to modify what the liquid script does or doesn't do.\n\n```typescript\ntype LiquidParams = {\n  shouldApproveTokens?: boolean,\n  shouldDeploy?: boolean,\n  shouldBootstrapLiquidity?: boolean,\n  shouldMintTokens?: boolean,\n  wethMintAmountAdmin?: number,\n  wethMintAmountUser?: number,\n  numPairs?: number,\n}\n```\n\nFor example, we can use liquid to mint more WETH into a user's account:\n\n```typescript\nawait (await flood.liquid({\n  shouldDeploy: false,\n  shouldBootstrapLiquidity: false,\n  wethMintAmountAdmin: 0,\n  wethMintAmountUser: 13.37, // mint 13.37 WETH using user's ETH balance\n}, userWallet))\n.deployToMempool()\n```\n\nWe can also send deployments to Flashbots instead of the mempool. We just have to initialize the Flashbots provider first:\n\n```typescript\n// account used to sign payloads to Flashbots, should not contain any ETH\nconst flashbotsSigner = new Wallet(\"0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a\")\nawait liquid.initFlashbots(flashbotsSigner)\nawait (await flood.liquid({}, userWallet)).deployToFlashbots()\n```\n\n#### Load \u0026 Save Deployment\n\nDeployments can be saved to disk so that you can use the same environment continually.\n\nSave:\n\n```typescript\nawait liquid.saveDeployment(\"deployment.json\")\n```\n\nLoad:\n\n```typescript\nconst flood = new MevFlood(adminWallet, provider).withDeploymentFile(\"deployment.json\")\n```\n\nYou can also use the raw LiquidDeployment object to instantiate an MevFlood instance:\n\n```typescript\nconst liquid = await flood.liquid()\n...\n// assume `flood` is now out of scope\nconst flood = new MevFlood(adminWallet, provider, liquid.deployment)\n```\n\nAlternatively, you can hot-swap deployments:\n\n```typescript\nawait flood.withDeployment(liquid.deployment).deployToMempool()\n```\n\n### swaps\n\nMevFlood can facilitate the sending of UniV2 swaps from an array of specified accounts.\n\n```typescript\nconst swaps = await flood.generateSwaps({}, [userWallet])\nawait swaps.sendToMempool()\n```\n\nSwaps have many options that enable you to test your strategy with certainty, or conversely, increase entropy (your choice!):\n\n```typescript\ntype SwapOptions = {\n    minUSD?: number,\n    maxUSD?: number,\n    swapOnA?: boolean,\n    daiIndex?: number, // useful if you deployed \u003e1 DAI tokens in the deploy step (using the `numPairs` option)\n    swapWethForDai?: boolean,\n}\n```\n\nExample:\n\n```typescript\nconst swaps = await flood.generateSwaps({\n  minUSD: 5000,\n  maxUSD: 5000,\n  swapOnA: true,\n  swapWethForDai: true,\n}, [userWallet])\nawait swaps.sendToMempool()\n```\n\n### backruns\n\nMevFlood contains an arbitrage engine that will attempt to create a transaction that arbitrages tokens from a user's trade by backrunning.\n\n```typescript\n// most likely you want to send backruns to Flashbots\nawait flood.initFlashbots(flashbotsSigner)\n\nprovider.on('pending', async pendingTx =\u003e {\n  const backrun = await flood.backrun(pendingTx)\n\n  // `sendToFlashbots` throws an error if `initFlashbots` hasn't been called on the MevFlood instance\n  await backrun.sendToFlashbots()\n})\n```\n\n\u003e The backrun tx is sent from the `adminWallet` account used to instantiate `MevFlood`.\n\nBackruns have some optionality to give you more control when you need it:\n\n```typescript\ntype BackrunOptions = {\n    minProfit?: BigNumber,\n    maxProfit?: BigNumber,\n    userPairReserves?: Reserves, // pre-trade reserves of pair that user swaps on; used to calculate optimal arb\n    nonce?: number, // override nonce used for backrun tx\n}\n```\n\n```typescript\nprovider.on('pending', async pendingTx =\u003e {\n  const backrun = await flood.backrun(pendingTx, {\n    minProfit: 0.05, // minimum 0.05 ETH estimated profit to execute\n  })\n  await backrun.sendToFlashbots()\n})\n```\n\n## the game\n\nThis repository originally started here. This is a game that simulates MEV-like activity, but it's not very applicable to the real world.\n\n\u003e Note: `MevFlood` does not currently export any of this functionality.\n\nCall `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.\n\n## system details\n\n![mev-flood system diagram](docs/sys-diagram.jpg)\n\nmev-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.\n\n### features\n\n* 100 test accounts to send from (excluding accounts set in .env)\n* `claim` does not revert when called by a non-winner (on purpose, to add technical complexity to the game)\n\n#### Daemons\n\n* **dumb-search:** blindly sends bid (constant `value`) \u0026 claim txs on every block\n  * helpful for stress-testing on testnet (don't run on mainnet!)\n  * mostly fails and wastes money on bids (for others to take)\n  * sends to FB builder, may also send to mempool (pending how/what we want to test)\n* **smart-search:** finds winning bid amount and uses a smart contract that atomically executes bid+claim to win the pool\n  * if only one instance is run, it's practically guaranteed to win every round\n  * if more than one instance is run, they will generate competing bids, and all txs that don't make a profit will revert\n* **fake-search** sends a uniswap v2 swap that will always revert\n  * helpful for early testing (not stress-testing)\n  * mainnet-friendly (use an account with no funds for `ADMIN_PRIVATE_KEY`)\n  * this sends a single-transaction bundle to Flashbots from the admin wallet (env: `ADMIN_PRIVATE_KEY`)\n* **swapd** generates a random swap for each wallet in the specified array, for every new block\n* **arbd** watches the mempool for transactions and tries to backrun them\n\n#### Scripts\n\n* **cancelPrivateTx**: cancel a private transaction sent to the bundle API given `txHash`\n* **createTestBundle**: prints a test bundle without sending or signing it (txs are signed)\n* **createWallets**: creates new `wallets.json` file populated w/ 100 wallets\n* **fundWallets**: send 0.1 ETH to each wallet in `wallets.json` from admin wallet (`ADMIN_PRIVATE_KEY`)\n* **getBundleStats**: get bundle stats for a given `bundleHash`\n* **sendPrivateTx**: send a private transaction to the bundle API\n* **getConflictingBundle**: quick-and-dirty interface to call getConflictingBundle from the cli; needs refactoring\n* **getUserStats**: get user stats for admin wallet (`ADMIN_PRIVATE_KEY`)\n* **liquid**: bootstrap a new uniswap v2 environment with tokens and pairs\n* **sendPrivateTx**: send a simple private tx to Flashbots\n* **sendProtectTx**: send a simple tx to Flashbots Protect RPC\n* **testSimpleBundle**: simulate \u0026 optionally send a bundle with simple transactions to Flashbots\n\nScripts with optional params are explained with the `help` flag:\n\n```sh\nyarn script.sendProtectTx --help\nyarn script.sendPrivateTx --help\nyarn script.cancelPrivateTx --help\n```\n\n## game setup\n\n```sh\nyarn install\n\n# pick your poison:\ncp .env.example .env.goerli\ncp .env.example .env.sepolia\ncp .env.example .env.mainnet\n\nvim .env.goerli\nvim .env.sepolia\nvim .env.mainnet\n```\n\n_Set preferred environment:_\n\n```sh\nexport NODE_ENV=sepolia\n```\n\n_Generate test accounts:_\n\n```sh\nmkdir src/output\nyarn script.createWallets\n```\n\n_Fund all 100 test accounts with ETH:_\n\u003e :warning: careful, this sends 50 ETH to each account by default.\n\n```sh\nyarn script.fundWallets\n\n# send 1 ETH to each wallet\nyarn script.fundWallets -e 1\n```\n\n## run\n\n_Run dumb-search simulator with 5 accounts (careful, it currently sends without checking for profit):_\n\n```sh\nyarn dumb-dev 0 5\n```\n\nNote: 5 is the _exclusive_ end index, meaning that arguments (`0 5`) will use `wallets[0, 1, 2, 3, 4]`.\n\n_Run smart-search simulator._\n\n```sh\nyarn smart-dev\n```\n\n_Run fake-search simulator._\n\n```sh\nyarn fake-dev\n```\n\n### help\n\nDaemons that have params/options include the `help` flag:\n\n```sh\nyarn dumb-dev --help\nyarn smart-dev --help\n```\n\n### production builds\n\n```sh\nyarn build\nyarn dumb-search $i $j\nyarn smart-search $i $j\nyarn fake-search\n```\n\n### mempool testing\n\nYou might need to use the mempool to test your transactions' validity before trying to use the bundle API.\n\nAdd the mempool flag `-m` or `--mempool` before the wallet index/indices.\n\n```sh\nyarn dumb-dev --mempool 13 21\nyarn smart-dev -m 21\n```\n\n### stress-test example\n\n_Run 49 dumb searchers and 2 smart searchers (a relatively realistic case):_\n\n```sh\n# terminal 1 (49 test wallets)\nyarn dumb-dev 0 49\n\n# terminal 2 (49 test wallets)\nyarn dumb-dev 49 98\n\n# terminal 3 (2 test wallets)\nyarn smart-dev 98 100\n```\n\n### Generate random orderflow on univ2 environment\n\n```sh\n# if you haven't already, deploy univ2 environment\nyarn script.liquid\n\n# if you haven't already, fund your wallets\nyarn script.fundWallets\n\n# generate orderflow w/ 10 wallets, send txs to mempool\nyarn swapd --mempool 10 20\n\n# (in another terminal) backrun orderflow (in mempool) generated by swapd using wallet #21 to sign the backrun tx\n# sends the backrun bundle to Flashbots\nyarn arbd 21\n```\n\n_Note: if you didn't run `yarn build` you can run `yarn swapd-dev` instead of `yarn swapd`. Same goes for `arbd`._\n\nIn 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.\n\n### other features\n\n_Get bundle stats:_\n\n```sh\nyarn script.getBundleStats 0x40d83aebb63f61730eb6309e1a806624cf6d52ff666d1b13d5ced535397f9a46 0x7088e9\n# alternatively you can use int block number\nyarn script.getBundleStats 0x40d83aebb63f61730eb6309e1a806624cf6d52ff666d1b13d5ced535397f9a46 7375081\n```\n\n_Send private tx:_\n\n```sh\n# send a lottery tx\nyarn script.sendPrivateTx\n\n# send a reverting univ2 swap\nyarn script.sendPrivateTx dummy\n```\n\n_Cancel private tx:_\n\n```sh\nyarn script.cancelPrivateTx 0xca79f3114de50a77e42dd595c0ba4e786d3ddf782c62075ec067fe32329e3ea2\n```\n\n_Print a test bundle (sends ETH from test wallet to itself):_\n\n```sh\nyarn script.createTestBundle\n```\n\n_Send tx to Protect:_\n\n```sh\nyarn script.sendProtectTx\n\n# send uniswapV2 router tx to Protect (works on any chain)\nyarn script.sendProtectTx dummy\n\n# send lottery contract tx to Protect with fast mode\nyarn script.sendProtectTx fast\n\n# send uniswapV2 router tx to Protect w/ fast mode\nyarn script.sendProtectTx fast dummy\n# or\nyarn script.sendProtectTx dummy fast\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflashbots%2Fmev-flood","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflashbots%2Fmev-flood","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflashbots%2Fmev-flood/lists"}