diff --git a/.eslintrc.js b/.eslintrc.js index 6115dd71c..f9adefb6c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -// const OFF = 0; +const OFF = 0; const WARNING = 1; const ERROR = 2; @@ -50,17 +50,26 @@ module.exports = { ' ', ], ], + 'import/no-unresolved': [ERROR, {ignore: ['^@docusaurus', '@theme']}], + 'import/no-extraneous-dependencies': [ERROR, {includeTypes: true}], + 'react/require-default-props': [ + WARNING, + { + functions: 'defaultArguments', + }, + ], + 'react/jsx-filename-extension': [ + WARNING, + {extensions: ['.js', '.jsx', '.ts', '.tsx']}, + ], + "react/jsx-props-no-spreading": OFF, }, settings: { - 'import/no-unresolved': ERROR, 'import/parsers': { '@typescript-eslint/parser': ['.ts', '.tsx'], }, 'import/resolver': { - 'webpack': true, - 'typescript': { - 'alwaysTryTypes': true, - }, + typescript: {}, }, // optional, if you want to lint code blocks at the same time 'mdx/code-blocks': true, diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..78cc8f64f --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,4 @@ +# These owners will be the default owners for everything in +# the repo. Unless a later match takes precedence, +# they will be requested for review when someone opens a pull request. +* @odysseus0 @sketsdever @zeroXbrock @sukoneck diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..b206ac8be --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "yarn" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" + groups: + dev-dependencies: + patterns: + - "*" diff --git a/.github/workflows/pr-tests.yml b/.github/workflows/pr-tests.yml index 36f6b6d69..11a33e5ba 100644 --- a/.github/workflows/pr-tests.yml +++ b/.github/workflows/pr-tests.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: - node-version: '16.x' + node-version: "22.x" - name: Test build env: TARGET_URL: "https://docs.flashbots.net" diff --git a/.gitignore b/.gitignore index 4df592086..7863ca119 100644 --- a/.gitignore +++ b/.gitignore @@ -25,5 +25,4 @@ node_modules .env*.local .idea/ -.vscode .eslintcache diff --git a/.nvmrc b/.nvmrc index 6276cf12f..53d1c14db 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v16.14.2 +v22 diff --git a/.prettierrc.json b/.prettierrc.json index d17d2ebb7..b2ff98524 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -5,5 +5,6 @@ "printWidth": 80, "proseWrap": "never", "singleQuote": true, - "trailingComma": "all" + "trailingComma": "all", + "plugins": ["prettier-plugin-tailwindcss"] } diff --git a/.stylelintrc.js b/.stylelintrc.js index 613632958..dba9dd231 100644 --- a/.stylelintrc.js +++ b/.stylelintrc.js @@ -1,14 +1,19 @@ module.exports = { extends: ['stylelint-config-standard', 'stylelint-config-prettier'], - plugins: ['stylelint-copyright'], rules: { - 'docusaurus/copyright-header': [ + 'at-rule-no-unknown': [ true, { - header: `* - * Copyright (c) Flashbots Ltd. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree.`, + ignoreAtRules: [ + 'tailwind', + 'apply', + 'variants', + 'responsive', + 'screen', + ], }, + ], + 'declaration-block-trailing-semicolon': null, + 'no-descending-specificity': null, + }, }; diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..2afab3882 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,20 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. + "recommendations": [ + "streetsidesoftware.code-spell-checker", + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint", + "stylelint.vscode-stylelint", + "EditorConfig.EditorConfig", + "Gruntfuggly.todo-tree", + "github.vscode-github-actions", + "GitHub.vscode-pull-request-github", + "GitHub.remotehub", + "eamodio.gitlens", + "unifiedjs.vscode-mdx", + "christian-kohler.npm-intellisense", + "christian-kohler.path-intellisense", + "bradlc.vscode-tailwindcss", + ], + "unwantedRecommendations": [] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..9926ef31d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.fixAll.stylelint": "explicit" + }, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "css.validate": false, + "scss.validate": false, + "javascript.validate.enable": false, + "typescript.validate.enable": true, + "javascript.suggest.paths": false, + "typescript.suggest.paths": false +} diff --git a/README.md b/README.md index eb2d24b37..2725c32dc 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern ## Installation -Use Node.js v18+ +Use Node.js v22.18+ Note: if you want to install the node packages from within a Docker container (recommended for security), then you can start it like this: ```bash -docker run -p 3000:3000 --rm -it -w /mnt -v $(pwd):/mnt node:18 /bin/bash +docker run -p 3000:3000 --rm -it -w /mnt -v $(pwd):/mnt node:22.18.0 /bin/bash ``` First create a copy of the environment file `.env.template` in the root of the codebase and rename it to `.env` diff --git a/docs/brand-assets.mdx b/docs/brand-assets.mdx new file mode 100644 index 000000000..17d214125 --- /dev/null +++ b/docs/brand-assets.mdx @@ -0,0 +1,7 @@ +--- +title: Brand Assets +--- + +import BrandAssets from "@site/src/components/BrandAssets/index.tsx"; + + \ No newline at end of file diff --git a/docs/community-tools.mdx b/docs/community-tools.mdx index 0317e0c9b..219a037b4 100644 --- a/docs/community-tools.mdx +++ b/docs/community-tools.mdx @@ -2,32 +2,26 @@ title: Community Tools --- -### [Flashbots Bundle Explorer](http://flashbots-explorer.marto.lol/) +### [DotPics Info](https://dotpics.info/) -- Inspect bundles (bundle merging supported!) -- Search by block number -- Shareable permalinks (e.g. https://flashbots-explorer.marto.lol/?block=12506647) +- A collection of interactive dashboards of the MEV-Boost ecosystem. -### [Mevboost.org](https://www.mevboost.org/) +### [MEV Data by EigenPhi](https://eigenphi.io/) -- Dashboard tracking the top relayers and builders of MEV-Boost. +- Analytical explorers detailing MEV and liquidity on-chain data. -### [MEV-Boost Dashboard](https://dune.com/ChainsightAnalytics/mev-after-ethereum-merge) - -- Overview of MEV-Boost adoption and profitability of proposers and block builders. +### [libMEV](https://libmev.com/) -### [mevboost.pics](https://mevboost.pics/) +- A living dashboard with MEV searcher data. -- Interactive dashboard of the MEV-Boost relay and builder markets. +### [Ethereum Block Value Analytics](https://payload.de/data/) -### [MEV Watch](https://www.mevwatch.info/) +- Transaction pool, value over time, and builder bids of Ethereum block. -- Visualization of the number of blocks proposed by MEV-Boost relays excluding certain transactions compared to content agnostic relays. - -### [Relay Monitor by Metrika](https://app.metrika.co/dashboard/ethereum/relay-monitor/north-america-east?tr=1d) +### [MEV-Boost Dashboard](https://dune.com/ChainsightAnalytics/mev-after-ethereum-merge) -- Monitor the bids, blocks and latency of MEV-Boost Relays. +- Overview of MEV-Boost adoption and profitability of proposers and block builders. -### [Rated Network](https://www.rated.network/?network=mainnet&view=pool&timeWindow=1d&page=1) +### [MEV-Boost Relay & Builder Stats](https://www.relayscan.io/) -- Information about validators, pools, relays, etc. \ No newline at end of file +- Ethereum MEV-Boost Relay Monitoring. diff --git a/docs/flashbots-auction/advanced/bundle-pricing.md b/docs/flashbots-auction/advanced/bundle-pricing.md index be7503865..e6d2ba8cc 100644 --- a/docs/flashbots-auction/advanced/bundle-pricing.md +++ b/docs/flashbots-auction/advanced/bundle-pricing.md @@ -33,4 +33,4 @@ The Flashbots builder employs a new algorithm aimed at maximizing block profitab There could be two potential reasons why your bundles are not being included. The first reason to consider is that the gas price of your bundles might not be higher than that at the tail end of a block. It's recommended to analyze the gas price your bundles are offering by initially simulating the bundles and observing the difference in the coinbase and the gas consumed. If this value is found to be lower than the tail end of recent blocks, it would be necessary to increase your gas price accordingly. -Alternatively, your bundles may not be included due to competition with other searchers targeting the same opportunities. These competitors might be offering a higher gas price than you. To address this, first simulate your bundles to check the gas price they are offering. Log the amount you are paying for a specific opportunity in a specific block. If your bundle is still not included, refer to the [blocks API](https://blocks.flashbots.net/) to identify the bundle that was included in your target block and the gas price they offered. +Alternatively, your bundles may not be included due to competition with other searchers targeting the same opportunities. These competitors might be offering a higher gas price than you. To address this, first simulate your bundles to check the gas price they are offering. Log the amount you are paying for a specific opportunity in a specific block. diff --git a/docs/flashbots-auction/advanced/co-locate.mdx b/docs/flashbots-auction/advanced/co-locate.mdx new file mode 100644 index 000000000..917ddf85f --- /dev/null +++ b/docs/flashbots-auction/advanced/co-locate.mdx @@ -0,0 +1,7 @@ +--- +title: Co-locate with Flashbots Builder +--- + +For searchers who want to optimize the latency of their bundle submission, they can choose to co-locate with Flashbots Builders. + +The Flashbots Builder is located in Ohio, USA. Specifically, it is located in the AWS `us-east-2` region. diff --git a/docs/flashbots-auction/advanced/coinbase-payment.mdx b/docs/flashbots-auction/advanced/coinbase-payment.mdx index ef374898e..db518d185 100644 --- a/docs/flashbots-auction/advanced/coinbase-payment.mdx +++ b/docs/flashbots-auction/advanced/coinbase-payment.mdx @@ -38,7 +38,7 @@ For more information on how coinbase transfers are priced see the [bundle pricin ## Managing payments to coinbase.address when it is a contract Validators will occasionally have a smart contract listed as their block.coinbase address. This changes the expected behavior of making payments to block.coinbase. Specifically it costs more gas to transfer ETH to block.coinbase if it is a contract than if it is an EOA, and as such many searchers will underestimate their gas consumption and their bundles will fail for validators who use contracts instead. -To handle this edge case searchers can up their gas limit to accomodate the additional payment to validators and call block.coinbase in the following way: +To handle this edge case searchers can up their gas limit to accommodate the additional payment to validators and call block.coinbase in the following way: ```solidity block.coinbase.call{value: _ethAmountToCoinbase}(new bytes(0)); diff --git a/docs/flashbots-auction/advanced/eip1559.mdx b/docs/flashbots-auction/advanced/eip1559.mdx index 4c10c7b36..3f29f5693 100644 --- a/docs/flashbots-auction/advanced/eip1559.mdx +++ b/docs/flashbots-auction/advanced/eip1559.mdx @@ -2,7 +2,7 @@ title: EIP-1559 Support --- -EIP-1559 is a new upgrade to the Ethereum network that changes how you pay for transactions. It introduces a base fee that varies depending on the network demand, and a priority fee that you can set to get faster confirmation. The base fee is burned, while the priority fee goes to the miner who includes your transaction in a block. Flashbots, starting from [mev-geth v1.10.5-mev-0.3.0](https://github.com/flashbots/mev-geth/releases/tag/v1.10.5-mev0.3.0), has integrated support for EIP-1559 transactions. +EIP-1559 is an upgrade to the Ethereum network that changes how you pay for transactions. It introduces a base fee that varies depending on the network demand, and a priority fee that you can set to get faster confirmation. The base fee is burned, while the priority fee goes to the miner who includes your transaction in a block. Flashbots, starting from [mev-geth v1.10.5-mev-0.3.0](https://github.com/flashbots/mev-geth/releases/tag/v1.10.5-mev0.3.0), has integrated support for EIP-1559 transactions. While users of the legacy transaction type don't need to make any configuration changes, they should be aware that it's now mandatory to include a `gasPrice` that is at least equal to the base fee. Coinbase transfer can still be used to incentivize faster inclusion, but it cannot be used to bypass the base fee requirement. diff --git a/docs/flashbots-auction/advanced/gas-fee-refunds.md b/docs/flashbots-auction/advanced/gas-fee-refunds.md new file mode 100644 index 000000000..12a0af4e9 --- /dev/null +++ b/docs/flashbots-auction/advanced/gas-fee-refunds.md @@ -0,0 +1,78 @@ +--- +title: Gas Fee Refunds +--- + +## Introduction + +Searchers and private transaction API users are automatically eligible to receive gas fee refunds. If a bundle can be included on chain for a lower price, you are eligible to receive a refund. + +Gas fee refunds do not change how bundles are executed and searchers do not need to make any changes to be eligible for them. + +## Where do refunds come from + +Gas fee refunds include both priority fees and coinbase transfers. + +In an optimal case, searchers are refunded the difference between their bid and the bid of the next-best bundle or transaction targeting the same state. Ie. the refund effectively results in the searcher paying the second price. In practice, searchers will receive some fraction of this amount depending on how much profit BuilderNet makes. + +## Which bundles receive refunds + +Flashbots provides refunds for bundles in blocks landed by [BuilderNet](https://buildernet.org/). Whether a bundle receives a refund depends on a few factors that vary from block to block: +* How much network congestion and competition there was +* Whether BuilderNet made a profit and how much +* How much the specific bundle contributed to the value of the block +* If the bundle was sent directly to Flashbots or BuilderNet, or shared with other block builders by the searcher + +Note that transactions seen in the public mempool are excluded and bundles containing only public mempool transactions do not receive refunds. + +## How to maximize both refunds and speed + +Transactions which are sent directly to the Flashbots Bundle Relay or BuilderNet, and not multiplexed _by the searcher_ to other block builders, are likely to receive higher refunds. This is because they increase the profit of BuilderNet which is used to provide refunds. + +BuilderNet does not land 100% of blocks. In order to land bundles in all blocks, searchers can ask Flashbots to share their bundles with other block builders in cases where BuilderNet does not win a block. Flashbots will automatically share with all specified builders on the searcher's behalf. + +### Smart multiplexing + +To share bundles with other builders, add the `builders` field to your `eth_sendBundle` request. The `builders` field accepts a list of strings which correspond to the "name" tags of [registered builders](https://github.com/flashbots/dowg/blob/main/builder-registrations.json). + +All `eth_sendBundle` requests are shared with BuilderNet. They are multiplexed to other block builders at the end of the slot if BuilderNet determines it will not win that block. + +For example: + +``` +{ + "jsonrpc": "2.0", + "id": 1, + "method": "eth_sendBundle", + "params": [ + { + "txs": ["0x123abc...", "0x456def..."], + "blockNumber": "0xb63dcd", + "minTimestamp": 0, + "maxTimestamp": 1615920932 + "builders": ["builder0x69", "beaverbuild.org"] + } + ] +} +``` + +Searchers can also use `mev_sendBundle` to multiplex bundles if they prefer. This method is more complex and not necessary for gas fee refunds. + +_Note: Smart multiplexing has a 1% rate of false positives, meaning that in 1% of MEV-Boost blocks there is a risk that searcher bundles will not be landed._ + +## How are refunds calculated + +BuilderNet uses a refund rule to retroactively calculate refunds for all bundles landed in its blocks. For more information, see the [BuilderNet docs](https://buildernet.org/docs/refunds). + +## Who receives refunds + +By default, the refund recipient is the signer used on the `eth_sendBundle`, `mev_sendBundle`, or `eth_sendPrivateTransaction` request. You can delegate your recipient to a different address using the `flashbots_setFeeRefundRecipient` API. + +## How to track refunds + +Refunds are tracked from a start date of July 8, 2024. Refunds are sent to recipients in batches, the first batch originated from the Flashbots builder address `0xdf99A0839818B3f120EBAC9B73f82B617Dc6A555` while newer batches originate from [`refunds.buildernet.eth`](https://etherscan.io/address/0x62a29205f7ff00f4233d9779c210150787638e7f). + +Track your refunds using the [`flashbots_getFeeRefundTotalsByRecipient`](/flashbots-auction/advanced/rpc-endpoint#flashbots_getfeerefundtotalsbyrecipient) RPC method or the [refund dashboard](https://app.hex.tech/9eb1e790-53f7-4c16-be76-4a22c1aa7d17/app/0c2d34ef-1304-481a-b3d6-b773ce9e0e19/latest) on Dune. + +## Distributed refunds + +The on-chain transactions corresponding to distributed refunds can be viewed with this Dune query: [https://dune.com/queries/4398421](https://dune.com/queries/4398421) diff --git a/docs/flashbots-auction/advanced/multiplexing.mdx b/docs/flashbots-auction/advanced/multiplexing.mdx new file mode 100644 index 000000000..0d1685568 --- /dev/null +++ b/docs/flashbots-auction/advanced/multiplexing.mdx @@ -0,0 +1,15 @@ +--- +title: Send transaction/bundle to multiple builders +--- + +import Builders from '../../specs/mev-share/_builders.mdx'; + +Some users might want to send their transactions or bundles to multiple builders for various reasons. The ability to multiplex is supported by our APIs. + +If you are using [`mev_sendBundle`](https://docs.flashbots.net/flashbots-auction/advanced/rpc-endpoint#mev_sendbundle) to send bundles, or [`eth_sendPrivateTransaction`](https://docs.flashbots.net/flashbots-auction/advanced/rpc-endpoint#eth_sendprivatetransaction) to send transactions, specify the builders you want to multiplex to in the `privacy.builders` parameter. + +If you are using [`eth_sendBundle`](https://docs.flashbots.net/flashbots-auction/advanced/rpc-endpoint#eth_sendbundle) to send bundles, specify the builders you want to multiplex to in the `builders` parameter. + +Below is the list of builders that you can multiplex to: + + diff --git a/docs/flashbots-auction/advanced/reputation.md b/docs/flashbots-auction/advanced/reputation.md index 1e93bacd3..da35c009f 100644 --- a/docs/flashbots-auction/advanced/reputation.md +++ b/docs/flashbots-auction/advanced/reputation.md @@ -16,21 +16,17 @@ $$ r(U) = \frac{\sum_{T\in H_U}(\Delta_{coinbase_T} + g_Tp_T)}{\sum_{T\in S_U}g_T} $$ - $r$: searcher reputation score. $H_U$: set of all transactions $T$ submitted by searcher $U$ to `eth_sendBundle` RPC and successfully landed on chain. $S_U$: set of all transactions $T$ submitted by searcher $U$ to `eth_sendBundle` and `eth_callBundle` RPC. $g_{T}$: _gas used_ by transaction $T$. $p_{T}$: _gas price_ of transaction $T$. $\Delta_{coinbase_T}$: coinbase difference from direct payment in transaction $T$. - ## Querying reputation Flashbots uses a dynamic threshold to classify users between the high reputation and low reputation queue. The dynamic variables are: 1) the historical time period considered to calculate reputation, 2) the cutoff reputation score which classifies a searcher as "high reputation". Using a dynamic threshold allows the builder to adapt in periods of high demand and maintain high reliability for top searchers. -A searcher can query their current reputation status using the [`flashbots_getUserStatsV2` RPC method](/flashbots-auction/advanced/rpc-endpoint#flashbots_getuserstatsv2). - ## Building reputation Searcher reputation is associated with the signing key used to authenticate with Flashbots. That is, the ethereum address associated with the `X-Flashbots-Signature` field of your bundle submission. diff --git a/docs/flashbots-auction/advanced/rpc-endpoint.mdx b/docs/flashbots-auction/advanced/rpc-endpoint.mdx index 041ccb48a..957d9f3db 100644 --- a/docs/flashbots-auction/advanced/rpc-endpoint.mdx +++ b/docs/flashbots-auction/advanced/rpc-endpoint.mdx @@ -1,12 +1,13 @@ --- -title: RPC Endpoint +title: JSON-RPC Endpoints --- -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; -import Hints from "../../specs/mev-share/_hints.mdx"; -import Builders from "../../specs/mev-share/_builders.mdx"; -import SendBundleSpec from "../../specs/mev-share/_mev_sendBundle.mdx"; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import Hints from '../../specs/mev-share/HintsTable'; +import Builders from '../../specs/mev-share/_builders.mdx'; +import SendBundleSpec from '../../specs/mev-share/_mev_sendBundle.mdx'; +import SimBundleSpec from '../../specs/mev-share/_mev_simBundle.mdx'; ## Interact directly with the Flashbots RPC endpoint @@ -14,13 +15,17 @@ Advanced users can interact with the RPC endpoint at `relay.flashbots.net`, or o ### Bundle Relay URLS -| Network | URL | -| ------- | ------------------------------------- | -| Mainnet | `https://relay.flashbots.net` | -| Goerli | `https://relay-goerli.flashbots.net` | -| Sepolia | `https://relay-sepolia.flashbots.net` | +| Network | URL | +| -------- | ---------------------------------------- | +| Mainnet | `https://relay.flashbots.net` | +| Sepolia | `https://relay-sepolia.flashbots.net` | -The API provides JSON-RPC methods for interfacing with Flashbots which are documented below: +The API provides JSON-RPC methods for interfacing with Flashbots. Below are some of the restrictions: + +- There is a rate limit of 10,000 requests per second per IP +- Each bundle (`txs` parameter) can contain at most 100 transactions and have a size limit of 300,000 bytes + +Each method is documented below. ### eth_sendBundle @@ -39,6 +44,7 @@ The API provides JSON-RPC methods for interfacing with Flashbots which are docum maxTimestamp, // (Optional) Number, the maximum timestamp for which this bundle is valid, in seconds since the unix epoch revertingTxHashes, // (Optional) Array[String], A list of tx hashes that are allowed to revert replacementUuid, // (Optional) String, UUID that can be used to cancel/replace this bundle + builders, // (Optional) Array[String], A list of [registered](https://github.com/flashbots/dowg/blob/main/builder-registrations.json) block builder names to share the bundle with } ] } @@ -74,10 +80,43 @@ example response: } ``` -### mev_sendBundle +If `builders` are specified, the response will include an additional `smart` field. + +example with `builders`: + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "eth_sendBundle", + "params": [ + { + "txs": ["0x123abc...", "0x456def..."], + "blockNumber": "0xb63dcd", + "minTimestamp": 0, + "maxTimestamp": 1615920932, + "builders": ["builder0x69"] + } + ] +} +``` + +example response: + +```json +{ + "jsonrpc": "2.0", + "id": "123", + "result": { + "bundleHash": "0x2228f5d8954ce31dc1601a8ba264dbd401bf1428388ce88238932815c5d6f23f", + "smart": "true" + } +} +``` -`mev_sendBundle` uses a new bundle format to send bundles to MEV-Share. See the [Sending Bundles](/flashbots-mev-share/searchers/sending-bundles#simulating_bundles) page for more information, or check out the [Sending Bundles](/flashbots-mev-share/searchers/sending-bundles) page for a short guide. +### mev_sendBundle +`mev_sendBundle` uses a new bundle format to send bundles to MEV-Share. See the [Understanding Bundles](/flashbots-mev-share/searchers/understanding-bundles) page for more information, or check out the [Sending Bundles](/flashbots-mev-share/searchers/sending-bundles) page for a short guide. Note that as of October 20, 2025, a bundle can now only contain one backrun transaction. example request: @@ -204,7 +243,7 @@ example response: `mev_simBundle` uses a new bundle format to simulate matched bundles on MEV-Share. See [mev-share spec](https://github.com/flashbots/mev-share/blob/main/specs) for more information. - + example request (sent after landing a bundle via `mev_sendBundle`): @@ -258,12 +297,17 @@ example response: ### eth_cancelBundle -`eth_cancelBundle` is used to prevent a submitted bundle from being included on-chain. -See [bundle cancellations](/flashbots-auction/advanced/bundle-cancellations) for more information. +`eth_cancelBundle` is used to prevent a submitted bundle from being included on-chain. See [bundle cancellations](/flashbots-auction/advanced/bundle-cancellations) for more information. [`eth_cancelPrivateTransaction`](https://docs.alchemy.com/alchemy/apis/ethereum/eth_cancelPrivateTransaction/?a=fb) is also supported on [Alchemy](https://alchemy.com/?a=fb). -> :information_source: `replacementUuid` must have been set when bundle was submitted. +:::caution +`replacementUuid` must have been set when bundle was submitted. +::: + +:::caution +When you cancel a bundle in Flashbots, the cancelled bundle is excluded from all future bids by the builder. However, there's no active adjustment to decrease the bid value on the relay for already placed bids. If the block value increases without your bundle, the bid might be replaced to reflect the new value. +::: ```json { @@ -295,7 +339,7 @@ This method has the following JSON-RPC format: tx, // String, raw signed transaction maxBlockNumber, // Hex-encoded number string, optional. Highest block number in which the transaction should be included. preferences?: { - fast: boolean, // Deprecated; required until this is removed from the API. Value has no effect. + fast: boolean, // Sends transactions to all registered block builders, sets MEV-Share revenue share to 50% privacy?: { // MEV-Share options; optional hints?: Array< // data about tx to share w/ searchers on mev-share "contract_address" | @@ -329,13 +373,13 @@ example request: "tx": "0x123abc...", "maxBlockNumber": "0xcd23a0", "preferences": { - "fast": true, // left for backwards compatibility; may be removed in a future version + "fast": true, "privacy": { "hints": ["calldata", "transaction_hash"], "builders": ["default"] }, "validity": { - "refund": [{ "address": "0xadd123", "percent": 50 }] + "refund": [{"address": "0xadd123", "percent": 50}] } } } @@ -355,12 +399,12 @@ example response: #### `privacy` -By default, transactions are sent to the Flashbots MEV-Share Node with the default [Stable](/flashbots-protect/mev-share#stable-configuration) configuration. The `privacy` parameter allows you to specify your own privacy parameters. +By default, transactions are sent to the Flashbots MEV-Share Node with the default [Stable](/flashbots-protect/mev-refunds#stable-configuration) configuration. The `privacy` parameter allows you to specify your own privacy parameters. -| Param | Type Info | Description | -| ---------- | ---------------- | ------------------------------------------------------------------------------------------------ | -| `hint` | Array of strings | Each hint specifies which data about the transaction will be shared with searchers on mev-share. | -| `builders` | Array of strings | Builders to grant permission to include the transaction in a block. | +| Param | Type Info | Description | +| --- | --- | --- | +| `hint` | Array of strings | Each hint specifies which data about the transaction will be shared with searchers on mev-share. | +| `builders` | Array of strings | Builders to grant permission to include the transaction in a block. | **`hint`** @@ -378,20 +422,17 @@ Validity is used to specify the address and percentage to pay refund from the ba By default, the refund is paid to the signer of the transaction and 90% of the backrun value is sent to the user by default. -If multiple refund addresses are specified, then the backrun value is split between them according to the percentage specified. -For example, if refund is `[{address: addr1, percent: 10}, {address: addr1, percent: 20}]` then 10% of the backrun value is sent to `addr1` and 20% is sent to `addr2` -and 70% of the backrun value is left to the builder. +If multiple refund addresses are specified, then the backrun value is split between them according to the percentage specified. For example, if refund is `[{address: addr1, percent: 10}, {address: addr1, percent: 20}]` then 10% of the backrun value is sent to `addr1` and 20% is sent to `addr2` and 70% of the backrun value is left to the builder. -| Param | Type Info | Description | -| ------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------- | -| `refund` | Array of objects | Each entry in the array specifies address that should receive refund from backrun and percent of the backrun value. | -| `refund[].address` | Address | Address that should receive refund. | -| `refund[].percent` | Number | Percentage of the total backrun value that this address should receive. | +| Param | Type Info | Description | +| --- | --- | --- | +| `refund` | Array of objects | Each entry in the array specifies address that should receive refund from backrun and percent of the backrun value. | +| `refund[].address` | Address | Address that should receive refund. | +| `refund[].percent` | Number | Percentage of the total backrun value that this address should receive. | ### eth_sendPrivateRawTransaction -`eth_sendPrivateRawTransaction` behaves like [eth_sendPrivateTransaction](#eth_sendprivatetransaction) but its format -is similar to that of [`eth_sendRawTransaction`](https://docs.alchemy.com/reference/eth-sendrawtransaction) +`eth_sendPrivateRawTransaction` behaves like [eth_sendPrivateTransaction](#eth_sendprivatetransaction) but its format is similar to that of [`eth_sendRawTransaction`](https://docs.alchemy.com/reference/eth-sendrawtransaction) This method has the following JSON-RPC format: @@ -402,7 +443,25 @@ This method has the following JSON-RPC format: method: "eth_sendPrivateRawTransaction", params: [ tx, // String, raw signed transaction - preferences? // Optional, see eth_sendPrivateTransaction + preferences?: { + fast: boolean, // Sends transactions to all registered block builders, sets MEV-Share revenue share to 50% + privacy?: { // MEV-Share options; optional + hints?: Array< // data about tx to share w/ searchers on mev-share + "contract_address" | + "function_selector" | + "calldata" | + "logs" | + "hash" + >, + builders?: Array< // MEV-Share builders to exclusively receive bundles; optional + "default" | + "flashbots" + >, + }, + validity?: { + refund?: Array<{address, percent}> + } + } ] } ``` @@ -428,10 +487,10 @@ example response: } ``` -| Param | Type Info | Description | -| ----------- | --------- | --------------------------------------------------------------------------------- | -| `params[0]` | String | Raw signed transaction | -| `params[1]` | Object | Optional private tx preferences, see `preferences` in eth_sendPrivateTransaction. | +| Param | Type Info | Description | +| --- | --- | --- | +| `params[0]` | String | Raw signed transaction | +| `params[1]` | Object | Optional private tx preferences, see `preferences` in eth_sendPrivateTransaction. | ### eth_cancelPrivateTransaction @@ -477,205 +536,291 @@ example response: } ``` -### flashbots_getUserStats +### flashbots_getFeeRefundTotalsByRecipient -:::caution - -flashbots_getUserStats will be deprecated soon, use [flashbots_getUserStatsV2](/flashbots-auction/advanced/rpc-endpoint#flashbots_getuserstatsv2) - -::: - -The `flashbots_getUserStats` JSON-RPC method returns a quick summary of how a searcher is performing in the Flashbots ecosystem, including their [reputation-based priority](/flashbots-auction/advanced/reputation). It is currently updated once every hour and has the following payload format: +The `flashbots_getFeeRefundTotalsByRecipient` JSON-RPC method returns the total amount of fee refunds that have been earned by a specific address. Our refund process calculates these values weekly. ```json { "jsonrpc": "2.0", "id": 1, - "method": "flashbots_getUserStats", + "method": "flashbots_getFeeRefundTotalsByRecipient", "params": [ - blockNumber, // String, a hex encoded recent block number, in order to prevent replay attacks. Must be within 20 blocks of the current chain tip. + recipient, // String, the address to query for fee refunds ] } ``` -example response: +The response contains three fields: ```json { - "is_high_priority": true, - "all_time_miner_payments": "1280749594841588639", - "all_time_gas_simulated": "30049470846", - "last_7d_miner_payments": "1280749594841588639", - "last_7d_gas_simulated": "30049470846", - "last_1d_miner_payments": "142305510537954293", - "last_1d_gas_simulated": "2731770076" + "pending":"0x17812ea4fbbe314", + "received":"0x108d1b27b63a213", + "maxBlockNumber":"0x13ddb08" } ``` -where +- `pending`: the total amount of fee refunds that have been earned but not yet received by the recipient +- `received`: the total amount of fee refunds that have been received by the recipient +- `maxBlockNumber`: the highest block number for which fee refunds have been processed -- `is_high_priority`: boolean representing if this searcher has a high enough reputation to be in the high priority queue -- `all_time_miner_payments`: the total amount paid to validators over all time -- `all_time_gas_simulated`: the total amount of gas simulated across all bundles submitted to Flashbots. This is the actual gas used in simulations, not gas limit +### flashbots_getFeeRefundsByRecipient + +The `flashbots_getFeeRefundsByRecipient` JSON-RPC method returns detailed information about [fee refunds](/flashbots-protect/gas-fee-refunds) that have been earned by a specific address. Our refund process usually calculates these values with a 4 hour delay. + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "flashbots_getFeeRefundsByRecipient", + "params": [ + { + recipient, // String, the address to query for fee refunds + cursor, // [optional] String, the cursor to continue from + } + ] +} +``` -:::note +Responses are paginated and contain the following fields: -Parameters with `miner` in the name are retrofitted with Flashbots block builder data to maintain backwards compatibility. This nomenclature will be changed in a future release to accurately reflect PoS Ethereum architecture. +```json +{ + "refunds": [ + { + "hash": "0x...", + "amount": "0x...", + "blockNumber": "0x13ddaa4", + "status": "pending", + "recipient": "0x..." + }, + ... + ], + "cursor": "0x..." +} +``` -::: +The `"refunds"` field contains an array of per-order fee refunds, each with the following fields: -### flashbots_getBundleStats +- `hash`: the bundle hash or transaction hash associated with the fee refund +- `amount`: the amount of the fee refund, in wei +- `blockNumber`: the block number the order was contained in +- `status`: the status of the fee refund, either "pending" or "received" +- `recipient`: the address the fee refund is credited to, either the bundle signer or transaction sender -:::caution +The `"cursor"` field is only included if there are more fee refunds to fetch. To continue fetching fee refunds, include the cursor as the second argument in the next request. -flashbots_getBundleStats will be deprecated soon, use [flashbots_getBundleStatsV2](/flashbots-auction/advanced/rpc-endpoint#flashbots_getbundlestatsv2) +NOTE: This API currently only returns details for bundles included in block 20802497 and later. To see total fee refunds processed for a specific address since inception, use the `flashbots_getFeeRefundTotalsByRecipient` method. -::: +### flashbots_getFeeRefundsByBundle -The `flashbots_getBundleStats` JSON-RPC method returns stats for a single bundle. You must provide a blockNumber and the bundleHash, and the signing address must be the same as the one who submitted the bundle. +The `flashbots_getFeeRefundsByBundle` is similar to `flashbots_getFeeRefundsByRecipient` but returns result for the given bundle. ```json { "jsonrpc": "2.0", "id": 1, - "method": "flashbots_getBundleStats", + "method": "flashbots_getFeeRefundsByBundle", "params": [ { - bundleHash, // String, returned by the flashbots api when calling eth_sendBundle - blockNumber, // String, the block number the bundle was targeting (hex encoded) + bundle_hash, // String, the hash of the bundle } ] } ``` -example response: +### flashbots_getFeeRefundsByBlock + +The `flashbots_getFeeRefundsByBlock` is similar to `flashbots_getFeeRefundsByRecipient` but returns result for the given block. ```json { - "isSimulated": true, - "isSentToMiners": true, - "isHighPriority": true, - "simulatedAt": "2021-08-06T21:36:06.317Z", - "submittedAt": "2021-08-06T21:36:06.250Z", - "sentToMinersAt": "2021-08-06T21:36:06.343Z", - "receivedAt": "2022-10-06T21:36:06.250Z", // Added for POS, will be included as part of V2 - "consideredByBuildersAt": [ - { - "pubkey": "0x81babeec8c9f2bb9c329fd8a3b176032fe0ab5f3b92a3f44d4575a231c7bd9c31d10b6328ef68ed1e8c02a3dbc8e80f9", - "timestamp": "2022-10-06T21:36:06.343Z" - }, - { - "pubkey": "0x81beef03aafd3dd33ffd7deb337407142c80fea2690e5b3190cfc01bde5753f28982a7857c96172a75a234cb7bcb994f", - "timestamp": "2022-10-06T21:36:06.394Z" - }, - { - "pubkey": "0xa1dead1e65f0a0eee7b5170223f20c8f0cbf122eac3324d61afbdb33a8885ff8cab2ef514ac2c7698ae0d6289ef27fc", - "timestamp": "2022-10-06T21:36:06.322Z" - } - ], // Added for POS, will be included as part of V2 - "sealedByBuildersAt": [ + "jsonrpc": "2.0", + "id": 1, + "method": "flashbots_getFeeRefundsByBlock", + "params": [ { - "pubkey": "0x81beef03aafd3dd33ffd7deb337407142c80fea2690e5b3190cfc01bde5753f28982a7857c96172a75a234cb7bcb994f", - "timestamp": "2022-10-06T21:36:07.742Z" + block_number, // String, hex-encoded block number (e.g. 0x15d0280) } - ] // Added for POS, will be included as part of V2 + ] } ``` -### flashbots_getUserStatsV2 -The `flashbots_getUserStatsV2` JSON-RPC method returns a quick summary of how a searcher is performing in the Flashbots ecosystem, including their [reputation-based priority](/flashbots-auction/advanced/reputation). It is currently updated once every hour and has the following payload format: + +### flashbots_setFeeRefundRecipient + +The `flashbots_setFeeRefundRecipient` JSON-RPC method allows a user to "delegate" their [fee refunds](/flashbots-auction/advanced/gas-fee-refunds) to a specific wallet address. Two addresses must be provided, the first is the address associated with the signing key used to authenticate your request, while the second is the address to send refunds to. ```json { "jsonrpc": "2.0", "id": 1, - "method": "flashbots_getUserStatsV2", + "method": "flashbots_setFeeRefundRecipient", "params": [ - { - blockNumber // String, a hex encoded recent block number, in order to prevent replay attacks. Must be within 20 blocks of the current chain tip. - } + "0xD2824D2D7D6399a4b9A47F258B870D2AFb213948", + "0xa273A268CE96E54cF6a7D879B7d016F57E396F48" ] } ``` -example response: +If the first address matches the authentication signature, then a response with `from` and `to` fields in the result will be returned: ```json { - "isHighPriority": true, - "allTimeValidatorPayments": "1280749594841588639", - "allTimeGasSimulated": "30049470846", - "last7dValidatorPayments": "1280749594841588639", - "last7dGasSimulated": "30049470846", - "last1dValidatorPayments": "142305510537954293", - "last1dGasSimulated": "2731770076" + "jsonrpc": "2.0", + "id": 1, + "result": { + "from":"0xd2824d2d7d6399a4b9a47f258b870d2afb213948", + "to":"0xa273a268ce96e54cf6a7d879b7d016f57e396f48" + } } ``` -where - -- `isHighPriority`: boolean representing if this searcher has a high enough reputation to be in the high priority queue -- `allTimeValidatorPayments`: the total amount paid to validators over all time -- `allTimeGasSimulated`: the total amount of gas simulated across all bundles submitted to Flashbots. This is the actual gas used in simulations, not gas limit +If the signature is invalid or does not match the first address, an appropriate error will be returned instead. -### flashbots_getBundleStatsV2 +### buildernet_getDelayedRefunds -The `flashbots_getBundleStatsV2` JSON-RPC method returns stats for a single bundle. You must provide a blockNumber and the bundleHash, and the signing address must be the same as the one who submitted the bundle. +The `buildernet_getDelayedRefunds` JSON-RPC method returns detailed information about delayed refunds. ```json { "jsonrpc": "2.0", "id": 1, - "method": "flashbots_getBundleStatsV2", + "method": "buildernet_getDelayedRefunds", "params": [ { - bundleHash, // String, returned by the flashbots api when calling eth_sendBundle - blockNumber, // String, the block number the bundle was targeting (hex encoded) + recipient, // String, the address that receives delayed refunds + blockRangeFrom, // [optional] String, hex-encoded block number for the start of the range (inclusive) + blockRangeTo, // [optional] String, hex-encoded block number for the end of the range (inclusive) + cursor, // [optional] String, the cursor to continue from + hash, // [optional] String, bundle hash; if provided, you must also set both blockRangeFrom and blockRangeTo } ] } ``` -example response: +Responses are paginated and contain the following fields: ```json { - "isHighPriority": true, - "isSimulated": true, - "simulatedAt": "2022-10-06T21:36:06.317Z", - "receivedAt": "2022-10-06T21:36:06.250Z", - "consideredByBuildersAt": [ - { - "pubkey": "0x81babeec8c9f2bb9c329fd8a3b176032fe0ab5f3b92a3f44d4575a231c7bd9c31d10b6328ef68ed1e8c02a3dbc8e80f9", - "timestamp": "2022-10-06T21:36:06.343Z" - }, + "refunds": [ { - "pubkey": "0x81beef03aafd3dd33ffd7deb337407142c80fea2690e5b3190cfc01bde5753f28982a7857c96172a75a234cb7bcb994f", - "timestamp": "2022-10-06T21:36:06.394Z" + "hash": "0x...", + "amount": "0x...", + "blockNumber": "0x13ddaa4", + "status": "pending", + "recipient": "0x..." }, - { - "pubkey": "0xa1dead1e65f0a0eee7b5170223f20c8f0cbf122eac3324d61afbdb33a8885ff8cab2ef514ac2c7698ae0d6289ef27fc", - "timestamp": "2022-10-06T21:36:06.322Z" - } + ... ], - "sealedByBuildersAt": [ - { - "pubkey": "0x81beef03aafd3dd33ffd7deb337407142c80fea2690e5b3190cfc01bde5753f28982a7857c96172a75a234cb7bcb994f", - "timestamp": "2022-10-06T21:36:07.742Z" - } - ] + "nextCursor": "0x..." + "indexedUpTo": "0x..." +} +``` + +The `"refunds"` field contains an array of per-order fee refunds, each with the following fields: + +- `hash`: the bundle hash that generated delayed refund +- `amount`: the amount of the delayed refund, in wei +- `blockNumber`: the block number the order was contained in +- `status`: the status of the delayed refund, either "pending" or "received" +- `recipient`: the address the delayed refund is credited to + +The `"cursor"` field is only included if there are more delayed refunds to fetch, some data might be avaiable in the future. To continue fetching, include the cursor as the second argument in the next request. If response is empty but contains cursor retry later. + +`"indexedUpTo"` contains maximum block number for which delayed refunds are indexed + +### buildernet_getDelayedRefundTotalsByRecipient + +The `buildernet_getDelayedRefundTotalsByRecipient` JSON-RPC method returns the total amount of delayed refunds that have been earned by a specific address. + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "buildernet_getDelayedRefundTotalsByRecipient", + "params": [{ + recipient, // String, the address to query for delayed refunds + blockRangeFrom, // [optional] String, hex-encoded block number for the start of the range (inclusive) + blockRangeTo, // [optional] String, hex-encoded block number for the end of the range (inclusive) + }] +} +``` + +The response contains three fields: + +```json +{ + "pending":"0x17812ea4fbbe314", + "received":"0x108d1b27b63a213", + "indexedUpTo":"0x13ddb08" +} +``` + +- `pending`: the total amount of fee refunds that have been earned but not yet received by the recipient +- `received`: the total amount of fee refunds that have been received by the recipient +- `indexedUpTo`: the highest block number for which delayed refunds have been processed + + +### flashbots_getMevRefundTotalByRecipient + +Returns the total amount of [MEV refunds](/flashbots-protect/mev-refunds) that have been paid to a specific recipient address. This API not require authentication. + +#### Request + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "flashbots_getMevRefundTotalByRecipient", + "params": ["0xDCDDAE87EDF1D9F62AE2F3A66EB2018ACD0B2508"] +} +``` + +#### Response + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "total": "0xeff5f44e097dcfac" + } +} +``` + +Note: The total is returned as a hexadecimal string representing the amount in wei. + +### flashbots_getMevRefundTotalBySender + +Returns the total amount of [MEV refunds](/flashbots-protect/mev-refunds) that have been generated on transactions or bundles from a specific sender address. The sender is the `tx.origin` for individual transactions or bundles of size 1, or the Flashbots signer for bundles of size > 1. It may be different from the recipient if the recipient has been delegated to another address. + +This API does not require authentication. + +#### Request + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "flashbots_getMevRefundTotalBySender", + "params": ["0xDCDDAE87EDF1D9F62AE2F3A66EB2018ACD0B2508"] } ``` -where +#### Response -- `isHighPriority`: boolean representing if this searcher has a high enough reputation to be in the high priority queue -- `isSimulated`: boolean representing whether the bundle gets simulated. All other fields will be omitted except simulated field if API didn't receive bundle -- `simulatedAt`: time at which the bundle gets simulated -- `receivedAt`: time at which the bundle API received the bundle -- `consideredByBuildersAt`: indicates time at which each builder selected the bundle to be included in the target block -- `sealedByBuildersAt`: indicates time at which each builder sealed a block containing the bundle +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "total": "0x4a817c800" + } +} +``` ### API Response @@ -705,13 +850,13 @@ The signature is calculated by taking the [EIP-191](https://eips.ethereum.org/EI ```ts -import { Wallet, utils } from "ethers"; +import {Wallet, id} from 'ethers'; -const privateKey = "0x1234"; +const privateKey = '0x1234'; const wallet = new Wallet(privateKey); const body = '{"jsonrpc":"2.0","method":"eth_sendBundle","params":[{see above}],"id":1}'; -const signature = wallet.address + ":" + wallet.signMessage(utils.id(body)); +const signature = wallet.address + ':' + wallet.signMessage(id(body)); ``` diff --git a/docs/flashbots-auction/advanced/testnets.mdx b/docs/flashbots-auction/advanced/testnets.mdx index b7fa079a6..1a361664f 100644 --- a/docs/flashbots-auction/advanced/testnets.mdx +++ b/docs/flashbots-auction/advanced/testnets.mdx @@ -2,14 +2,13 @@ title: Testnets --- -Flashbots operates on Goerli and Sepolia, so that searchers can test Flashbots without risking real funds. +Flashbots operates on Sepolia so that searchers can test Flashbots without risking real funds. ## Bundle Relay URLS | Network | URL | | --- | --- | | Mainnet | `https://relay.flashbots.net` | -| Goerli | `https://relay-goerli.flashbots.net` | | Sepolia | `https://relay-sepolia.flashbots.net` | ## Examples diff --git a/docs/flashbots-auction/advanced/troubleshooting.mdx b/docs/flashbots-auction/advanced/troubleshooting.mdx index f6d5a859f..dbebe0ebf 100644 --- a/docs/flashbots-auction/advanced/troubleshooting.mdx +++ b/docs/flashbots-auction/advanced/troubleshooting.mdx @@ -14,7 +14,7 @@ Unlike broadcasting a transaction which lands on-chain even if the transaction f 5. The validator for the target slot is not running mev-boost ``` -Instead of relying on [Etherscan](https://etherscan.io) to examine the execution of your transaction, its on-chain status, and its comparison with competitors, you'll need a different approach with Flashbots. This is because Flashbots prevents failed transactions from appearing on the chain. For effective debugging, we highly recommend simulating your transactions, logging the results, and maintaining a record of all submitted data, including the complete bundle and its signed transactions. +Instead of relying on [Etherscan](https://etherscan.io) to examine the execution of your transaction, its on-chain status, and its comparison with competitors, you'll need a different approach with Flashbots. This is because Flashbots prevents failed transactions from appearing on the chain. For effective debugging, we highly recommend simulating your transactions, logging the results, and maintaining a record of all submitted data, including the complete bundle and its signed transactions. If you are a TEE searcher, you will receive logs with full transaction information at a 5 minute delay to help with troubleshooting and debugging. The issues listed above are arranged in the order of their priority for consideration. In the following sections, we will explore each issue in detail, providing guidance on how to identify and address them. While the examples provided assume the use of the [Flashbots Ethers Provider](https://github.com/flashbots/ethers-provider-flashbots-bundle), the [RPC calls are standard](/flashbots-auction/advanced/rpc-endpoint) and the suggested strategies can be easily adapted for use with [other providers](/flashbots-auction/libraries/golang). @@ -90,9 +90,9 @@ Covers: 3. Competitors paying more ``` -[Flashbots bundles adhere to a "blind" auction](/flashbots-auction/overview), where bundle pricing is not released by Flashbots prior to landing on-chain. The winning "bids" are revealed _only_ after the block containing winning bundles is propagated (via the transactions themselves and [blocks-api](https://blocks.flashbots.net/) for recognizing which set of transactions belong to a bundle). +[Flashbots bundles adhere to a "blind" auction](/flashbots-auction/overview), where bundle pricing is not released by Flashbots prior to landing on-chain. The winning "bids" are revealed _only_ after the block containing winning bundles is propagated. -While you cannot see a competitor's bid in real time, it is possible to look AFTER the fact to: +While you cannot see a competitor's bid in real time, it is possible to look onchain AFTER the fact to: 1. Identify the exact bundle (if any) that conflicted with yours 2. Compare the conflicting bundle's `effective priority fee` with your own (to see if you should be bidding more to remain competitive) @@ -211,7 +211,7 @@ Each bundle submission is designed to target a specific block number. Therefore, All these steps need to be completed before the targeted block is proposed. If you're targeting `blockNumber +1`, which is common for most bundles, it's vital to deliver your bundle to your builder(s) as quickly as you can. -It's important to remember that there's a time frame for every block when your local perspective of block height is `X`, while `X+1` has already been discovered and propagated to a portion of the network, but hasn't reached your local node yet. During this period of partial propagation, submitting a bundle targeting `X+1` may seem valid from your network perspective, but could be pointless if builders have already started working on solving X+2. In rare cases, targeting the `X+1` block just before its discovery can also cause bundle failure due to insufficient time for the bundle to complete the above listed 4 steps, each of which takes aroun 1-2 seconds. +It's important to remember that there's a time frame for every block when your local perspective of block height is `X`, while `X+1` has already been discovered and propagated to a portion of the network, but hasn't reached your local node yet. During this period of partial propagation, submitting a bundle targeting `X+1` may seem valid from your network perspective, but could be pointless if builders have already started working on solving X+2. In rare cases, targeting the `X+1` block just before its discovery can also cause bundle failure due to insufficient time for the bundle to complete the above listed 4 steps, each of which takes around 1-2 seconds. To monitor the time taken from the submission of your bundle to the Flashbots and the proposal of the next block, Flashbots provides an RPC endpoint `eth_getBundleStats`. This endpoint returns timing information based on a previously-submitted bundle. Each submitted bundle is uniquely identified by a bundleHash and target block number for future reference. The bundleHash is straightforward to calculate, as shown [here](https://github.com/flashbots/ethers-provider-flashbots-bundle/blob/0d404bb041b82c12789bd62b18e218304a095b6f/src/index.ts#L266-L269). @@ -256,11 +256,7 @@ Analyze the timestamps above in relation to when you observe the targeted block mev-boost is an opt-in system that runs alongside a validator's consensus client. Unless every validator on Ethereum runs mev-boost, some slots cannot be targeted with Flashbots. Additionally, your builder must be connected to the same relay as the proposer for the target slot. -If no bundles are detected in the blocks-api response, check if other blocks from the same validator ever have Flashbots bundles. If no blocks from a particular validator contain Flashbots bundles, it is possible your bundle was not seen by the validator who proposed the block for the target block height. - -## New Blocks API fields - -New fields have been added to the blocks API to align the API with PoS Ethereum nomenclature. Details can be found in the [Blocks API page](/flashbots-data/blockapi). +If no blocks from a particular validator contain Flashbots bundles, it is possible your bundle was not seen by the validator who proposed the block for the target block height. ## Everything checks out, what's next? diff --git a/docs/flashbots-auction/libraries/alchemyprovider.md b/docs/flashbots-auction/libraries/alchemyprovider.md index e5be0fee1..aec5c4086 100644 --- a/docs/flashbots-auction/libraries/alchemyprovider.md +++ b/docs/flashbots-auction/libraries/alchemyprovider.md @@ -15,6 +15,6 @@ To get started: * [https://www.alchemy.com/sdk](https://www.alchemy.com/sdk) -* [https://docs.alchemy.com/reference/eth-sendprivatetransaction](https://docs.alchemy.com/reference/eth-sendprivatetransaction) +* [https://docs.alchemy.com/reference/sendprivatetransaction-sdk-v3](https://docs.alchemy.com/reference/sendprivatetransaction-sdk-v3) * [https://github.com/alchemyplatform/alchemy-sdk-js](https://github.com/alchemyplatform/alchemy-sdk-js) diff --git a/docs/flashbots-auction/libraries/rust-provider.md b/docs/flashbots-auction/libraries/rust-provider.md new file mode 100644 index 000000000..f4f983733 --- /dev/null +++ b/docs/flashbots-auction/libraries/rust-provider.md @@ -0,0 +1,11 @@ +--- +title: Rust Provider +--- + +Ethers-flashbots is a robust and user-friendly Rust library for interacting with flashbots. + +By using this library, you can easily access the flashbots endpoints and send bundles of transactions with little effort from you favorite language. + +This library is built on [ethers-rs,](https://github.com/gakonst/ethers-rs) which is a port of the popular ethers.js library, and it provides a convenient middleware layer for integrating with ethers-rs. + +With ethers-flashbots, you can quickly and easily automate your trading activities on DEXs, allowing you to take advantage of market opportunities and maximize your profits. To learn more about ethers-flashbots and its features, visit the library's repository [here.](https://github.com/onbjerg/ethers-flashbots) \ No newline at end of file diff --git a/docs/flashbots-auction/libraries/web3py-provider.md b/docs/flashbots-auction/libraries/web3py-provider.md index e4f82f2d2..25041032d 100644 --- a/docs/flashbots-auction/libraries/web3py-provider.md +++ b/docs/flashbots-auction/libraries/web3py-provider.md @@ -5,6 +5,6 @@ web3-flashbots is a repository containing a library that works by injecting a ne a middleware which captures calls to `eth_sendBundle` and `eth_callBundle`, and sends them to an RPC endpoint which you have specified, which corresponds your preferred block builder. -To apply correct headers we use FlashbotProvider which injects the correct header on post +To apply correct headers, we use FlashbotProvider which injects the correct header on post. Access the web3-flashbots repository [here](https://github.com/flashbots/web3-flashbots). diff --git a/docs/flashbots-auction/overview.mdx b/docs/flashbots-auction/overview.mdx index b48adf713..4553022b7 100644 --- a/docs/flashbots-auction/overview.mdx +++ b/docs/flashbots-auction/overview.mdx @@ -10,7 +10,7 @@ In PoS Ethereum, the Flashbots Auction is built on [mev-boost](https://boost.fla ## Why Flashbots Auction? -Throughout the second half of 2020 and begining of 2021, a spike in Ethereum usage has revealed a set of negative externalities brought by MEV. These include network congestion (i.e. p2p network load) and chain congestion (i.e. block space usage) caused by inefficient communication between PGA bot operators and (PoW) miners for transaction order preference. These negative externalities create a deadweight loss which is shouldered by regular Ethereum users though high gas price volatility and artificially scarce blockspace. +Throughout the second half of 2020 and beginning of 2021, a spike in Ethereum usage has revealed a set of negative externalities brought by MEV. These include network congestion (i.e. p2p network load) and chain congestion (i.e. block space usage) caused by inefficient communication between PGA bot operators and (PoW) miners for transaction order preference. These negative externalities create a deadweight loss which is shouldered by regular Ethereum users though high gas price volatility and artificially scarce blockspace. The extraction of MEV introduces an existential threat to Ethereum's consensus security. This is primarily due to the potential for chain history re-org to extract past MEV, known as [time-bandit attacks](https://arxiv.org/pdf/1904.05234.pdf), and the centralization of transaction routing for the benefits of privacy, low latency, and control over transaction order. These factors critically undermine Ethereum's foundational principles of finality and permissionlessness, posing a serious risk to its very existence. diff --git a/docs/flashbots-auction/quick-start.mdx b/docs/flashbots-auction/quick-start.mdx index 912a9d50f..90ec3c105 100644 --- a/docs/flashbots-auction/quick-start.mdx +++ b/docs/flashbots-auction/quick-start.mdx @@ -14,7 +14,6 @@ See you on-chain! ⚡🤖 | Network | URL | | ------- | ------------------------------------- | | Mainnet | `https://relay.flashbots.net` | -| Goerli | `https://relay-goerli.flashbots.net` | | Sepolia | `https://relay-sepolia.flashbots.net` | ### Who should use Flashbots Auction? @@ -38,7 +37,7 @@ To access the Flashbots network you will need three things: - [Alchemy](https://docs.alchemy.com/docs/how-to-send-a-private-transaction-on-ethereum?a=fb) provides a convenient way to dispatch individual transactions to Flashbots. 3. A "bundle" comprising your transactions -When you send bundles to Flashbots, they are signed with your key, which allows us to confirm your identity and accumulate your [reputation](/flashbots-auction/advanced/reputation) over time. Reputation system is set up to protect the infrastructure from attacks like DDoS. Searcheres with higher reputation will have better access to the network especially during times of high congestion. +When you send bundles to Flashbots, they are signed with your key, which allows us to confirm your identity and accumulate your [reputation](/flashbots-auction/advanced/reputation) over time. Reputation system is set up to protect the infrastructure from attacks like DDoS. Searchers with higher reputation will have better access to the network especially during times of high congestion. It's crucial to understand that this key **does not** manage any funds and does **not** have to be the main Ethereum key used for authenticating transactions. Its only function is to establish your identity with Flashbots. You can use any ECDSA-secp256k1 key for this purpose. @@ -50,12 +49,13 @@ Next, you need a means to communicate with the Flashbots network. The Flashbots { label: 'ethers.js', value: 'ethers.js', }, { label: 'web3.py', value: 'web3.py' }, { label: 'go', value: 'go' }, + { label: 'rust', value: 'rust'}, ]} > ```ts -const ethers = require("ethers.js"); +const { ethers } = require("ethers"); const { FlashbotsBundleProvider, } = require("@flashbots/ethers-provider-bundle"); @@ -113,7 +113,6 @@ import ( "encoding/json" "fmt" "io/ioutil" - "math/big" "net/http" "time" @@ -123,14 +122,13 @@ import ( ) const ( - j = "application/json" flashbotURL = "https://relay.flashbots.net" - stats = "flashbots_getUserStats" flashbotXHeader = "X-Flashbots-Signature" - p = "POST" ) var ( + // authSigner is an Ethereum private key that does NOT store funds and is NOT your bot's primary key. + // This is an identifying key for signing payloads to establish reputation and whitelisting privateKey, _ = crypto.HexToECDSA( "2e19800fcbbf0abb7cf6d72ee7171f08943bc8e5c3568d1d7420e52136898154", ) @@ -142,40 +140,87 @@ func flashbotHeader(signature []byte, privateKey *ecdsa.PrivateKey) string { } func main() { + // Example: create a Flashbots authenticated request mevHTTPClient := &http.Client{ Timeout: time.Second * 3, } - currentBlock := big.NewInt(12_900_000) + + // Prepare your RPC request (e.g., eth_sendBundle, eth_callBundle, etc.) params := map[string]interface{}{ "jsonrpc": "2.0", "id": 1, - "method": stats, - "params": []interface{}{ - fmt.Sprintf("0x%x", currentBlock.Uint64()), - }, + "method": "eth_sendBundle", // or other Flashbots RPC methods + "params": []interface{}{ /* your bundle params */ }, } + payload, _ := json.Marshal(params) - req, _ := http.NewRequest(p, flashbotURL, bytes.NewBuffer(payload)) + req, _ := http.NewRequest("POST", flashbotURL, bytes.NewBuffer(payload)) + + // Sign the payload for Flashbots authentication headerReady, _ := crypto.Sign( accounts.TextHash([]byte(hexutil.Encode(crypto.Keccak256(payload)))), privateKey, ) - req.Header.Add("content-type", j) - req.Header.Add("Accept", j) + + req.Header.Add("content-type", "application/json") + req.Header.Add("Accept", "application/json") req.Header.Add(flashbotXHeader, flashbotHeader(headerReady, privateKey)) + resp, _ := mevHTTPClient.Do(req) res, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(res)) } ``` + + + +```rust +use ethers::core::rand::thread_rng; +use ethers::prelude::*; +use ethers_flashbots::*; +use std::convert::TryFrom; +use url::Url; + +#[tokio::main] +async fn main() { + // Connect to the network + let provider = Provider::::try_from("https://www.ankr.com/rpc/eth/").unwrap(); + + // This is your searcher identity + let bundle_signer = LocalWallet::new(&mut thread_rng()); + + // This signs transactions and is randomly generated in this example + let wallet = LocalWallet::new(&mut thread_rng()); + + // Add signer and Flashbots middleware + let flashbots_client = SignerMiddleware::new( + FlashbotsMiddleware::new( + provider, + Url::parse("https://relay.flashbots.net").unwrap(), + bundle_signer, + ), + wallet, + ); +} +``` + -Now that we have a private key to identify ourselves with and a Flashbots provider we can create and send a bundle. Here's an example in node.js +Now that we have a private key to identify ourselves with and a Flashbots provider we can create and send a bundle. Here's how: + + + ```js -const ethers = require("ethers.js"); +const { ethers } = require("ethers"); const { FlashbotsBundleProvider, } = require("@flashbots/ethers-provider-bundle"); @@ -204,6 +249,28 @@ const bundleReceipt = await flashbotsProvider.sendRawBundle( ); ``` + + + +See https://github.com/onbjerg/ethers-flashbots + +```rust +let tx = TransactionRequest::pay("vitalik.eth", 100); +let pending_tx = client.send_transaction(tx, None).await?; + +// Get the receipt +let receipt = pending_tx + .await? + .ok_or_else(|| eyre::format_err!("tx not included"))?; +let tx = client.get_transaction(receipt.transaction_hash).await?; + +println!("Sent transaction: {}\n", serde_json::to_string(&tx)?); +println!("Receipt: {}\n", serde_json::to_string(&receipt)?); +``` + + + + That's it! ### Next steps diff --git a/docs/flashbots-data/blockapi.md b/docs/flashbots-data/blockapi.md deleted file mode 100644 index a1b7dbeab..000000000 --- a/docs/flashbots-data/blockapi.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: MEV-Blocks API ---- -mev-blocks is a a public API for displaying flashbots blocks and transactions. - -Access it here: [blocks.flashbots.net](https://blocks.flashbots.net/) - -## New Blocks API fields - -For the PoS Ethereum merge, we added new fields to the Blocks API response to align the API with PoS Ethereum nomenclature. - -Old fields were left in place for backwards compatibility with clients, and have been retrofitted to populate with data from the Flashbots builder. - -| Parent Type | Old Name | New Name | -| --- | --- | --- | -| _`blocks`_ | `miner` | `fee_recipient` | -| _`blocks`_ | `miner_reward` | `fee_recipient_eth_diff` | -| _`blocks`_ | `coinbase_transfers` | `eth_sent_to_fee_recipient` | -| _`transactions`_ | `total_miner_reward` | `fee_recipient_eth_diff` | -| _`transactions`_ | `coinbase_transfer` | `eth_sent_to_fee_recipient` | - -:::note - -Old names will be removed in a future release. - -::: diff --git a/docs/flashbots-data/dashboard.md b/docs/flashbots-data/dashboard.md deleted file mode 100644 index df57bd0f9..000000000 --- a/docs/flashbots-data/dashboard.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Flashbots Transparency Dashboard ---- - -The [Flashbots Transparency Dashboard](https://transparency.flashbots.net/) is a public dashboard with metrics on Realised Extractable Value (REV) on Ethereum, as well as data related to the Flashbots MEV-Boost Relay. The dashboard includes data from the Ethereum mainnet since block #15537940 on September 15th 2022 and has a freshness delay of 1 week. Pre-merge MEV activity can be explored here: [MEV-Explore](https://explore.flashbots.net/). - -The Transparency Dashboard is a key component of our commitment to provide transparency on the wider MEV ecosystem and our products. It serves as a valuable resource for contributors and collaborators by providing data for research. Methodology and more information can be found in the [forum post](https://collective.flashbots.net/t/will-the-real-mev-please-stand-up/1686)) introducing the dashboard. diff --git a/docs/flashbots-data/mev-inspect-py/data/arbitrages.md b/docs/flashbots-data/mev-inspect-py/data/arbitrages.md deleted file mode 100644 index 69c5890bb..000000000 --- a/docs/flashbots-data/mev-inspect-py/data/arbitrages.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: arbitrages ---- -### description - -an **arbitrage** is an circuit of swaps - -arbitrages are joined to their corresponding swaps in the **arbitrage_swaps** table - -### fields - -| Column | Type | Nullable | Description | -|----------------------|-----------------------------|----------|-----------------------------------------------------------------------| -| id | character varying(256) | not null | unique id | -| created_at | timestamp without time zone | not null | when the entry was added to the database | -| block_number | numeric | not null | block number | -| transaction_hash | character varying(256) | not null | transaction hash | -| account_address | character varying(256) | not null | address that took the profit of the arb - can be a contract or an EOA | -| profit_token_address | character varying(256) | not null | token that profit was taken in | -| profit_amount | numeric | not null | gross profit - note: this does not account for miner payment | -| start_amount | numeric | not null | starting amount of the profit token | -| end_amount | numeric | not null | end amount of the profit token | - -:::note - -The "miner" nomenclature will be replaced in a future release to accurately reflect PoS Ethereum architecture. - -::: diff --git a/docs/flashbots-data/mev-inspect-py/data/classified_traces.md b/docs/flashbots-data/mev-inspect-py/data/classified_traces.md deleted file mode 100644 index 254d8254f..000000000 --- a/docs/flashbots-data/mev-inspect-py/data/classified_traces.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: classified_traces ---- -### description - -a **classified trace** represents a single trace - -classified traces optionally include: -- a classification for the call (ex: transfer, swap, liquidation) -- decoded function name and inputs - -### fields - -| Column | Type | Nullable | Description | -|--------------------|-----------------------------|----------|-------------------------------------------------------------------------------------------| -| classified_at | timestamp without time zone | not null | when this trace was added to the database | -| block_number | numeric | not null | block number | -| transaction_hash | character varying(66) | not null | transaction hash | -| trace_address | integer[] | not null | trace address | -| trace_type | character varying(256) | not null | the type of call in the trace - one of `call`, `create`, `delegate_call`, `reward`, `suicide` | -| classification | character varying(256) | not null | classification for the trace - one of `unknown`, `swap`, `burn`, `transfer`, `liquidate` | -| protocol | character varying(256) | | the protocol associated with the trace | -| abi_name | character varying(1024) | | the ABI used to decode this trace | -| function_name | character varying(2048) | | the name of the function called | -| function_signature | character varying(2048) | | the signature of the function called | -| inputs | json | | inputs of the function | -| from_address | character varying(256) | | from address | -| to_address | character varying(256) | | to address | -| gas | numeric | | gas | -| value | numeric | | ETH value | -| gas_used | numeric | | gas used | -| error | character varying(256) | | error | diff --git a/docs/flashbots-data/mev-inspect-py/data/miner_payments.md b/docs/flashbots-data/mev-inspect-py/data/miner_payments.md deleted file mode 100644 index 590204b8e..000000000 --- a/docs/flashbots-data/mev-inspect-py/data/miner_payments.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: miner_payments ---- -### description - -a **miner payment** is how much was paid to a miner in a given transaction - -miner payment includes payment through gas and coinbase transfers - -### fields - -| Column | Type | Nullable | Description | -|----------------------------------|-----------------------------|----------|--------------------------------------------------------| -| created_at | timestamp without time zone | not null | when the entry was added to the database | -| block_number | numeric | not null | block number | -| transaction_hash | character varying(66) | not null | transaction hash | -| transaction_index | numeric | not null | transaction index | -| miner_address | character varying(256) | not null | address of the miner | -| coinbase_transfer | numeric | not null | amount of ETH was paid as direct transfer to the miner | -| base_fee_per_gas | numeric | not null | base fee for this block | -| gas_price | numeric | not null | gas price (excludes coinbase transfer) | -| gas_price_with_coinbase_transfer | numeric | not null | gas price (includes coinbase transfer) | -| gas_used | numeric | not null | total gas used by the transaction | -| transaction_to_address | character varying(256) | | to address of the transaction | -| transaction_from_address | character varying(256) | | from address of the transaction | - -:::note - -The "miner" nomenclature will be replaced in a future release to accurately reflect PoS Ethereum architecture. - -::: diff --git a/docs/flashbots-data/mev-inspect-py/data/swaps.md b/docs/flashbots-data/mev-inspect-py/data/swaps.md deleted file mode 100644 index 2d6082ec2..000000000 --- a/docs/flashbots-data/mev-inspect-py/data/swaps.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: swaps ---- -### description - -a **swap** is a swap between two ERC-20 tokens - -### fields -| Column | Type | Nullable | Description | -|-------------------|-----------------------------|----------|-------------------------------------------| -| created_at | timestamp without time zone | not null | when the entry was added to the database | -| block_number | numeric | not null | block number | -| transaction_hash | character varying(66) | not null | transaction hash | -| trace_address | integer[] | not null | trace address | -| abi_name | character varying(1024) | not null | name of the ABI used to decode the swap | -| pool_address | character varying(256) | not null | pool address | -| from_address | character varying(256) | not null | address where tokens are coming from | -| to_address | character varying(256) | not null | address where swapped tokens are going to | -| token_in_address | character varying(256) | not null | address of the token going in | -| token_in_amount | numeric | not null | amount of the token going in | -| token_out_address | character varying(256) | not null | address of the token going out | -| token_out_amount | numeric | not null | amount of the token going out | -| protocol | character varying(256) | | protocol | -| error | character varying(256) | | error | diff --git a/docs/flashbots-data/mev-inspect-py/data/transfers.md b/docs/flashbots-data/mev-inspect-py/data/transfers.md deleted file mode 100644 index 343f7bee7..000000000 --- a/docs/flashbots-data/mev-inspect-py/data/transfers.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: transfers ---- -### description - -a **transfer** is an ERC-20 token transfer - -### fields - -| Column | Type | Nullable | Description | -|------------------|-----------------------------|----------|---------------------------------------------| -| created_at | timestamp without time zone | not null | when the transfer was added to the database | -| block_number | numeric | not null | block number | -| transaction_hash | character varying(66) | not null | transaction hash | -| trace_address | character varying(256) | not null | trace address | -| from_address | character varying(256) | not null | who the tokens are transfering from | -| to_address | character varying(256) | not null | who the tokens are transfering to | -| token_address | character varying(256) | not null | token address | -| amount | numeric | not null | amount | -| protocol | character varying(256) | | protocol associated with the transfer | -| error | character varying(256) | | error | diff --git a/docs/flashbots-data/mev-inspect-py/exploring.md b/docs/flashbots-data/mev-inspect-py/exploring.md deleted file mode 100644 index ab638ef41..000000000 --- a/docs/flashbots-data/mev-inspect-py/exploring.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Exploring ---- - -All inspect output data is stored in Postgres. - -To connect to the local Postgres database for querying, launch a client container with: - -```sh -./mev db -``` - -When you see the prompt - -```sh -mev_inspect=# -``` - -You're ready to query! - -Try finding the total number of swaps decoded with UniswapV3Pool - -```sql -SELECT COUNT(*) FROM swaps WHERE abi_name='UniswapV3Pool'; -``` - -or top 10 arbs by gross profit that took profit in WETH - -```sql -SELECT * -FROM arbitrages -WHERE profit_token_address = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' -ORDER BY profit_amount DESC -LIMIT 10; -``` - -Postgres tip: Enter `\x` to enter "Expanded display" mode which looks nicer for results with many columns diff --git a/docs/flashbots-data/mev-inspect-py/inspecting.md b/docs/flashbots-data/mev-inspect-py/inspecting.md deleted file mode 100644 index 041083f95..000000000 --- a/docs/flashbots-data/mev-inspect-py/inspecting.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Inspecting ---- - -Executing an inspection for a block will perform the following operations: - -- Retrieve traces, receipts, and block data from the RPC endpoint. -- Decode the traces using recognized ABIs. -- Extract structured objects such as transfers and swaps. -- Store all these elements in the database for future querying. - -## Examples - -### Inspect a single block - -Inspecting block [12914944](https://twitter.com/mevalphaleak/status/1420416437575901185): - -```sh -./mev inspect 12914944 -``` - -### Inspect many blocks - -Inspecting blocks 12914944 to 12914954: - -```sh -./mev inspect-many 12914944 12914954 -``` - -### Inspect all incoming blocks - -Start a block listener with: - -```sh -./mev listener start -``` - -By default, it will pick up wherever you left off. -If running for the first time, listener starts at the latest block. - -Tail logs for the listener with: - -```sh -./mev listener tail -``` - -And stop the listener with: - -```sh -./mev listener stop -``` - -### Backfilling - -For larger backfills, you can inspect many blocks in parallel using kubernetes - -To inspect blocks 12914944 to 12915044 divided across 10 worker pods: - -```sh -./mev backfill 12914944 12915044 10 -``` - -You can see worker pods spin up then complete by watching the status of all pods - -```sh -watch kubectl get pods -``` - -To watch the logs for a given pod, take its pod name using the above, then run: - -```sh -kubectl logs -f pod/mev-inspect-backfill-abcdefg -``` - -(where `mev-inspect-backfill-abcdefg` is your actual pod name) diff --git a/docs/flashbots-data/mev-inspect-py/overview.md b/docs/flashbots-data/mev-inspect-py/overview.md deleted file mode 100644 index 784bd6ce5..000000000 --- a/docs/flashbots-data/mev-inspect-py/overview.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Overview ---- - -**mev-inspect-py** is an MEV inspector for Ethereum - -Given a block, mev-inspect finds: - -- Validator payments (gas + coinbase) -- Tokens transfers and profit -- Swaps and [arbitrages](https://twitter.com/bertcmiller/status/1427632028263059462) -- ...and more - -All data is stored in Postgres for querying and analysis - -To get started, check out the [quick start](/flashbots-data/mev-inspect-py/quick-start.md) - -To see which data inspect produces, check out the [data](/flashbots-data/mev-inspect-py/data/classified_traces.md) section - -Access and contribute to the public mev-inspect-py repository [here](https://github.com/flashbots/mev-inspect-py). diff --git a/docs/flashbots-data/mev-inspect-py/quick-start.md b/docs/flashbots-data/mev-inspect-py/quick-start.md deleted file mode 100644 index c75e74d65..000000000 --- a/docs/flashbots-data/mev-inspect-py/quick-start.md +++ /dev/null @@ -1,208 +0,0 @@ ---- -title: Quick Start ---- - -Let's use mev-inspect to find the same arbitrage as [MEV Alpha Leak](https://twitter.com/mevalphaleak/status/1420416437575901185) - -## Install - -mev-inspect-py is built to run on kubernetes locally and in production - -### Install dependencies - -First, setup a local kubernetes deployment - we use [Docker](https://www.docker.com/products/docker-desktop) and [kind](https://kind.sigs.k8s.io/docs/user/quick-start) - -If using kind, create a new cluster with: - -```sh -kind create cluster -``` - -Next, install the kubernetes CLI [`kubectl`](https://kubernetes.io/docs/tasks/tools/) - -Then, install [helm](https://helm.sh/docs/intro/install/) - helm is a package manager for kubernetes - -Lastly, setup [Tilt](https://docs.tilt.dev/install.html) which manages running and updating kubernetes resources locally - -### Start up - -Set an environment variable `RPC_URL` to an RPC for fetching blocks -Example: - -```sh -export RPC_URL="http://111.111.111.111:8546" -``` - -:::note - -mev-inspect-py currently requires and RPC with support for OpenEthereum / Erigon traces (not geth 😔) - -::: - -Next, start all servcies with: - -```sh -tilt up -``` - -Press "space" to see a browser of the services starting up - -On first startup, you'll need to apply database migrations. Apply with: - -```sh -./mev exec alembic upgrade head -``` - -### Tear down - -First stop the running tilt window with `Ctrl+C` - -Then run - -```sh -tilt down -``` - -## Inspect a block - -Using the [linked etherscan transaction](https://etherscan.io/tx/0xfcf4558f6432689ea57737fe63124a5ec39fd6ba6aaf198df13a825dd599bffc), we can see the block number is 12914944. - -To inspect this block, run - -```sh -./mev inspect 12914944 -``` - -## Connect to Postgres - -We'll connect to the Postgres database to see the data inspect found in that block - -Let's start up a client container connected to the DB: - -```sh -./mev db -``` - -When you see the prompt - -```sh -mev_inspect=# -``` - -You're ready to query! - -To make the data display nice, switch into "Expanded display" mode by running - -```sh -\x -``` - -## Query for arbitrage data - -Let's find that arbitrage by querying the `arbitrages` table: - -```sql -SELECT * -FROM arbitrages -WHERE - block_number = 12914944 AND - transaction_hash = '0xfcf4558f6432689ea57737fe63124a5ec39fd6ba6aaf198df13a825dd599bffc' -``` - -You should see output like this: - -```txt -id | ff2deb13-c2c1-4ef5-a6ff-0ca813a07d6b -created_at | 2021-09-27 15:26:58.193263 -account_address | 0x0000fee6275dab194ab538a01dd8b18b02b20000 -profit_token_address | 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 -block_number | 12914944 -transaction_hash | 0xfcf4558f6432689ea57737fe63124a5ec39fd6ba6aaf198df13a825dd599bffc -start_amount | 70287643212620210176 -end_amount | 123848351154563483804 -profit_amount | 53560707941943273628 -``` - -We can see this matches the original tweet description! - -The `profit_token_address` is the address for WETH, our `start_amount` is 70 WETH (assuming 18 decimals), and our `end_amount` is 123 WETH - -## Query for arbitrage swaps - -We can learn about the swaps involed in this arbitrage by joining against the `arbitrage_swaps` and `swaps` tables - -:::note -You'll need to switch in the id you got in the first query for arbitrage_id -::: - -```sql -SELECT s.* -FROM swaps s -JOIN arbitrage_swaps arb_swaps ON - s.transaction_hash = arb_swaps.swap_transaction_hash AND - s.trace_address = arb_swaps.swap_trace_address -WHERE arb_swaps.arbitrage_id = 'ff2deb13-c2c1-4ef5-a6ff-0ca813a07d6b'; -``` - -You should see output like this: - -```txt --[ RECORD 1 ]-----+------------------------------------------------------------------- -created_at | 2021-09-27 15:26:58.180131 -abi_name | UniswapV3Pool -transaction_hash | 0xfcf4558f6432689ea57737fe63124a5ec39fd6ba6aaf198df13a825dd599bffc -block_number | 12914944 -protocol | -pool_address | 0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640 -from_address | 0x7ec0b75a98997c927ace6d87958147a105147ea0 -to_address | 0x0000fee6275dab194ab538a01dd8b18b02b20000 -token_in_address | 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 -token_in_amount | 283588902010 -token_out_address | 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 -token_out_amount | 123848351154563483804 -trace_address | {0,0} -error | --[ RECORD 2 ]-----+------------------------------------------------------------------- -... -``` - -## Query for miner payment - -Lastly, we can see how much was paid to the miner for this transaction by querying by the transaction hash: - -```sql -SELECT * -FROM miner_payments -WHERE transaction_hash = '0xfcf4558f6432689ea57737fe63124a5ec39fd6ba6aaf198df13a825dd599bffc'; -``` - -You should see results like this: - -```txt -created_at | 2021-09-27 15:26:58.245444 -block_number | 12914944 -transaction_hash | 0xfcf4558f6432689ea57737fe63124a5ec39fd6ba6aaf198df13a825dd599bffc -transaction_index | 1 -miner_address | 0x5A0b54D5dc17e0AadC383d2db43B0a0D3E029c4c -coinbase_transfer | 48204637147748941824 -base_fee_per_gas | 0 -gas_price | 0 -gas_price_with_coinbase_transfer | 200463421638605 -gas_used | 240466 -transaction_to_address | 0x00000000454a11ca3a574738c0aab442b62d5d45 -transaction_from_address | 0xd80276cd0348e9b3c5d017e1f7529f0a785fec3a -``` - -`gas_price` is the gas price paid directly as gas (it includes the EIP-1559 base fee) - -`coinbase_transfer` is the amount of ETH paid directly as a transfer to the validator's address - -`gas_price_with_coinbase_transfer` is the gas price including both original gas and coinbase transfers - -So in total, this searcher paid 48.2 ETH to make 53.5 ETH for a net profit of 5.3 ETh - -## Next steps - -To see what other data is available for querying, check out the [data](/flashbots-data/mev-inspect-py/data/classified_traces) section - -To learn about inspecting blocks in bulk or listening for new blocks as they come in, check out the [inspecting](/flashbots-data/mev-inspect-py/inspecting) section diff --git a/docs/flashbots-mev-boost/architecture-overview/block-proposal.md b/docs/flashbots-mev-boost/architecture-overview/block-proposal.md index 87c880144..ddf1f5d61 100644 --- a/docs/flashbots-mev-boost/architecture-overview/block-proposal.md +++ b/docs/flashbots-mev-boost/architecture-overview/block-proposal.md @@ -7,6 +7,6 @@ title: MEV-Boost Block Proposal As depicted above and described in the [Builder — Honest Validator](https://github.com/ethereum/builder-specs) repository, the MEV-Boost block proposal process begins with a [registration step](https://github.com/ethereum/builder-specs) that validators must perform ahead of proposal duties. Registration ensures builders can craft blocks for a given validator’ block proposal. Once registered, validators wait until selected to propose a block. Once selected, a block proposer building a block on top of a beacon `state` in a given `slot` must take the following actions to obtain an [execution payload](https://github.com/ethereum/consensus-specs/blob/a45ee9bf5b1fde766d69e551a6b1a21fe2531734/specs/merge/beacon-chain.md#executionpayload): 1. Users/searchers send transactions to block builders through public or private peer-to-peer transaction pools. -2. Builders construct execution payloads using received transactions, and parameters the block proposer provided during registration. To process MEV payment, builders set their own address as the payload’s coinbase address and append a transaction to the [block proposers’ feeRecipient address](https://flashbots.notion.site/WIP-Builder-Payments-to-Block-Proposers-530eb36c60ad417a8702dd26da810b72)at the end of their proposed block. The block is then forwarded to relays. +2. Builders construct execution payloads using received transactions, and parameters the block proposer provided during registration. To process MEV payment, builders set their own address as the payload’s coinbase address and append a transaction to the [block proposers’ feeRecipient address](https://flashbots.notion.site/WIP-Builder-Payments-to-Block-Proposers-530eb36c60ad417a8702dd26da810b72) at the end of their proposed block. The block is then forwarded to relays. 3. Relays verify the validity of payloads (including amount of ETH paid to the block proposers’ feeRecipient), and send an [`ExecutionPayloadHeader`](https://github.com/ethereum/consensus-specs/blob/a45ee9bf5b1fde766d69e551a6b1a21fe2531734/specs/merge/beacon-chain.md#executionpayloadheader) (execution payloads stripped of transaction content) to MEV-Boost. MEV-boost selects the most valuable payload and forwards it to the block proposer. 4. The block proposer signs the payload and passes it back to MEV-Boost via a [`submitBlindedBlock`](https://ethereum.github.io/builder-specs/#/Builder/submitBlindedBlock) call, which is forwarded to the relay. Once the relay verifies the proposers’ signature, it responds with the full execution payload body for the validator to use when proposing a `SignedBeaconBlock` to the network. diff --git a/docs/flashbots-mev-boost/architecture-overview/specifications.md b/docs/flashbots-mev-boost/architecture-overview/specifications.md index dce65e486..064adc4db 100644 --- a/docs/flashbots-mev-boost/architecture-overview/specifications.md +++ b/docs/flashbots-mev-boost/architecture-overview/specifications.md @@ -25,4 +25,3 @@ title: MEV-Boost Specifications - [MEV-Boost Relay](https://github.com/flashbots/mev-boost-relay) - [Go Boost Utils](https://github.com/flashbots/go-boost-utils) - [MEV-Boost Builder](https://github.com/flashbots/boost-geth-builder) -- [Relay Status Page ](https://0xpanoramix.github.io/flashbots-boost-status/) \ No newline at end of file diff --git a/docs/flashbots-mev-boost/block-builders.md b/docs/flashbots-mev-boost/block-builders.md index ae9ca5b0d..66f3288ee 100644 --- a/docs/flashbots-mev-boost/block-builders.md +++ b/docs/flashbots-mev-boost/block-builders.md @@ -35,14 +35,14 @@ Constructing a payment proof for this scoring method requires a Merkle Proof of ## External Builders -External builders can submit blocks to Mainnet, Goerli and Sepolia Flashbots relays. The table below outlines Builder API methods available on each network. +External builders can submit blocks to Mainnet and Sepolia Flashbots relays. The table below outlines Builder API methods available on each network. ### Relay Block Submission Endpoints by Network -| | | Mainnet | Goerli | Sepolia | -| --------------- | ------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------- | -| `getValidators` | GET Request - Returns an array of validator registrations with assigned duties in the current and next epoch | [Mainnet](https://boost-relay.flashbots.net/relay/v1/builder/validators)  | [Goerli](https://boost-relay-goerli.flashbots.net/relay/v1/builder/validators)  | [Sepolia](https://boost-relay-sepolia.flashbots.net/relay/v1/builder/validators) | -| `submitBlock` | POST Request - submits a block to the builder | [Mainnet](https://boost-relay.flashbots.net/relay/v1/builder/blocks)  | [Goerli](https://boost-relay-goerli.flashbots.net/relay/v1/builder/blocks) | [Sepolia](https://boost-relay-sepolia.flashbots.net/relay/v1/builder/blocks)  | +| | | Mainnet | Sepolia | +| --- | --- | --- | --- | +| `getValidators` | GET Request - Returns an array of validator registrations with assigned duties in the current and next epoch | [Mainnet](https://boost-relay.flashbots.net/relay/v1/builder/validators)  | [Sepolia](https://boost-relay-sepolia.flashbots.net/relay/v1/builder/validators) | +| `submitBlock` | POST Request - submits a block to the relay | [Mainnet](https://boost-relay.flashbots.net/relay/v1/builder/blocks) | [Sepolia](https://boost-relay-sepolia.flashbots.net/relay/v1/builder/blocks)  | - See also the [Relay API documentation - Block Builder API](https://bit.ly/3BmGZ3T) for more details on the API and payloads. - The example [Flashbots builder implementation](https://github.com/flashbots/boost-geth-builder) is a good external builder reference, and is currently used in production by several builders. @@ -51,27 +51,17 @@ External builders can submit blocks to Mainnet, Goerli and Sepolia Flashbots rel Submissions to all relays are currently rate-limited to 600 submissions / 5m / IP, which translates to in average 2 submissions / sec /IP. -## Flashbots Builders +## BuilderNet Block Builders -All Flashbots builders pay block proposers from the [`flashbots-builder.eth` ENS address](https://etherscan.io/address/0xdafea492d9c6733ae3d56b7ed1adb60692c98bc5). Each Flashbots builder uses a different public key (`builder_pubkey`) for relay identification and analytics purposes. - -The various `builder_pubkeys` used to identify Flashbots builders to relays are listed below: - -| **Builder Public Key** | -| -------------------------------------------------------------------------------------------------- | -| 0x81babeec8c9f2bb9c329fd8a3b176032fe0ab5f3b92a3f44d4575a231c7bd9c31d10b6328ef68ed1e8c02a3dbc8e80f9 | -| 0x81beef03aafd3dd33ffd7deb337407142c80fea2690e5b3190cfc01bde5753f28982a7857c96172a75a234cb7bcb994f | -| 0xa1dead1e65f0a0eee7b5170223f20c8f0cbf122eac3324d61afbdb33a8885ff8cab2ef514ac2c7698ae0d6289ef27fc | -| 0xa1defa73d675983a6972e8686360022c1ebc73395067dd1908f7ac76a526a19ac75e4f03ccab6788c54fdb81ff84fc1b | -| 0x81babad2d5fd9413c942f49bfd86bc1dca5b02ff4cd065a10c7ab05713e63883056e6a87777e236424574aa25bbe3e99 | -| 0xa35e2b13ef528efbed8d2f709c0eb9eceb1225ed0605a653ba923588b0150c94772a9ba1c809d048e321f6b73d905c60 | +The keys used in BuilderNet are listed here: https://buildernet.org/docs/public-identity#bls-keys-for-submitting-blocks-to-mev-boost-relays ## Additional Links & References -- [MEV-Boost Geth Builder](https://github.com/flashbots/boost-geth-builder) - an example builder implementation +- [rbuilder](https://github.com/flashbots/rbuilder) - Blazingly fast, cutting edge block builder written in Rust. - [Relay API documentation - Block Builder API](https://bit.ly/3BmGZ3T) - Block Builder Self-Help Group: [https://collective.flashbots.net/c/builders/14](https://collective.flashbots.net/c/builders/14) - Github issue about becoming block builder: [https://github.com/flashbots/mev-boost/issues/145](https://github.com/flashbots/mev-boost/issues/145). -- [Mevboost.org\*](https://www.mevboost.org/) - Tracking MEV-Boost relays and block builders. A quick hack by [Anish](https://anishagnihotri.com/). Design inspired by file.app. +- [Mevboost.pics](https://www.mevboost.pics/) - Tracking MEV-Boost relays and block builders, by [Toni Wahrstätter](https://twitter.com/nero_eth). +- [Relayscan.io](https://www.relayscan.io/) - Up-to-date stats on the MEV-Boost ecosystem, by [Chris Hager](https://twitter.com/metachris). _Note: Flashbots does not control and cannot verify the data coming from external people and organizations. Please direct questions or issues directly to the creators of external data sources._ diff --git a/docs/flashbots-mev-boost/community-tools.md b/docs/flashbots-mev-boost/community-tools.md deleted file mode 100644 index e0ca63af8..000000000 --- a/docs/flashbots-mev-boost/community-tools.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Community Tools ---- - -## Flashbots Relayer Status - -[Monitor Flashbots Relays](https://0xpanoramix.github.io/flashbots-boost-status/) status on various timescales, by 0xpanoramix. - -![Untitled](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F4c213924-8672-4c83-9e9f-605c5399503d%2FUntitled.png?table=block&id=5fce516f-d542-4ff1-8f46-a2f127897e49&spaceId=075d04b3-e5c0-4a97-8020-80f2e2b2206e&width=2000&userId=5d4ec963-edaf-46de-9bbd-bec711cebde4&cache=v2) diff --git a/docs/flashbots-mev-boost/getting-started/system-requirements.md b/docs/flashbots-mev-boost/getting-started/system-requirements.md index 9967fad0f..5b8688bf8 100644 --- a/docs/flashbots-mev-boost/getting-started/system-requirements.md +++ b/docs/flashbots-mev-boost/getting-started/system-requirements.md @@ -2,7 +2,7 @@ title: System Requirements --- -This guide assumes a pre-installed and hardened Ubuntu installation [as well as Docker](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04). Excellent introductory resources to start with are: [Coincashew](https://www.coincashew.com/coins/overview-eth/guide-or-security-best-practices-for-a-eth2-validator-beaconchain-node), and [Rocketpool's Securing your Node](https://docs.rocketpool.net/guides/node/securing-your-node.html#securing-your-node) +This guide assumes a pre-installed and hardened Ubuntu installation [as well as Docker](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04). Excellent introductory resources to start with are: [Coincashew](https://www.coincashew.com/coins/overview-eth/archived-guides/guide-or-how-to-setup-a-validator-on-eth2-mainnet/part-i-installation/guide-or-security-best-practices-for-a-eth2-validator-beaconchain-node), and [Rocketpool's Securing your Node](https://docs.rocketpool.net/guides/node/securing-your-node.html#securing-your-node) ## Requirements for different systems @@ -38,5 +38,5 @@ There are variations in client resource usage. Please review [CoinCashew’s Cli | Teku | [Guide](hthttps://docs.teku.consensys.net/Concepts/Builder-Network/tps://hackmd.io/@StefanBratanov/BkMlo1RO9) | | Prysm | [Guide](https://hackmd.io/@prysmaticlabs/BJeinxFsq) | | Lighthouse | [Guide](https://lighthouse-book.sigmaprime.io/builders.html#mev-and-lighthouse) | -| Lodestar | [Guide](https://github.com/ChainSafe/lodestar/blob/unstable/docs/usage/mev-integration.md) | +| Lodestar | [Guide](https://github.com/ChainSafe/lodestar/blob/unstable/docs/pages/beacon-management/mev-and-builder-integration.md) | | Nimbus | [Guide](https://nimbus.guide/external-block-builder.html) | diff --git a/docs/flashbots-mev-boost/getting-started/usage.md b/docs/flashbots-mev-boost/getting-started/usage.md index 706b00f23..c57e76d5c 100644 --- a/docs/flashbots-mev-boost/getting-started/usage.md +++ b/docs/flashbots-mev-boost/getting-started/usage.md @@ -7,10 +7,8 @@ When connecting to different networks using mev-boost, specify the desired netwo | Network | Flag | | --------------- | -------- | | Mainnet | -mainnet | -| Goerli Testnet | -goerli | | Sepolia Testnet | -sepolia | | Kiln | -kiln | -| Ropsten | -ropsten | You can add multiple relays comma-separated to the `-relays` flag, like this: `-relays RELAY_URL_1,RELAY_URL_2`. Refer to ETH staker [Relay List](https://github.com/eth-educators/ethstaker-guides/blob/main/MEV-relay-list.md) for a list of available relays. @@ -22,14 +20,6 @@ Run mev-boost pointed at our [Mainnet Relay:](https://0xac6e77dfe25ecd6110b8e78 ./mev-boost -mainnet -relay-check -relays https://0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae@boost-relay.flashbots.net ``` -### Goerli testnet - -Run mev-boost pointed at our [Goerli Relay](https://builder-relay-goerli.flashbots.net/): - -```bash -./mev-boost -goerli -relay-check -relays https://0xafa4c6985aa049fb79dd37010438cfebeb0f2bd42b115b89dd678dab0670c1de38da0c4e9138c9290a398ecd9a0b3110@builder-relay-goerli.flashbots.net -``` - ### Sepolia testnet Run mev-boost pointed at our [Sepolia Relay](https://builder-relay-sepolia.flashbots.net/): @@ -49,8 +39,6 @@ Usage of ./mev-boost: shorthand for '-loglevel debug' -genesis-fork-version string use a custom genesis fork version - -goerli - use Goerli -json log in JSON format instead of text -loglevel string diff --git a/docs/flashbots-mev-boost/introduction.md b/docs/flashbots-mev-boost/introduction.md index 9975006b9..07904c057 100644 --- a/docs/flashbots-mev-boost/introduction.md +++ b/docs/flashbots-mev-boost/introduction.md @@ -24,7 +24,7 @@ Validators running MEV-Boost maximize their staking reward by selling their bloc ## How does MEV-Boost work? -![MEV Boost Integration Overview](https://raw.githubusercontent.com/flashbots/mev-boost/develop/docs/mev-boost-integration-overview.png) +![MEV Boost Integration Overview](/img/mev-boost-integration-overview.jpg) PoS node operators must run three pieces of software: a validator client, consensus client, and an execution client. MEV-boost is a sidecar for the consensus client, a separate piece of open source software, which queries and outsources block-building to a network of builders. diff --git a/docs/flashbots-mev-boost/relay.md b/docs/flashbots-mev-boost/relay.md index 12ce0169b..8fc06dadf 100644 --- a/docs/flashbots-mev-boost/relay.md +++ b/docs/flashbots-mev-boost/relay.md @@ -28,7 +28,7 @@ A relay has several responsibilities: The current specification for the [open-source Flashbots relay](https://github.com/flashbots/mev-boost-relay). Diagram below displays the current architecture: -![Relay Architecture](https://i.imgur.com/Z1AtQpw.png) +![Relay Architecture](/img/relay_architecture.jpg) ### [Proposer API](https://flashbots.notion.site/Relay-API-Spec-5fb0819366954962bc02e81cb33840f5) @@ -47,16 +47,12 @@ Get a list of validator registrations for the current and next epoch, submit a n Provides data about received blocks from builders, payloads delivered to proposers as well as insights into validator registrations. -## [Relay Monitor](https://hackmd.io/@ralexstokes/SynPJN_pq) - -While relays are trusted actors, the ability to run a relay is permissionless. To mitigate potential abuses of this role, Flashbots [has suggested](https://github.com/flashbots/mev-boost/issues/142) a “relay monitor,” which uses publicly available data to form a view on the behavior and performance of the set of relays it is monitoring. More details can be found in the [relay monitor design documentation](https://hackmd.io/@ralexstokes/SynPJN_pq), [keeping MEV-Boost relays honest](https://notes.ethereum.org/@yoav/BJeOQ8rI5), and [understanding liveness risks](https://writings.flashbots.net/understanding-mev-boost-liveness-risks). - ## [Circuit Breaker](https://hackmd.io/@ralexstokes/BJn9N6Thc) -The circuit breaker is implemented by client software teams to define “circuit breaking” conditions using globally available inputs (simply, the chain) which determine whether clients should make a decision to terminate an external builder network in favor of local block production. Once the circuit breaker condition is met, the only way to reset the state is to restart the beacon node where the missing slots tally will be 0. +The circuit breaker is implemented by client software teams to define “circuit breaking” conditions using globally available inputs (such as the chain) to determine whether clients should stop sourcing blocks from an external block builder network and fallback to local block production instead. Each consensus client implements different circuit breaker conditions and once the circuit breaker condition is met, clients have different behaviour regarding when to resume sourcing external blocks. -Each consensus client implements different circuit breaker conditions, as an example: +For the exact behavior and available configuration around circuit breaker conditions for a specific client, please refer to the documentation for the specific consensus client. + +## [Relay Monitor](https://hackmd.io/@ralexstokes/SynPJN_pq) -| Name | Value | Units | -| ------------------------- | ----- | ------- | -| MAX_ALLOWED_MISSING_SLOTS | 5 | slot(s) | +While relays are trusted actors, the ability to run a relay is permissionless. To mitigate potential abuses of this role, Flashbots [has suggested](https://github.com/flashbots/mev-boost/issues/142) a “relay monitor,” which uses publicly available data to form a view on the behavior and performance of the set of relays it is monitoring. This is an ongoing proposal and more details can be found in the [relay monitor design documentation](https://hackmd.io/@ralexstokes/SynPJN_pq), [keeping MEV-Boost relays honest](https://notes.ethereum.org/@yoav/BJeOQ8rI5), and [understanding liveness risks](https://writings.flashbots.net/understanding-mev-boost-liveness-risks). \ No newline at end of file diff --git a/docs/flashbots-mev-boost/resources.md b/docs/flashbots-mev-boost/resources.md index 255ab55f3..3f271a1e0 100644 --- a/docs/flashbots-mev-boost/resources.md +++ b/docs/flashbots-mev-boost/resources.md @@ -6,7 +6,7 @@ title: Resources - [The Hitchhiker's Guide to Ethereum](https://members.delphidigital.io/reports/the-hitchhikers-guide-to-ethereum/) - [Combining Ghost and Casper - Vitalik Buterin et al.](https://arxiv.org/pdf/2003.03052.pdf) -- [Endgame - Vitalik Buterin](https://vitalik.ca/general/2021/12/06/endgame.html) +- [Endgame - Vitalik Buterin](https://vitalik.eth.limo/general/2021/12/06/endgame.html) - [Fork Choice](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/fork-choice.md) - [A compiled list of resources from Flashbots Research](https://github.com/flashbots/mev-boost/wiki/Research#open-questions) @@ -30,4 +30,4 @@ title: Resources - [Validator Checklist - launchpad.ethereum.org](https://launchpad.ethereum.org/en/merge-readiness) - [eth-docker: Docker automation for Ethereum consensus and execution clients.](https://github.com/eth-educators/eth-docker) - [Validator Slashing Prevention Tips - Prysmatic Labs](https://medium.com/prysmatic-labs/eth2-slashing-prevention-tips-f6faa5025f50) -- [Understanding Eth2 Slashing Preventative Measures](https://www.bloxstaking.com/blog/ethereum-2-0/understanding-eth2-slashing-preventative-measures/) \ No newline at end of file +- [Understanding Eth2 Slashing Preventative Measures](https://www.bloxstaking.com/blog/ethereum-2-0/understanding-eth2-slashing-preventative-measures/) diff --git a/docs/flashbots-mev-share/introduction.mdx b/docs/flashbots-mev-share/introduction.mdx index bb571cb48..4b83384ff 100644 --- a/docs/flashbots-mev-share/introduction.mdx +++ b/docs/flashbots-mev-share/introduction.mdx @@ -9,18 +9,19 @@ import WhatsMevShareAdvanced from "../specs/mev-share/blurbs/_whatsMevShareAdvan ## What is MEV-Share? -To start earning MEV refunds from MEV-share, submit your transactions to the Flashbots **MEV-Share Node**, either by [connecting your wallet to the Protect RPC](/flashbots-protect/quick-start/#using-flashbots-protect), or sending a [private transaction](/flashbots-auction/advanced/rpc-endpoint#eth_sendprivatetransaction) to the MEV-Share Node API. +To start earning MEV refunds from MEV-Share, submit your transactions to the Flashbots **MEV-Share Node**, either by [connecting your wallet to the Protect RPC](/flashbots-protect/quick-start/#using-flashbots-protect), or sending a [private transaction](/flashbots-auction/advanced/rpc-endpoint#eth_sendprivatetransaction) to the MEV-Share Node API. ## Why MEV-Share? MEV-Share redistributes MEV back to the party that creates it in the first place: users. It does so through a design that is built to scale and be decentralized, which means that it is permissionless for searchers to integrate and it does not enshrine a single block builder. ## How does MEV-Share work? -Users send their transactions to a specialized actor called a MEV-Share Node. The MEV-Share Node selectively shares information about the user's transaction according to their privacy preferences. Seeing this information, searchers submit partial bundles to the MEV-Share Node to attempt to extract MEV from user's transactions without seeing the full transaction data. MEV-Share Nodes simulate each of these searcher bundles and forward the successful ones on to builders along with a condition that the user must be paid back 90% of the MEV their transactions create. +Users send their transactions to a specialized actor called a MEV-Share Node. The MEV-Share Node selectively shares information about the user's transaction according to their privacy preferences. Seeing this information, searchers submit partial bundles to the MEV-Share Node to attempt to extract MEV from user's transactions without seeing the full transaction data. MEV-Share Nodes simulate each of these searcher bundles and forward the successful ones on to builders along with a condition that the user must be paid back specified percentage (by default 90%) of the MEV their transactions create. -At the moment, MEV-Share Nodes ony accept backruns. +At the moment, MEV-Share Nodes only accept backruns. ## How do I use MEV-Share? -The most simple way to use MEV-Share is by sending transactions to [Flashbots Protect](/flashbots-protect/quick-start), which leverages the [Flashbots MEV-Share Node](/flashbots-protect/mev-share). Wallet and application developers should check out the [Flashbots Protect MEV-Share section](/flashbots-protect/mev-share) for information about integrating and configuring the Flashbots MEV-Share Node. +The simplest way to use MEV-Share is by sending transactions to [Flashbots Protect](/flashbots-protect/quick-start), which leverages the [Flashbots MEV-Share Node](/flashbots-protect/mev-refunds). Wallet and application developers should check out the [Flashbots Protect MEV-Share section](/flashbots-protect/mev-refunds) for information about integrating and configuring the Flashbots MEV-Share Node. + ## How do I search on MEV-Share? -Searchers should see the [Getting Started](/flashbots-mev-share/searchers/getting-started) guide for a walkthrough of MEV-Share and how it differs from traditional searching. \ No newline at end of file +Searchers should see the [Getting Started](/flashbots-mev-share/searchers/getting-started) guide for a walkthrough of MEV-Share and how it differs from traditional searching. diff --git a/docs/flashbots-mev-share/orderflow-providers.mdx b/docs/flashbots-mev-share/orderflow-providers.mdx index 54612946e..391a02b8e 100644 --- a/docs/flashbots-mev-share/orderflow-providers.mdx +++ b/docs/flashbots-mev-share/orderflow-providers.mdx @@ -2,4 +2,4 @@ title: For Orderflow Providers --- -Flashbots runs a MEV-Share Node that can be used by sending transactions to [Flashbots Protect](/flashbots-protect/quick-start). Wallets and application developers should see the [Protect MEV-Share Node guide](/flashbots-protect/mev-share) to configure your integration. \ No newline at end of file +Flashbots runs a MEV-Share Node that can be used by sending transactions to [Flashbots Protect](/flashbots-protect/quick-start). Wallets and application developers should see the [Protect MEV-Share Node guide](/flashbots-protect/mev-refunds) to configure your integration. \ No newline at end of file diff --git a/docs/flashbots-mev-share/release-notes/2023-03.mdx b/docs/flashbots-mev-share/release-notes/2023-03.mdx index 60cfee33e..056d35a9e 100644 --- a/docs/flashbots-mev-share/release-notes/2023-03.mdx +++ b/docs/flashbots-mev-share/release-notes/2023-03.mdx @@ -8,7 +8,7 @@ https://github.com/flashbots/mev-share New endpoints added to Flashbots bundle relay (relay.flashbots.net): -- `mev_sendBundle` - send bundles with a [new format](https://github.com/flashbots/mev-share/blob/main/specs/bundles/v0.1.md), enabling modular privacy settings and sets the stage for future innovations +- `mev_sendBundle` - send bundles with a [new format](https://github.com/flashbots/mev-share/blob/main/specs/bundles/v0.1.md), enabling modular privacy settings and sets the stage for future innovations. - `mev_simBundle` - simulate bundles in the context of MEV-Share using the new format. ## SSE Event Stream diff --git a/docs/flashbots-mev-share/release-notes/2023-07.mdx b/docs/flashbots-mev-share/release-notes/2023-07.mdx index 5cc30610c..9ca987c0d 100644 --- a/docs/flashbots-mev-share/release-notes/2023-07.mdx +++ b/docs/flashbots-mev-share/release-notes/2023-07.mdx @@ -2,13 +2,13 @@ ## customized refunds -Configure the percent(s) and recipient(s) for MEV-Share refunds by adding the [`refund`](/flashbots-protect/mev-share#refunds) query parameter to Protect RPC requests +Configure the percent(s) and recipient(s) for MEV-Share refunds by adding the [`refund`](/flashbots-protect/settings-guide#refunds) query parameter to Protect RPC requests or by adding `preferences.validity.refund` argument to the `eth_sendPrivateTransaction` JSON-RPC [method](/flashbots-auction/advanced/rpc-endpoint#eth_sendprivatetransaction). ## builder sharing Share transactions and bundles with additional builders for faster inclusion. -- Users: [Opt in to share with registered builders](/flashbots-protect/mev-share#builders) +- Users: [Opt in to share with registered builders](/flashbots-protect/settings-guide#builders) - Builders: [Register to receive bundles](https://github.com/flashbots/dowg#builders) ## debugging guide diff --git a/docs/flashbots-mev-share/release-notes/2023-09.mdx b/docs/flashbots-mev-share/release-notes/2023-09.mdx index 99c92a6a6..ee9e6b185 100644 --- a/docs/flashbots-mev-share/release-notes/2023-09.mdx +++ b/docs/flashbots-mev-share/release-notes/2023-09.mdx @@ -2,7 +2,7 @@ ## default logs hint -A new hint which shares a subset of logs, as described in the [stable configuration](/flashbots-protect/mev-share#stable-configuration). +A new hint which shares a subset of logs, as described in the [hints] settings(/flashbots-protect/settings-guide#hints). Previously these logs were shared by default. Now, users of the private transaction API, Protect RPC, and bundle relay can also request to share these logs when customizing their settings. diff --git a/docs/flashbots-mev-share/searchers/debugging.mdx b/docs/flashbots-mev-share/searchers/debugging.mdx index c8b81dc58..5d4a080f1 100644 --- a/docs/flashbots-mev-share/searchers/debugging.mdx +++ b/docs/flashbots-mev-share/searchers/debugging.mdx @@ -123,7 +123,7 @@ This happens when one of your transactions reverts. Since our `simulateBundle` f If you see this error when running the bot, it most likely means that the transaction you tried to backrun didn't affect the price enough to meet our target. This is expected — it's a feature, not a bug! -However, if you want to be sure, a good way to further verify what's happening is to simulate transactions in a local development environment. Toolkits such as [foundry](https://github.com/foundry-rs/foundry) or [hardhat](https://hardhat.org/docs) give you tools to compile contracts, create local nodes that fork their state from public nodes (e.g. mainnet, goerli), and simulate transactions locally, with stack traces to show you where things went wrong. +However, if you want to be sure, a good way to further verify what's happening is to simulate transactions in a local development environment. Toolkits such as [foundry](https://github.com/foundry-rs/foundry) or [hardhat](https://hardhat.org/docs) give you tools to compile contracts, create local nodes that fork their state from public nodes, and simulate transactions locally, with stack traces to show you where things went wrong. ## Did it pay enough gas? @@ -231,4 +231,4 @@ async function isBlockBuiltByFlashbots(blockNum: number) { } ``` -With this function, look at each block from `bundleParams.inclusion.block` through `bundleParams.inclusion.maxBlock` (if you set it) for a bundle to determine whether it was possible for the bundle to land in that block. \ No newline at end of file +With this function, look at each block from `bundleParams.inclusion.block` through `bundleParams.inclusion.maxBlock` (if you set it) for a bundle to determine whether it was possible for the bundle to land in that block. diff --git a/docs/flashbots-mev-share/searchers/event-stream.mdx b/docs/flashbots-mev-share/searchers/event-stream.mdx index 18ace8672..431e4da4e 100644 --- a/docs/flashbots-mev-share/searchers/event-stream.mdx +++ b/docs/flashbots-mev-share/searchers/event-stream.mdx @@ -5,8 +5,9 @@ title: Event Stream import Tabs from '@theme/Tabs' import TabItem from '@theme/TabItem' import StreamEvent from '@site/docs/specs/mev-share/_streamEvent.mdx' +import RemoteCodeBlock from "@site/src/components/RemoteCodeBlock" -Events on MEV-Share are distributed via an SSE endpoint. Searchers listen to this endpoint to receive a stream of new events, which contain data they can use in their bundles. Currently, the events refer to Ethereum transactions. +Events on MEV-Share are distributed via an Server-Sent Events (SSE) streaming endpoint. Searchers listen to this endpoint to receive a stream of new events, which contain data they can use in their bundles. Currently, the events refer to Ethereum transactions. ## Quickstart @@ -38,6 +39,10 @@ bundleHandler.close() ``` + + + + ```bash @@ -68,7 +73,7 @@ Events currently represent pending transactions, but eventually may be expanded | Network | URL | |-|-| | Mainnet | https://mev-share.flashbots.net | -| Goerli | https://mev-share-goerli.flashbots.net | +| Sepolia | https://mev-share-sepolia.flashbots.net | The endpoint sends an event with the message `:ping` every 15 seconds if no other messages were sent in the last 15 seconds. @@ -80,6 +85,76 @@ Events dispatched via the SSE endpoint are JSON-encoded objects that adhere to t Note that each of these properties are optional; if a field is not present, it means that the transaction sender chose not to share that information. +Below is an example of a transaction event received from the stream: + +```json +{ + "hash":"0xb756c9f6c34309d32c32daf1289c96d64a1068dfc2ead5e9bd0504640b91249e", + "logs":[ + { + "address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "topics":[ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000001b59718eafa2bffe5318e07c1c3cb2edde354f9c", + "0x0000000000000000000000005c7bcd6e7de5423a257d81b442095a1a6ced35c5" + ], + "data":"0x000000000000000000000000000000000000000000000000161545fdcf782a85" + }, + { + "address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "topics":[ + "0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65", + "0x0000000000000000000000005c7bcd6e7de5423a257d81b442095a1a6ced35c5" + ], + "data":"0x000000000000000000000000000000000000000000000000161545fdcf782a85" + }, + { + "address":"0x5c7bcd6e7de5423a257d81b442095a1a6ced35c5", + "topics":[ + "0x8ab9dc6c19fe88e69bc70221b339c84332752fdd49591b7c51e66bae3947b73c", + "0x0000000000000000000000000000000000000000000000000000000000000089", + "0x0000000000000000000000000000000000000000000000000000000000117363", + "0x0000000000000000000000003a23f943181408eac424116af7b7790c94cb97a5" + ], + "data":"0x000000000000000000000000000000000000000000000000161fb772f99eaf7a000000000000000000000000000000000000000000000000161fb772f99eaf7a000000000000000000000000000000000000000000000000161fb772f99eaf7a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000005216e484d6dde00000000000000000000000000000000000000000000000000016b90ac92248e000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000001b59718eafa2bffe5318e07c1c3cb2edde354f9c000000000000000000000000b658ba58f7153e99c05c9b7610f17bfeeab6bff5000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b658ba58f7153e99c05c9b7610f17bfeeab6bff500000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000005216e484d6dde000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + ], + "txs":[ + { + "to":"0x5c7bcd6e7de5423a257d81b442095a1a6ced35c5", + "functionSelector":"0x44b8be68", + "callData":"0x44b8be680000000000000000000000003a23f943181408eac424116af7b7790c94cb97a5000000000000000000000000b658ba58f7153e99c05c9b7610f17bfeeab6bff5000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000161fb772f99eaf7a000000000000000000000000000000000000000000000000161fb772f99eaf7a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008900000000000000000000000000000000000000000000000000016b90ac92248e0000000000000000000000000000000000000000000000000005216e484d6dde00000000000000000000000000000000000000000000000000000000001173630000000000000000000000000000000000000000000000000000000000000180ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000" + } + ] +} +``` + +### Understanding double-hash + +Note that the `hash` field is actually a keccak256 hash of the underlying bundle/transaction hash, essentially a double-hash. + +Below is code-snippet in golang to calculate double-hash for testing purposes. + +```go +package main + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "golang.org/x/crypto/sha3" +) + +func main() { + underlyingHash := common.HexToHash("0xd2d662b8aa0e8d86ea75d363522c9ede42ef538ae353da564d501c044a885293") + doubleHasher := sha3.NewLegacyKeccak256() + doubleHasher.Write(underlyingHash.Bytes()) + dHash := doubleHasher.Sum(nil) + matchingHash := common.BytesToHash(dHash) + fmt.Println(matchingHash.String()) //prints 0x90b4f5664cc201c3aa112d6bb2fa414c4aee10f00994692b282c1d14a1db6e4d +} +``` + --- Now that you've started listening to transactions, you're almost ready to start searching! Read on to the next page to learn [about bundles](/flashbots-mev-share/searchers/understanding-bundles). @@ -133,9 +208,7 @@ Returns an array of historical hints. ### Example - - -Get available historical hint data: +#### Get information about historical hint data ```bash curl https://mev-share-goerli.flashbots.net/api/v1/history/info @@ -154,12 +227,18 @@ _Response:_ } ``` -Get historical hint data for a block range: +#### Get historical event data beginning at start of stream history ```bash curl https://mev-share-goerli.flashbots.net/api/v1/history ``` +#### Get historical hint data from a specific block range + +```bash +curl 'https://mev-share-goerli.flashbots.net/api/v1/history?blockStart=9091377&blockEnd=9091379' +``` + _Response:_ ```json @@ -194,5 +273,21 @@ _Response:_ } ] ``` - - + +#### Querying with Offset & Limit + +Event history results are returned in chunks whose size are defined by `limit`, the maximum limit being specified in the [`/history/info` endpoint](#get-apiv1historyinfo). + +```bash +# assuming the limit is 500 +curl 'https://mev-share-goerli.flashbots.net/api/v1/history?blockStart=9091377' +curl 'https://mev-share-goerli.flashbots.net/api/v1/history?blockStart=9091377&offset=500' +curl 'https://mev-share-goerli.flashbots.net/api/v1/history?blockStart=9091377&offset=1000' +curl 'https://mev-share-goerli.flashbots.net/api/v1/history?blockStart=9091377&offset=1500' + +# or with a custom limit +curl 'https://mev-share-goerli.flashbots.net/api/v1/history?blockStart=9091377&limit=100' +curl 'https://mev-share-goerli.flashbots.net/api/v1/history?blockStart=9091377&limit=100&offset=100' +curl 'https://mev-share-goerli.flashbots.net/api/v1/history?blockStart=9091377&limit=100&offset=200' +curl 'https://mev-share-goerli.flashbots.net/api/v1/history?blockStart=9091377&limit=100&offset=300' +``` diff --git a/docs/flashbots-mev-share/searchers/getting-started.mdx b/docs/flashbots-mev-share/searchers/getting-started.mdx index 9261785b6..4bff2f018 100644 --- a/docs/flashbots-mev-share/searchers/getting-started.mdx +++ b/docs/flashbots-mev-share/searchers/getting-started.mdx @@ -2,69 +2,69 @@ title: Getting Started --- -import Tabs from '@theme/Tabs' -import TabItem from '@theme/TabItem' +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; To start searching on MEV-Share, you will first need to connect to a MEV-Share Node. As a reminder, the MEV-Share Node is responsible for receiving transactions and bundles from users, and selectively sharing information ("hints") about them with searchers. When a searcher wants to include a transaction in their bundle, they use that transaction's hash. The MEV-Share Node replaces it with the original transaction before sending the bundle to a block builder. ## Connect to MEV-Share Node -Flashbots operates an MEV-Share Node on the Ethereum mainnet. This Node provides endpoints for user transactions and searcher bundles. Additionally, it offers an SSE event stream endpoint, broadcasting pending events/transactions to searchers. +Flashbots operates an MEV-Share Node on the Ethereum mainnet. This Node provides endpoints for user transactions and searcher bundles. Additionally, it offers a Server-Sent Events (SSE) streaming endpoint, broadcasting pending events/transactions to searchers. The simplest way to connect to the Flashbots MEV-Share Node is to use a [client library](/flashbots-auction/libraries/mev-share-clients). For this guide, we'll refer to [mev-share-client-ts](https://github.com/flashbots/mev-share-client-ts). - + -*Add library to your project:* +_Add library to your project:_ ```bash yarn add @flashbots/mev-share-client ``` -*Use the following code to import the library* (Replace ALL_CAPS placeholders with your data): -```typescript -import { Wallet, JsonRpcProvider } from "ethers" -import MevShareClient, { - BundleParams, - HintPreferences, - IPendingBundle, - IPendingTransaction, - TransactionOptions -} from "@flashbots/mev-share-client" - -const provider = new JsonRpcProvider(RPC_URL) -const authSigner = new Wallet(FB_REPUTATION_PRIVATE_KEY, provider) -const mevShareClient = MevShareClient.useEthereumMainnet(authSigner) -``` - -_Connecting to Goerli:_ +_Use the following code to import the library_ (Replace ALL_CAPS placeholders with your data): ```typescript -const mevShareClient = MevShareClient.useEthereumGoerli(authSigner) +import {Wallet, JsonRpcProvider} from 'ethers'; +import MevShareClient, { + BundleParams, + IPendingBundle, + IPendingTransaction, + TransactionOptions, +} from '@flashbots/mev-share-client'; + +const provider = new JsonRpcProvider(RPC_URL); +const authSigner = new Wallet(FB_REPUTATION_PRIVATE_KEY, provider); +const mevShareClient = MevShareClient.useEthereumMainnet(authSigner); ``` -*Advanced setup* (for developers): +To use custom network parameters, you can instantiate a new MevShareClient instance directly. This example is what the client uses to connect to mainnet: ```typescript // connect to MEV-Share on mainnet const mevShareClient = new MevShareClient(authSigner, { - name: "mainnet", - chainId: 1, - streamUrl: "https://mev-share.flashbots.net", - apiUrl: "https://relay.flashbots.net", -}) + name: 'mainnet', + chainId: 1, + streamUrl: 'https://mev-share.flashbots.net', + apiUrl: 'https://relay.flashbots.net', +}); ``` Further documentation on the client library can be found in the [mev-share-client-ts](https://github.com/flashbots/mev-share-client-ts). -### A note on other languages + -If you're coding in a language that doesn't yet have a MEV-Share Node client library, you can send transactions and bundles directly with the [JSON-RPC endpoint](/flashbots-auction/advanced/rpc-endpoint). To listen for transactions, all you need is an HTTP client. More details on that in the [Event Stream](/flashbots-mev-share/searchers/event-stream) page. + +For Rust users, thanks to Paradigm's effort, we have a Rust MEV-Share client [mev-share-rs](https://github.com/paradigmxyz/mev-share-rs). +If you want a complete MEV bot framework, you could also directly go for [Artemis](https://github.com/paradigmxyz/artemis), which has built-in support for MEV-Share as outlined in this [example](https://github.com/paradigmxyz/artemis/blob/main/examples/mev-share-arb/src/main.rs). +### A note on other languages + +If you're coding in a language that doesn't yet have a MEV-Share Node client library, you can send transactions and bundles directly with the [JSON-RPC endpoint](/flashbots-auction/advanced/rpc-endpoint). To listen for transactions, all you need is an HTTP client. More details on that in the [Event Stream](/flashbots-mev-share/searchers/event-stream) page. + --- Now you should be connected to the Flashbots MEV-Share Node. Continue reading on the next page to learn how to [listen for hints](/flashbots-mev-share/searchers/event-stream) about pending transactions shared by the MEV-Share Node. @@ -74,9 +74,9 @@ Now you should be connected to the Flashbots MEV-Share Node. Continue reading on Searching on MEV-Share is different from searching on the mempool in that only certain parts of a transaction are shared with searchers. In the mempool, we can see all parts of a transaction, such as its calldata or who the transaction is from. But on MEV-Share, a transaction might only reveal its function selector, making a traditional arbitrage calculation infeasible. There are three primary strategies for searching on MEV-Share: -* Probabilistically: send many bundles that probabilistically backrun MEV-Share orderflow. -* On-chain: perform more of your searching on-chain instead of off-chain. -* Existing: only search on transactions which share all the information you need. + +- Probabilistically: send many bundles that probabilistically backrun MEV-Share orderflow. +- On-chain: perform more of your searching on-chain instead of off-chain. +- Existing: only search on transactions which share all the information you need. To maximally leverage MEV-Share searchers will need to employ new strategies. -::: diff --git a/docs/flashbots-mev-share/searchers/ratelimiting.mdx b/docs/flashbots-mev-share/searchers/ratelimiting.mdx new file mode 100644 index 000000000..37d3d63fa --- /dev/null +++ b/docs/flashbots-mev-share/searchers/ratelimiting.mdx @@ -0,0 +1,24 @@ +--- +title: Rate Limits +--- + +In order to protect our services from abuse we have rate limits on the number of requests that can be made. Currently, the rate limits are set as follows. + +## `relay.flashbots.net` - Bundles + +| Method | Limit | +|---------------------|--------------------| +| `eth_sendBundle` | 1800 / IP / 1 min | +| `mev_sendBundle` | 1800 / IP / 1 min | +| `eth_cancelBundle` | 600 / IP / 1 min | +| `mev_simBundle` | 300 / IP / 1 min | +| `eth_callBundle` | 300 / IP / 1 min | +| All others | 120 / IP / 1 min | + +Note that this is _requests_ and not _transactions_ submitted per second. There is no limitation on the number of transactions in a request. + +RPC rate limits for retail user transactions sent to `rpc.flashbots.net` [can be found here](../../flashbots-protect/ratelimiting). + +## Rate limit exceptions + +If you require a higher rate limit please reach out to [Shea Ketsdever](https://twitter.com/SheaKetsdever). diff --git a/docs/flashbots-mev-share/searchers/sending-bundles.mdx b/docs/flashbots-mev-share/searchers/sending-bundles.mdx index bf08ce42e..812aa89b2 100644 --- a/docs/flashbots-mev-share/searchers/sending-bundles.mdx +++ b/docs/flashbots-mev-share/searchers/sending-bundles.mdx @@ -39,6 +39,10 @@ const params: BundleParams = { maxBlock: targetBlock + 3, }, body: bundle, + // send the bundles to more builders to speed up inclusion + privacy: { + builders: ["flashbots", "beaverbuild.org", "rsync", "Titan"] + } } const bundleResult = await mevShareClient.sendBundle(params) @@ -82,7 +86,7 @@ const params: BundleParams = { }, body: [ {tx: "0x02...", canRevert: false}, - {tx: "0x02...", canRevert: false}, + //can only include one backrun tx ], privacy: { hints: { diff --git a/docs/flashbots-mev-share/searchers/tutorials/flash-loan-arbitrage/bot.mdx b/docs/flashbots-mev-share/searchers/tutorials/flash-loan-arbitrage/bot.mdx index e8ea7ac72..3bb022821 100644 --- a/docs/flashbots-mev-share/searchers/tutorials/flash-loan-arbitrage/bot.mdx +++ b/docs/flashbots-mev-share/searchers/tutorials/flash-loan-arbitrage/bot.mdx @@ -26,7 +26,7 @@ Client libraries have been developed for the following programming languages (mo To reiterate our goal, we need to find pending transactions from other Ethereum users and backrun them (send our transaction immediately after the user's transaction). If the user's trade moves the price enough, we'll arbitrage the trading pair between two exchanges for a profit. -As MEV-Share receives new transactions, it broadcasts them to searchers via the [Event Stream](/flashbots-mev-share/searchers/event-stream). Each transaction shares varying amounts of data via [hints](/flashbots-protect/mev-share#hints), but by default, transactions that trade on Uniswap, Balancer, or Curve will expose the trading pair's contract address in the log topics. +As MEV-Share receives new transactions, it broadcasts them to searchers via the [Event Stream](/flashbots-mev-share/searchers/event-stream). Each transaction shares varying amounts of data via [hints](/flashbots-protect/mev-refunds#hints), but by default, transactions that trade on Uniswap, Balancer, or Curve will expose the trading pair's contract address in the log topics. Here's an example of an event generated by a user who's (most likely) using MEV-Share's default privacy settings: @@ -60,7 +60,7 @@ Here's an example of an event generated by a user who's (most likely) using MEV- If we [look up the address](https://etherscan.io/address/0xca25091555d36ac0be8119ad967898ac30223b41) specified in the log topics, we'll see that it's a trading pair contract for QPEPE/WETH on Uniswap V2. This tells us that the user is buying/selling QPEPE on Uniswap, which means that we may be able to arbitrage it with Sushiswap or another Uni-V2 derivative. -![](/img/mevshare-flashloan-arb-guide/qpepe5.png "arbitrage profit per amount_in") +![](/img/mevshare-flashloan-arb-guide/qpepe5.jpg "arbitrage profit per amount_in") To detect events yourself, listen to the SSE Event Stream at [https://mev-share.flashbots.net](https://mev-share.flashbots.net). @@ -141,7 +141,7 @@ _To read more about how the SSE stream works, see the [Event Stream docs](/flash ## Filtering Relevant Transactions -MEV-Share uses [**hints**](/flashbots-protect/mev-share#hints) to selectively share information about a transaction. Based on the hint preferences specifies by the user when connecting, the transactions (or bundles) they send will trigger events containing information about their transaction which is filtered according to their hint preferences. +MEV-Share uses [**hints**](/flashbots-protect/mev-refunds#hints) to selectively share information about a transaction. Based on the hint preferences specifies by the user when connecting, the transactions (or bundles) they send will trigger events containing information about their transaction which is filtered according to their hint preferences. In this guide, we're only concerned with the fields in `logs`: `address` and `topics`. Other fields not covered in this guide are detailed in the [Event Scheme docs](/flashbots-mev-share/searchers/event-stream#event-scheme). diff --git a/docs/flashbots-mev-share/searchers/tutorials/flash-loan-arbitrage/simple-blind-arbitrage.mdx b/docs/flashbots-mev-share/searchers/tutorials/flash-loan-arbitrage/simple-blind-arbitrage.mdx index 5b9fa168c..7aad97d16 100644 --- a/docs/flashbots-mev-share/searchers/tutorials/flash-loan-arbitrage/simple-blind-arbitrage.mdx +++ b/docs/flashbots-mev-share/searchers/tutorials/flash-loan-arbitrage/simple-blind-arbitrage.mdx @@ -105,7 +105,7 @@ Once we know which token is which, we can make assertions about our profits and We use the values calculated from `getAmountOut` as inputs to the token pairs' swap functions: we use `amountIn` (the "optimal arbitrage" value) as the amount (of WETH) to send for the first trade, then use the output (`firstPairAmountOut`) of the first trade as the input to the second trade, selling all the tokens we bought from the first exchange to the other. -Once we've executed our trades, we should expect to have more ETH (or WETH) than we started with. But that won't always be the case. To ensure that we don't pay for an unprofitable trade, we check the WETH balance at the end of the `_executeArbitrage` function. If the balance isn't greater than when we first called the function, the transaction will revert. This protects us from malicious tokens, unforseen market conditions, and a variety of other ways you can lose your money. +Once we've executed our trades, we should expect to have more ETH (or WETH) than we started with. But that won't always be the case. To ensure that we don't pay for an unprofitable trade, we check the WETH balance at the end of the `_executeArbitrage` function. If the balance isn't greater than when we first called the function, the transaction will revert. This protects us from malicious tokens, unforeseen market conditions, and a variety of other ways you can lose your money. When we do turn a profit, we need to pay some of it to the validators/builders in order to get our transactions on-chain. Block builders have differing preferences & ordering algorithms, but a good rule of thumb is to use `maxBaseFeePerGas` and `maxPriorityFeePerGas` values that are slightly higher than the market average, and then tip a percentage of your profits to the builder. MEV-Share uses this builder tip to pay the user; this is the "MEV kickback." diff --git a/docs/flashbots-mev-share/searchers/tutorials/limit-order/sending-bundles.mdx b/docs/flashbots-mev-share/searchers/tutorials/limit-order/sending-bundles.mdx index da05d33bc..4c5b6f8e0 100644 --- a/docs/flashbots-mev-share/searchers/tutorials/limit-order/sending-bundles.mdx +++ b/docs/flashbots-mev-share/searchers/tutorials/limit-order/sending-bundles.mdx @@ -4,7 +4,7 @@ title: Sending Bundles ## Getting our trade ready -After we find a transaction that touches the trading pair we're targeting, we need to calculate how many tokens we should expect to receive. In this project, we are specifically *buying* DAI with ETH (technically WETH, because Uniswap only trades ERC-20 tokens), so we want the price of DAI/WETH to be as low as possible. In code, we define our price requirements in terms of the *amount of tokens we receive* from the trade — so we want the *highest* amount of tokens possible, but we have a definite minimum (1800 DAI). +After we find a transaction that touches the trading pair we're targeting, we need to calculate how many tokens we should expect to receive. In this project, we are specifically *buying* DAI with ETH (technically WETH, because Uniswap only trades ERC-20 tokens), so we want the price of DAI/WETH to be as low as possible. In code, we define our price requirements in terms of the *amount of tokens we receive* from the trade — so we want the *highest* amount of tokens possible, but we have a definite minimum (1800 DAI). In terms of a limit order, we're saying that we want our order to be filled when the price is *at most* 1800 DAI, but if the price is lower, then we want to fill at the lower price, which yields more DAI per WETH. @@ -73,7 +73,7 @@ async function backrunAttempt( currentBlockNumber: number, nonce: number, pendin } ``` -The `getSignedBackrunTx` function creates the transaction we'll send to execute our trade on Uniswap. We set a fixed gas price here for simplicity. If you prefer, you could replace the with dynamic fees that track the base fee of the chain. But constant gas prices may work better if you don't want to spend a lot on gas, and don't mind having to wait if the network's base fee exceeds your settings. +The `getSignedBackrunTx` function creates the transaction we'll send to execute our trade on Uniswap. We set a fixed gas price here for simplicity. If you prefer, you could replace it with dynamic fees that track the base fee of the chain. But constant gas prices may work better if you don't want to spend a lot on gas, and don't mind having to wait if the network's base fee exceeds your settings. The `backrunAttempt` function defines our price requirement logic: we make sure that `outputAmount` is at least our previously-defined cutoff amount. However, if the simulated output amount is higher, then we set `outputAmount` to expect that much, which protects us from [slippage](https://en.wikipedia.org/wiki/Slippage_(finance)) in case other transactions in the block happen to trade on the same pair. This function then sends our bundle to MEV-Share. If the bundle was received successfully, we should see a bundle hash logged to our console. @@ -167,18 +167,69 @@ async function main() { > For a full, working code example, check out https://github.com/flashbots/simple-limit-order-bot -![Mario finish](/img/mario-finish.png) +![Mario finish](/img/mario-finish.jpg) *That's all you need!* This code will listen for new transactions and blocks, and trigger our code to send bundles when we find a transaction that changes the price. Run the code and you should see something like this: -![First logs](/img/limit-order-logs-1.png) +```bash +$ npx ts-node src/index.ts +mev-share auth address: 0xE52A621a647A1013cE44EEBB37676F4c7205F87e +executor address: 0x5b2c1E34C3Be923c123Ec858F474645B1Fcee0A3 +skipping tx: 0x8ec57508495115338395a0de7cb9b85956845c83047bc523fc5b169fc9820251 +skipping tx: 0xbe8be3ddfe27c03d79d44bf5f46a40e3491960c85fc29ceb9b9d7b968e3c7760 +skipping tx: 0xd8bdceffde345bf71fb8058c0baae04eee58c25739dd31d3354c9777162be769 +skipping tx: 0xfdc9ed3cd98e15d9e2b6bcea832f7f178d23f7c20d7900de5cf23af9051337c3 +skipping tx: 0x4878de9bf339cffd8facb5037698839f97e8624806dec97f39d71254101ed712 +skipping tx: 0x0b1964af41ddf4d4082f6d68073f200b1d72ffc9852441aa7621feba34c4e045 +skipping tx: 0x23494341ec01dd3797778958e02cf9a8dbb8bb91989150b162cc7c16fe177267 +skipping tx: 0xb201acbfe4c140a14cdd90b84d3a2c277d14bbb53e9bbacc095282c7b5e93c93 +skipping tx: 0x8777978ea1c14af518d32ce74c8671905619ee8b6008c4c6f9a94e83fa2dda15 +skipping tx: 0x6f25db574493009c6a9a22f3c15370038f80b8c86f3547f72811c0c58dfc6160 +skipping tx: 0xb98f1e587f9a292043738f5c70e6532a6cd94a2f530a060556ce99256ca52e05 +skipping tx: 0x0c347e08df1fee8bb0f4fafe606b1a1b8159804623bbcd78c03097dc316ca47a +skipping tx: 0x2081950a40ca29cbc46c043f846a1e3205f3baaa09a8e531a20ff63c649617ed +skipping tx: 0x8ccc554df02cf2c8880bde8ea4b7dcfecc533ec4c799e2a14a55282937934abf +skipping tx: 0x7258bf29fb9879f10ee859ae80f491a7a652caf0825a1b2196cb2b39747e9a77 +skipping tx: 0x8d49b3d723457845484c16b1d637265821a63c601dc0184417c2a20789ec2881 +skipping tx: 0xfacd7b58b52184724fc1d8ad688544d0f45fb005110f49b790d320997e5ba79e +skipping tx: 0x176d69b0353ea5cb421f7218f94ec54191bdca3cc1d659587546235d73ae8837 +skipping tx: 0x518f3b9844a92d617146520b61face546aa399358f40136827fc24db8827b9ea +skipping tx: 0x58da384fd342fdc8d8ba96faf3e12bc89417c7099888eaedfd77a00bcf10f701 +skipping tx: 0x1431112c598a1a7969f048d6893b3ad72424fcc7a1de0b880ffc98585fcd2e7d +skipping tx: 0x55bb0a2209665e464a385b188d0dcc1d91c93bae1509368cdc5abf9cb38afdfe +skipping tx: 0x0978078667fd1bd834c5b8ca20e06b403e0df6311455de6dc6651c33542a594d +skipping tx: 0xed23e27981fba7b4e661c10c9d4e70ada3eafb9cd4197a24f4566c1c5266e601 +skipping tx: 0x3734c599be31a485a84376cf108fd76d5edc9637f834a9982a1600f0abd533d0 +skipping tx: 0xc932320f77f8436037ab27ead89c004acc8f8bc52e0c19dcb6ecea103bc2973a +skipping tx: 0xe880ce068eba29657bf14c535f421adefc43933fe84ef157cf4cdf7524edd22e +skipping tx: 0x350aaae85d6167e219480fb60104d27a773675ff387c2634da44f1b36bbeba6b +skipping tx: 0xfddcfb509e19be4500e4a1a03c97d77b2261fe41d8f019d48e0c0cea11cd1cc8 +skipping tx: 0x08867976aecc2b09c57cf17d2e16dda9e3c3026da9c2ca3fed3187c7b577fa91 +``` And after some time… -![Second logs](/img/limit-order-logs-2.png) +```bash +skipping tx: 0x82b46667867fd7e1684f14dd34503ee9b9bbe106352c00006592ceae8e58a9d7 +skipping tx: 0x51c79454c4e86df176b51524fc254ab2e04c0861c329cdeab7a90d2e3309c3b7 +skipping tx: 0xf0977236782c93462ea442514a28be64f11cd5feee647929b74834adff0b527a +skipping tx: 0x8d5273f1eefa3a6daa40355df621e488dcf434e7bffb6201e0d98c26709ea35b +skipping tx: 0x382ba4c5d62557277f494032b2578ba52435cccef7fd236f02278df337fa0f7b +skipping tx: 0x04b40010c4a986f19fdedde1c2b0b92bf146074fae98693dc53a10d32a15bbba +skipping tx: 0x7c89acc455e040f8690933af2fa40cac714f5f2790758972a35d4ea39ced32c9 +skipping tx: 0xfcb49a980017cc3e0e5d5d4a0ff40aa170dc2e32021f81319c8d2b117b12bf52 +skipping tx: 0x1861b5afc21a2e82dbdb8bc26777ced087c6a4830482b2f65273ba7159c204c8 +skipping tx: 0x0817d834d6a537b6839858465f5e7ce2f95c9c5e353cf85282cd0f1da5b90e50 +skipping tx: 0x387dd96be2b59da5f6e991b41d670f752fecd4d6571198729f1037996a4e2d3c +skipping tx: 0x6b8577d861ce46f1e780c7ce59925ac9be40fd5428954c15a7e115cacaf974e2 +skipping tx: 0xc41d53c886897aeda1fc401f337a2d8b3ef737e78f06a52cbbe29b501a1c7736 +skipping tx: 0x52f2f383b4af41aa47f09ed8fd237358b32f33a0f471fc7be40b83179e513458 +skipping tx: 0xbcc799ad42925730cbb724c0fe5ed7b8444e7fbc8a4219d7346a2a03e8ac5131 +It's a match: 0xf76ce750b75ccd34b9174fdf8b574d129630d51422f3ca84f4f308952a4ea3b4 +``` It may take a while to find a match — remember, the code scans for a trade on the ETH/DAI pair on Uniswap V2. There are lots of other events to consider for future improvements to this bot! -You may also consider removing the code that checks the event to see if it matches our pair address. It's possible that the price could move to our target level without us seeing an event to backrun. If we simply backrun every transaction we see, then we can potentially benefit from opportunities that we can't yet see. However, it is essential to understand how to use logs on MEV-Share, as they provide critical data that can be used for a multitude of other purposes, so we've introduced it here as a practical example. \ No newline at end of file +You may also consider removing the code that checks the event to see if it matches our pair address. It's possible that the price could move to our target level without us seeing an event to backrun. If we simply backrun every transaction we see, then we can potentially benefit from opportunities that we can't yet see. However, it is essential to understand how to use logs on MEV-Share, as they provide critical data that can be used for a multitude of other purposes, so we've introduced it here as a practical example. diff --git a/docs/flashbots-mev-share/searchers/tutorials/limit-order/using-events.mdx b/docs/flashbots-mev-share/searchers/tutorials/limit-order/using-events.mdx index 5c40b1162..a8454e326 100644 --- a/docs/flashbots-mev-share/searchers/tutorials/limit-order/using-events.mdx +++ b/docs/flashbots-mev-share/searchers/tutorials/limit-order/using-events.mdx @@ -38,7 +38,53 @@ npx ts-node src/index.ts You should see events popping up in the console. Something like this: -![MEV-Share events](/img/mev-share-events.png) +```tsx +PendingTransaction { + hash: '0x26aba6f3c5083d58915161efb0cd0f713418cdd7a95425cdde451efd1dfb5dff', + logs: [ + { + address: '0x8255ffbb54bbb825cc544b67ccf36526e6101f5e', + topics: [Array], + data: 'Ox' + }, + { + address: '0x8255ffbb54bbb825cc544b67ccf36526e6101f5e' + topics: [Array], + data: 'Ox' + } + ], + to: null, + functionSelector: null, + callData: null, + gasUsed: undefined, + mevGasPrice: undefined +} +PendingTransaction { + hash: '0xeb0d75030e0c7253b60a17a58eb2a2e66a6e3ca58343cadece70a528dfd378a1', + logs: [ + { + address: 'Oxdac17f958d2ee523a2206206994597c13d831ec7', + topics: [Array], + data: '0x0000000000000000000000000000000000000000000000000000000253f52170' + }, + { + address: 'Oxdac17f958d2ee523a2206206994597c13d831ec7', + topics: [Array], + data: '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + }, + { + address: 'Oxdac17f958d2ee523a2206206994597c13d831ec7', + topics: [Array], + data: '0x0000000000000000000000000000000000000000000000000000000253f52170' + }, + { + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + topics: [Array], + data: '0x00000000000000000000000000000000000000000000021e08ad287c5f8d3bff' + } + ] +} +``` > Traffic is often low on goerli, so you may want to try connecting to mainnet with `MevShareClient.useEthereumMainnet(authSigner)` to see more events. @@ -121,7 +167,7 @@ async function main() { console.log('skipping tx: ' + pendingTx.hash) return } - console.log(`It's a match: ${ pendingTx.hash }`) + console.log(`It's a match: ${ pendingTx.hash }`) }) } ``` @@ -137,4 +183,4 @@ const mevshare = MevShareClient.useEthereumMainnet(authSigner) :::info For the Adventurous Try logging `pendingTx` in its entirety; look at all the fields. Or in code, check out the [interface](https://github.com/flashbots/matchmaker-ts/blob/main/src/api/interfaces.ts#L258) directly. See if you can find any patterns in the `logs` parameter. -:::info \ No newline at end of file +:::info diff --git a/docs/flashbots-mev-share/searchers/understanding-bundles.mdx b/docs/flashbots-mev-share/searchers/understanding-bundles.mdx index 44cbcf593..74469ab88 100644 --- a/docs/flashbots-mev-share/searchers/understanding-bundles.mdx +++ b/docs/flashbots-mev-share/searchers/understanding-bundles.mdx @@ -6,7 +6,7 @@ import Tabs from '@theme/Tabs' import TabItem from '@theme/TabItem' import SendBundleRpc from '@site/docs/specs/mev-share/_mev_sendBundle.mdx' import BuilderInheritance from '@site/docs/specs/mev-share/blurbs/_builderInheritance.mdx' -import Hints from '@site/docs/specs/mev-share/_hints.mdx' +import Hints from '@site/docs/specs/mev-share/HintsTable' Bundles on MEV-Share are conceptually the same as bundles on MEV-Boost: they are an ordered array of transactions that execute atomically. However, their structure is a bit different. MEV-Share bundles use a new method called [`mev_sendBundle`](https://github.com/flashbots/mev-share/blob/main/specs/bundles/v0.1.md) which has additional fields used to specify privacy preferences and introduce other new features like post-execution validity checks. @@ -82,5 +82,5 @@ Bundles that set the `privacy` parameter can only contain original signed transa ::: See [Sending Bundles](/flashbots-mev-share/searchers/sending-bundles#share-bundle-data) for more information. --- -Now that we know all the different ways in which we can send and share bundles, we're finally ready to [send a bundle](/flashbots-mev-share/searchers/sending-bundles). \ No newline at end of file +-- +Now that we know all the different ways in which we can send and share bundles, we're finally ready to [send a bundle](/flashbots-mev-share/searchers/sending-bundles). diff --git a/docs/flashbots-protect/additional-documentation/bundle-cache.md b/docs/flashbots-protect/additional-documentation/bundle-cache.md deleted file mode 100644 index e84fbff76..000000000 --- a/docs/flashbots-protect/additional-documentation/bundle-cache.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: bundle cache API ---- - -To create a bundle iteratively (e.g. by signing & sending transactions one at a time with Metamask), you can use the bundle cache API to cache signed transactions and retrieve them with a bundle ID. - -This will be used for whitehat recoveries. By enabling users to sign transactions on their own machines and send them privately to Flashbots, we remove the need to ask for the compromised private key. - -## Create a Bundle ID - -To start addding transactions to a bundle, first create a bundle ID. We recommend using a UUID (v4). You can generate a UUID at [uuidgenerator.net](https://www.uuidgenerator.net/version4) or with any uuid library. - -## Connect to Flashbots Protect with Bundle ID - -Connecting to the Flashbots Protect RPC Endpoint with a bundle ID parameter will automatically add incoming transactions to a queue without sending them. - -```url -https://rpc.flashbots.net?bundle= -``` - -Chain ID should be set to `1`. - -## Add Transaction to Bundle - -To add a transaction to the bundle, sign and send the transaction as you normally would (e.g. via Metamask). The transaction will stay pending until it's included on-chain (after the bundle is sent). - -## Get Bundle Transactions - -You can get the array of transactions included in your bundle using the `GET /bundle?id=` endpoint: - -```bash -curl https://rpc.flashbots.net/bundle?id= -``` - -This will return a JSON object with your signed transactions: - -```json -{ - "bundleId": "cbd900bf-44c5-4f6b-bf14-9b8d2ae27510", - "rawTxs": ["0x02f879827a6901849502...", "0x02f875827a6960849502..."] -} -``` - -Note: The transaction sent last is the first in the `rawTxs` array. - -## Send Bundle - -Once all the transactions you want to include in your bundle are added to the queue, query the bundle with `GET /bundle?id=` and send the returned signed transactions to Flashbots as a bundle. - -If you're being helped with a whitehat recovery, we may provide a web interface for you to do this. - -If you want to send a bundle directly, check out the [Flashbots Auction Docs](/flashbots-auction/quick-start#how-to-send-your-first-flashbots-bundle) for instructions on how to do this. - -## Fake Funds - -Querying the balance of an address when using the `?bundle=` argument will return a fake balance of 100 ETH, to allow crafting transactions without the account having actual funds. diff --git a/docs/flashbots-protect/additional-documentation/eth-sendPrivateTransaction.mdx b/docs/flashbots-protect/additional-documentation/eth-sendPrivateTransaction.mdx index 5a8c63029..b238c4a7b 100644 --- a/docs/flashbots-protect/additional-documentation/eth-sendPrivateTransaction.mdx +++ b/docs/flashbots-protect/additional-documentation/eth-sendPrivateTransaction.mdx @@ -4,7 +4,7 @@ title: eth_sendPrivateTransaction import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -import Hints from "../../specs/mev-share/_hints.mdx"; +import Hints from "../../specs/mev-share/HintsTable"; import Builders from "../../specs/mev-share/_builders.mdx"; ## Introduction @@ -25,6 +25,12 @@ You can access this method using the following libraries: - For Python, use [web3-flashbots.py](/flashbots-auction/libraries/web3py-provider). - Additionally, [`eth_sendPrivateTransaction`](https://docs.alchemy.com/reference/eth-sendprivatetransaction?a=fb) is freely supported on [Alchemy](https://alchemy.com?a=fb). +## Priority fee + +When sending transaction using `eth_sendPrivateTransaction` or `eth_sendPrivateRawTransaction` methods you should set +priority fee (tips) to be strictly greater than zero. Transactions with 0 priority fee will not be shared with block +builders and included on chain, unless they are bundled by a searcher via MEV-Share. + ## Examples The following code examples show how to use eth_sendPrivateTransaction using the Flashbots ethers and web3.py libraries. @@ -117,7 +123,7 @@ Detailed JSON-RPC structure for the method are below: tx, // String, raw signed transaction maxBlockNumber, // Hex-encoded number string, optional. Highest block number in which the transaction should be included. preferences?: { - fast: boolean, // Deprecated; required until this is removed from the API. Value has no effect. + fast: boolean, // Sends transactions to all registered block builders, sets MEV-Share revenue share to 50% privacy?: { // MEV-Share options; optional hints?: Array< // data about tx to share w/ searchers on mev-share "contract_address" | @@ -151,7 +157,7 @@ example request: "tx": "0x123abc...", "maxBlockNumber": "0xcd23a0", "preferences": { - "fast": true, // left for backwards compatibility; may be removed in a future version + "fast": true, "privacy": { "hints": ["calldata", "transaction_hash"], "builders": ["default"] @@ -177,7 +183,7 @@ example response: #### Privacy options -By default, transactions are sent to the Flashbots MEV-Share Node with the default [Stable](/flashbots-protect/mev-share#stable-configuration) configuration. The `privacy` parameter allows you to customize privacy settings: +By default, transactions are sent to the Flashbots MEV-Share Node with the default [Stable](/flashbots-protect/mev-refunds#stable-configuration) configuration. The `privacy` parameter allows you to customize privacy settings: | Parameter | Type | Description | | ---------- | ------------ | -------------------------------------------------------------------- | @@ -214,7 +220,7 @@ and 70% of the backrun value is left to the builder. ### eth_sendPrivateRawTransaction -`eth_sendPrivateRawTransaction` behaves like [eth_sendPrivateTransaction](#eth_sendprivatetransaction) but its format +`eth_sendPrivateRawTransaction` behaves like [eth_sendPrivateTransaction](#) but its format is similar to that of [`eth_sendRawTransaction`](https://docs.alchemy.com/reference/eth-sendrawtransaction) This method has the following JSON-RPC format: diff --git a/docs/flashbots-protect/additional-documentation/ratelimiting.md b/docs/flashbots-protect/additional-documentation/ratelimiting.md deleted file mode 100644 index 5c59fd5d7..000000000 --- a/docs/flashbots-protect/additional-documentation/ratelimiting.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: rate limiting ---- - -In order to protect our service from abuse we have rate limits on the number of requests that can be made to Flashbots Protect RPC. Currently, the rate limits are set as follows: - -- Maximum Requests per Second: 80 requests - -- Burst Limit: Up to 100 requests - -Note that this is _requests_ and not _transactions_ submitted per second. There is no limitation on the number of transactions in a request. -Note that you are not required to read JSON RPC requests to send transactions to Flashbots Protect RPC. - -## Rate limiting exceptions - -If you are a wallet or application integrating with protect and you require a higher rate limit please reach out to [bertcmiller](https://twitter.com/bertcmiller). - -## Batch request support - -Flashbots Protect RPC is not supporting batch JSON-RPC requests. diff --git a/docs/flashbots-protect/additional-documentation/status-api.md b/docs/flashbots-protect/additional-documentation/status-api.md index 0cdd13d55..fff1195af 100644 --- a/docs/flashbots-protect/additional-documentation/status-api.md +++ b/docs/flashbots-protect/additional-documentation/status-api.md @@ -4,6 +4,15 @@ title: Transaction Status API Transactions that you submit to Flashbots Protect won't be observable in the public mempool. However, you can use our status API to check the status of your transactions. The URL for doing so is: `https://protect.flashbots.net/tx/YOUR_TX_HASH_HERE`, and you can also use Etherscan as you normally would for transactions. They will show the status of your transaction from the status API as well. +The Transaction Status API is also available on test networks. Below is a table of URLs for accessing the API across different networks: + +| Network | URL | +| -------- | -------------------------------------------------- | +| Mainnet | `https://protect.flashbots.net/tx/` | +| Sepolia | `https://protect-sepolia.flashbots.net/tx/` | + + + In turn you will receive a JSON response that looks like the following: ```json @@ -21,7 +30,10 @@ In turn you will receive a JSON response that looks like the following: "value": "" }, "fastMode": true, // for backwards compatibility; may be removed in a future version - "seenInMempool": false + "seenInMempool": false, + "simError": "", + "revertReason": "", + "isRevert": false } ``` @@ -37,7 +49,7 @@ Below is a table of status codes that can be returned: ## Privacy -The `transaction` fields are disclosed only for transactions with an `INCLUDED` status to maintain privacy for trades that are pending, failed, or cancelled. These fields will remain empty for transactions with `PENDING`, `FAILED`, `UNKNOWN`, or `CANCELLED` statuses. +The `transaction` fields are disclosed only for transactions with an `INCLUDED` status to maintain privacy for trades that are pending, failed, or cancelled. These fields will remain empty for transactions with `PENDING`, `FAILED`, `UNKNOWN`, or `CANCELLED` statuses. Protect fast mode transactions are an exception to this rule as TEE searchers will receive all fields (without signature) for all transactions, including reverted or failed transactions, with a 5 minute delay for troubleshooting and debugging purposes. For instance, once a transaction is included, the JSON response will be populated with data for all fields: @@ -56,6 +68,23 @@ For instance, once a transaction is included, the JSON response will be populate "value": "10000000000" }, "fastMode": true, // for backwards compatibility; may be removed in a future version - "seenInMempool": false + "seenInMempool": false, + "isRevert": false } ``` + +While your transaction is `PENDING` or `FAILED` we will try to respond with the latest seen simulation error and revert reason if exists. + +Below is the table of currently supported `simError` values. + +| Sim error | Description | +|------------------------------|---------------------------------------------------------------------------------------------| +| `SimErrorMaxFeePerGasTooLow` | Consensus incompatible tx that wasn't caught on rpc | +| `SimErrorInsufficientFunds` | Insufficient ETH balance to pay for gas | +| `SimErrorNonceTooLow` | Nonce too low | +| `SimErrorNonceTooHigh` | Nonce too high | +| `SimErrorInvalidChainId` | Consensus incompatible tx that wasn't caught on rpc | +| `SimErrorExecutionReverted` | Execution reverted (slippage tolerance exceeded). Check revertReason field for more details | +| `SimErrorOutOfGas` | Ran out of gas during execution (gas limit too low) | + +`revertReason` field is a valid utf-8 part of the simulation result. Example: `TRANSFER_FROM_FAILED`, `UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT` diff --git a/docs/flashbots-protect/cancellations.md b/docs/flashbots-protect/cancellations.md index 3828269b5..d62ad707b 100644 --- a/docs/flashbots-protect/cancellations.md +++ b/docs/flashbots-protect/cancellations.md @@ -8,7 +8,7 @@ Flashbots Protect provides the functionality to cancel pending transactions. To - It must be submitted from the **same address** as the original transaction that is intended to be cancelled. - It should have the **same nonce** as the original transaction. -- The **from and to addresses** should match those of the original transaction. +- The **from and to addresses** should both be set to the **from address** of the original transaction. - The **data field** of the cancellation transaction should be left empty. ## No cost to cancel diff --git a/docs/flashbots-protect/gas-fee-refunds.md b/docs/flashbots-protect/gas-fee-refunds.md new file mode 100644 index 000000000..bd943c5c6 --- /dev/null +++ b/docs/flashbots-protect/gas-fee-refunds.md @@ -0,0 +1,51 @@ +--- +title: Gas Fee Refunds +--- + +## Introduction + +Flashbots Protect users are automatically eligible to receive gas fee refunds, if a transaction can be landed onchain for a lower price. This applies to both the RPC and the private transaction API. + +Gas fee refunds do not change how transactions are executed and users do not need to make any changes to be eligible for them. Gas fee refunds are calculated separately, and applied in addition to, MEV refunds from [MEV-Share](/flashbots-protect/mev-refunds). + +## Where do refunds come from + +Users and orderflow providers (like wallets) often pay high priority fees to land transactions on chain. Many of these transactions could be executed just as quickly for a fraction of the gas cost. + +It can be difficult to estimate gas correctly when sending a transaction. Flashbots Protect sends all transactions to [BuilderNet](https://buildernet.org/), which calculates the optimal fee on your behalf and refunds transactions that overpay. + +Gas fee refunds include both priority fees (more common in user transactions) and coinbase transfers (less common). + +## Which transactions receive refunds + +Flashbots Protect provides refunds for transactions in blocks landed by BuilderNet. Whether a transaction receives a refund depends on a few factors that vary from block to block: +* How much network congestion and competition there was +* Whether BuilderNet made a profit and how much +* How much the specific transaction contributed to the value of the block +* If the transaction was sent directly to Flashbots Protect, or shared with other RPCs and block builders + +Note that transactions seen in the public mempool are excluded and do not receive refunds. + +## How to maximize both refunds and speed + +Transactions which are sent directly to the Flashbots RPC or API, and not multiplexed _by the user_ to other RPCs or block builders, are likely to receive higher refunds. This is because they increase the profit of BuilderNet which is used to provide refunds. + +BuilderNet does not land 100% of blocks. In order to improve inclusion speed, users can ask Flashbots to share their transactions with other block builders in cases where BuilderNet does not win a block. Flashbots will automatically share with all specified builders on the user's behalf. + +There are two ways to share with other builders: +* Use [fast mode](/flashbots-protect/quick-start#faster-transactions) to share with all registered builders +* Choose [specific builders](/flashbots-protect/settings-guide#builders) to share transactions with + +## Who receives refunds + +For the RPC: The refund recipient is the address specified in the first [refund parameter](/flashbots-protect/settings-guide#refunds) on an RPC request, if one is provided. Otherwise, refunds are sent to the transaction originator (`tx.origin`) by default. + +For the private transaction API: The refund recipient is the signer used on the `eth_sendPrivateTransaction` request. + +## How to track refunds + +Refunds are tracked from a start date of July 8, 2024. Refunds are sent to recipients in batches, the first batch originated from the Flashbots builder address `0xdf99A0839818B3f120EBAC9B73f82B617Dc6A555` while newer batches originate from [`refunds.buildernet.eth`](https://etherscan.io/address/0x62a29205f7ff00f4233d9779c210150787638e7f). The recipient can track the status of their refunds using the [`flashbots_getFeeRefundTotalsByRecipient`](/flashbots-auction/advanced/rpc-endpoint#flashbots_getfeerefundtotalsbyrecipient) RPC method. + +## Distributed refunds + +The on-chain transactions corresponding to distributed refunds can be viewed with this Dune query: [https://dune.com/queries/4398421](https://dune.com/queries/4398421) diff --git a/docs/flashbots-protect/large-transactions.md b/docs/flashbots-protect/large-transactions.md new file mode 100644 index 000000000..a1db19805 --- /dev/null +++ b/docs/flashbots-protect/large-transactions.md @@ -0,0 +1,7 @@ +--- +title: Large Transaction Allowlist +--- + +Some projects may need to post larger transactions (measured in bytes) than the transaction pool allows. Flashbots bundles are not subject to the transaction pool size constraints. However, at the RPC level only transactions to certain contracts are allowed to be over 128kb. + +The list of contracts supporting large transactions can be seen in the [RPC endpoint's allowlist](https://github.com/flashbots/rpc-endpoint/blob/main/server/whitelist.go#L21). To add your contract to this list please make a PR to the RPC endpoint appending your contract address to the allowlist and share a description of your use case in the body of the PR. diff --git a/docs/flashbots-protect/mev-refunds.mdx b/docs/flashbots-protect/mev-refunds.mdx new file mode 100644 index 000000000..1a910a0d8 --- /dev/null +++ b/docs/flashbots-protect/mev-refunds.mdx @@ -0,0 +1,50 @@ +--- +title: MEV Refunds +--- + +import ProtectButton from '@site/src/components/ProtectButton'; + +## Introduction + +Flashbots Protect users are automatically eligible to receive MEV refunds from [MEV-Share](/flashbots-mev-share/introduction). If your transaction (eg. a large DEX swap) generates MEV, MEV-Share can help you reclaim a significant portion of this value. The remainder is split with searchers and validators to facilitate transaction inclusion. + +By default, all Protect transactions use the [default](/flashbots-protect/settings-guide#default) privacy setting which is continuously optimized by Flashbots to balance efficient execution and protection against harmful MEV. Advanced users can customize their settings when configuring their RPC or by manually editing the query parameters their Protect RPC request. + + + +## Common privacy settings + +You can customize how much information is shared about your transactions in MEV-Share. Each piece of information is called a "hint". Sharing more hints can increase refunds, while sharing fewer hints can increase privacy. Below are some common hint choices for different levels of privacy. See the complete [settings page](/flashbots-protect/settings-guide) for a full list of all settings you can apply to your RPC request. + +### Default + +To use the default privacy settings, you don't need to specify any query parameters. + +```url +https://rpc.flashbots.net +``` + +Currently, this configuration shares the following information: + +- The `hash` of all transactions +- `default_logs` Partial logs (the pool id and the fact that a swap was made) for curve, balancer, and uniswapV2/V3/V4-style trades + +### Max Privacy + +To use Protect with full privacy, set _only_ the `hash` hint in your Protect RPC URL: + +```url +https://rpc.flashbots.net?hint=hash +``` + +This configuration ensures that all identifiable transaction data sent to the MEV-Share Node is concealed from searchers. However, it's important to note that this could make it more challenging for searchers to spot MEV opportunities, leading to a very likely decrease in your MEV refund. + +### Max Refund + +To use Protect with the maximum refund, set _all_ hints in your Protect RPC URL: + +```url +https://rpc.flashbots.net?hint=calldata&hint=contract_address&hint=function_selector&hint=logs +``` + +This configuration provides searchers with comprehensive details about your transaction, giving them a better chance to identify more MEV opportunities and return MEV refunds. diff --git a/docs/flashbots-protect/mev-share.mdx b/docs/flashbots-protect/mev-share.mdx deleted file mode 100644 index 10e964149..000000000 --- a/docs/flashbots-protect/mev-share.mdx +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: MEV-Share ---- - -import ProtectButton from "protect-button"; -import HintsTable from "../specs/mev-share/_hints.mdx"; -import RpcHints from "../specs/protect-rpc/_hints.mdx"; -import Builders from "../specs/mev-share/_builders.mdx"; -import ProtectButtonSelector from "@site/src/components/ProtectButtonSelector"; - -## Introduction -MEV-Share allows users to gain up to 90% of the MEV that their transactions create. By default, Protect users' transactions are sent to Flashbots [MEV-Share Node](/flashbots-mev-share/introduction), which returns them up to 90% of the MEV that their transactions create. By default, Protect users will be connected with the [Stable](/flashbots-protect/mev-share#stable-configuration) configuration, which is continuously tuned by Flashbots to optimize execution while protecting users from harmful MEV. This document guides users on the nuances and configurations of MEV-Share. - -MEV-Share enables users to reclaim up to 90% of the MEV generated by their transactions. By default, transactions from Protect users are directed to the Flashbots [MEV-Share Node](/flashbots-mev-share/introduction), which facilitates this return. Users are automatically connected to the [Stable](/flashbots-protect/mev-share#stable-configuration) configuration, a setting continuously optimized by Flashbots to balance efficient execution and protection against harmful MEV. This document provides a guide on the mechanism and various configurations of MEV-Share. - -Advanced users can exert more control over their transactions and preferences through the advanced panel or by manually configuring their Protect RPC request. - - - -## Common configurations - -### Stable Configuration - -The Stable configuration is the default configuration for Protect RPC. No query parameters are specified to use it. - -```url -https://rpc.flashbots.net -``` - -Currently, this configuration shares the following information: - -- The `hash` of all transactions -- `default_logs` Partial logs (the pool id and the fact that a swap was made) for curve, balancer, and uniswapV2/V3-style trades -- Transactions are only forwarded to the Flashbots block builder - -This may change over time as we gather more data and fine-tune the configuration to maximize benefits. - -### Max Privacy - -To use Protect with full privacy, set _only_ the `hash` hint in your Protect RPC URL: - -```url -https://rpc.flashbots.net?hint=hash -``` - -This configuration ensures that all identifiable transaction data sent to the MEV-Share Node is concealed from searchers. However, it's important to note that this could make it more challenging for searchers to spot MEV opportunities, leading to a very likely decrease in your MEV kickback. - -### Max Kickback - -To use Protect with the maximum kickback, set _all_ hints in your Protect RPC URL: - -```url -https://rpc.flashbots.net?hint=calldata&hint=contract_address&hint=function_selector&hint=logs&hint=hash -``` - -This configuration provides searchers with comprehensive details about your transaction, giving them better chance to identify more MEV opportunities and to return more MEV kickback to you. - -## Examples - -Here are some examples of configurations that you might choose, depending on your goals. - -|
Goal
| Flashbots Protect RPC URL | -| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -| Stable | `https://rpc.flashbots.net` | -| Max Privacy | `https://rpc.flashbots.net?hint=hash` | -| Max Kickback | `https://rpc.flashbots.net/?hint=calldata&hint=contract_address&hint=function_selector&hint=logs&hint=hash` | -| Add Builders (share with other builders for faster inclusion) | `https://rpc.flashbots.net?builder=flashbots&builder=XYZ` | -| Change Refund (send more to validator for faster inclusion) | `https://rpc.flashbots.net?refund=userAddr:10` | - -## Configuration Reference - -The Protect RPC uses query parameters within the URL to convey your preferences. These parameters can include hints about your transaction, the builders to whom your transaction is directed, and the distribution of potential refunds if your transaction is bundled. - -### Hints - -To customize your hint setup, use the hint parameter to control the visibility of your transaction data to searchers. If no hints are provided, the default [Stable](/flashbots-protect/mev-share#stable-configuration) hint configuration will be used. If you specify one or more hints, any hint that is _not_ included will be disabled. - - - -Here is an example: - -```url -https://rpc.flashbots.net?hint=calldata&hint=logs&hint=hash -``` - -This configuration shares the calldata, logs, and hash of your transaction with searchers. It does not share the contract address or function selector. - -### Builders - -To designate the builders who will receive your transactions, use the `builder` parameter. This parameter can be repeated multiple times to include multiple builders. The builders listed below are currently supported. - - - -It's important to understand that while adding more builders can increase your transaction inclusion rate, it also requires you to place trust in those builders. Here's an example of how to utilize the `builder` parameter: - -```url -https://rpc.flashbots.net?builder=flashbots&builder=XYZ -``` - -This configuration sends your transaction to the Flashbots block builder and the XYZ block builder. - -### Refunds - -You can tailor your refund settings using the refund parameter. This determines the distribution of the searcher's payment among different addresses if your transaction is bundled. If not specified, the transaction originator (tx.origin) will by default receive 90% of the searcher's payment. - -The refund parameter contains two colon-separated values: an address for the refund and the percentage of the searcher's payment to be refunded. To distribute the payment across multiple addresses, append a new refund parameter for each. - -Here is an example of a refund parameter that sends 10% of the searcher's payment to the address `userAddr`: - -```url -https://rpc.flashbots.net?refund=userAddr:10 -``` - -All percentages in the refund parameters must total less than 100. The remaining percentage, inferred from 100 - total refund percentages, is the payment to the validator. Note that keeping a larger percentage of the refund may result in longer inclusion times, because it reduces the payment to the validator. diff --git a/docs/flashbots-protect/nonce-management.mdx b/docs/flashbots-protect/nonce-management.mdx new file mode 100644 index 000000000..f7face46b --- /dev/null +++ b/docs/flashbots-protect/nonce-management.mdx @@ -0,0 +1,85 @@ +--- +title: Nonce Management +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Normally, a wallet can call `eth_getTransactionCount` to get the next nonce to use for a transaction. +However, since transactions sent to Flashbots Protect are potentially sensitive, even exposing the incremented nonce can leak information about the user's activity. + +As such, transactions sent to Flashbots Protect are only included in the `eth_getTransactionCount` results when querying the `"pending"` nonce, and only if the request is signed by the user's private key. + +This is done by sending a JSON-RPC request to the Flashbots Protect RPC endpoint with the following parameters: + +```json +{ + "jsonrpc": "2.0", + "method": "eth_getTransactionCount", + "params": [ + "0xYOUR_ADDRESS", + "pending" + ], + "id": 1 +} +``` + +The request is then signed and the signature is included in the `X-Flashbots-Signature` header. Without such a signature, the returned nonce will only include transactions sent to the public mempool. + +### Authentication + +To authenticate your request, sign the payload and include the signed payload in the `X-Flashbots-Signature` header of your request. + +```curl +curl -X POST -H "Content-Type: application/json" -H "X-Flashbots-Signature: :" --data '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0xYOUR_ADDRESS","pending"],"id":1}' https://rpc.flashbots.net +``` + +The private key of the address your want to query must be used to sign the payload. + +The signature is calculated by taking the [EIP-191](https://eips.ethereum.org/EIPS/eip-191) hash of the json body encoded as UTF-8 bytes. Here's an example using ethers.js: + + + + +```ts +import {Wallet, utils} from 'ethers'; + +const privateKey = '0x1234'; +const wallet = new Wallet(privateKey); +const body = + '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0xYOUR_ADDRESS","pending"],"id":1}'; +const signature = wallet.address + ':' + wallet.signMessage(utils.id(body)); +``` + + + + +```py +from web3 import Web3 +from eth_account import Account, messages + +body = '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0xYOUR_ADDRESS","pending"],"id":1}' +message = messages.encode_defunct(text=Web3.keccak(text=body).hex()) +signature = Account.from_key(private_key).address + ':' + Account.sign_message(message, private_key).signature.hex() +``` + + + + +```go +body := `{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0xYOUR_ADDRESS","pending"],"id":1}` +hashedBody := crypto.Keccak256Hash([]byte(body)).Hex() +sig, err := crypto.Sign(accounts.TextHash([]byte(hashedBody)), privKey) +signature := crypto.PubkeyToAddress(privKey.PublicKey).Hex() + ":" + hexutil.Encode(sig) +``` + + + + diff --git a/docs/flashbots-protect/overview.mdx b/docs/flashbots-protect/overview.mdx index b75a74e9c..a04126b90 100644 --- a/docs/flashbots-protect/overview.mdx +++ b/docs/flashbots-protect/overview.mdx @@ -1,25 +1,32 @@ --- -title: Overview +title: MEV Protection Overview --- -import ProtectButtonSelector from "@site/src/components/ProtectButtonSelector"; + + MEV Protection - Block MEV With Flashbots Protect RPC + + -> **Privacy notice: Flashbots Protect RPC does not track** any kind of user information (i.e. IP, location, etc.). No user information is ever stored or even logged. +import ProtectButton from '@site/src/components/ProtectButton'; -Flashbots Protect is a user-friendly, secure, and powerful way to transact on Ethereum for both novices and sophisticated users. +Flashbots Protect is a cheaper and safer way to transact on Ethereum. It protects your transactions from frontrunning and gives you refunds on gas fees and MEV. -It has the following key benefits: +Key benefits: +- **Frontrunning protection:** Transactions are sent to a private Flashbots mempool where they will be hidden from frontrunning and sandwich bots. +- **Refunds**: If your transaction creates MEV, you can earn an [MEV refund](/flashbots-protect/mev-refunds). If your transaction pays high priority fees, you can earn [gas fee refunds](/flashbots-protect/gas-fee-refunds). +- **No failed transactions:** Transactions are only included in the block if they do not revert. Users do not pay fees for failed transactions. +- **Configurable:** You can customize your privacy, speed, and refund settings. -- **Configurable:** you can choose which builders to send to and your mev-share settings. -- **Frontrunning protection:** your transaction will not be seen by bots hungry to frontrun you in the public mempool. -- **Get backrunning MEV back**: if your transaction creates MEV in backrunning, you get up to 90% of it back through [MEV-Share](/flashbots-mev-share/introduction). -- **No failed transactions:** your transaction will only be included if it doesn't include any reverts, so you don't pay for failed transactions. +Use Flashbots Protect by clicking the button below or by sending `eth_sendRawTransaction` API requests to `rpc.flashbots.net/fast`. -You can use Flashbots Protect by clicking the button below, or by sending transactions using `eth_sendRawTransaction` to `rpc.flashbots.net` or the custom URL based on your advanced configuration below. - - +

-We want to thank MiningDAO, mistX and Nethermind for significant code contributions, testing, and being early adopters of Flashbots Protect. +We want to thank MiningDAO, mistX, and Nethermind for significant code contributions, testing, and being early adopters of Flashbots Protect. + +**Privacy notice: Flashbots Protect RPC does not track** user information (i.e. IP, location, etc.). No user information is stored or logged. diff --git a/docs/flashbots-protect/quick-start.mdx b/docs/flashbots-protect/quick-start.mdx index 56b240aad..9d2e87f45 100644 --- a/docs/flashbots-protect/quick-start.mdx +++ b/docs/flashbots-protect/quick-start.mdx @@ -1,38 +1,55 @@ --- -title: Quick start +title: Quick Start --- -import ProtectButtonSelector from "@site/src/components/ProtectButtonSelector"; +import ProtectButton from '@site/src/components/ProtectButton'; -## Key Considerations +### Key Considerations Flashbots Protect has the following key benefits: -- **Configurable:** you can choose which builders to send to and your mev-share settings. -- **Frontrunning protection:** your transaction will not be seen by hungry sandwich bots in the public mempool. -- **Get MEV back**: if your transaction creates MEV, you get up to 90% of it back through [MEV-Share](/flashbots-mev-share/introduction). -- **No failed transactions:** your transaction will only be included if it doesn't include any reverts, so you don't pay for failed transactions. + +- **Frontrunning protection:** Transactions are hidden from the public mempool away from front-running and sandwich bots. +- **Refunds**: If your transaction creates MEV, you can earn an [MEV refund](/flashbots-protect/mev-refunds). If your transaction pays high priority fees, you can earn [gas fee refunds](/flashbots-protect/gas-fee-refunds). +- **No failed transactions:** Transactions are only included in the block if they do not revert. Users do not pay fees for failed transactions. +- **Configurable:** You can customize your privacy, speed, and refund settings. ### Faster Transactions -You can speed up your transaction's inclusion by using Protect in fast mode. Click the "fast" option when [configuring your Protect RPC](/flashbots-protect/quick-start#using-flashbots-protect) or manually set your RPC to `rpc.flashbots.net/fast`. +Use Protect in fast mode to land your transactions faster on chain. Click the "fast" option when [configuring your Protect RPC](/flashbots-protect/quick-start#using-flashbots-protect) or manually set your RPC to `rpc.flashbots.net/fast`. + +Fast mode details: + +1. **Shared with all builders:** Transactions are multiplexed, or shared, with all [registered builders](https://github.com/flashbots/dowg/blob/main/builder-registrations.json) within one block after they are received. Multiplexing increases the probability that the transaction will be sent to the builder building the winning block. +2. **Larger validator payment:** With the default RPC, 10% of the MEV-Share refund is paid to validators. In fast mode, validators receive a higher percentage of the MEV-Share refund increasing the probability that the transaction will be included in the winning block. +3. **Shared with TEE searchers:** Full transaction information is also shared with searchers in TEEs (secure enviroments), leading to better MEV refunds while preserving frontrunning protection. + +**Note**: When you send your transaction to a builder, you trust them not to frontrun your transaction or disclose it to third-party MEV searchers. + +### Customer Support + +Wallets and applications can receive customer support for transactions tagged with their `originId`. To opt into customer support, update your RPC URL to `rpc.flashbots.net/fast?originId=[your-wallet-name]`. -Fast mode has 2 key differences from the default Protect experience: -1. **Shared with all builders:** By default, Protect transactions are only shared with the Flashbots Builder, which builds only a subset of all Ethereum blocks. In fast mode, transactions are shared with all [registered builders](https://github.com/flashbots/dowg/blob/main/builder-registrations.json) to increase the number of blocks the user's transaction can be included in. -2. **Larger refund paid to validator:** By default, only 10% of MEV-Share refunds are paid to validators. In fast mode, validators receive 50% of refunds which makes it more likely that the user’s transactions will be chosen in a given block. +:::warning Do Not Switch RPCs Before Transaction Confirmation -**Note**: When you send your transaction to a builder, you are entrusting them not to frontrun your transaction or disclose it to third parties who might. +If you submit a transaction through Flashbots Protect via the MetaMask wallet, do not switch RPCs before transaction confirmation. MetaMask may resend the transaction to the public mempool exposing your transaction to potential MEV attacks if RPCs are switched before transaction confirmation. + +::: + +### 0 Priority Fees + +Flashbots Protect does not accept transactions with a priority fee of 0. They will be dropped and a standard error message will be returned. ## Using Flashbots Protect There are three ways to use Flashbots Protect: -1. Add the Flashbots Protect RPC to your wallet. Most users will do this. +1. Add the Flashbots Protect RPC to your wallet. 2. Send transactions to the RPC URL using [eth_sendRawTransaction](https://docs.alchemy.com/reference/eth-sendrawtransaction). 3. Send transactions to Flashbots using [eth_sendPrivateTransaction](/flashbots-protect/additional-documentation/eth-sendPrivateTransaction). -Which way you integrate is up to you and your preferences. The most simple way to use Flashbots Protect is to add the Flashbots Protect RPC to your wallet. You can do so using the below button or by following the manual instructions below. **Note that you can configure the builders you send to and your MEV-Share hints as well**. +The easiest way to use Flashbots Protect is to add the Flashbots Protect RPC to your wallet. Use the button below to create a custom Protect RPC or follow the manual instructions. **Note that you can configure the builders you send to and your MEV-Share hints as well**. - + ## Adding Flashbots Protect RPC Manually @@ -43,24 +60,27 @@ You can also add Flashbots Protect RPC manually in MetaMask by following these s 3. Click “Add a network manually” and fill in the following information: - **Network Name:** Flashbots Protect -- **New RPC URL:** https://rpc.flashbots.net or the URL provided above based on your configuration +- **New RPC URL:** [https://rpc.flashbots.net/fast](https://rpc.flashbots.net/fast) or the URL provided above based on your configuration - **Chain ID:** 1 - **Currency Symbol:** ETH -- **Block Explorer URL:** https://etherscan.io/ +- **Block Explorer URL:** [https://etherscan.io/](https://etherscan.io/) 4. Click “Save.” 5. Click “Switch to Flashbots Protect” ![mm_rpc](/img/mm_rpc.png) -Flashbots Protect RPC for Goerli testnet can be added with these details: +Below is the list of Flashbots Protect RPCs we currently support across Ethereum mainnet and testnets: -- **Network Name:** Goerli Flashbots Protect -- **New RPC URL:** https://rpc-goerli.flashbots.net -- **Chain ID:** 5 -- **Currency Symbol:** ETH -- **Block Explorer URL**: https://goerli.etherscan.io/ +| Network | URL | +| ------- | ------------------------------------ | +| Mainnet | `https://rpc.flashbots.net/fast` | +| Sepolia | `https://rpc-sepolia.flashbots.net/` | ## Stuck transactions -If a transaction is "stuck" as pending then please see our [stuck transactions guide](/flashbots-protect/stuck_transactions). +Please see our [stuck transactions guide](/flashbots-protect/stuck_transactions) for help with dealing with transactions that are "stuck" as pending. + +## Proxy via Tor + +Protect RPC supports access through the Tor network, allowing users to maintain privacy and anonymity. To access through Tor, use http://protectfbnoqyfgo3t5ouw3c7odp55qqoxnfdd7u24nzz5pkbclbzzyd.onion instead of https://rpc.flashbots.net diff --git a/docs/flashbots-protect/ratelimiting.mdx b/docs/flashbots-protect/ratelimiting.mdx new file mode 100644 index 000000000..673facb98 --- /dev/null +++ b/docs/flashbots-protect/ratelimiting.mdx @@ -0,0 +1,28 @@ +--- +title: Rate Limits +--- + +In order to protect our services from abuse we have rate limits on the number of requests that can be made. Currently, the rate limits are set as follows. + +## `rpc.flashbots.net` - Flashbots Protect RPC + +| Method | Limit | +|--------------------------------------------|-------------------| +| `eth_sendRawTransaction` | None | +| `eth_call` | 200 / IP / 5 min | +| `eth_getTransactionReceipt` | 200 / IP / 5 min | +| `eth_getTransactionByBlockNumberAndIndex` | 200 / IP / 5 min | +| `eth_getBalance` | 200 / IP / 5 min | +| All others | 600 / IP / 5 min | + +Note that you are not required to read JSON RPC requests to send transactions to Flashbots Protect RPC. + +Relay rate limits for advanced user bundles sent to `relay.flashbots.net` [can be found here](../flashbots-mev-share/searchers/ratelimiting). + +## Rate limiting exceptions + +If you are a wallet or application integrating with protect and you require a higher rate limit please reach out to [Shea Ketsdever](https://twitter.com/SheaKetsdever). + +## Batch request support + +Flashbots Protect RPC is not supporting batch JSON-RPC requests. diff --git a/docs/flashbots-protect/settings-guide.md b/docs/flashbots-protect/settings-guide.md new file mode 100644 index 000000000..a5179c102 --- /dev/null +++ b/docs/flashbots-protect/settings-guide.md @@ -0,0 +1,154 @@ +--- +title: Settings Guide +--- + +import HintsTable from '../specs/mev-share/HintsTable'; +import Builders from '../specs/mev-share/_builders.mdx'; + +The Protect RPC uses query parameters and URL paths to convey your preferences. These parameters indicate which builders to share your transaction with, how potential refunds should be distributed, when to send transactions to the mempool, and other features. + +### Default + +```url +https://rpc.flashbots.net +``` + +By default, Flashbots Protect uses the following settings: +- Transactions are only forwarded to the Flashbots block builder +- Transactions are retried for 25 blocks and dropped if they do not land on chain within this time +- The `hash` and `default_logs` [hints](/flashbots-protect/settings-guide#hints) are shared with MEV-Share searchers +- 90% of MEV refunds are sent to `tx.origin` (the remaining 10% is sent to the validator) +- 100% of gas fee refunds are sent to `tx.origin` +- 0 priority fee transactions are not included on chain +- Reverted transactions are not included on chain + +This may change as the configuration is tuned to maximize benefits. + +### Fast + +Speed up your transactions by using fast mode. + +```url +https://rpc.flashbots.net/fast +``` + +Compared with the default configuration: +- Transactions are shared with all [registered builders](https://github.com/flashbots/dowg/blob/main/builder-registrations.json) +- Validators receive a higher percentage of the MEV-Share refund increasing the probability that the transaction will be included in the winning block. +- Full transaction information (without signatures) is shared with searchers inside TEEs to increase MEV refunds while preserving frontrunning protection. Searchers not in TEEs will receive only the hints specified. TEE searchers will be able to see full transaction information (even for failed or reverted transactions) after a 5-minute delay for troubleshooting and debugging purposes. + +### Hints + +Change what transaction data is visible to MEV-Share searchers with the `hint` query parameter. The [default](/flashbots-protect/settings-guide#default) hint configuration will be used if no hints are provided. If you specify one or more hints, any hint that is _not_ included will be disabled. If fast mode is used, searchers not in TEEs will only receive the hints specified while TEE searchers will receive all hints regardless of specification. + + + +Here is an example: + +```url +https://rpc.flashbots.net?hint=contract_address&hint=logs +``` + +This configuration shares the contract address and logs with searchers. It does not share the calldata or function selector. + +### Builders + +Designate which builders will receive your transaction with the `builder` query parameter. This parameter can be repeated multiple times to include different builders. The builders listed below are currently supported. + +Note that all transactions are shared with the Flashbots block builder, even if it is not explicitly specified. + + + +It's important to understand that while adding more builders can increase your transaction inclusion rate, it also requires you to place trust in those builders. Here's an example of how to utilize the `builder` parameter: + +```url +https://rpc.flashbots.net?builder=ABC&builder=XYZ +``` + +This configuration sends your transaction to ABC block builder, XYZ block builder, and the Flashbots block builder. + +### Refunds + +Tailor your refund settings using the `refund` query parameter. This determines how MEV and gas fee refunds will be distributed across different addresses. If not specified, the transaction originator (tx.origin) will receive all refunds. + +The refund parameter contains two colon-separated values: an address for the refund and the percentage of the payment that should be refunded to that address. + +Here is an example of a refund parameter that sends 10% of refunds to the address `recipientAddress`: + +```URL +https://rpc.flashbots.net?refund=recipientAddress:10 +``` + +#### MEV Refund Recipients + +MEV refunds can be split across multiple recipients. To distribute the payment across multiple addresses, append a new refund parameter for each address. + +The sum of all refund percentages must be less than 100. The remaining percentage, inferred from 100 - total refund percentages, is the payment to the validator. + +**Note**: Keeping a larger percentage of the refund may result in longer block inclusion times as it reduces the payment to the validator. + +#### Gas Fee Refund Recipients + +Gas fee refunds can only be sent to a single recipient. If multiple addresses are specified, the first refund address listed will receive 100% of the gas fee refund. There is no additional payment split with the validator. + +### Mempool Configuration + +Send certain transactions to the public mempool to improve the likelihood of inclusion by including the `useMempool` query parameter. If either of the following conditions are true, Flashbots will send all pending transactions with this parameter to the public mempool: +1. The Ethereum validator responsible for proposing the next block does not run [MEV-Boost](/flashbots-mev-boost/introduction). Approximately 10% of Ethereum blocks do not include any private transactions. Sending your transaction to the public mempool will give you access to those blocks at the expense of privacy and MEV refunds. +2. The transaction has not been included for 25 blocks: Some transactions pay very low priority fees are unlikely to land within 25 blocks. Send them to the public mempool to allow them to wait for lower gas prices. + +To enable this feature, add the `useMempool` parameter to your Protect RPC URL: + +```url +https://rpc.flashbots.net?useMempool=true +``` + +For analytics or other purposes, you can also specify a custom mempool URL by adding the `mempoolRpc` parameter: + +```url +https://rpc.flashbots.net?useMempool=true&mempoolRpc=https://your-custom-node-url +``` + +Note: If this setting is enabled, all cancellations will be immediately forwarded to the public mempool, regardless of if the transaction itself has been made public. + +### Reverted Transactions + +Allow reverted transactions by including the `canRevert` query parameter in your request. By default, Flashbots Protect does not land reverted transactions on chain to save users gas fees. You can override this feature to receive faster feedback about failing transactions. + +```url +https://rpc.flashbots.net?canRevert=true +``` + +### Block range + +By default we try to land transactions in the next 25 blocks. You can change this range by including the `blockRange` query parameter in your request. + +```url +https://rpc.flashbots.net?blockRange=10 +``` + +### Bundle Mode + +Use the Protect PRC in bundle mode to interactively construct a bundle of transactions that you want to be land together. This setting is typically used for whitehat rescues and you can find the complete documentation in the [Flashbots API docs](https://docs.flashbots.net/flashbots-protect/additional-documentation/bundle-cache). + +Bundle mode has a few differences from the regular Protect experience: +- Protect will not immediately attempt to land transactions sent in bundle mode. Instead, new transactions will be queued and kept in a pending state. +- To send all pending transactions as a bundle, you must make a separate API request to Flashbots. +- Querying the balance of an address in bundle mode will return a fake balance of 100 ETH. + +### Custom Read RPC + +Use a custom RPC endpoint for **read** requests by including the `url` query parameter in your request. **Write** requests (eg. `eth_sendRawTransaction`) will still be sent to the Protect RPC. This feature is recommended for wallets and applications with large volumes of read requests. + +```url +https://rpc.flashbots.net?url=http://RPC-ENDPOINT.COM +``` + +### Auction timeout + +If `auctionTimeout=T`, where `T` is the time in milliseconds, is specified, and a transaction arrives within `T` milliseconds of the end of the current slot, it will be scheduled for the next slot. +This ensures the transaction is processed at the beginning of the next slot, giving searchers the full slot duration to submit their bundles and backruns. + +``` +https://rpc.flashbots.net?auctionTimeout=3000 +``` diff --git a/docs/flashbots-protect/stuck_transactions.md b/docs/flashbots-protect/stuck_transactions.md index b03a76f86..e4f160b84 100644 --- a/docs/flashbots-protect/stuck_transactions.md +++ b/docs/flashbots-protect/stuck_transactions.md @@ -2,7 +2,9 @@ title: Fixing Stuck Transactions --- -In the case that your transaction is stuck in a "pending" state or you have an extremely high nonce, you will need to clear activity and nonce data in your MetaMask. This will cause it to update the nonce and transaction history from the network. Your funds and keys are safe during this process. +If your transaction is stuck in a "pending" state or you have an extremely high nonce, you should clear your activity and nonce data in your MetaMask. This will cause Metamask to update the nonce and transaction history from the network. + +**Note**: Your funds and keys are safe during this process. To reset your MetaMask account, follow these steps: diff --git a/docs/guide-send-tx-bundle.mdx b/docs/guide-send-tx-bundle.mdx new file mode 100644 index 000000000..550d113df --- /dev/null +++ b/docs/guide-send-tx-bundle.mdx @@ -0,0 +1,37 @@ +--- +title: Sending Tx and Bundles +--- + +Flashbots provides a variety of methods for submitting transactions and bundles. This guide is designed to help you understand these options and select the one that best fits your needs. + +## Understanding Relay and RPC Endpoints + +Flashbots offers two primary JSON-RPC endpoints on Ethereum Mainnet: `rpc.flashbots.net` and `relay.flashbots.net`. + +### `rpc.flashbots.net` - For Retail Users +- **Purpose**: Designed specifically for retail users as a drop-in RPC replacement in their wallet. +- **Features**: Provides MEV protection and MEV refunds for eligible transactions. Support all the regular [Ethereum JSON RPC methods](https://docs.infura.io/networks/ethereum/json-rpc-methods/) but not [Flashbots specific JSON RPC +methods](flashbots-auction/advanced/rpc-endpoint). +- **Note**: Transactions are submitted through `eth_sendRawTransaction` to fit wallet RPC interface. Underneath, the endpoint uses `relay.flashbots.net` to submit transactions. + +### `relay.flashbots.net` - For Advanced Users +- **Purpose**: Designed for advanced users, including searchers, applications, and Telegram bots. It accepts both transactions and bundles. +- **Features**: Support all [Flashbots specific JSON RPC methods](flashbots-auction/advanced/rpc-endpoint). Does not support regular [Ethereum JSON RPC methods](https://docs.infura.io/networks/ethereum/json-rpc-methods/). +- **Recommendation**: Ideal for activities beyond simple transaction submissions via wallets. + +## Choosing the Right JSON-RPC Method + +With `relay.flashbots.net` identified as the go-to for advanced operations, the choice of JSON-RPC methods is as follows: + +- **For Single Transactions**: Use `eth_sendPrivateTransaction`. +- **For Bundles of Transactions**: + - **Use**: `mev_sendBundle` for more flexibility and power, like leveraging the [new bundle format](flashbots-mev-share/searchers/understanding-bundles) and [MEV-Share](flashbots-mev-share/introduction). + - **Use**: `eth_sendBundle` if you want something simple and quick! The OG way of sending bundles. + - Both bundle APIs support [multiplexing to multiple builders](flashbots-auction/advanced/multiplexing). + +## Rate Limits + +In order to protect our services from abuse we have rate limits on the number of requests that can be made. + +- [RPC rate limits for retail user transactions sent to](flashbots-protect/ratelimiting) `rpc.flashbots.net` +- [Relay rate limits for advanced user bundles sent to](flashbots-mev-share/searchers/ratelimiting) `relay.flashbots.net` diff --git a/docs/joining-flashbots.mdx b/docs/joining-flashbots.mdx index 281979ed4..515abc90a 100644 --- a/docs/joining-flashbots.mdx +++ b/docs/joining-flashbots.mdx @@ -5,7 +5,7 @@ title: Join Flashbots ### Interested in joining Flashbots? If you are a self-directed individual who puts collective success above your own and are motivated by solving hard problems with asymmetric impact, you will fit right in. -* [Open job positions](https://boards.greenhouse.io/flashbots) - full-time roles we're actively recruiting for. +* [Open job positions](https://www.flashbots.net/jobs) - full-time roles we're actively recruiting for. * [Flashbots research fellowship](https://github.com/flashbots/mev-research/blob/main/grants.md) - we issue research grants to flashbots research proposals submitters. Find out more in our research repo. * Flashbots part-time contractor - become a part-time contractor in Flashbots and join one of our ongoing projects. Reach out to the team to learn more! * Nothing fits in the above? reach out at jobs@flashbots.net diff --git a/docs/policies/terms-of-service.mdx b/docs/policies/terms-of-service.mdx index efef79ebf..f6dc398af 100644 --- a/docs/policies/terms-of-service.mdx +++ b/docs/policies/terms-of-service.mdx @@ -79,7 +79,7 @@ FLASHBOTS hereby grants You a single, revocable, non-exclusive, non-transferable ### LICENSE GRANT TO FLASHBOTS -Unless otherwise agreed upon by You and FLASHBOTS, Your transaction, transaction bundle, or blocks of transactions (Your “Protected Data”) will be treated as proprietary and confidential to the extent not published to a public blockchain or other public record by virtue of the operation of such networks. You hereby grant FLASHBOTS a limited, non-exclusive license to use, adapt, or reproduce Your Protected Data for purely internal purposes, such as improvement of the Flashbots Service; as part of an anonymized, aggregated data set, or otherwise consistent with the purposes for which such information was disclosed to FLASHBOTS. +Unless otherwise agreed upon by You and FLASHBOTS, Your transaction, transaction bundle, or blocks of transactions (Your “Protected Data”) will be treated as proprietary and confidential to the extent not published to a public blockchain or other public record by virtue of the operation of such networks. You hereby grant FLASHBOTS a limited, non-exclusive license to use, adapt, or reproduce Your Protected Data for purely internal purposes, such as improvement of the Flashbots Service; as part of an anonymized, aggregated data set; to derive and publish system performance metrics and logs; or otherwise consistent with the purposes for which such information was disclosed to FLASHBOTS. ### TAXES & FEES @@ -93,7 +93,7 @@ You alone assume the sole responsibility of evaluating the merits and risks asso ### CERTAIN INFORMATION MADE AVAILABLE BY FLASHBOTS -FLASHBOTS may make available to You certain public data and other information (including, without limitation, information derived from public blockchain records), including information that we obtain from our agents, including but not limited to partners, vendors, and infrastructure providers. FLASHBOTS makes this information available to You as a service for Your convenience; the Flashbots Parties neither endorse nor approve any such information. The Flashbots Parties neither (1) guarantee the accuracy, timeliness, or completeness of any such information, nor (2) warrant any results from Your use or reliance on such information. You agree that You use any such information at Your own risk. +FLASHBOTS may make available to You certain public data and other information (including, without limitation, information derived from public blockchain records, system logs, and other operational metrics), including information that we obtain from our agents, including but not limited to partners, vendors, and infrastructure providers. FLASHBOTS makes this information available to You as a service for Your convenience; the Flashbots Parties neither endorse nor approve any such information. The Flashbots Parties neither (1) guarantee the accuracy, timeliness, or completeness of any such information, nor (2) warrant any results from Your use or reliance on such information. You agree that You use any such information at Your own risk. ### DISCLAIMER diff --git a/docs/sidebars.js b/docs/sidebars.js index 2b0dd03d4..d4be5831d 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -8,7 +8,7 @@ module.exports = { docs: [ { "Welcome": [ - 'welcome', 'new-to-mev', 'code-of-conduct' + 'welcome', 'new-to-mev', 'code-of-conduct', 'guide-send-tx-bundle' ], }, { @@ -29,17 +29,20 @@ module.exports = { 'flashbots-auction/libraries/ethers-js-provider', 'flashbots-auction/libraries/web3py-provider', 'flashbots-auction/libraries/alchemyprovider', + 'flashbots-auction/libraries/rust-provider', ], "Advanced Concepts": [ 'flashbots-auction/advanced/understanding-bundles', + 'flashbots-auction/advanced/multiplexing', + 'flashbots-auction/advanced/gas-fee-refunds', 'flashbots-auction/advanced/coinbase-payment', 'flashbots-auction/advanced/bundle-pricing', - 'flashbots-auction/advanced/rpc-endpoint', 'flashbots-auction/advanced/reputation', 'flashbots-auction/advanced/testnets', 'flashbots-auction/advanced/eip1559', 'flashbots-auction/advanced/troubleshooting', 'flashbots-auction/advanced/bundle-cancellations', + 'flashbots-auction/advanced/co-locate', ], }, 'flashbots-auction/faq', @@ -50,42 +53,21 @@ module.exports = { "Flashbots Protect": [ 'flashbots-protect/overview', 'flashbots-protect/quick-start', - 'flashbots-protect/mev-share', + 'flashbots-protect/mev-refunds', + 'flashbots-protect/gas-fee-refunds', + 'flashbots-protect/settings-guide', 'flashbots-protect/cancellations', + 'flashbots-protect/nonce-management', 'flashbots-protect/stuck_transactions', + 'flashbots-protect/large-transactions', + 'flashbots-protect/ratelimiting', { 'Additional Documentation': [ 'flashbots-protect/additional-documentation/eth-sendPrivateTransaction', - 'flashbots-protect/additional-documentation/status-api', - 'flashbots-protect/additional-documentation/ratelimiting', - 'flashbots-protect/additional-documentation/bundle-cache', ], } ], }, - { - "Flashbots Data": [ - { - 'MEV-Inspect': [ - 'flashbots-data/mev-inspect-py/overview', - 'flashbots-data/mev-inspect-py/quick-start', - 'flashbots-data/mev-inspect-py/inspecting', - 'flashbots-data/mev-inspect-py/exploring', - { - "Data": [ - 'flashbots-data/mev-inspect-py/data/classified_traces', - 'flashbots-data/mev-inspect-py/data/transfers', - 'flashbots-data/mev-inspect-py/data/swaps', - 'flashbots-data/mev-inspect-py/data/arbitrages', - 'flashbots-data/mev-inspect-py/data/miner_payments', - ], - }, - ] - }, - 'flashbots-data/blockapi', - 'flashbots-data/dashboard', - ], - }, { "MEV-Boost": [ 'flashbots-mev-boost/introduction', @@ -113,7 +95,6 @@ module.exports = { 'flashbots-mev-boost/FAQ', 'flashbots-mev-boost/glossary', 'flashbots-mev-boost/resources', - 'flashbots-mev-boost/community-tools', ], }, { @@ -128,6 +109,7 @@ module.exports = { 'flashbots-mev-share/searchers/understanding-bundles', 'flashbots-mev-share/searchers/sending-bundles', 'flashbots-mev-share/searchers/debugging', + 'flashbots-mev-share/searchers/ratelimiting', { 'Tutorials': [ { @@ -188,6 +170,10 @@ module.exports = { href: 'https://status.flashbots.net/', label: 'Status', }, - 'policies/privacy','policies/terms-of-service', 'policies/prohibited-use-policy', + 'policies/privacy','policies/terms-of-service', 'policies/prohibited-use-policy', 'brand-assets', ], + api: [ + "flashbots-auction/advanced/rpc-endpoint", + "flashbots-protect/additional-documentation/status-api", + ] }; diff --git a/docs/specs/mev-share/HintsTable.jsx b/docs/specs/mev-share/HintsTable.jsx new file mode 100644 index 000000000..d5f334d14 --- /dev/null +++ b/docs/specs/mev-share/HintsTable.jsx @@ -0,0 +1,28 @@ +/** + * Copyright (c) Flashbots Ltd. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import hints from "./hints.json" + +export default function HintsTable() { + return ( + + + + + + + + + {hints.map((hint, index) => ( + + + + + ))} + +
HintDescription
{hint.name}{hint.description}
+ ); +} diff --git a/docs/specs/mev-share/_hints.mdx b/docs/specs/mev-share/_hints.mdx deleted file mode 100644 index 28d538efe..000000000 --- a/docs/specs/mev-share/_hints.mdx +++ /dev/null @@ -1,5 +0,0 @@ -import HintsTable from "./hintsTable.jsx" - -export default () => { - return () -} diff --git a/docs/specs/mev-share/_mev_sendBundle.mdx b/docs/specs/mev-share/_mev_sendBundle.mdx index 335f599fd..074ff91d1 100644 --- a/docs/specs/mev-share/_mev_sendBundle.mdx +++ b/docs/specs/mev-share/_mev_sendBundle.mdx @@ -39,7 +39,8 @@ "logs" | "function_selector" | "hash" | - "tx_hash" + "tx_hash" | + "full" >, builders?: Array, }, diff --git a/docs/specs/mev-share/_mev_simBundle.mdx b/docs/specs/mev-share/_mev_simBundle.mdx index adcb82669..67fc2c1e5 100644 --- a/docs/specs/mev-share/_mev_simBundle.mdx +++ b/docs/specs/mev-share/_mev_simBundle.mdx @@ -33,12 +33,22 @@ "logs" | "function_selector" | "hash" | - "tx_hash" + "tx_hash" | + "full" >, builders?: Array, }, metadata?: { originId?: string, + }, + simOptions?: { /* SimBundleOptions */ + parentBlock?: number | string, // Block used for simulation state. Defaults to latest block. + blockNumber?: number, // default = parentBlock.number + 1 + coinbase?: string, // default = parentBlock.coinbase + timestamp?: number, // default = parentBlock.timestamp + 12 + gasLimit?: number, // default = parentBlock.gasLimit + baseFee?: bigint, // default = parentBlock.baseFeePerGas + timeout?: number, // default = 5 (defined in seconds) } }] } diff --git a/docs/specs/mev-share/_streamEvent.mdx b/docs/specs/mev-share/_streamEvent.mdx index a90b2df0b..64fd4c1c4 100644 --- a/docs/specs/mev-share/_streamEvent.mdx +++ b/docs/specs/mev-share/_streamEvent.mdx @@ -1,3 +1,4 @@ + ```typescript { hash: string, @@ -7,16 +8,39 @@ callData?: string, functionSelector?: string, to?: string, + from?: string, + value?: string, + maxFeePerGas?: string, + maxPriorityFeePerGas?: string, + nonce?: string, + chainId?: string, + accessList?: Array<{ + address: string, + storageKeys: string[] + }>, + gas?: string, + type?: string }> } ``` | Param | Type Info | Description | |-|-|-| -| `hash` | Hex-string | Transaction hash. | +| `hash` | Hex-string | [Double-hashed](/flashbots-mev-share/searchers/event-stream#understanding-double-hash) transaction hash, or, bundle hash | | `logs` | Array of JSON-encoded events | Event logs emitted by executing the transaction. | | `txs` | Array of JSON objects | Transactions from the event. Will only be one if event is a transaction, otherwise event is a bundle. | `txs.hash` | Hex-string | Transaction hash. | | `txs.callData` | Hex-string | Calldata of the transaction. | | `txs.functionSelector` | Hex-string | 4-byte function selector. | | `txs.to` | Hex-string | Transaction recipient address. | +| `txs.from` | Hex-string | Transaction sender address. | +| `txs.value` | Hex-string | Value transferred in the transaction. | +| `txs.maxFeePerGas` | Hex-string | Maximum fee per gas of the transaction. GasFeeCap | +| `txs.maxPriorityFeePerGas` | Hex-string | Maximum priority fee per gas of the transaction. GasTipCap | +| `txs.nonce` | Hex-string | Nonce of the transaction. | +| `txs.chainId` | Hex-string | Chain ID of the transaction. | +| `txs.accessList` | Array of JSON objects | Access list of the transaction. | +| `txs.accessList.address` | Hex-string | Address in the access list. | +| `txs.accessList.storageKeys` | Array of hex-strings | Storage keys in the access list. | +| `txs.gas` | Hex-string | Gas limit of the transaction. | +| `txs.type` | Hex-string | Type of the transaction. | diff --git a/docs/specs/mev-share/hints.json b/docs/specs/mev-share/hints.json index 43f78d68d..7e41bd262 100644 --- a/docs/specs/mev-share/hints.json +++ b/docs/specs/mev-share/hints.json @@ -26,5 +26,9 @@ { "name": "tx_hash", "description": "Share individual tx hashes in the bundle." + }, + { + "name": "full", + "description": "Share all fields of individual txs except signature. This includes nonce, gas price, gas limit, to, from, value, data, and chainId." } ] diff --git a/docs/specs/mev-share/hintsTable.jsx b/docs/specs/mev-share/hintsTable.jsx deleted file mode 100644 index 81535cd74..000000000 --- a/docs/specs/mev-share/hintsTable.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from "react" -import hints from "./hints.json" - -export default () => { - return ( - - - - - {hints.map(hint => - - - )} -
HintDescription
{hint.name}{hint.description}
) -} diff --git a/docs/welcome.mdx b/docs/welcome.mdx index d5eb78a22..1eea52fb2 100644 --- a/docs/welcome.mdx +++ b/docs/welcome.mdx @@ -23,6 +23,8 @@ Flashbots is a research and development organization formed to mitigate the nega Discover how to capture MEV opportunities on Ethereum responsibly with Flashbots. - [Understanding Bundles](/flashbots-auction/advanced/understanding-bundles)
+- [Guide to Sending Transactions and Bundles on Flashbots](/guide-send-tx-bundle)
+- [Multiplexing](/flashbots-auction/advanced/multiplexing)
- [RPC Docs](/flashbots-auction/advanced/rpc-endpoint)
- [Client Libs](/flashbots-auction/libraries/ethers-js-provider)
- [Help & FAQs](https://collective.flashbots.net/tags/c/searchers/12/question) @@ -38,9 +40,9 @@ Link your wallet to Flashbots Protect to safeguard against frontrunning, benefit -Validators and builders, leverage MEV-Boost to access a competitive block-building market, fostering greater competition, decentralization, and censorship-resistance for Ethereum. +Leverage MEV-Boost to access a competitive block-building market, fostering greater competition, decentralization, and censorship-resistance for Ethereum. -- [Mev-Boost Docs](/flashbots-mev-boost/introduction)
+- [MEV-Boost Docs](/flashbots-mev-boost/introduction)
@@ -49,15 +51,15 @@ Validators and builders, leverage MEV-Boost to access a competitive block-buildi Our primary focus is to enable a permissionless, transparent, and sustainable ecosystem for MEV, via a three-pronged approach: -- Illuminate: bringing transparency to MEV activity. -- Democratize: democratizing access to MEV revenue. -- Distribute: enabling sustainable distribution of MEV revenue. +- **Illuminate**: bringing transparency to MEV activity, quantifying its impact, and reducing information asymmetry between participants. +- **Democratize**: democratizing access to MEV via open platforms that maximize competition and are freely available to all. +- **Distribute**: enabling sustainable distribution of any remaining MEV. Product & research are the semi-autonomous dual engines that propel our organization forward: -- [Flashbots Product](/) builds core infrastructure and ecosystem tooling that redefine the block production supply chain across blockchains. +- [Flashbots Product](/) builds core infrastructure and ecosystem tooling that redefine the block production supply chain across blockchains and protect users. - [Flashbots Research](https://github.com/flashbots/mev-research) explores MEV market dynamics and blockchain design challenges at the intersection of economics, security, and cryptography. -You can interact with Flashbots on [Discord](https://discord.gg/7hvTycdNcK), [Github](https://github.com/flashbots/pm), and our [Discourse forum](https://collective.flashbots.net/). We have dedicated channels on Discord for each of our efforts and welcome your contributions. Our work is open source and you can follow our progress in each Github repository of the Flashbots organization. +You can interact with Flashbots via our [Forum](https://collective.flashbots.net/) where we have dedicated categories for each of our efforts and welcome your contributions. Our work is open source and you can follow our progress under each [Github](https://github.com/flashbots/pm) repository of the Flashbots organization. -[Mission](https://writings.flashbots.net/frontrunning-mev-crisis) | [Discord](https://discord.gg/7hvTycdNcK) | [Discourse Forum](https://collective.flashbots.net/) | [Blog](https://writings.flashbots.net) | [Github](https://github.com/flashbots/pm) | [Transparency Reports](https://writings.flashbots.net/tags/transparency-report) | [Status](https://status.flashbots.net) +[Mission](https://writings.flashbots.net/frontrunning-mev-crisis) | [Forum](https://collective.flashbots.net/) | [Writings](https://writings.flashbots.net) | [GitHub](https://github.com/flashbots/pm) | [Discord](https://discord.gg/7hvTycdNcK) | [Status](https://status.flashbots.net) diff --git a/docs/whitehat.mdx b/docs/whitehat.mdx index 9e3efa535..b77c93147 100644 --- a/docs/whitehat.mdx +++ b/docs/whitehat.mdx @@ -8,5 +8,5 @@ Please go to https://whitehat.flashbots.net (and only to this address) to submit Ensure you only interact with [Flashbots Discord](https://discord.gg/flashbots) members with the "whitehat", "whitehat-associate", or "serv.eth" role. -We can only attempt to rescue remaining funds, we won't be able to get back funds that have already been transfered out from the address. +We can only attempt to rescue remaining funds, we won't be able to get back funds that have already been transferred out from the address. Please note that the Whitehat team can only assist if remaining assets in the compromised address exceed the minimum rescue amount of $1000. diff --git a/docusaurus.config.js b/docusaurus.config.js index 73685ba5a..e65c1e82f 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -7,6 +7,8 @@ require('dotenv').config() const { themes: { github: lightCodeTheme } } = require('prism-react-renderer'); const { themes: { dracula: darkCodeTheme } } = require('prism-react-renderer'); +const tailwindcss = require('tailwindcss'); +const autoprefixer = require('autoprefixer'); /** @returns {Promise} */ module.exports = async function createConfigAsync() { @@ -49,12 +51,24 @@ module.exports = async function createConfigAsync() { } }, navbar: { - title: 'Flashbots Docs', + title: 'Flashbots', logo: { alt: 'Flashbots Logo', src: 'img/logo.png', }, items: [ + { + type: 'docSidebar', + label: 'Docs', + sidebarId: 'docs', + position: 'left', + }, + { + type: 'docSidebar', + label: 'API', + sidebarId: 'api', + position: 'left', + }, { href: 'https://github.com/flashbots/docs', label: 'GitHub', @@ -76,19 +90,31 @@ module.exports = async function createConfigAsync() { routeBasePath: '/', editUrl: 'https://github.com/flashbots/flashbots-docs/edit/main/', - showLastUpdateAuthor: true, showLastUpdateTime: true, remarkPlugins: [(await import('remark-math')).default], rehypePlugins: [(await import('rehype-katex')).default], }, theme: { - customCss: require.resolve("./src/scss/custom.scss") + customCss: require.resolve('./src/css/custom.css'), }, }), ], ], plugins: [ - 'docusaurus-plugin-sass', + // eslint-disable-next-line @typescript-eslint/no-unused-vars + async function tailwindcssSupport(context, options) { + return { + name: "docusaurus-tailwindcss", + configurePostCss(postcssOptions) { + // Appends TailwindCSS and AutoPrefixer. + postcssOptions.plugins.push('tailwindcss/nesting') + postcssOptions.plugins.push(tailwindcss); + postcssOptions.plugins.push(autoprefixer); + return postcssOptions; + }, + }; + }, + 'docusaurus-plugin-sass' ], } } diff --git a/package.json b/package.json index dec5d2a02..898b85bfc 100644 --- a/package.json +++ b/package.json @@ -21,27 +21,34 @@ }, "dependencies": { "@algolia/client-search": "^4.20.0", - "@docusaurus/core": "^3.0.0-beta.0", - "@docusaurus/plugin-content-docs": "^3.0.0-beta.0", - "@docusaurus/plugin-sitemap": "^3.0.0-beta.0", - "@docusaurus/preset-classic": "^3.0.0-beta.0", - "@docusaurus/utils": "^3.0.0-beta.0", - "@docusaurus/utils-common": "^3.0.0-beta.0", - "@mdx-js/react": "^2.3.0", + "@docusaurus/core": "^3.0.0", + "@docusaurus/plugin-content-docs": "^3.0.0", + "@docusaurus/plugin-sitemap": "^3.0.0", + "@docusaurus/preset-classic": "^3.0.0", + "@docusaurus/utils": "^3.0.0", + "@docusaurus/utils-common": "^3.0.0", + "@mdx-js/react": "^3.0.0", + "@radix-ui/react-switch": "^1.0.3", "@vercel/analytics": "^0.1.11", - "axios": "^1.4.0", + "autoprefixer": "^10.4.16", + "axios": "^1.6.0", + "change-case": "^5.1.2", "clsx": "^1.1.1", - "docusaurus-plugin-sass": "^0.2.1", + "docusaurus-plugin-sass": "^0.2.5", "dotenv": "^8.2.0", + "ethers": "^6.7.1", + "postcss": "^8.4.31", "prism-react-renderer": "^2.1.0", + "prop-types": "^15.8.1", "protect-button": "^0.4.6", "react": "^18.2.0", "react-dom": "^18.2.0", "react-loadable": "^5.5.0", - "rehype-katex": "^6.0.3", - "remark-math": "^5.1.1", - "sass": "^1.39.0", + "rehype-katex": "^7", + "remark-math": "^6", + "sass": "^1.69.5", "search-insights": "^2.8.3", + "tailwindcss": "^3.3.3", "webpack": "^5.88.1" }, "browserslist": { @@ -57,9 +64,10 @@ ] }, "devDependencies": { - "@docusaurus/eslint-plugin": "^3.0.0-beta.0", - "@docusaurus/module-type-aliases": "^3.0.0-beta.0", - "@docusaurus/tsconfig": "^3.0.0-beta.0", + "@docusaurus/eslint-plugin": "^3.0.0", + "@docusaurus/module-type-aliases": "^3.0.0", + "@docusaurus/tsconfig": "^3.0.0", + "@flashbots/mev-share-client": "^0.7.10", "@tsconfig/docusaurus": "^2.0.2", "@types/react": "^18.2.23", "@types/react-helmet": "^6.1.2", @@ -67,14 +75,14 @@ "@typescript-eslint/eslint-plugin": "^6.7.3", "@typescript-eslint/parser": "^6.7.3", "cspell": "^6.31.2", + "debug": "^4.3.4", "eslint": "^8.48.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-typescript": "^3.6.1", - "eslint-import-resolver-webpack": "^0.13.7", "eslint-plugin-header": "^3.1.1", - "eslint-plugin-import": "^2.28.1", + "eslint-plugin-import": "^2.29.0", "eslint-plugin-jest": "^27.4.2", "eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-mdx": "^2.2.0", @@ -83,11 +91,16 @@ "eslint-plugin-regexp": "^1.15.0", "lint-staged": "^13.2.3", "markdownlint-cli2": "^0.9.2", + "mocha": "^10.2.0", "prettier": "^3.0.2", "prettier-plugin-organize-imports": "^3.2.3", + "prettier-plugin-tailwindcss": "^0.5.6", "stylelint": "^14.16.1", "stylelint-config-prettier": "^9.0.5", "stylelint-config-standard": "^29.0.0", "typescript": "^5.2.2" + }, + "engines": { + "node": ">=22.18.0" } } diff --git a/project-words.txt b/project-words.txt index 35eb3e3b6..f58ef5390 100644 --- a/project-words.txt +++ b/project-words.txt @@ -1,8 +1,13 @@ camelcase dogfood +flashbot flashbots Flashbots hideable +Inpage katex +MMSDK rehype +SEPOLIA stylelint +tailwindcss diff --git a/src/components/AlignItems/AlignItems.tsx b/src/components/AlignItems/AlignItems.tsx deleted file mode 100644 index 6f71c9ad8..000000000 --- a/src/components/AlignItems/AlignItems.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import React, { Children, ReactElement, ReactNode, useMemo } from "react" -import styles from './styles.module.scss'; - -interface IAlignItems { - children: ReactNode | ReactNode[] - horizontal?: "left" | "center" | "right" | "space-evenly" | "space-between" - vertical?: "top" | "center" | "bottom" - direction?: "column" | "row" - sideMargin?: number -} - -const AlignItems = ({ - children, - horizontal = "center", - sideMargin = 0, - vertical = "center" - }: IAlignItems) => { - - const justifyContent = useMemo(() => { - switch (horizontal) { - case "left": - return "flex-start" - case "center": - return "center" - case "right": - return "flex-end" - case "space-between": - return "space-between" - case "space-evenly": - return "space-evenly" - default: - return "center" - } - }, [horizontal]) - - const alignItems = useMemo(() => { - switch (vertical) { - case "top": - return "flex-start" - case "center": - return "center" - case "bottom": - return "flex-end" - default: - return "center" - } - }, [vertical]) - - const margin = useMemo(() => { - return sideMargin ? `0 ${sideMargin}rem` : undefined - }, [sideMargin]) - - const correctChildren = useMemo(() => { - if (Children.count(children) === 1) { - let childrenParsed; - Children.toArray(children).map((child)=> { - if (!childrenParsed) { - childrenParsed = (child as ReactElement).props.children - } - }) - return childrenParsed - } else { - return children - } - }, [children, margin]) - - - return ( -
- { - correctChildren - } -
- ) -} - -export default AlignItems \ No newline at end of file diff --git a/src/components/AlignItems/styles.module.scss b/src/components/AlignItems/styles.module.scss deleted file mode 100644 index 6f5442d68..000000000 --- a/src/components/AlignItems/styles.module.scss +++ /dev/null @@ -1,8 +0,0 @@ -.root { - display: flex; - - & > * { - display: block; - margin: var(--align-items-margin) - } -} diff --git a/src/components/Banner/Banner.custom.module.scss b/src/components/Banner/Banner.custom.module.scss new file mode 100644 index 000000000..712a63ac1 --- /dev/null +++ b/src/components/Banner/Banner.custom.module.scss @@ -0,0 +1,21 @@ +@use '_base'; + +/* +Add custom CSS styling for your banner here + +You can add any classes you'd like based on the markup for your banner +The .banner class is already provided and apply to the parent element of +the banner. + +The '@extend %banner-structure' defines the structural properties for the +banner and should not be removed. +*/ + +.banner { + @extend %banner-structure; // Do not remove +} + + +[data-theme=dark] .banner { + @extend %banner-structure; // Do not remove +} diff --git a/src/components/Banner/Banner.module.scss b/src/components/Banner/Banner.module.scss new file mode 100644 index 000000000..fb95fa28f --- /dev/null +++ b/src/components/Banner/Banner.module.scss @@ -0,0 +1,12 @@ +@use 'base'; + +.banner { + @extend %banner-structure; + + background-color: var(--banner-background-color, var(--ifm-navbar-background-color)); + color: var(--banner-text-color, var(--ifm-font-color-base)); + + a { + color: var(--banner-text-color , var(--ifm-font-color-base)); + } +} diff --git a/src/components/Banner/Banner.tsx b/src/components/Banner/Banner.tsx new file mode 100644 index 000000000..ae51c7f16 --- /dev/null +++ b/src/components/Banner/Banner.tsx @@ -0,0 +1,82 @@ +/* Custom Banner Module +Use it to quickly deploy a simple banner to the Flashbots homepage + +To add a new banner all you need to do is edit the ./banner.config.tsx +file and set the applicable properties. No other work is necessary. + +You'll find more in-depth documentation there. +*/ + +import React from 'react' +import clsx from 'clsx' +import bannerConfig from './banner.config' +import customStyles from './Banner.custom.module.scss' +import bannerStyles from './Banner.module.scss' + +export interface BannerOptions { + bannerContent?: JSX.Element | string | null + backgroundColor: string + textColor: string + startDate: string | null + endDate: string | null + customBannerCSS: boolean +} + +class BannerConfigs { + options: BannerOptions + + constructor(options: BannerOptions) { + this.options = options + } + + // Sets the appropriate CSS rules for the element + // based on the `customCSS` option + getBannerStyle(): React.CSSProperties | null { + return !this.options.customBannerCSS + ? { + "--banner-text-color": this.options.textColor, + "--banner-background-color": this.options.backgroundColor + } + : null + } + + // Sets the appropriate class name for the element + // based on the `customCSS` option + getBannerClass(): string { + const styles = this.options.customBannerCSS ? customStyles : bannerStyles + + return clsx(styles.banner) + } + + // Determines whether the banner should appear based on: + // 1. Whether there is content to be shown + // 2. The start and end dates exist and are valid + shouldShowBanner(): boolean { + if (!this.options.bannerContent) { + return false + } + + const parsedStart = Date.parse(this.options.startDate) + const parsedEnd = Date.parse(this.options.endDate) + const currentDate = Date.now() + + return ( + (isNaN(parsedStart) || parsedStart <= currentDate) && + (isNaN(parsedEnd) || parsedEnd >= currentDate) + ) + } +} + +export default function Banner(): JSX.Element { + const configs = new BannerConfigs(bannerConfig) + + if (!configs.shouldShowBanner()) { + return null + } + + return ( +
+ {configs.options.bannerContent} +
+ ) +} diff --git a/src/components/Banner/_base.scss b/src/components/Banner/_base.scss new file mode 100644 index 000000000..615f14e85 --- /dev/null +++ b/src/components/Banner/_base.scss @@ -0,0 +1,19 @@ +%banner-structure { + height: fit-content; + padding: 0.5rem 2rem; + text-align: center; + line-height: 1.25; + + a{ + cursor: pointer; + text-decoration: none; + + &:hover { + text-decoration: underline; + } + } + + @media (max-width: 720px){ + padding: 0.5rem 2rem; + } +} diff --git a/src/components/Banner/banner.config.tsx b/src/components/Banner/banner.config.tsx new file mode 100644 index 000000000..7ace62ee8 --- /dev/null +++ b/src/components/Banner/banner.config.tsx @@ -0,0 +1,93 @@ +/* Custom Banner Module +Use it to quickly deploy a simple banner to the Flashbots homepage + +To add a new banner all you need to do is edit the properties below and set them +to your desired values. + +For simple banners with just a couple of colors - for copy and background - you +can use the properties here. But if the banner requires more sophisticated styling +you can override the color options by setting `customCSS: true` and adding your CSS +rules to ./Banner.custom.module.scss. + +There are detailed explanations for each property below, but here's a quick guide: + - bannerContent: What should appear inside the banner + - backgroundColor: Solid, single color for the banner + - textColor: Solid, single color for all the copy inside the banner + - startDate: When should the banner start appearing on the site + - endDate: When should the banner stop appearing on the site + - customCSS: Whether the banner should make use of custom CSS rules loaded from ./Banner.custom.module.scss +*/ + +import React from 'react' +import BannerOptions from './Banner' + +export const bannerConfig: BannerOptions = { + /* + bannerContent: The pure text or HTML markup to appear in the banner + - Banner won't appear when set to null + + Examples: + - bannerContent: null + - bannerContent: "Banner content!" + - bannerContent: (Banner content! Link) + */ + bannerContent: null, + + /* + backgroundColor: Single, solid background color for the banner + - Will default to the site's background when set to null + - Has no effect if customCSS is true + + Examples: + - backgroundColor: null + - backgroundColor: "#023047" + */ + backgroundColor: null, + + /* + textColor: Single, solid text color for the banner + - Will default to the site's text color when set to null + - Has no effect if customCSS is true + + Examples: + - textColor: null + - textColor: "#ffb703" + */ + textColor: null, + + /* + startDate: Date and time (UTC) when the banner should start appearing on the website + - When set to null a banner will always appear, provided there is content to be shown + and the endDate, if there is one, hasn't been reached + Format: "YYYY-MM-DD HH:mmZ" + + Examples: + - startDate: null + - startDate: "2001-09-14 16:00Z" + */ + startDate: null, + + /* + endDate: Date and time (UTC) when the banner should stop appearing on the website + - When set to null a banner will always appear, provided there is content to be shown + and the startDate, if there is one, has been reached + Format: "YYYY-MM-DD HH:mmZ" + + Examples: + - endDate: null + - endDate: "2007-02-01 00:00Z" + */ + endDate: null, + + /* + customCSS: Determines whether to use a custom CSS instead instead of the color options + - Custom CSS must be set in ./Banner.custom.module.scss + - Will completely bypass backgroundColor and textColor if set to true + + Examples: + - customCSS: true + */ + customBannerCSS: false +} + +export default bannerConfig diff --git a/src/components/BrandAssets/AssetCard.tsx b/src/components/BrandAssets/AssetCard.tsx new file mode 100644 index 000000000..a9857b815 --- /dev/null +++ b/src/components/BrandAssets/AssetCard.tsx @@ -0,0 +1,31 @@ +/** + * Copyright (c) Flashbots Ltd. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import React, { ReactNode } from "react" +import styles from './styles.module.css'; +import Download from "./Download"; + +interface IAssetCard { + title?: string + cover?: string + svg?: string + png?: string +} + +function AssetCard({ title, cover, svg, png }: IAssetCard) { + return ( +
+ +
+

{ title }

+ + +
+
+ ) +} + +export default AssetCard diff --git a/src/components/BrandAssets/Download.tsx b/src/components/BrandAssets/Download.tsx new file mode 100644 index 000000000..4d1ad66c2 --- /dev/null +++ b/src/components/BrandAssets/Download.tsx @@ -0,0 +1,25 @@ +/** + * Copyright (c) Flashbots Ltd. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import React, { ReactNode } from "react" + +interface IDownload { + file?: string +} + +function Download({ file, type }: IDownload) { + return ( + + + + + + { type } + + ) +} + +export default Download diff --git a/src/components/BrandAssets/index.tsx b/src/components/BrandAssets/index.tsx new file mode 100644 index 000000000..7dd9b3e2b --- /dev/null +++ b/src/components/BrandAssets/index.tsx @@ -0,0 +1,41 @@ +/** + * Copyright (c) Flashbots Ltd. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import {useState} from 'react'; +import AssetCard from './AssetCard'; + +export default function BrandAssets() { + + return ( +
+
+ + +
+ +
+ +
+
+ +
+ ); +} diff --git a/src/components/BrandAssets/styles.module.css b/src/components/BrandAssets/styles.module.css new file mode 100644 index 000000000..d0f35e417 --- /dev/null +++ b/src/components/BrandAssets/styles.module.css @@ -0,0 +1,6 @@ +.root { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(clamp(100px,(1024px - 100vw) *1000, 100%), 1fr)); + gap: 1rem; + margin-bottom: 2rem; +} diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx deleted file mode 100644 index 912adbb93..000000000 --- a/src/components/Button/Button.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { useHistory } from "@docusaurus/router"; -import React, { ReactNode, useCallback } from "react" -import styles from './styles.module.scss'; - -interface IButton { - children: ReactNode | ReactNode[] - href?: string - action?: () => void - inline?: boolean -} - -const Button = ({ children, href, action, inline = false }: IButton) => { - const history = useHistory() - const onClick = useCallback(() => { - action && action() - if (href) { - if (href.includes("http://") || href.includes("https://")) { - let a = document.createElement('a'); - a.target = '_blank'; - a.href= href; - a.click(); - } else { - history.push(href) - } - } - }, [href, action]); - - return inline ? () : ( -
- -
- ) -} - -export default Button \ No newline at end of file diff --git a/src/components/Button/styles.module.scss b/src/components/Button/styles.module.scss deleted file mode 100644 index 3c4d4ea00..000000000 --- a/src/components/Button/styles.module.scss +++ /dev/null @@ -1,8 +0,0 @@ -.root { - text-align: center; -} - -.wrapper { - display: flex; - justify-content: center; -} diff --git a/src/components/CenterText/CenterText.tsx b/src/components/CenterText/CenterText.tsx deleted file mode 100644 index f47f13c1d..000000000 --- a/src/components/CenterText/CenterText.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React, { ReactNode } from "react" -import styles from './styles.module.scss'; - -interface ICenterText { - children: ReactNode | ReactNode[] -} - -const CenterText = ({ children }: ICenterText) => { - - return ( - {children} - ) -} - -export default CenterText \ No newline at end of file diff --git a/src/components/CenterText/styles.module.scss b/src/components/CenterText/styles.module.scss deleted file mode 100644 index b59fba603..000000000 --- a/src/components/CenterText/styles.module.scss +++ /dev/null @@ -1,3 +0,0 @@ -.root { - text-align: center; -} \ No newline at end of file diff --git a/src/components/Checkbox/index.tsx b/src/components/Checkbox/index.tsx index 2647cb0c8..6255cf492 100644 --- a/src/components/Checkbox/index.tsx +++ b/src/components/Checkbox/index.tsx @@ -1,27 +1,44 @@ -import React from "react" -import styles from './styles.module.scss' +/** + * Copyright (c) Flashbots Ltd. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ -const Checkbox = ( - { label, id, checked, onChange, disabled, arrangement, orientation }: - { - disabled?: boolean, - label: string, - id: string, - arrangement?: "vertical" | "horizontal", - orientation?: "first" | "last", - checked: boolean, - onChange: (val: boolean) => void - } -) => { - const elements = [ - , - { - onChange(e.target.checked) - }} /> - ] - return
- {orientation === "last" ? elements : elements.reverse()} +function Checkbox({ + label, + checked, + onChange, + disabled = false, +}: { + label: string; + checked: boolean; + onChange: (val: boolean) => void; + disabled: boolean; +}) { + const elements = [ + { + onChange(e.target.checked); + }} + />, + , + ]; + return ( +
+ {elements}
+ ); } -export default Checkbox +export default Checkbox; diff --git a/src/components/Checkbox/styles.module.scss b/src/components/Checkbox/styles.module.scss deleted file mode 100644 index 6f6d5cb50..000000000 --- a/src/components/Checkbox/styles.module.scss +++ /dev/null @@ -1,4 +0,0 @@ -.checkboxContext { - padding: 4px; - padding-right: 16px; -} diff --git a/src/components/Grid/Grid.tsx b/src/components/Grid/Grid.tsx index db676cdc2..c43a6ee5a 100644 --- a/src/components/Grid/Grid.tsx +++ b/src/components/Grid/Grid.tsx @@ -1,15 +1,21 @@ -import React, { ReactNode } from "react" -import styles from './styles.module.scss'; +/** + * Copyright (c) Flashbots Ltd. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import { ReactNode } from "react" +import styles from './styles.module.css'; interface IGrid { children: ReactNode | ReactNode[] } -const Grid = ({ children }: IGrid) => { +function Grid({ children }: IGrid) { return (
{ children }
) } -export default Grid \ No newline at end of file +export default Grid diff --git a/src/components/Grid/styles.module.css b/src/components/Grid/styles.module.css new file mode 100644 index 000000000..d0f35e417 --- /dev/null +++ b/src/components/Grid/styles.module.css @@ -0,0 +1,6 @@ +.root { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(clamp(100px,(1024px - 100vw) *1000, 100%), 1fr)); + gap: 1rem; + margin-bottom: 2rem; +} diff --git a/src/components/Grid/styles.module.scss b/src/components/Grid/styles.module.scss deleted file mode 100644 index 8bde4b64d..000000000 --- a/src/components/Grid/styles.module.scss +++ /dev/null @@ -1,7 +0,0 @@ -// https://stackoverflow.com/questions/65782044/without-media-queries-how-to-achieve-3-column-desktop-to-1-column-mobile-layout -.root { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(clamp(100px,(1024px - 100vw)*1000, 100%), 1fr)); - gap: 1rem; - margin-bottom: 2rem; -} \ No newline at end of file diff --git a/src/components/GridBlock/GridBlock.tsx b/src/components/GridBlock/GridBlock.tsx index 2dc4a8b70..2f705fb11 100644 --- a/src/components/GridBlock/GridBlock.tsx +++ b/src/components/GridBlock/GridBlock.tsx @@ -1,17 +1,23 @@ -import React, { ReactNode } from "react" -import styles from './styles.module.scss'; +/** + * Copyright (c) Flashbots Ltd. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import { ReactNode } from "react" +import styles from './styles.module.css'; interface IGridBlock { children: ReactNode | ReactNode[] - symbol?: string - title?: string + symbol: string + title: string } -const GridBlock = ({ children, symbol, title }: IGridBlock) => { +function GridBlock({ children, symbol, title }: IGridBlock) { return (
-
-
+
+
@@ -36,4 +42,4 @@ const GridBlock = ({ children, symbol, title }: IGridBlock) => {
) } -export default GridBlock \ No newline at end of file +export default GridBlock diff --git a/src/components/GridBlock/styles.module.css b/src/components/GridBlock/styles.module.css new file mode 100644 index 000000000..d65c8db75 --- /dev/null +++ b/src/components/GridBlock/styles.module.css @@ -0,0 +1,85 @@ +.root { + position: relative; + padding: 2rem 1rem 1.5rem; +} + +.background { + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + z-index: -1; +} + +.background > *:first-child { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: calc((100% - 25px) + 1px); + border-top: 1px solid var(--ifm-color-emphasis-200); + border-left: 1px solid var(--ifm-color-emphasis-200); + border-right: 1px solid var(--ifm-color-emphasis-200); +} + +.background > *:nth-child(2) { + position: absolute; + bottom: 0; + left: 0; + width: calc((100% - 25px) + 1px); + height: 25px; + border-bottom: 1px solid var(--ifm-color-emphasis-200); + border-left: 1px solid var(--ifm-color-emphasis-200); +} + +.background > *:last-child { + position: absolute; + bottom: 0; + right: 0; +} + +.title { + text-align: center; + height: 7rem; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.title p { + margin-bottom: 8px; + font-size: 11px; + font-weight: 700; +} + +.title span { + flex-grow: 2; + font-size: 1.2rem; + line-height: 1.25; + font-weight: 500; + font-family: CMU-Serif, 'Times New Roman', Garamond, Georgia, serif; +} + +.title hr { + width: 48px; + margin: 16px auto; +} + +.content { + font-size: .9em; + line-height: var(--ifm-line-height-base); +} + +.content ul, .content ol { + padding-left: 1ch; +} + +.content ul li { + padding-inline-start: 1ch; + list-style-type: '•'; +} + +.content ul li::marker { + color: var(--ifm-color-primary); +} diff --git a/src/components/GridBlock/styles.module.scss b/src/components/GridBlock/styles.module.scss deleted file mode 100644 index cd1474c2d..000000000 --- a/src/components/GridBlock/styles.module.scss +++ /dev/null @@ -1,81 +0,0 @@ -.root { - position: relative; - padding: 2rem 1rem 1.5rem; -} - -.background { - position: absolute; - top: 0; - left: 0; - height: 100%; - width: 100%; - z-index: -1; - & > * { - &:first-child { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: calc((100% - 25px) + 1px); - border-top: 1px solid var(--ifm-color-emphasis-200); - border-left: 1px solid var(--ifm-color-emphasis-200); - border-right: 1px solid var(--ifm-color-emphasis-200); - } - &:nth-child(2) { - position: absolute; - bottom: 0; - left: 0; - width: calc((100% - 25px) + 1px); - height: 25px; - border-bottom: 1px solid var(--ifm-color-emphasis-200); - border-left: 1px solid var(--ifm-color-emphasis-200); - } - &:last-child { - position: absolute; - bottom: 0; - right: 0; - } - } -} - -.title { - text-align: center; - height: 7rem; - display: flex; - flex-direction: column; - justify-content: space-between; - - & p { - margin-bottom: 8px; - font-size: 11px; - font-weight: 700; - } - - & span { - flex-grow: 2; - font-size: 1.2rem; - line-height: 1.25; - font-weight: 500; - font-family: 'CMU-Serif', 'Times New Roman', Garamond, Georgia, serif; - } - - & hr { - width: 48px; - margin: 16px auto; - } -} - -.content { - font-size: .9em; - line-height: var(--ifm-line-height-base); - & ul, & ol { - padding-left: 1ch; - } - & ul li { - padding-inline-start: 1ch; - list-style-type: '•'; - &::marker { - color: var(--ifm-color-primary); - } - } -} \ No newline at end of file diff --git a/src/components/ProtectButton/index.tsx b/src/components/ProtectButton/index.tsx new file mode 100644 index 000000000..70c7d2c56 --- /dev/null +++ b/src/components/ProtectButton/index.tsx @@ -0,0 +1,36 @@ +/** + * Copyright (c) Flashbots Ltd. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { useEffect, useState } from 'react'; + +export default function ProtectButton() { + + // listen for light/dark theme changes + const [theme, setTheme] = useState('light') + useEffect(() => { + const htmlElement = document.documentElement; + const handleThemeChange = () => { + const currentTheme = htmlElement.getAttribute('data-theme'); + setTheme(currentTheme || 'light'); + }; + handleThemeChange(); + const observer = new MutationObserver(handleThemeChange); + observer.observe(htmlElement, { attributes: true, attributeFilter: ['data-theme'] }); + }, []) + + return ( +
+