diff --git a/.github/issue_template.md b/.github/issue_template.md deleted file mode 100644 index 56c442a5..00000000 --- a/.github/issue_template.md +++ /dev/null @@ -1,8 +0,0 @@ -## Context -< Please provide some background about why you’re providing this feedback. This could include a brief description of what you were trying to do or what part of the codebase your feedback is related to. > - -## Suggested Changes -< If you have any suggestions for how we could improve, please describe them here. This could include changes to the code, new features, updates to the documentation, etc. > - -## Additional Information -< If there’s anything else you want to add, you can do that here. This could include code samples, screenshots, etc. > diff --git a/.prettierignore b/.prettierignore index 4827f79b..8213aae5 100644 --- a/.prettierignore +++ b/.prettierignore @@ -11,11 +11,6 @@ pnpm-lock.yaml /docs/.vitepress/public /docs/.vuepress/styles -#dev -/docs/dev/using-metamask/src/HelloWorld.sol.js -/docs/dev/using-metamask/src/HelloWorld.sol - - /docs/public/img /docs/public/api3-whitepaper-v1.0.3.pdf @@ -23,8 +18,6 @@ pnpm-lock.yaml /docs/reference/ois/latest/assets /docs/reference/airnode/latest/assets /docs/reference/dao-members/assets -/docs/dapis/reference/assets /docs/reference/chainapi/assets /docs/reference/qrng/assets /docs/oev-searchers/assets -/docs/dapis/assets diff --git a/.vscode/settings.json b/.vscode/settings.json index b0ca0f8e..aa2b01c5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,7 +18,6 @@ "collateralized", "composability", "dapi", - "dapis", "decentrally", "docset", "docsets", diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c7e84a56..21867d33 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,103 +1,29 @@ -## Contributor's Guide +# Contributors' guide -Welcome to the Api3 Documentation Repository. This guide will help you get -started with contributing to the Api3 documentation. - -## How to get started - -The Api3 Docs uses [VitePress](https://vitepress.dev/), a Vue-powered static +Welcome to the Api3 documentation repository. This guide will help you get +started with contributing to the Api3 documentation. The docs use [VitePress](https://vitepress.dev/), a Vue-powered static site generator. Follow the steps below to get started. -Make sure to check out https://docs.api3.org/dev/ for more details and -information about getting started and making a contribution to the Api3 Docs. - -### Pre-requisites - -- [Node.js](https://nodejs.org/en/) (version 20 or higher). -- Unix/macOS/WSL for the scripts to work properly. - -### Installation - -```bash -pnpm install -``` - -### Running the local development server - -Run the following command to start the local development server on port `5173`: - -```bash -pnpm docs:dev -``` - -### Structure - -The Api3 Docs repository is structured as follows: - -- `/docs/dapis`: Explore section within the Api3 Docs. -- `/docs/oev`: All the guides that demonstrate the use of Airnode, QRNG and - dAPIs. -- `/docs/reference`: Contains the core documentation for Airnode, QRNG and - dAPIs. - -Each section will have a `sidebar.js` file that contains the sidebar structure -for that section. - -`/_components`: Contains the custom vue components used in the Api3 Docs. - -[Check this out](https://docs.api3.org/dev/docsets.html) for more info about the -structure of the docs. - -### Building the static site - -```bash -pnpm docs:build -``` - -### Prettier Formatting - -Make sure to run the following command before submitting a PR to format the -markdown. The Github action will check for prettier formatting: - -```bash -pnpm format -``` - -### Formatting and Styling - -You can use markdown to format the content. Check out the -[docs development section](https://docs.api3.org/dev/) for more info. Some -useful links: - -- [Page styling](https://docs.api3.org/dev/page-styling.html) -- [Formatting guides](https://docs.api3.org/dev/oev-format.html) -- [VitePress Containers](https://docs.api3.org/dev/containers.html) - -### Git Workflow: - -- `main` branch: for the current live site - [docs.api3.org](https://docs.api3.org) - -[Check this out](https://docs.api3.org/dev/firebase.html#repo-branches) for more -info about the branches. - -### Submitting an Issue +## Submitting an issue You can submit an issue if you find any bugs or have any feature requests. Please make sure to check if the issue already exists before submitting a new one. -You can: - -- Submit an issue for a bug. -- Submit an issue for a feature request. -- Submit an issue for a documentation request. +## Making a pull request -### Making a PR - -After making changes in a feature branch, submit a PR against the `main` branch. +After making changes in a feature branch, submit a pull request (PR) against the `main` branch. Make sure to link the corresponding GitHub Issue in the PR description e.g. `Closes #1`. You will be able to see the changes within a Firebase preview deployment that is unique to the PR. The PR will be reviewed by the team and merged into the `main` branch, which will result in the changes going live into production. + +### Getting started + +After cloning the repo locally, install the dependencies and run the docs locally. + +```bash +pnpm install +pnpm docs:dev +``` diff --git a/README.md b/README.md index 85fe90cb..ad826516 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,7 @@ -# OEV docs preview +# OEV docs -This technical documentation is a fork of the official -[Api3 technical documentation](https://docs.api3.org). The intent is to develop -OEV-related documentation here privately then merge into the official repo when -ready. +> The main API3 documentation -## Instructions +## Contributing -To install deps: - -```sh -pnpm install -``` - -and to run in dev mode: - -```sh -pnpm run docs:dev -``` - -## Deployment - -Firebase is used to host the `oev-docs` technical documentation. A preview -deployment is generated for every PR, while the main deployment is updated with -every merge to the `main` branch. The url for the main deployment is: -[https://oev-docs.web.app](https://oev-docs.web.app). +Head out to [CONTRIBUTING.md](./CONTRIBUTING.md) for details. diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index 65d3cfa9..816774a1 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -85,7 +85,6 @@ export default { sidebar: { '/dapps/': require('../dapps/sidebar.js'), '/oev-searchers/': require('../oev-searchers/sidebar.js'), - '/dev/': require('../dev/sidebar.js'), }, nav: nav(), }, diff --git a/docs/dapps/index.md b/docs/dapps/index.md index a37a6448..1b615c3b 100644 --- a/docs/dapps/index.md +++ b/docs/dapps/index.md @@ -30,7 +30,7 @@ Rent-seeking third parties can exploit this fact to extract funds from data feed [Oracle Extractable Value (OEV)](https://medium.com/api3/oracle-extractable-value-oev-13c1b6d53c5b) is a subset of MEV that oracles have priority in extracting by batching additional operations with their updates. Furthermore, instead of searching for such OEV opportunities themselves, oracles can auction off this privilege. -Api3 holds transparent and permissionless auctions for OEV opportunities on OEV Network, and [pays](/dapps/oev-rewards/) the auction proceeds to the respective dApps. +Api3 holds transparent and permissionless auctions for OEV opportunities on OEV Network, and [pays](/dapps/oev-rewards/) 80% of the auction proceeds to the respective dApps. OEV Rewards serves as a new and sustainable revenue stream for dApps. ::: info ⚠️ Disclaimer diff --git a/docs/dapps/oev-rewards/index.md b/docs/dapps/oev-rewards/index.md index 258d193b..17abf465 100644 --- a/docs/dapps/oev-rewards/index.md +++ b/docs/dapps/oev-rewards/index.md @@ -10,7 +10,7 @@ pageHeader: dApps → OEV Rewards dApps that use traditional data feeds are constantly exploited by MEV bots that manipulate the order of operations around individual data feed updates. In practice, this causes dApps to suffer significant and continuous financial losses. As the antidote, Api3's OEV Network auctions off to OEV searchers the privilege to determine the order of operations around data feed updates. -The resulting auction proceeds are paid to the dApp in the form of OEV Rewards. +80% of resulting auction proceeds are paid to the dApp in the form of OEV Rewards. Assuming competitive auctions, OEV Rewards will be equal to the amount that would otherwise have been lost to the MEV bots. Api3 data feeds work identically to traditional data feeds, which means that you do not need to modify your contracts in any way to use them. diff --git a/docs/dev/assets/images/ssr-cloudflare.png b/docs/dev/assets/images/ssr-cloudflare.png deleted file mode 100644 index ebc8c72f..00000000 Binary files a/docs/dev/assets/images/ssr-cloudflare.png and /dev/null differ diff --git a/docs/dev/assets/images/version-search.png b/docs/dev/assets/images/version-search.png deleted file mode 100644 index 767fa269..00000000 Binary files a/docs/dev/assets/images/version-search.png and /dev/null differ diff --git a/docs/dev/containers.md b/docs/dev/containers.md deleted file mode 100644 index 91c50a3c..00000000 --- a/docs/dev/containers.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: VitePress Containers -pageHeader: Docs Development -outline: deep ---- - - - -# {{$frontmatter.title}} - -VitePress provides several containers. The following examples explain how they -should be used in `vitepress-docs`. - -::: info - -The info box is the default go-to for the Api3 technical documentation. - -::: - -::: tip - -Try to avoid using this container. It overwhelms the theme's dark mode. - -::: - -::: warning - -Express to the reader not to do something. - -::: - -::: danger - -Rarely used. Expresses an important failure concern to the reader should they -fail to follow instructions. - -::: - -::: details - -Use the details container with extended code samples in order to compress them. - -```json -{} -``` - -::: - -## Usage - -```md -::: info My custom title - -Custom title here Content of the container goes here. - -::: -``` - -::: info My custom title - -Custom title here Content of the container goes here. - -::: diff --git a/docs/dev/docsets.md b/docs/dev/docsets.md deleted file mode 100644 index 213997b8..00000000 --- a/docs/dev/docsets.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: DocSets -pageHeader: Docs Development -outline: deep ---- - - - -# {{$frontmatter.title}} - -A docset is a logically grouped set of pages. Every docset has a root folder. -The current docsets are as follows: - -- dAPIs: `/dapis/` -- OEV: `/oev-searchers/` -- Docs Development `/dev/` diff --git a/docs/dev/firebase.md b/docs/dev/firebase.md deleted file mode 100644 index e0b638cc..00000000 --- a/docs/dev/firebase.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Firebase -pageHeader: Docs Development -outline: deep ---- - - - -# {{$frontmatter.title}} - -All production and PR preview deployments are published on Firebase hosting and -are built automatically using GitHub -[workflows](https://github.com/api3dao/vitepress-docs/tree/main/.github/workflows) -stored in the `vitepress-docs` repo. - -- Production: https://vitepress-docs.web.app (and https://docs.api3.org) - -## Repo Branches - -When a PR is merged into the default branch, `main`, a Firebase deployment of -the docs production website is triggered. - -## Firebase emulator - -You can run the docs using the firebase emulator after updating the flex indexes -and prior to pushing changes to the repo. Run the following commands from the -root of the project after ensuring that the firebase CLI is installed. - -```sh -firebase:emulator -``` - -OR - -```sh -pnpm docs:build - -firebase emulators:start -``` diff --git a/docs/dev/frontmatter.md b/docs/dev/frontmatter.md deleted file mode 100644 index 35931851..00000000 --- a/docs/dev/frontmatter.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: Frontmatter -pageHeader: Docs Development -outline: deep ---- - - - -# {{$frontmatter.title}} - -The frontmatter must be at the top of the Markdown file, and must take the form -of valid YAML set between triple-dashed lines. Each page must contain -`$frontmatter` which is used to provide navigation, navigation labels, and -search criteria. Below is the `$frontmatter` for this page. - -```yaml ---- -title: Frontmatter -pageHeader: Docs Development -outline: deep ---- -``` - -## Fields - -Most `$frontmatter` keys are required. - -### `title` - -(required) Sets the page's title. This title is not used by the sidebars which -must provide a title for each page using the key `text`. They can be the same or -different. - -### `path` - -(required) The path to the page. The path is used by the search engine as a -target URL and to logically group search results for display to the reader. - -### `version` - -(required for Airnode and OIS) The version number for the Airnode and OIS -docsets. - -### `outline` - -(optional) Each page has its own table of contents component displayed on its -right side if the page use heading elements H2-H6. Without a value for `outline` -only H2 elements will be displayed. A value of deep will show all elements -H2-H6. - -- `outline: null`: Shows H2 -- `outline: false`: The TOC is hidden -- `outline: [2,4]`: Shows H2-H4 -- `outline: deep`: Shows H2-H6 - -### `tags` - -(optional) For future use, provides important key search words for the search -engine. diff --git a/docs/dev/ga4.md b/docs/dev/ga4.md deleted file mode 100644 index 336cf624..00000000 --- a/docs/dev/ga4.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Google Analytics -pageHeader: Docs Development -outline: deep ---- - - - -# {{$frontmatter.title}} - -::: danger Work in progress - -Not worth reading at this point. Still working on it. - -::: - -`https://www.google.com/search?client=safari&rls=en&q=tutorial+google+analyticts+4&ie=UTF-8&oe=UTF-8#fpstate=ive&vld=cid:dd7bbe7d,vid:iJyGEuiIjOk` - -https://github.com/vuejs/vitepress/issues/1131 diff --git a/docs/dev/hyperlinks.md b/docs/dev/hyperlinks.md deleted file mode 100644 index 46a9101a..00000000 --- a/docs/dev/hyperlinks.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Hyperlinks -pageHeader: Docs Development -outline: deep ---- - - - -# {{$frontmatter.title}} - -Consider the following markdown based links in a file -`/reference/ois/latest/specifications.md`. - -- `/reference/ois/latest/reserved-parameters.md#gasprice` - -- `reserved-parameters.md#gasprice` - -- `./reserved-parameters.md#gasprice` - -Because `reserved-parameters.md` is in the same folder as `specifications.md`, -all three links will work. However with the later two links, VitePress will add -`/reference/ois/latest/` at SPA runtime. This is problematic for link validator -scripts such as `/lib/link-validator.js`. - -During the release of VitePress 1.0.0-alpha.46 someone thought it best to add -the base path to all markdown URLS at runtime. This was not thought through. It -is entirely possible in the future they will flip on this. This was introduced -as a breaking change. - -::: info VitePress 1.0.0-alpha.46 BREAKING CHANGES - -build: base is now prepended to all internal (non-relative) links, including any -reference to a file present in the public directory. If you want the earlier -behavior for such links, use absolute links. - -::: - -Even the description for the breaking change is poorly written. The commit can -be seen -[here](https://github.com/vuejs/vitepress/commit/dcf29419f24bfb0fe99e424771be931bf77b9961). - -The safest solution is to use the full path from the root of `/docs` or in the -case of the examples above, -`/reference/ois/latest/reserved-parameters.md#gasprice`. Doing so will safe -guard the docs from pattern substitutions by VitePress that could change in -future releases. This will inconvenience writers of the docs but will will save -countless hours tracking down bad links. diff --git a/docs/dev/index.md b/docs/dev/index.md deleted file mode 100644 index ba514340..00000000 --- a/docs/dev/index.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: Getting Started -pageHeader: Docs Development -outline: deep ---- - - - -# {{$frontmatter.title}} - -Use newer versions of Nodejs. Currently the builds on GitHub are using `v20`. -Mac users (Apple silicon) should see the page -[Rosetta, Nodejs, esbuild](/dev/rosetta.md) if you get an error. - -::: info Nodejs `v20` - -It is best to use nodejs `v20` which gives the best performance and is the -engine described in the -[package.json](https://github.com/api3dao/vitepress-docs/blob/main/package.json) -file. - -::: - -## Clone the remote repo - -Clone the remote repo and install it packages. - -```sh -git clone git@github.com:api3dao/vitepress-docs.git -cd vitepress-docs -pnpm install -``` - -Create a working branch. - -```sh -git checkout -b -``` - -Run the development server. - -```sh -pnpm docs:dev -``` - -## Push the working branch - -Before pushing your working branch to the remote repo, be sure that the branch -builds. - -```sh -pnpm docs:build -``` - -The output should look like this: - -```sh - vitepress v1.0.0-alpha.61 - -✓ building client + server bundles... -✓ rendering pages... -build complete in 5.20s. -✨ Done in 6.19s. -``` - -If the build displays errors or warnings (such as broken links) address them as -needed. - -## Memory - -It maybe necessary to increase the memory for Nodejs to run `pnpm docs:dev` or -`pnpm docs:build`. This can be done with the command below, with a higher value -potentially necessary. For Apple silicon this may be a sign of a -[Rosetta issue](/dev/rosetta.md) which should be addressed before committing to -additional memory for Nodejs. - -```sh -export NODE_OPTIONS=--max_old_space_size=1024 -``` diff --git a/docs/dev/link-validation.md b/docs/dev/link-validation.md deleted file mode 100644 index 67b09a13..00000000 --- a/docs/dev/link-validation.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Link Validation -pageHeader: Docs Development -outline: deep ---- - - - -# {{$frontmatter.title}} - -Use the script `/libs/link-validator.js` to validate links with or without -attached anchors. The link validator is a manual process that should be -performed as often as possible. - -The script is part of a three step process to keep the links in the docs clean. - -The three steps: - -1. `pnpm docs:build`: When doing a local build VitePress will valid markdown - links and does so very well. Fix them before proceeding. This step will also - catch bad `src` paths for images. It does not validate anchors. -2. Search the code base for `](#`. This will show markdown links that link - directly to an anchor. While this will work, the anchors cannot be validated - by `/libs/link-validator.js`, see [Hyperlinks](/dev/hyperlinks.md) to - understand how to fix them. -3. Run the `/libs/link-validator.js` script. - -## Using the script - -The script must be run locally and will not work as a GitHub action. - -### 1. Build the docs - -Build the docs as usual using the standard build command provided by VitePress. - -```sh -pnpm docs:build -``` - -Note that the build script may in fact catch bad links in of itself. Any -reported links should be fixed before proceeding. - -### 2. Start the local VitePress server - -VitePress has a built-in http server that publishes the files from the `/dist` -folder. - -```sh -pnpm docs:serve -``` - -### 3. Run the script - -Open a new terminal window to run the script. The script's output will display -an indicator for failures as it steps through each file. There will be a summary -of all link failures at the end of the script output. - -You can run the Link Validator against the entire `/dist` folder which will -validate all docsets but this can be time consuming. Narrowing the scope of the -validation to a particular folder (docset) can hasten the validation process. Be -sure to use the correct port displayed by VitePress server. - -```sh -node ./libs/link-validator.js http://localhost:8082 ./docs/.vitepress/dist/ -``` diff --git a/docs/dev/page-styling.md b/docs/dev/page-styling.md deleted file mode 100644 index e1e4cbc3..00000000 --- a/docs/dev/page-styling.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Page Styling -pageHeader: Docs Development -outline: deep ---- - - - -# {{$frontmatter.title}} - -You can add a style definition just for a single page. Be careful not to use -class names used by VitePress. Prefixing `api3` to all class names is a best -practice to protect VitePress classes. - -
this-smaller-font
-
- -

- -```css - - -``` - - - diff --git a/docs/dev/rosetta.md b/docs/dev/rosetta.md deleted file mode 100644 index 315bfe4f..00000000 --- a/docs/dev/rosetta.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: Rosetta, Nodejs, esbuild -pageHeader: Docs Development -outline: deep ---- - - - -# {{$frontmatter.title}} - -This page refers to Apple silicon Macs that have implemented the use of Rosetta. -It is best not to use Rosetta with the VitePress docs. While it may work it -almost always results in longer builds and other processes. Other issues can -arise such as the Rosetta platform error. This usually happens when Nodejs and -NPM are installed using CLI running with Rosetta on, and NPM will install the -wrong [esbuild](https://esbuild.github.io/getting-started/) package. It is best -to use a version of Nodejs and NPM installed with its installer or install it -using your CLI with Rosetta deactivated. - -::: info Nodejs `v20` - -It is best to use nodejs `v20` which gives the best performance and is the -engine described in the -[package.json](https://github.com/api3dao/vitepress-docs/blob/main/package.json) -file. - -::: - -```sh -failed to load config from /Users/warren/DEV/vitepress-docs/docs/.vitepress/config.js -build error: - Error: -You installed esbuild for another platform than the one you're currently using. -This won't work because esbuild is written with native code and needs to -install a platform-specific binary executable. - -Specifically the "@esbuild/darwin-arm64" package is present but this platform -needs the "@esbuild/darwin-x64" package instead. People often get into this -situation by installing esbuild with npm running inside of Rosetta 2 and then -trying to use it with node running outside of Rosetta 2, or vice versa (Rosetta -2 is Apple's on-the-fly x86_64-to-arm64 translation service). - -If you are installing with npm, you can try ensuring that both npm and node are -not running under Rosetta 2 and then reinstalling esbuild. This likely involves -changing how you installed npm and/or node. For example, installing node with -the universal installer here should work: https://nodejs.org/en/download/. Or -you could consider using pnpm instead of npm which has built-in support for -installing a package on multiple platforms simultaneously. -... -``` - -## How to correct - -If you run `pnpm docs:build` and get the above error you may have an `esbuild` -package for use with the non-native platform for Apple silicon probably install -using NPM. Run the following (only using pnpm) to update `esbuild`. If your CLI -is not running under Rosetta, it will install for the proper platform. - -`esbuild` will not appear in `packages.json` under `devDependencies`, but it -does update. - -```sh -pnpm install --dev esbuild -``` - -Next run a VitePress build. - -```sh -pnpm docs:build -``` diff --git a/docs/dev/sidebar.js b/docs/dev/sidebar.js deleted file mode 100644 index c8cb19e2..00000000 --- a/docs/dev/sidebar.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = [ - { - text: '', - items: [ - { text: 'Getting Started', link: '/dev/' }, - { text: 'DocSets', link: '/dev/docsets' }, - { text: 'Firebase', link: '/dev/firebase' }, - { text: 'Frontmatter', link: '/dev/frontmatter' }, - { text: 'Hyperlinks', link: '/dev/hyperlinks' }, - { text: 'Link Validation', link: '/dev/link-validation' }, - { text: 'Page Styling', link: '/dev/page-styling' }, - { text: 'Rosetta, Nodejs, esbuild', link: '/dev/rosetta' }, - { text: 'Google Analytics 4', link: '/dev/ga4' }, - { text: 'VitePress Containers', link: '/dev/containers' }, - { text: 'SSR on CloudFlare', link: '/dev/ssr' }, - ], - }, -]; diff --git a/docs/dev/ssr.md b/docs/dev/ssr.md deleted file mode 100644 index 58d6a964..00000000 --- a/docs/dev/ssr.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: SSR on CloudFlare -pageHeader: Docs Development -outline: deep ---- - - - -# {{$frontmatter.title}} - -Api3 uses CloudFlare for DNS records which includes the docs. If SSR is turned -on for any domain related to the docs, then CloudFlare will minify the already -minified build files from Firebase. This will result in the merging of pages -visible to the reader. - - - -Because the docs are not using SSR and relying are on a CDN (Firebase), caching -isn't necessary. The CDN is effectively a cache as the data is static. So -caching for DNS records related to the docs should be turned off. diff --git a/docs/oev-searchers/auctions-overview.svg b/docs/oev-searchers/auctions-overview.svg new file mode 100644 index 00000000..80fd6c20 --- /dev/null +++ b/docs/oev-searchers/auctions-overview.svg @@ -0,0 +1,2 @@ +Auction #1Auction #2Auction #3TimeAwardphase #1Awardphase #2Awardphase #3Bid phase #1Bid phase #2Bid phase #3...Cutoff #1Cutoff #2Cutoff #3Fulfillment #1Fulfillment #2 \ No newline at end of file diff --git a/docs/oev-searchers/glossary.md b/docs/oev-searchers/glossary.md index 19c6f243..2a47dbf3 100644 --- a/docs/oev-searchers/glossary.md +++ b/docs/oev-searchers/glossary.md @@ -32,13 +32,13 @@ the schema used while encoding. is a specification built on contract ABI to allow encoding without knowing the schema. -### Airnode Address +### Airnode address All [API providers](#api-provider) [sign their data](#signed-data) with an EOA wallet. The address of this wallet is announced by the respective API provider in the DNS records of the base URL of their API. -### Airnode Feed +### Airnode feed [Airnode feed](https://github.com/api3dao/signed-api/tree/main/packages/airnode-feed) is an iteration on [Airnode](#airnode) that is optimized to power data feeds. @@ -47,7 +47,7 @@ identified by the respective [Airnode address](#airnode-address). The [wallet](#airnode-wallet) of this account is used to cryptographically [sign the data](#signed-data) to prove the validity of the data. -### Airnode Wallet +### Airnode wallet A secret wallet only known to the [API provider](#api-provider) who deploys the [Airnode](#airnode) or [Airnode feed](#airnode-feed) used to sign its data. @@ -59,14 +59,14 @@ periodically fetches [signed data](#signed-data) from [Signed APIs](#signed-api) to update [data feeds](#data-feed) whenever the conditions specified by the [update parameters](#update-parameters) are satisfied. -### AirseekerRegistry Contract +### AirseekerRegistry contract [AirseekerRegistry contract](https://github.com/api3dao/contracts/blob/main/contracts/api3-server-v1/AirseekerRegistry.sol) serves as an on-chain configuration file for [Airseeker](#airseeker). It provides a source of truth for [dAPIs](#dapi) and can be used to obtain which [data feed](#data-feed) a dAPI points to and what its sources are. -### API Provider +### API provider An API provider is a business that has productized their services in the form of an API. @@ -76,29 +76,37 @@ an API. [Api3 Market](https://market.api3.org/) is a [dApp](#dapp) where users can purchase [dAPI](#dapi) plans, which get reflected on-chain immediately. -### Api3ServerV1 Contract +### Api3ServerV1 contract [Api3ServerV1 contract](https://github.com/api3dao/contracts/blob/main/contracts/api3-server-v1/Api3ServerV1.sol) is the main contract for [dAPIs](#dapi). It is used by [Airseekers](#airseeker) to update [base feeds](#base-feed). -### Api3ServerV1OevExtension Contract +### Api3ServerV1OevExtension contract [Api3ServerV1OevExtension contract](https://github.com/api3dao/contracts/blob/main/contracts/api3-server-v1/Api3ServerV1OevExtension.sol) is an extension of the [Api3ServerV1 contract](#api3serverv1-contract). It is used by [searchers](#searcher) for [OEV feed](#oev-feed) updates. +### Auction + +Auction, in the context of OEV auctions, is an order flow auction (OFA) providing exclusive priority for updating data feeds for particular dApp to capture OEV. + ### Auctioneer Short term for [OEV Auctioneer](#oev-auctioneer). -### Award Phase +### Award details + +The award details provide the auction winner the exclusive priority to update the price feeds for a particular dApp. The award details format is enforced by [Auctioneer](#auctioneer). + +### Award phase Award phase is the second phase of an [OEV auction](#oev-auction) where [OEV Auctioneer](#oev-auctioneer) resolves the auction and awards the winner. It is preceded by the [bid phase](#bid-phase). -### Base Feed +### Base feed In the context of OEV extraction, the base feed refers to a [data feed](#data-feed) behind a particular [dAPI](#dapi). An update of this @@ -114,7 +122,7 @@ the respective [Airnode address](#airnode-address) and [template](#template) ID. beaconId = keccak256(abi.encodePacked(airnode, templateId)); ``` -### Beacon Set +### Beacon set A beacon set is an on-chain aggregation of [beacons](#beacon). A beacon set is identified by the hash of the constituting beacon IDs. @@ -129,17 +137,25 @@ beaconSetId = keccak256(abi.encode(beaconIds)); in [OEV auctions](#oev-auction) to obtain exclusive rights to capture [OEV](#oev). -### Bid Amount +### Bid details + +Required part of a [bid](#bid) providing the details of the bid. The bid details format is enforced by [Auctioneer](#auctioneer). + +### Bid amount The amount a [searcher](#searcher) is willing to pay for winning the [OEV auction](#oev-auction). -### Bid Phase +### Bid phase Bid phase is the first phase of an [OEV auction](#oev-auction) where [searchers](#searcher) are supposed to place their [bids](#bid). It is followed by the [award phase](#award-phase). +### Bid topic + +A [bid](#bid) is placed for a particular auction, which is identified by the combination of a bid topic and chain ID. The bid topic format is enforced by [Auctioneer](#auctioneer). + ### Collateral Also referred to as collateral amount. @@ -163,16 +179,16 @@ mapping is managed by Api3 DAO. ### dApp An application that uses smart contracts. Usually referred to as a source of -[OEV](#oev). Each dApp eligible for [OEV proceeds](#oev-proceeds) has a -[dApp ID](#dapp-id) assigned and uses [OEV proxies](#oev-proxy). +[OEV](#oev). Each dApp eligible for [OEV Rewards](#oev-rewards) has a +[dApp ID](#dapp-id) assigned and uses its own [OEV proxies](#oev-proxy). ### dApp ID Api3 holds separate [OEV auctions](#oev-auction) for different [dApps](#dapp) to -keep their [proceeds](#oev-proceeds) isolated. In this scheme, dApps are +keep their [rewards](#oev-rewards) isolated. In this scheme, dApps are identified by IDs that are assigned by Api3 DAO. -### Data Feed +### Data feed The common term used to refer to a [beacon](#beacon) or a [beacon set](#beacon-set). Each [data feed](#data-feed) has a @@ -204,7 +220,7 @@ An endpoint is identified by the respective endpointId = keccak256(abi.encode(oisTitle, endpointName)); ``` -### First-party Oracles +### First-party oracles An [API provider](#api-provider) that provides oracle services without the use of any middlemen is a first-party oracle. @@ -217,6 +233,10 @@ The [searcher](#searcher) that has won an [OEV auction](#oev-auction) is expected to pay their [bid amount](#bid-amount). This payment is referred to as a fulfillment in the context of [OevAuctionHouse](#oev-auction-house). +### Fulfillment details + +Fulfillment details are required part of [fulfillment](#fulfillment) and their format is enforced by [Auctioneer](#auctioneer). + ### Heartbeat A heartbeat is a [data feed](#data-feed) update that was made to uphold a @@ -235,12 +255,12 @@ by guaranteeing a specific relative order of oracle updates and related interactions within a transaction. Api3 monetizes its [dAPI](#dapi) services by holding -[OEV auctions](#oev-auction) and forwarding the [proceeds](#oev-proceeds) to the +[OEV auctions](#oev-auction) and paying [OEV Rewards](#oev-rewards) to the respective [dApps](#dapp). This is both a net gain for the dApps (which otherwise would have bled these funds to [MEV](#mev) bots and validators) and a fair and scalable business model for Api3 DAO. -### OEV Auction +### OEV auction Api3 periodically holds [OEV](#oev) auctions on [OEV Network](#oev-network) where [searchers](#searcher) [bid](#bid) to receive exclusive update rights to @@ -251,42 +271,46 @@ update the data feeds for a specific [dApp](#dapp) for a limited amount of time. OEV Auctioneer, or simply Auctioneer, is the off-chain component powering the [OEV Auctions](#oev-auction). -### OEV Beacon +### OEV beacon Each [base feed](#base-feed) beacon has a corresponding OEV beacon, which is derived from the original one by hashing the [template](#template) ID using `keccak256`. These beacons are needed for [OEV searchers](#searcher) to query [Signed APIs](#signed-api) for their real-time values. -### OEV Feed +### OEV feed In the context of OEV extraction, the OEV feed refers to a [data feed](#data-feed) used by [OEV proxy](#oev-proxy). This feed is proxy specific and can be updated by a searcher who won the [OEV auction](#oev-auction). +### OEV updates + +OEV updates are data feed updates performed by searchers after winning the auction with the intention of capturing OEV. These updates are an extension of our [base feed](#base-feed) updates. + ### OEV Network OEV Network is an Arbitrum Nitro L2. Its chain ID is 4913 and it uses ETH as the gas token. Its purpose is to hold [OEV auctions](#oev-auction) in a transparent and retrospectively verifiable way. -### OEV Proceeds +### OEV proceeds -We refer to OEV proceeds in two contexts: +OEV proceeds refer to auction proceeds, which is the amount searchers pay for auctions. Vast majority of OEV proceeds goes back to the dApp in the form of [OEV Rewards](#oev-rewards), while the rest is kept as protocol fee for Api3. -1. As the revenue from capturing the OEV opportunities. -2. As the amount paid to the [dApps](#dapp) as a result of - [bid amount](#bid-amount) payments of [OEV auction](#oev-auction) winners. - -### OEV Proxy +### OEV proxy An OEV proxy is a proxy contract that reads a value from both [base feed](#base-feed) and [OEV feed](#oev-feed) and prefers the fresher out of the two. Our implementation is called `Api3ReaderProxyV1` and partially supports Chainlink's AggregatorV2V3Interface for convenience. -### Protocol Fee +### OEV Rewards + +OEV Rewards refer to the amount paid to the dApp. These rewards constitute the majority portion of the [OEV proceeds](#oev-proceeds). + +### Protocol fee When [Auctioneer](#auctioneer) confirms a [fulfillment](#fulfillment) and releases the [collateral amount](#collateral), it deducts a protocol fee which @@ -306,13 +330,13 @@ receives signed data from [Airnode feeds](#airnode-feed) and serves it to the public through an API. For example, an [Airseeker](#airseeker) depends on Signed APIs to update [data feeds](#data-feed). -### Signed Data +### Signed data Refers to the data signed by [Airnode feeds](#airnode-feed), served by [Signed APIs](#signed-api) and used by [Airseekers](#airseeker) to update [data feeds](#data-feed). -### Target Chain +### Target chain Target chain is the chain where the [Api3ServerV1 contract](#api3serverv1-contract), @@ -331,7 +355,7 @@ parameters. templateId = keccak256(abi.encode(endpointID, parameters)); ``` -### Update Parameters +### Update parameters Parameters that specify when an [Airseeker](#airseeker) should update a [data feed](#data-feed). Typically, there are two aspects that require an diff --git a/docs/oev-searchers/in-depth/dapis/beacon-set.svg b/docs/oev-searchers/in-depth/data-feeds/beacon-set.svg similarity index 100% rename from docs/oev-searchers/in-depth/dapis/beacon-set.svg rename to docs/oev-searchers/in-depth/data-feeds/beacon-set.svg diff --git a/docs/oev-searchers/in-depth/dapis/beacon.svg b/docs/oev-searchers/in-depth/data-feeds/beacon.svg similarity index 100% rename from docs/oev-searchers/in-depth/dapis/beacon.svg rename to docs/oev-searchers/in-depth/data-feeds/beacon.svg diff --git a/docs/oev-searchers/in-depth/dapis/dapi-mapping.svg b/docs/oev-searchers/in-depth/data-feeds/dapi-mapping.svg similarity index 100% rename from docs/oev-searchers/in-depth/dapis/dapi-mapping.svg rename to docs/oev-searchers/in-depth/data-feeds/dapi-mapping.svg diff --git a/docs/oev-searchers/in-depth/dapis/dapi-overview.svg b/docs/oev-searchers/in-depth/data-feeds/dapi-overview.svg similarity index 100% rename from docs/oev-searchers/in-depth/dapis/dapi-overview.svg rename to docs/oev-searchers/in-depth/data-feeds/dapi-overview.svg diff --git a/docs/oev-searchers/in-depth/dapis/index.md b/docs/oev-searchers/in-depth/data-feeds/index.md similarity index 83% rename from docs/oev-searchers/in-depth/dapis/index.md rename to docs/oev-searchers/in-depth/data-feeds/index.md index ebcb7b31..0806b741 100644 --- a/docs/oev-searchers/in-depth/dapis/index.md +++ b/docs/oev-searchers/in-depth/data-feeds/index.md @@ -1,29 +1,28 @@ --- -title: dAPIs +title: Data feeds pageHeader: OEV Searchers → In Depth outline: deep --- -# dAPIs +# Data feeds Searchers need a way to monitor real-time off-chain prices to find profitable opportunities. Traditionally, searchers have needed to buy API subscriptions from underlying oracle sources, creating additional friction in the process. Api3 simplifies this process by providing the same data that is used for -updating dAPIs to searchers publicly - and without cost. +updating data feeds to searchers publicly and without cost. -The price feed solution from Api3 is called dAPIs, and their design allows -extracting OEV with ease. +## How data feeds work? -## How dAPIs Work? - -Let's start from the ground up. The dAPI logic is dictated by the Api3ServerV1 +Let's start from the ground up. The data feed logic is dictated by the Api3ServerV1 contract. The central part of Api3 feeds is first-party oracles, relying on cryptographic signatures verified on-chain. -### dAPI Structure +Internally, we refer to our data feeds as dAPIs. This is also the terminology used across Api3 contracts. We'll be following the same terminology in this section. + +### dAPI structure The simplest primitive is a "beacon". @@ -37,22 +36,21 @@ It consists of: ETH/USD. Together they represent a data point from a specific data provider. Beacons are -identified by the hash of their Airnode address and template ID. They can be +identified by beacon ID, which is the hash of their Airnode address and template ID. They can be aggregated into "beacon sets" which are identified by the IDs of the constituent beacons. -Both beacons and beacon sets can be used as price feeds. The latter are -preferred because of the aggregation. We use the term "data feed" to refer to -either of them. Finally, a dAPI is simply a mapping from a human-readable name -to a data feed. +Both beacons and beacon sets can be used as price feeds. We use the term "data feed" to refer to +either of them. Term data feed ID is a common name for beacon ID or beacon set ID. Finally, a dAPI is simply a mapping from a human-readable data feed name +to a data feed ID. -### Updating dAPI Value +### Updating data feed value So far, we've referred to dAPIs and data feeds as sources of data, not mentioning how they are kept up-to-date. Api3 feeds are permissionless and @@ -80,12 +78,12 @@ function updateBeaconSetWithBeacons( By updating a beacon set, we aggregate the values and timestamps of the constituent beacons. The typical dAPI refers to a beacon set of multiple -sources. Modifying the underlying beacon set also updates the dAPI value. +sources. As dAPI references a particular data feed under the hood, modifying the underlying beacon set also updates the dAPI value. -### Off-chain Components +### Off-chain components There are several off-chain components that are used to keep dAPI values up to date: @@ -104,13 +102,13 @@ date: All of these tools are open-sourced for transparency. -### Update Schedule +### Update schedule dAPIs are updated based on the configured update parameters. An update is performed whenever a dAPI value exceeds the allowed threshold or the feed was -not updated for a long time. The latter is called a heartbeat update. +not updated for a particular amount time. -## OEV Updates +## OEV updates After a dAPI is updated, the changed value is reflected across all protocols that use the particular dAPI. We call these "base feed updates" to differentiate @@ -125,7 +123,7 @@ base feed or the OEV feed, whichever is fresher. The OEV feed is specific to the dApp, and its update only reflects the price for -the dApp that uses this proxy. This is accomplished by the proxy having an +the dApp that uses this proxy. This is accomplished by the proxy being tied to an immutable dApp ID field. This allows separate auctions to be held for each dApp. To guarantee searchers' exclusivity privilege to capture OEV, the base feed @@ -133,7 +131,13 @@ updates are delayed. Searchers bid for real-time data that can be used to update the OEV feed. By winning an auction, a searcher is guaranteed that the data is fresher than the base feed. -### OEV Feed +::: info ℹ️ Info + +Base feed delay is accomplished by Signed APIs being configured to serve the signed data with 60s delay and provide a real-time version of this data, usable only for the auction winner. This design choice guarantees searchers the exclusive rights for data feeds update. + +::: + +### OEV feed The OEV feed is derived from the base feed by changing its beacons to OEV beacons. @@ -142,16 +146,14 @@ An OEV beacon is derived from the base feed beacon by hashing its template ID using `keccak256`. This makes it possible to share the signed data for OEV beacons freely, because they cannot be used to update the base feed. The Api3ServerV1OevExtension contract allows them to be used only by the auction -winner who has paid the correct amount. - -::: info +winner who has paid the adequate amount. -**Example:** +::: info ℹ️ Example Say we have the following base feed beacon: -```json -"0xfe395743aff41835420d109be4bf98b93e9d9670f5539fc6392578b4626ecedf": { +```jsonc +"0xfe395743aff41835420d109be4bf98b93e9d9670f5539fc6392578b4626ecedf": { // Beacon ID "airnode": "0xc52EeA00154B4fF1EbbF8Ba39FDe37F1AC3B9Fd4", "templateId": "0x1bb9efc88ac9d910a9edc28e8cad8959d196a551e15c9af3af21247f1605873f", } @@ -167,7 +169,7 @@ keccak256(abi.encodePacked(bytes32(0x1bb9efc88ac9d910a9edc28e8cad8959d196a551e15 Which gives us the following OEV beacon: ```json -"0x154ca7c81eb1ed9ce151d5b6ad894c5ab79d19bee20d89eb061aaf24f788221f": { +"0x154ca7c81eb1ed9ce151d5b6ad894c5ab79d19bee20d89eb061aaf24f788221f": { // Beacon ID "airnode": "0xc52EeA00154B4fF1EbbF8Ba39FDe37F1AC3B9Fd4", "templateId": "0xbc7896315bfd4b1186a05f219ec71a95def0d038617e7ae534075317866bfd1b", } @@ -177,9 +179,6 @@ Notice that the beacon ID is different, but the Airnode address is the same. ::: -The OEV update flow is explained in more depth in -[OEV searching](/oev-searchers/in-depth/oev-searching) docs. - ### dApp IDs Each dApp that uses OEV feeds is assigned a unique ID, called the "dApp ID". The @@ -188,18 +187,32 @@ to update any of the price feeds associated with this dApp ID. This ID is hardcoded in the OEV proxies of the dApp. The ID has no meaning other than to group proxies of the same dApp together. -Searchers can obtain the dApp ID from the -[OEV dApps catalog](/oev-searchers/in-depth/#oev-dapps-catalog). -### dApp Sources +Searchers can derive the dApp ID from the information provided in the +[OEV dApps catalog](/oev-searchers/in-depth/#oev-dapps). Searchers can use [`unsafeComputeDappId`](https://github.com/api3dao/contracts/blob/52109d0d285d3ac485a2f0ed68bd7799e75a9722/src/proxy.ts#L57) from the `@api3/contracts` package. + +::: info ℹ️ Example + +Say we want to determine dApp ID for [dTRINITY](https://dtrinity.org/). From the OEV dapps catalog, we see the dApp alias is `dtrinity` and the chain is Fraxtal. Fraxtal has chain ID `252`. To derive the dApp ID we call `unsafeComputeDappId` with arguments `dtrinity` and `252`. + +```js +const dTrinityDappId = unsafeComputeDappId('dtrinity', 252); +// 16210721173577624589952893185091679941657223823840386808143855919126917477566 +``` + +::: + +### dApp sources Searchers need to know the proxy address and the underlying dAPI name used by -the OEV proxy. The dApps have full control over what proxies they use, so it is -best to refer to their documentation or inspect their contracts to get an +the OEV proxy. The dApps have full control over what proxies they use, and searchers +should refer to their documentation or inspect the chain-state of their contracts to get an up-to-date proxy address. To determine the underlying beacons used by the dAPI, you can use the -AirseekerRegistry contract on the target chain. +AirseekerRegistry contract on the target chain. Searchers need to monitor values for these beacons with the public Signed APIs. Note +that these are the base feed beacons and the searcher is expected to derive +the OEV beacons to monitor the OEV data. #### Data feed details encoding @@ -234,7 +247,7 @@ To know which encoding to use, you can check the length of the both `address` and `bytes32` are encoded using 32 bytes. For a beacon set, the length depends on the number of beacons encoded. -#### Example +::: info ℹ️ Example Say there is a dApp proxy that uses the `ETH/USD` dAPI. We can compute the details for this dAPI off-chain by: @@ -354,24 +367,22 @@ Say the following is the output after decoding the data feed details: ] ``` -Searchers need to monitor these data sources with the public Signed APIs. Note -that these are the base feed data feeds and the searcher is expected to derive -the OEV feeds to monitor the OEV data. +::: ## Public Signed APIs Signed APIs store the data pushed by Airnode feeds and expose them to the public -via an API. As mentioned, base feed updates are permissionless and can be -updated by anyone. The OEV feed data can only be used by the OEV auction winner. +via an API. As mentioned, base feed updates are delayed, permissionless and can be +updated by anyone. The OEV feeds are real-time and can only be updated by the OEV auction winner. Api3 runs Signed APIs and makes them publicly available. They are deployed on AWS, ensuring maximum uptime and reliability. -Signed APIs only support querying data for a particular Airnode feed. The +Signed APIs only support querying data for a particular Airnode feed at a time. The Airnode address is supplied as an HTTP path parameter. The endpoint is cached and can be called repeatedly. However, excessive call frequency is restricted by rate limiting or full access denial. -### Base Feed Endpoints +### Base feed endpoints The following are the base feed endpoints that are publicly available: @@ -381,7 +392,7 @@ The following are the base feed endpoints that are publicly available: For example, see the [Api3 response for Nodary Airnode feed](https://signed-api.api3.org/public/0xc52EeA00154B4fF1EbbF8Ba39FDe37F1AC3B9Fd4). -### OEV Endpoints +### OEV endpoints The following are the OEV endpoints that are publicly available: diff --git a/docs/oev-searchers/in-depth/dapis/oev-proxy.svg b/docs/oev-searchers/in-depth/data-feeds/oev-proxy.svg similarity index 100% rename from docs/oev-searchers/in-depth/dapis/oev-proxy.svg rename to docs/oev-searchers/in-depth/data-feeds/oev-proxy.svg diff --git a/docs/oev-searchers/in-depth/examples.md b/docs/oev-searchers/in-depth/examples.md deleted file mode 100644 index 6153dfa1..00000000 --- a/docs/oev-searchers/in-depth/examples.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Examples -pageHeader: OEV Searchers → In Depth -outline: deep ---- - - - -# Examples - -We've decided to launch our own dApp built with Api3 OEV proxies with minimal -liquidity. This allows us to build a fully functional OEV bot and share it as a -reference without promoting a particular dApp. Because of the small liquidity, -we expect very little competition, making it an ideal way to start with OEV. - -## Compound3 Fork - -::: warning - -The dApp uses real assets to allow for a more realistic experience, but the goal -is to allow testing of the OEV flow. If you're just looking to borrow/lend -assets, use the real Compound dApp or another platform instead. - -::: - -The dApp is a Compound3 fork launched on the Base network. The dApp offers a -very basic UI for borrowing and lending assets. It mirrors the real -[USDC comet on Base](https://app.compound.finance/markets/usdc-basemainnet) and -allows for borrowing USDC by supplying any of ETH, cbETH, or wstETH as -collateral. - -Refer to this table for dApp details: - -| Name | Description | -| ----------------------------------------------------------------------------------------------- | ------------------------ | -| [Api3 Compound dApp](https://oev-v1-compound.vercel.app/markets) | The OEV dApp. | -| [USDC Comet contract](https://basescan.org/address/0x07BD845d340a59A88B913769E12df30F99f6384C) | The USDC Comet contract. | -| [USDC contract](https://basescan.org/address/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913#code) | The USDC token. | -| [WETH contract](https://basescan.org/address/0x4200000000000000000000000000000000000006#code) | The WETH token. | -| [cbETH contract](https://basescan.org/address/0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22#code) | The cbETH token. | -| [wstETH contract](https://basescan.org/address/0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452#code) | The wstETH token. | - -## The OEV Bot - -See the -[OEV v1 Compound example bot](https://github.com/api3dao/oev-v1-compound-bot) -for details. diff --git a/docs/oev-searchers/in-depth/index.md b/docs/oev-searchers/in-depth/index.md index 33a03534..96789496 100644 --- a/docs/oev-searchers/in-depth/index.md +++ b/docs/oev-searchers/in-depth/index.md @@ -1,62 +1,74 @@ --- -title: Searchers +title: Getting started pageHeader: OEV Searchers → In Depth outline: deep --- -# Searchers +# Getting started -This part of the docs is dedicated to searchers. It details how OEV auctions -work and explains basic searching strategies to simplify the onboarding of +This is a good starting place for searchers. It includes the list of good dApp candidates for searching, details how OEV auctions +work and explains basic OEV searching strategy to simplify the onboarding of existing MEV searchers to OEV. -## OEV dApps Catalog +## dApps catalog -We maintain an open-source list of all dApps that have integrated Api3 feeds as -part of the [dApp registry](https://github.com/api3dao/dapp-registry). However, -not all of the dApps are suitable for OEV extraction, so we provide a separate -list of currently suitable candidates for OEV searching. +Api3 feeds are used across many dApps, but not all are suitable for OEV searching. This catalog includes those dApps that are generating significant OEV amounts and are open for searchers to participate. - +### OEV dApps -1. [Hana protocol on Taiko](https://www.hana.finance/) -2. [Lendle protocol on Mantle](https://lendle.xyz/) -3. [Orbit protocol on Blast](https://orbitlending.io/) -4. [Silo protocol on Arbitrum](https://app.silo.finance/) -5. [Yei protocol on Sei](https://www.yei.finance/) + -Currently, these protocols use outdated Api3 proxies that support the previous -version of OEV auctions, which are no longer supported. Searchers can still +The following table includes dApps which integrated OEV proxies and are good candidates for OEV searching. The chain and dApp alias define are unique for every market and are required when implementing searcher bots. + +| dApp | Chain | dApp alias | +| ---------------------------------------------------- | ------- | ---------------- | +| [dTRINITY](https://dtrinity.org/) | Fraxtal | `dtrinity` | +| [INIT Capital](https://app.init.capital/?chain=5000) | Mantle | `init` | +| [Lendle](https://lendle.xyz/) | Mantle | `lendle` | +| [MachFi](https://www.machfi.xyz/) | Sonic | `mach-finance` | +| [Vicuna Finance](https://vicunafinance.com/) | Sonic | `vicuna-finance` | +| [Yei Finance](https://www.yei.finance/) | Sei | `yei` | + +### Legacy integrations + +Some dApps are still using the legacy design of oracle proxies, which do not support OEV auctions. It's expected these will migrate the OEV supported ones soon. That said, searchers can already perform [MEV with Signed APIs](/oev-searchers/in-depth/mev-with-signed-apis) -extraction though. +extraction. + + + +| dApp | Chain | +| ---------------------------------------------------------------------------------------------------- | -------- | +| [Compound Finance USDe market](https://app.compound.finance/markets/usde-mantle) | Mantle | +| [Hana Finance](https://www.hana.finance/) | Taiko | +| [INIT Capital](https://app.init.capital/?chain=81457) | Blast | +| [Orbit Protocol](https://orbitlending.io/) | Blast | +| [Silo Finance RDNT market](https://app.silo.finance/silo/0x19d3F8D09773065867e9fD11716229e73481c55A) | Ethereum | -## From MEV Searching +## From MEV searching MEV searching has a well-established community and expertise in securing health and stability across many dApps and chains. We want to motivate this community to join OEV searching by outlining the steps to transition from MEV to OEV. -Let's emphasize that MEV searchers can still use their existing infrastructure -and searching bots even when opting into OEV. OEV should be treated as an -extension to MEV that searchers can capitalize on. OEV can increase profits -through lower fees paid to block validators when compared to traditional MEV. +OEV can be considered an extension of MEV that searchers can capitalize on. While traditional searching prioritizes low latency, OEV searchers can secure guaranteed profits through exclusive priority access for updating data feeds. -The following is a list of things that need to be done to enable an existing MEV +The following is a short list of requirements to upgrade an existing MEV bot to participate in OEV searching: 1. Bridge funds to the OEV network 2. Deposit funds to the OevAuctionHouse contract -3. Monitor off-chain signed data for dAPIs used by the dApp +3. Monitor off-chain signed data for data feeds used by the dApp 4. Simulate the data feed update on-chain to determine OEV opportunities 5. Place a bid on the OEV Network -6. Wait for auction award -7. Use the award to update the on-chain data feed on target chain and capture +6. Wait for the auction to end +7. Provided the auction is won, use the award to update the on-chain data feed on target chain and capture the OEV Most of these steps require small additions to the existing MEV bot, but it is required to understand the mental model behind OEV and our -[dAPIs](#/oev-searchers/in-depth/dapis/). Because of this, we recommend starting +[data feeds](/oev-searchers/in-depth/data-feeds/). Because of this, we recommend starting with an in-between solution we call [MEV with Signed APIs](/oev-searchers/in-depth/mev-with-signed-apis). diff --git a/docs/oev-searchers/in-depth/mev-with-signed-apis.md b/docs/oev-searchers/in-depth/mev-with-signed-apis.md index 64d4a0ac..307828b5 100644 --- a/docs/oev-searchers/in-depth/mev-with-signed-apis.md +++ b/docs/oev-searchers/in-depth/mev-with-signed-apis.md @@ -10,13 +10,11 @@ outline: deep An intermediate step towards OEV searching is to extend MEV bots to utilize the public -[base feed endpoints](/oev-searchers/in-depth/dapis/#base-feed-endpoints). These -endpoints are also used by the Api3 push oracle, so there is tight competition -to be the fastest with the on-chain transaction. +[base feed endpoints](/oev-searchers/in-depth/data-feeds/#base-feed-endpoints). This data is delayed compared to data in the [OEV endpoints](/oev-searchers/in-depth/data-feeds/#oev-endpoints), so it's expected searchers won't be able to extract much value this way. That said, it is a good backup in case OEV auctions are paused or encountering unexpected technical issues. It also the only way to extract value for [legacy integrations](/oev-searchers/in-depth/#legacy-integrations). -The existing MEV bot can utilize this off-chain open-source data and make a base +The existing MEV bot can utilize the off-chain open-source data and make a base feed update on-chain whenever there is OEV to be captured. Refer to -[updating dAPI value](/oev-searchers/in-depth/dapis/#updating-dapi-value) +[updating data feed value](/oev-searchers/in-depth/data-feeds/#updating-data-feed-value) section for more details. One advantage of using this data is that searchers can easily simulate the data @@ -24,32 +22,35 @@ feed update (which is permissionless for base feeds) to determine OEV opportunities more easily. This is a direct improvement over monitoring data source values and predicting the next oracle update. -This solution is also a backup in case OEV is down or under maintenance. +::: info 💰 Financial -## Monitoring Signed Data +This improvement on its own provides a major competitive advantage over existing MEV competition and leads to a significant increase in profits. That said, this strategy will not work when the competition is doing OEV searching. -First, searchers need to have a list of dAPIs used by the dApp and -[obtain its beacons](/oev-searchers/in-depth/dapis/#dapp-sources). Note that -this operation can be heavily cached because they change only when the -underlying base feed changes, which happens only when the dAPI is reconfigured. +::: + +## Monitor signed data + +First, searchers need to have a list of data feeds used by the dApp and +[obtain its beacons](/oev-searchers/in-depth/data-feeds/#dapp-sources). Note that +this can be cached because beacons change only when the +underlying base feed dAPI changes, which happens rarely, only when a dAPI is reconfigured. Once the list of base feed beacons is known, searchers should periodically call the public -[base feed endpoints](/oev-searchers/in-depth/dapis/#base-feed-endpoints) to get +[base feed endpoints](/oev-searchers/in-depth/data-feeds/#base-feed-endpoints) to get the real-time values for the base feed beacons used by the dApp. This data may be used immediately to look for OEV opportunities. -## Simulating a Data Feed Update +## Simulate a data feed update Assuming a searcher called the Signed APIs and has valid data to update the base feed, they can use them to simulate the data feed update on-chain followed by a call to check for OEV opportunities. The code below demonstrates how this process can be implemented in JavaScript -with the ethers library for an imaginary liquidation protocol. Note that this -code makes use of variables that are not defined in the code snippet. Their -purpose can be understood from the context and is left out to keep the example -concise and focused on the general idea. +with the `ethers` library for an imaginary liquidation protocol. Note that this +code makes use of variables that are not defined in the context of the code snippet for brevity. Their +purpose can be understood from the context. The snippet makes use of a well-known [Multicall3 contract](https://www.multicall3.com/). ```javascript const beaconsIds = []; // Assume the data feed is a beacon set with these beacons @@ -98,13 +99,8 @@ staticcall. Note that the signed data for base feeds is delayed to ensure OEV searchers have exclusive priority for OEV extraction. -## Example - -One can refer to the -[OEV v1 Compound example bot](https://github.com/api3dao/oev-v1-compound-bot/tree/mev-with-signed-apis) -and inspect the -[changes](https://github.com/api3dao/oev-v1-compound-bot/compare/mev...mev-with-signed-apis) -needed to migrate the MEV bot to MEV with Signed APIs bot. +## Reference implementation -The bot is configured to run against a forked Compound3 protocol on Base -network. Follow the description in the README for details. +- [Example OEV Compound bot](https://github.com/api3dao/oev-v1-compound-bot/tree/mev-with-signed-apis) - You can also inspect the + [changes](https://github.com/api3dao/oev-v1-compound-bot/compare/mev...mev-with-signed-apis) + needed to add the MEV with Signed APIs functionality to an existing MEV bot. diff --git a/docs/oev-searchers/in-depth/oev-auctioneer.md b/docs/oev-searchers/in-depth/oev-auctioneer.md index 892c50a7..134522c6 100644 --- a/docs/oev-searchers/in-depth/oev-auctioneer.md +++ b/docs/oev-searchers/in-depth/oev-auctioneer.md @@ -9,12 +9,10 @@ outline: deep # OEV Auctioneer OEV Auctioneer is the off-chain system managed by the Api3 DAO to process -auctions hosted on the OEV network. This off-chain component is necessary -because hosting auctions fully on-chain would be extremely gas-intensive and -wouldn't scale performance-wise. The correctness and honesty of OEV Auctioneer +auctions hosted on the OEV network. The honesty of OEV Auctioneer can be verified on-chain because the logic is based solely on the [OevAuctionHouse](/oev-searchers/in-depth/oev-network/#oevauctionhouse) contract -state and events at a given time. +state. OEV Auctioneer has two main responsibilities: @@ -33,10 +31,9 @@ well-established security. It has an Auctioneer wallet that is given the rights to resolve the auctions and confirm/contradict fulfillments. The only cross-chain communication happens during fulfillment verification - all -other operations are performed solely on OEV Network or the target chain of the -dApp. This minimizes latency and improves the resiliency. +other operations are performed solely on OEV Network. This minimizes latency and improves the resiliency. -## Enforced Conventions +## Enforced conventions Auctioneer enforces a few conventions. These are important for searchers to understand and comply with in order to successfully participate in auctions. @@ -48,12 +45,12 @@ understand and comply with in order to successfully participate in auctions. | AUCTION_LENGTH_SECONDS | 30 | How long an auction lasts. | | OEV_AUCTIONS_MAJOR_VERSION | 1 | Increased when we release any breaking change relevant to OEV auctions. | | COLLATERAL_REQUIREMENT_BUFFER_PERCENT | 5 | The additional percentage of the bidder's collateral to mitigate against price changes. | -| BIDDING_PHASE_LENGTH_SECONDS | 25 | The length of the bidding phase during which searchers can place their bids. | +| BID_PHASE_LENGTH_SECONDS | 25 | The length of the bid phase during which searchers can place their bids. | | REPORT_FULFILLMENT_PERIOD_SECONDS | 86400 | The fulfillment period, during which the auction winner is able to report payment for the OEV bid. | | MINIMUM_BID_EXPIRING_SECONDS | 15 | The minimum expiring time for a bid to be considered eligible for award. | | PLACED_BIDS_BLOCK_RANGE | 300 | The number of blocks queried for placed bids during award phase. | -### Auction Offset +### Auction offset Auctions repeat indefinitely and take a fixed amount of time. The first auction starts at the UNIX timestamp 0 (midnight UTC on 1st of January 1970) plus an @@ -63,9 +60,7 @@ offset based on the dApp ID. uint256(keccak256(abi.encodePacked(uint256(dAppId)))) % AUCTION_LENGTH_SECONDS; ``` -::: info - -**Example:** +::: info ℹ️ Example Say there is a dApp with ID `13` and `AUCTION_LENGTH_SECONDS=30` @@ -80,7 +75,7 @@ second auction starts at timestamp `47`, the third at `77`, and so on... ::: -### Bid Topic +### Bid topic Auctioneer uses the following convention for the bid topic: @@ -105,20 +100,18 @@ Let's break down the components of the bid topic: 3. `auctionLength` - The length of the auction. This parameter must be set to `AUCTION_LENGTH_SECONDS`. It is one of the most important parameters, so we're explicitly including it in the bid topic to highlight its importance. -4. `signedDataTimestampCutoff` - The cutoff timestamp of the signed data. Only - signed data with timestamps smaller than or equal to this value are permitted - to update the data feed. It is equal to the end of the bidding phase of the - auction, that is `startTimestamp + BIDDING_PHASE_LENGTH_SECONDS`. +4. `signedDataTimestampCutoff` - The cutoff timestamp of the signed data. The auction winner is permitted to only use signed data with timestamps smaller than or equal to this. It is equal to the end of the bid phase of the + auction. -::: info +::: info ℹ️ Info Auctions repeat continuously and indefinitely. To calculate the `signedDataTimestampCutoff` that is to be specified in the bid topic, one needs -to calculate the `startTimestamp` of the auction. This depends on the auction -offset and `BIDDING_PHASE_LENGTH_SECONDS`. +to calculate the `startTimestamp` of the next auction. This depends on the auction +offset, `BID_PHASE_LENGTH_SECONDS` and the current time. For example, dApp with ID `13` has an auction offset of `17`. With -`AUCTION_LENGTH_SECONDS=30` and `BIDDING_PHASE_LENGTH_SECONDS=25` this gives the +`AUCTION_LENGTH_SECONDS=30` and `BID_PHASE_LENGTH_SECONDS=25` this gives the following sequence of auctions: | `startTimestamp` | `signedDataTimestampCutoff` | End of award phase | @@ -131,7 +124,7 @@ and so on... ::: -### Bid Details +### Bid details The bid details follow this convention: @@ -148,18 +141,18 @@ The arguments are: update the data feed, if the bid wins the auction. 2. `nonce` - A random nonce to prevent bid ID conflicts. -### Award Details +### Award details The award details contain a signature that the auction winner uses to pay the OEV bid, which allows them to update the price feeds. -### Fulfillment Details +### Fulfillment details The fulfillment details are a single `bytes32` value that represents the transaction hash on the target chain in which the auction winner paid for the OEV bid. -## Bid Eligibility +## Bid eligibility Auctions are open for everyone. Searchers interact with the OevAuctionHouse contract when placing a bid, which enforces a few restrictions. Apart from the @@ -181,9 +174,7 @@ Auctioneer fetches the required information from the OevAuctionHouse contract. In a rare case when Auctioneer fails to fetch eligibility for a bidder, it will abort awarding the current auction. -::: info - -**Edge case:** +::: info ⚠️ Warning If a bidder places multiple bids across different dApps in quick succession, with only enough collateral to cover a subset of the bids, then Auctioneer may @@ -209,18 +200,16 @@ transaction. ::: -## Auction Resolution +## Auction resolution Each auction is split into two phases: -1. Bidding phase - During this phase, searchers are free to submit their bids. - This phase takes `BIDDING_PHASE_LENGTH_SECONDS`. +1. Bid phase - During this phase, searchers are free to submit their bids. + This phase takes `BID_PHASE_LENGTH_SECONDS`. 2. Award phase - During this phase, Auctioneer determines and awards the winner. - Bids placed during this period are ignored. This phase takes the remainder of - the auction length, which is - `AUCTION_LENGTH_SECONDS - BIDDING_PHASE_LENGTH_SECONDS`. + Bids placed during this period are ignored. -As soon as the bidding phase is over, Auctioneer attempts to resolve the auction +As soon as the bid phase is over, Auctioneer attempts to resolve the auction as soon as possible. The following happens under the hood: 1. Compute the bid topic for the current auction @@ -237,20 +226,24 @@ logs from the OEV Network, the auction will be aborted and no winner is chosen. Similarly, if the auction award transaction fails, there will be no retry, because the award signature was already exposed publicly. -### Bidding Phase Guarantee +### Bid guarantees -Auctioneer guarantees that any bid placed during the bidding phase will be +Auctioneer guarantees that any bid placed during the bid phase will be processed. The timestamp of the placed bid is determined by the block timestamp in which the transaction is included. Searchers need to be mindful of that and -of the block time of the OEV Network and make sure to place their bids in time. +consider practical limitations like the OEV Network block time and make sure their bids are placed in time. + +::: info ⚠️ Warning -That said, Auctioneer may also include bids placed before or slightly after the -bidding phase. This is because Auctioneer fetches the logs from the OEV Network +Auctioneer may also include bids placed before or slightly after the +bid phase. This is because Auctioneer fetches the logs from the OEV Network some time in the award phase. It fetches logs from a sufficient block range with -some buffer to ensure the full bidding phase is included. This behavior might +some buffer to ensure the full bid phase is included. This behavior might change in time and searchers should not rely on it. -## Processing Fulfillments +::: + +## Processing fulfillments After the auction winner is awarded, they are expected to fulfill their duties by paying for the awarded OEV bid. After they've made the transaction on the @@ -259,8 +252,7 @@ Network to get their collateral released. Auction winners are advised to wait a sufficient time for the transaction to reach enough finality on the target chain. -Auctioneer periodically queries the OEV Network logs for such events by doing -the following: +Auctioneer periodically queries the OEV Network logs for such events and performs the following operations: 1. Fetch all logs regarding fulfillments for a sufficient time period - AwardedBid, ReportedFulfillment, ConfirmedFulfillment and @@ -270,7 +262,7 @@ the following: 2. Contradict all AwardedBid events that are `REPORT_FULFILLMENT_PERIOD_SECONDS` old without a matching reported fulfillment. Make no action for other - AwardedBid events because they are within the fulfillment period. + AwardedBid events that are within the fulfillment period. 3. For all ReportedFulfillment events without a matching ConfirmedFulfillment or ContradictedFulfillment, fetch the PlacedBid event to determine which chain @@ -284,7 +276,7 @@ to process the fulfillment later. Its utmost priority is to avoid slashing honest searchers. That said, once the Auctioneer disproves the fulfillment, it will promptly slash. -::: info +::: info ℹ️ Info Note that the auction winner may choose not to update the price feed when they pay for the awarded bid. This is an allowed way to withhold the updates because @@ -295,7 +287,7 @@ threshold. ::: -## Auctioneer Addresses +## Auctioneer addresses OEV Auctioneers use dedicated wallets to award auctions and process fulfillments. These addresses are granted the respective privileges on the @@ -317,3 +309,9 @@ Auctioneer is maintained by the Api3 DAO, which is responsible for its uptime and reliable auction processing. In case of a planned migration or maintenance, there will be an announcement shared in advance. It's expected that maintenance periods will be very rare and short. + +::: info 💡 Tip + +In fact, ever since we launched OEV Network, there was not a single period of time that resulted in a downtime. + +::: diff --git a/docs/oev-searchers/in-depth/oev-network/index.md b/docs/oev-searchers/in-depth/oev-network/index.md index 726dd0a1..a31fa0e7 100644 --- a/docs/oev-searchers/in-depth/oev-network/index.md +++ b/docs/oev-searchers/in-depth/oev-network/index.md @@ -11,9 +11,8 @@ outline: deep ![OEV Network image](./oev-network.svg) The OEV Network operates as a standard Arbitrum Nitro L2 optimistic-rollup. The -system ensures transparency and allows verification of the auction process. In -this marketplace, OEV searchers place bids for the exclusive opportunity to -update dAPIs for a short period of time. +system ensures transparency and allows verification of the auction process. It allows searchers to place bids for the exclusive opportunity to +update a dApp's data feeds for a short period of time. By hosting auctions on-chain, we address two big issues: @@ -23,7 +22,7 @@ By hosting auctions on-chain, we address two big issues: long-solved problem in blockchains through gas fees. 2. Transparency - Auctions are awarded via an off-chain system, called OEV Auctioneer, so it is important to be able to reason about the correctness of - auction outcomes. Blockchains are the perfect tool for this, as all the data + auction outcomes. Blockchains are the perfect tool for this, as all the transactions and data is public and verifiable. To participate in auctions, searchers need to have a sufficient amount of ETH @@ -32,7 +31,7 @@ bridged to the OEV network and interact with the ## Using the OEV Network -The OEV Network can be added as a custom network to an EVM compatible wallet. +The OEV Network can be added as a custom network to any EVM compatible wallet. | Details | Value | | ------------------ | ------------------------------ | @@ -44,6 +43,16 @@ The OEV Network can be added as a custom network to an EVM compatible wallet. | Block Explorer URL | https://oev.explorer.api3.org/ | | Bridge URL | https://oev.bridge.api3.org/ | +::: info 💡 Tip + +Apart from the official bridge, Api3 hosts an extended version available at https://oev-explorer-extended.api3.org/. This is a fork of the explorer with small additions for relevant to OEV. + +For example, when browsing logs for [this transaction](https://oev-explorer-extended.api3.org/tx/0x2bbe268d6f2c837af9c842158183fdb5cce641bb35c7a3b0de1af06112371051?tab=logs), the extended explorer shows decoded OEV details for users' convenience. + +![OEV extended explorer](./oev-extended-explorer.png) + +::: + ## Properties Here are some of the key properties of the OEV Network: @@ -52,7 +61,7 @@ Here are some of the key properties of the OEV Network: 250ms. Note that the OEV Network only produces blocks when there are transactions. 2. Gas fees - The gas fees are paid in ETH, and because the network is an - optimistic L2 rollup, the gas fees are low. + optimistic L2 rollup, the gas fees are low and get cheaper with the increased number of transactions. 3. Using Anytrust - By using AnyTrust DAC, the OEV Network achieves further cost reduction. @@ -77,7 +86,7 @@ OEV Network. The implementation of the audited Api3ServerV1 contract is publicly available [here](https://github.com/api3dao/contracts/blob/main/contracts/api3-server-v1/Api3ServerV1.sol). -The Api3ServerV1 contract powers dAPIs on the OEV Network, which are used in the +The Api3ServerV1 contract powers data feeds on the OEV Network, which are used in the OevAuctionHouse contract to compute collateral and protocol fee from the bid amount. Note that this chain is not officially listed on the Api3 market because the OEV Network is primarily intended to be used for OEV auctions. @@ -114,7 +123,7 @@ The interactions with this contract include: Tech-savvy users can refer to the contract's source for details. -### Depositing Collateral +### Depositing collateral To be eligible to win OEV auctions, searchers need to have enough collateral deposited in the OevAuctionHouse contract. See @@ -143,7 +152,7 @@ For an advanced usage where the bidder is a contract, refer to [bidding contract](/oev-searchers/in-depth/oev-searching#bidding-contract) section. -### Withdrawing Collateral +### Withdrawing collateral Withdrawal of deposited collateral is implemented as a two-way process to prevent denial of service by frontrunning the award transaction by withdrawing @@ -171,11 +180,10 @@ function withdraw( ) external; ``` -### Collateral and Protocol Fee +### Collateral and protocol fee For a searcher to win an auction, they are required to have enough ETH deposited -in the OevAuctionHouse contract. Similarly, the value the searcher can win is -limited by the amount they have deposited. Refer to +in the OevAuctionHouse contract. Refer to [bid eligibility](/oev-searchers/in-depth/oev-auctioneer#bid-eligibility) section for details. @@ -277,7 +285,7 @@ how to use these functions, we need to understand how [Expediting a bid](/oev-searchers/in-depth/oev-searching#expediting-a-bid) section for more details. -## Deployed Contracts +## Deployed contracts These are the relevant contracts deployed on the OEV Network: diff --git a/docs/oev-searchers/in-depth/oev-network/oev-extended-explorer.png b/docs/oev-searchers/in-depth/oev-network/oev-extended-explorer.png new file mode 100644 index 00000000..64ebfdf3 Binary files /dev/null and b/docs/oev-searchers/in-depth/oev-network/oev-extended-explorer.png differ diff --git a/docs/oev-searchers/in-depth/oev-searching.md b/docs/oev-searchers/in-depth/oev-searching.md index fd813102..7fd09fef 100644 --- a/docs/oev-searchers/in-depth/oev-searching.md +++ b/docs/oev-searchers/in-depth/oev-searching.md @@ -1,60 +1,35 @@ --- -title: OEV Searching +title: OEV searching pageHeader: OEV Searchers → In Depth outline: deep --- -# OEV Searching +# OEV searching We assume that a searcher has an existing MEV bot and is familiar with the OEV Network and OEV Auctioneer. Let's glue these concepts together and detail the steps to start OEV searching. -## Auction Schedule +## Monitoring signed data -OEV Auctioneer runs auctions continuously. These auctions are very short-lived. -This is to ensure OEV updates are performed in a timely manner and the base feed -delay is minimal. - -Searchers are expected to align with the auction schedule. The bidding phase -should be used to monitor the off-chain data for possible OEV. Any combination -of signed data from within the bidding phase has an exclusivity guarantee. The -more time spent doing off-chain monitoring means more potential data points can -be used for OEV extraction. That said, the bids need to be already included -on-chain during the Auctioneer award phase, so searchers should place their bids -reasonably close to the end of the bidding phase. - -Once a searcher wins an auction, they have the update privilege until the next -auction winner is selected or until the data is exposed via base feeds Signed -API endpoints. The winner is guaranteed privileges at least until the end of the -next bidding phase. Note that on some chains, especially during peak usage, it's -recommended to increase the gas costs. - -## Monitoring Signed Data - -Searchers need to have a list of dAPIs used by the dApp and -[obtain its beacons](/oev-searchers/in-depth/dapis/#dapp-sources). However, +Searchers need to have a list of data feeds used by the dApp and +[obtain its beacons](/oev-searchers/in-depth/data-feeds/#dapp-sources). However, these are the beacons of the base feed. For each of these beacons, the searcher must derive the OEV counterpart to obtain the -[OEV beacon](/oev-searchers/in-depth/dapis/#oev-feed). Note that this operation -can be cached because they change only when the underlying base feed changes, -which happens only when the dAPI is reconfigured. +[OEV beacon](/oev-searchers/in-depth/data-feeds/#oev-feed). Once the list of OEV beacons is known, searchers should periodically call the -public [OEV endpoints](/oev-searchers/in-depth/dapis/#oev-endpoints) to get the +public [OEV endpoints](/oev-searchers/in-depth/data-feeds/#oev-endpoints) to get the real-time values for the OEV beacons used by the dApp. It's necessary to persist these values for a brief period of time - in case they win the auction and need to update the data feed. -OEV auctions provide exclusivity guarantees only for data points with timestamps -from within the bidding phase. Note that for older signed data, there may be a -previous auction winner who can also use them to update the feed. Moreover, it's -not possible to use data fresher than the end of the bidding phase. This is to -ensure the same guarantees apply for the subsequent auction winner. +OEV auctions provide exclusivity guarantees only for signed data with timestamps +from within the bid phase. Note that using older signed data is permitted, but it's likely that such data is already exposed to the public via [base feed endpoints](/oev-searchers/in-depth/data-feeds/#base-feed-endpoints), so their use is discouraged. -## Simulating a Data Feed Update +## Simulating a data feed update Compared to the base feed updates, OEV updates are permissioned - allowing only the auction winner to update the data feed. This makes the OEV update on-chain @@ -63,15 +38,76 @@ extraction, so we built this into the protocol. This works via `simulateDappOevDataFeedUpdate` and `simulateExternalCall` functions, which can be called only with `address(0)`. The only way to -impersonate a zero address is during staticcall simulation. The intended usage -is to do a multicall that simulates the data feed update(s) and then makes an +impersonate a zero address is during a staticcall simulation. The intended usage +is to do a multicall that simulates some data feed update(s) and then makes an arbitrary number of external calls. -To understand how to construct the payload for data feed simulation, refer to -the -[update the data feed](/oev-searchers/in-depth/oev-searching#updating-the-data-feed) -section. The following is an example code snippet demonstrating the expected -usage in JavaScript with the ethers library. +### On-chain details + +To simulate a data feed update, call the `simulateDappOevDataFeedUpdate` function with sender `address(0)`. + +```solidity +function simulateDappOevDataFeedUpdate( + uint256 dappId, // The ID of the dApp that the searcher wants to update + bytes[] calldata signedData // The ABI encoded signed data used for updating the data feeds +) + external + returns ( + bytes32 baseDataFeedId, // The data feed ID that was updated + int224 updatedValue, // The aggregated value of the update + uint32 updatedTimestamp // The aggregated timestamp of the update + ); +``` + +The ABI encoded signed data are expected to be decoded to the following fields: + +- `address airnode` - The address of the Airnode wallet. +- `bytes32 templateId` - The template ID of the base feed beacon - **not** the + template ID of the OEV beacon. +- `uint256 timestamp` - The timestamp of the data. +- `bytes memory data` - The encoded value. +- `bytes memory signature` - The signature for this signed data - signed for the + base feed beacon. + +::: info ⚠️ Warning + +It might be a bit surprising to pass the template ID of the base feed beacon, +because the data and the signature are supplied for the OEV beacon. However, the +contract needs to know both. While hashing the base feed template ID to obtain +the template ID of the OEV beacon is possible - "un-hashing" the base feed +template ID from the OEV template ID is not. + +Say the searcher wants to update the value of base feed beacon with template ID +`0x1bb9efc88ac9d910a9edc28e8cad8959d196a551e15c9af3af21247f1605873f` and they +want to use the following signed data for the OEV beacon: + +```json +"0x154ca7c81eb1ed9ce151d5b6ad894c5ab79d19bee20d89eb061aaf24f788221f": { + "airnode": "0xc52EeA00154B4fF1EbbF8Ba39FDe37F1AC3B9Fd4", + "encodedValue": "0x000000000000000000000000000000000000000000000000003f9c9ba19d0d78", + "signature": "0xf5f454722652215823cb868fd53b7a0c63090dff46e65ba7cdd5fb120df3a520522b80b1fa41f2599c429daa0e48c4f42f60f25b41dab3a8a9be1d2547ebe9811b", + "templateId": "0xbc7896315bfd4b1186a05f219ec71a95def0d038617e7ae534075317866bfd1b", + "timestamp": "1726474901" +} +``` + +they would encode the signed data as follows: + +```solidity +abi.encode( + address(0xc52EeA00154B4fF1EbbF8Ba39FDe37F1AC3B9Fd4), + bytes32(0x1bb9efc88ac9d910a9edc28e8cad8959d196a551e15c9af3af21247f1605873f), + uint256(1726474901), + hex"000000000000000000000000000000000000000000000000003f9c9ba19d0d78", + hex"f5f454722652215823cb868fd53b7a0c63090dff46e65ba7cdd5fb120df3a520522b80b1fa41f2599c429daa0e48c4f42f60f25b41dab3a8a9be1d2547ebe9811b" +) +``` + +::: + +### Searcher bot snippet + +The following is an example code snippet demonstrating a relevant searcher bot implementation in JavaScript using the ethers library. ```js const signedDataCollection = [...] // Assume we have the signed data for the beacons. @@ -102,12 +138,12 @@ const simulationResult = await api3ServerV1OevExtensionImpersonated.multicall.st ); ``` -## Placing a Bid +## Placing a bid After a profitable OEV opportunity is identified, the searcher needs to place a -bid in the auction. There are multiple ways to +bid in the auction. There are two ways to [place a bid](/oev-searchers/in-depth/oev-network/#placing-a-bid), but the -recommended way is to call `placeBidWithExpiration`. +idiomatic way is to call `placeBidWithExpiration`. It accepts the following parameters: @@ -124,22 +160,21 @@ It accepts the following parameters: The most intuitive way to place the bid is to follow the recommendations above and provide a percentage of the profit as the bid amount. Note that the searcher needs to be mindful of all the gas costs on both the target chain and OEV -Network, the paid bid amount, and the respective collateral and protocol fee. +Network, the paid bid amount, external risks due to liquidity changes on target chain and the respective collateral and protocol fee on OEV Network. -For a bid to be valid, it needs to use the correct arguments. Out of these, the -most important is the bid topic, which also identifies the auction. For the bid -to be considered, the place bid transaction needs to be mined during the bidding +For a bid to be valid, it needs to use the correct arguments, most importantly the bid topic, which identifies the auction. For the bid +to be considered, the place bid transaction needs to be mined during the bid phase. Searchers should be mindful of the block time on the OEV Network to make sure their transaction is mined in time. -## Expediting a Bid +## Expediting a bid Because OEV Auctions are short-lived and the minimum bid lifetime is 15 seconds, there is little reason to place long-lived bids. However, in rare cases when a bid is placed by mistake, one can expedite it manually to prevent potential issues. -There are multiple ways to +There are two ways to [expedite a bid](/oev-searchers/in-depth/oev-network/#expediting-a-bid), but the recommended way is to call `expediteBidExpirationMaximally`. @@ -150,9 +185,9 @@ It accepts the following parameters: | bidTopic | bytes32 | The [bid topic](/oev-searchers/in-depth/oev-auctioneer#bid-topic) of the current auction. | | bidDetailsHash | bytes32 | The hash of the [bid details](/oev-searchers/in-depth/oev-auctioneer#bid-details) of the bid. | -## Waiting for Auction Award +## Waiting for auction award -Immediately after the bidding phase is over, Auctioneer enters the award phase, +Immediately after the bid phase is over, Auctioneer enters the award phase, determines the auction winner, and submits the `awardBid` transaction, which emits an AwardedBid event. This event indexes the three most important arguments: @@ -171,12 +206,12 @@ possible. Auctioneer should in practice award the bid during the award phase, but searchers are recommended to poll longer. If Auctioneer does not respond even -within the next bidding phase, there is likely something wrong. Whether the +within the next bid phase, there is likely something wrong. Whether the issue is caused by Auctioneer or the searcher can be determined by looking at the OEV Network. If the issue was caused by Auctioneer, the searcher can [open a dispute](/oev-searchers/in-depth/oev-searching#handling-disputes). -::: info +::: info 💡 Tip Searchers can monitor the auction in real-time and can determine the auction winner themselves (or even attempt to increase their bid). @@ -200,27 +235,26 @@ The OEV capabilities are enabled by the This contract allows the auction winner to pay for the winning bid and update the data feed values. -### Paying for the OEV Bid +### Paying for the OEV bid Paying for the OEV bid presents a problem. The searcher does not have funds upfront - they only receive these once they capture OEV. This challenge has a -workaround - let the searcher use a flash-loan for the amount to be paid and -repay it via the OEV proceeds. However, searchers often need to take a loan for -the OEV recapture. This presents a problem because protocols often implement -reentrancy guards, preventing nested flash-loans. The alternative is to compute -the flash-loan amount to account for both OEV recapture and bid payment. +workaround - let the searcher take a loan. However, searchers often need to take a loan to +capture the OEV opportunity. This presents a problem because protocols often implement +reentrancy guards, preventing nested loans. The alternative is to compute +the loan amount to account for both OEV opportunity and the bid payment. We expected this to degrade the UX, so we implemented the OEV payment in a way -that allows OEV recapture before paying for the OEV bid amount. This works -similarly to taking a flash-loan. The searcher calls `payOevBid` function, which +that allows capturing the OEV opportunity before paying for the OEV bid amount. This works +similarly to taking a loan. The searcher calls `payOevBid` function, which allows the `msg.sender` to update the dApp data feeds and calls the `onOevBidPayment` callback. After the callback is executed, the function verifies that the contract's balance increased by at least the corresponding bid amount. In the `onOevBidPayment` callback, the searcher can capture the OEV, -swap the proceeds to native currency, and send the adequate bid amount to +swap the revenue to native currency, and send the adequate bid amount to Api3ServerV1OevExtension contract. -This is the signature of the function: +This is the signature of the `payOevBid` function: ```solidity function payOevBid( @@ -237,73 +271,39 @@ cutoff. If the searcher provides incorrect values, the signature verification will fail, causing the transaction to revert. If the signature is valid, the contract allows the sender to update the data feed(s). Due to exclusivity guarantees, the winner is guaranteed to be the only one who can update the feed -with data from within the bidding phase of the respective auction. +with data from within the bid phase of the respective auction. -### Updating the Data Feed +### Api3ServerV1OevExtensionOevBidPayer -To update the data feed values, call the `updateDappOevDataFeed` function. This -requires the sender to be whitelisted by paying for the OEV bid first. +The `onOevBidPayment` function is a required for searchers to implement. For simplicity, Api3 provides an interface searchers can use in their contracts. ```solidity -function updateDappOevDataFeed( - uint256 dappId, // The ID of the dApp that the searcher wants to update - bytes[] calldata signedData // The ABI encoded signed data that the searcher wants to update the dAPI with -) - external - returns ( - bytes32 baseDataFeedId, // The data feed ID that was updated - int224 updatedValue, // The aggregated value of the update - uint32 updatedTimestamp // The aggregated timestamp of the update - ); -``` - -The ABI encoded signed data are expected to be decoded to the following fields: - -- `address airnode` - The address of the Airnode wallet. -- `bytes32 templateId` - The template ID of the base feed beacon - **not** the - template ID of the OEV beacon. -- `uint256 timestamp` - The timestamp of the data. -- `bytes memory data` - The encoded value. -- `bytes memory signature` - The signature for this signed data - signed for the - base feed beacon. - -::: info - -**Important** - -It might be a bit surprising to pass the template ID of the base feed beacon, -because the data and the signature are supplied for the OEV beacon. However, the -contract needs to know both. While hashing the base feed template ID to obtain -the template ID of the OEV beacon is possible - "un-hashing" the base feed -template ID from the OEV template ID is not. - -Say the searcher wants to update the value of base feed beacon with template ID -`0x1bb9efc88ac9d910a9edc28e8cad8959d196a551e15c9af3af21247f1605873f` and they -want to use the following signed data for the OEV beacon: - -```json -"0x154ca7c81eb1ed9ce151d5b6ad894c5ab79d19bee20d89eb061aaf24f788221f": { - "airnode": "0xc52EeA00154B4fF1EbbF8Ba39FDe37F1AC3B9Fd4", - "encodedValue": "0x000000000000000000000000000000000000000000000000003f9c9ba19d0d78", - "signature": "0xf5f454722652215823cb868fd53b7a0c63090dff46e65ba7cdd5fb120df3a520522b80b1fa41f2599c429daa0e48c4f42f60f25b41dab3a8a9be1d2547ebe9811b", - "templateId": "0xbc7896315bfd4b1186a05f219ec71a95def0d038617e7ae534075317866bfd1b", - "timestamp": "1726474901" +/// @title Interface that OEV bid payers (i.e., contracts that call +/// `payOevBid()` of Api3ServerV1OevExtension) must implement +interface IApi3ServerV1OevExtensionOevBidPayer { + /// @notice Called back by Api3ServerV1OevExtension after an OEV bid payer + /// has called `payOevBid()` of Api3ServerV1OevExtension. During the + /// callback, the OEV bid payer will be allowed to update the OEV feeds + /// of the respective dApp. Before returning, the OEV bid payer must ensure + /// that at least the bid amount has been sent to Api3ServerV1OevExtension. + /// The returndata must start with the keccak256 hash of + /// "Api3ServerV1OevExtensionOevBidPayer.onOevBidPayment". + /// @param bidAmount Bid amount + /// @param data Data that is passed through the callback + /// @return oevBidPaymentCallbackSuccess OEV bid payment callback success + /// code + function onOevBidPayment( + uint256 bidAmount, + bytes calldata data + ) external returns (bytes32 oevBidPaymentCallbackSuccess); } ``` -they would encode the signed data as follows: +### Updating the data feed -```solidity -abi.encode( - address(0xc52EeA00154B4fF1EbbF8Ba39FDe37F1AC3B9Fd4), - bytes32(0x1bb9efc88ac9d910a9edc28e8cad8959d196a551e15c9af3af21247f1605873f), - uint256(1726474901), - hex"000000000000000000000000000000000000000000000000003f9c9ba19d0d78", - hex"f5f454722652215823cb868fd53b7a0c63090dff46e65ba7cdd5fb120df3a520522b80b1fa41f2599c429daa0e48c4f42f60f25b41dab3a8a9be1d2547ebe9811b" -) -``` +To update the data feed values for a dApp, you can use `updateDappOevDataFeed` function which has the same function signature as `simulateDappOevDataFeedUpdate`. Refer to [Simulating a data feed update](#simulating-a-data-feed-update) section for details. -::: +::: info 💡 Tip The auction winner can update the data feed multiple times and in multiple transactions. However, the contract enforces tight security measures. The @@ -313,36 +313,19 @@ beacons must change the base feed - either increase the timestamp or change the aggregated value. This enforces time monotonicity at the contract level, making sure OEV updates provide only the freshest data. -### Api3ServerV1OevExtensionOevBidPayer - -As part of the `payOevBid` function, the Api3ServerV1OevExtension contract -assumes `msg.sender` is a contract that implements the -IApi3ServerV1OevExtensionOevBidPayer interface. It calls the `onOevBidPayment` -callback and requires the return value to equal: - -```solidity -keccak256("Api3ServerV1OevExtensionOevBidPayer.onOevBidPayment") -``` - -Searchers are recommended to create a specialized, permissioned liquidator -contract that only they can call. +::: -## Bidding Contract +## Bidding contract The bidder can be either an EOA or a contract. The former is simpler but has -certain drawbacks. Imagine a searcher firm where individual developers work on -the searcher bots. Each bot has a dedicated EOA to interact with OEV Network and -capture OEV on the target chain. The product owner only provides liquidity to -each EOA for the OEV collateral. There are a few immediate drawbacks: +certain drawbacks: 1. The EOA has full control over the deposit in the OevAuctionHouse contract 2. The collateral liquidity is fragmented across multiple EOAs Both of these downsides can be mitigated by a role-based bidding contract. One -can imagine the product owner being the only one who can withdraw the funds and -give bidding permissions to other accounts. These accounts can be used to place -bids through the contract. The contract can have additional use cases, but there -are a few important considerations to keep in mind when designing the contract: +role for withdrawing the funds and the other giving bidding permissions. There +are a few important considerations to keep in mind when designing such contract: 1. The OevAuctionsHouse expects the same account to call `reportFulfillment`. This means the bidding contract needs to be reporting fulfillments as well. @@ -350,14 +333,14 @@ are a few important considerations to keep in mind when designing the contract: called by the same address. The bidding contract needs to be allowed to call all of these. Note that withdrawal cancellation may be omitted if the contract doesn't need to have this capability. Access to these functions - should be limited. For example, a malicious actor who has access to it may - call `initiateWithdrawal` so that the auctioneer bots disregard the + should be restricted. For example, a malicious actor who has access to these may + call `initiateWithdrawal` and make the Auctioneer disregard the respective bids, or call `cancelWithdrawal` whenever a withdrawal is initiated to prevent the funds from ever being withdrawn. 3. The withdrawal recipient is specified in the `withdraw` call. Make sure the recipient is payable and the funds will not remain locked. -## Handling Disputes +## Handling disputes In case of a dispute, the OEV Network is considered the source of truth and can be used to resolve it. This may include Auctioneer awarding the wrong bidder or @@ -371,15 +354,8 @@ To open a dispute, head to the [OEV Discord channel](https://discord.com/channels/758003776174030948/1062909222347603989) and create a post with the description of the dispute. -## Example - -One can refer to the -[OEV v1 Compound example bot](https://github.com/api3dao/oev-v1-compound-bot) -and inspect the -[changes](https://github.com/api3dao/oev-v1-compound-bot/compare/mev-with-signed-apis...oev) -needed to migrate the -[MEV with Signed APIs](/oev-searchers/in-depth/mev-with-signed-apis) bot to OEV -bot. +## Reference implementation -The bot is configured to run against a forked Compound3 protocol on Base -network. Follow the description in the README for details. +- [Example OEV Compound bot](https://github.com/api3dao/oev-v1-compound-bot) - You can also inspect the + [changes](https://github.com/api3dao/oev-v1-compound-bot/compare/mev-with-signed-apis...oev) + needed to add the OEV functionality to an existing bot supporting [MEV with Signed APIs](/oev-searchers/in-depth/mev-with-signed-apis). diff --git a/docs/oev-searchers/index.md b/docs/oev-searchers/index.md index c2182673..93a2baae 100644 --- a/docs/oev-searchers/index.md +++ b/docs/oev-searchers/index.md @@ -8,17 +8,11 @@ outline: deep # Overview -Oracle Extractable Value (OEV) is a subset of Maximal Extractable Value (MEV) -that occurs as a result of an oracle update. Traditional oracle solutions update -data feeds blindly, exposing dApps to significant value loss and providing -suboptimal data feed resolution. For searchers, these updates start latency wars -over who captures the MEV first. - -OEV updates are an addition to these push oracle updates that improve the -efficiency of price feeds. The idea is that not all oracle updates are the same. -Some oracle updates expose opportunities in the market that can be captured by -searchers. Searchers monitor the market for profitable opportunities and compete -with each other to realize them first - paying the majority of the exposed value +Oracle Extractable Value (OEV) is a subset of Maximal Extractable Value (MEV) that occurs as a result of an oracle update. + +The idea is that different oracle updates have different importance. +Some updates expose profitable opportunities on the market. Searchers actively compete +with each other to be the first to realize these - paying a majority of the exposed value to block validators in the process. This dynamic is unhealthy, because the majority of the value should be split between the dApp and the searcher that realizes the opportunity. @@ -27,16 +21,14 @@ OEV solves this problem by auctioning off the exclusive rights to execute the oracle update(s), allowing searchers to atomically update the price feed(s) used by the dApps and capture opportunities in the market. The exclusive update rights guarantee no competition and searchers avoid paying premiums on gas fees. -Additionally, the auction proceeds are distributed back to the dApp that created -this opportunity, thus generating a completely new revenue stream. With OEV, searchers announce their intent to perform oracle updates along with -the amount they are willing to pay. The process is facilitated by open auctions, +the amount they are willing to pay for it. The process is facilitated by open auctions, bound by rules enforced on-chain. The auction winner must pay the announced -amount, which in return allows them to use the oracle update and capture +amount, which in return allows them to perform the oracle update and capture profitable opportunities. -## Example +## Practical example Imagine an overcollateralized lending platform that uses Api3 price feeds. Borrowers in the protocol can be liquidated with an incentive whenever their @@ -46,18 +38,17 @@ what happens with the protocol's health over time. Assume that initially there are no unhealthy positions. Many of the price feed updates that happen are "unnecessary" because they don't expose any unhealthy -positions and the protocol remains healthy. However, over time there may be a +positions and the protocol remains healthy. However, after some time there is a price drop that causes many positions using that asset as collateral to approach the 90% liquidation threshold. In this scenario, the next price update that causes a position to become -unhealthy has intrinsic value. From the protocol's perspective, this affects its -solvency and presents a threat. For a searcher, however, this presents a -profitable opportunity. The intrinsic value of the price update equals the -profit the searcher can make. The profit is simply the liquidation incentive -minus the operational gas costs. +unhealthy is valuable. From the protocol's perspective, this affects its +solvency and presents a threat. For a searcher, this presents a +profitable opportunity. In theory, the value of the price update equals to the +profit the searcher can make. -A searcher monitors the dApp and sees that a position will become unhealthy +Searcher monitors the dApp and public Api3 data sources and sees that a position will become unhealthy using the oracle data. They announce that they want to purchase exclusive priority for updating the price feeds and pay X in return. They win the auction, pay X to the dApp, and execute the price feed updates and liquidation @@ -67,36 +58,46 @@ The concept of OEV is not limited to liquidations but can occur anywhere where price feed updates potentially expose profitable opportunities, such as arbitrage and many others. -## OEV Proceeds Distribution +## OEV distribution To update the data feed, the auction winner must pay the bid amount they -announced during the auction. In return, they get exclusive rights to capture -the OEV. Searchers are compensated for this activity through the remaining OEV -proceeds. Thus, the majority of the OEV is distributed to the dApp and the -searchers. +announced during the auction. These payments constitute auction proceeds. Majority of these proceeds go back to the dApp in the form of [OEV Rewards](/dapps/oev-rewards/). Searchers, in return, get exclusive rights to capture +the OEV and get to capitalize on the remaining revenue of the opportunity. -## How do Auctions Work? +Thus, the majority of the OEV is distributed to the dApp and the +searchers. -Api3 has developed a specialized on-chain Order Flow Auction (OFA) similar to -the one you might be familiar with from Flashbots and MEV-Boost. +## How do auctions work? -We use a combination of the [OEV Network](#oev-network) and the +Api3 uses a combination of the [OEV Network](#oev-network) and the [OEV Auctioneer](#oev-auctioneer) to power the OEV auctions in a secure and transparent way. At a high level, auctions repeat continuously and indefinitely. There is a -separate auction for each dApp. Each auction takes a fixed amount of time. -Searchers place bids during the auction and announce a bid amount they're -willing to pay. When the auction ends, the highest eligible bidder is declared -the winner and provided a cryptographic signature. The signature gives them -exclusive rights to update any price feed(s) for the dApp for a limited period -of time. Each time an auction ends, a new one begins and the same process +separate auction for each dApp and each auction takes a fixed amount of time. Each time an auction ends, a new one begins and the same process repeats. -After an auction winner fulfills their duties by paying for the winning bid, -they need to report this back to the OEV network. If they fail to do so, part of -their collateral is slashed. This is an important security measure to prevent -denial of OEV recapture through withheld auction payments. + + + +### Bid phase + +Auctions run in two phases - the bid phase and the award phase. During the +bid phase, searchers look for OEV opportunities for the particular dApp +by monitoring the off-chain data. When an opportunity is detected, they +place their bid based on its value. + +It is important to understand that bids must be placed before the end of the bid phase, which establishes a cutoff period. The auction winner is able to use only price feed data with timestamp up to this cutoff period. + +### Award phase + +The award phase starts immediately after the end of the bid phase. All bids placed during the bid phase are evaluated and the eligible bid with highest amount is selected as winner and provided a cryptographic signature allowing them to make the price feed updates up to the cutoff period. This signature is usable only by the auction winner. A requirement for updating the price feed is paying the announced bid amount in the same transaction. + +### Fulfillment + +Auction winner is required to make use of the auction data and pay for the winning bid to fulfill the purpose of the auction. After paying for the auction, they are required to report the fulfillment to the auction platform with the transaction hash of the update. + +The fulfillment is verified and provided the update was correct, the auction winner's collateral is released. If the fulfillment is not reported or incorrect information is submitted, the collateral is slashed. Fulfillment has a large reporting period and the auction winner is in full control of when they choose to report. ### OEV Network @@ -113,97 +114,13 @@ and it is managed by the Api3 DAO. The integrity of OEV Auctioneer is ensured by using the OEV Network for all important actions, such as announcing the auction winner. -## Auction Cycle - -In this section, we're going to walk through the entire auction cycle at a high -level, explaining the steps involved in the auction process. This section aims -to provide a basic mental model for searchers before reading the in-depth -[Searchers documentation](/oev-searchers/in-depth/). - -### Start of the Bidding Phase - -Auctions run in two phases - the bidding phase and the award phase. During the -bidding phase, searchers can look for OEV opportunities for the particular dApp -by monitoring the off-chain data. When an opportunity is detected, they can -place their bid. - -### Find an OEV Opportunity - -Searchers compare data from off-chain Signed APIs to the on-chain values of -dAPIs. This process often involves taking the off-chain data, simulating the -dAPI updates, and inspecting the state changes of the dApp. - -### Bid Submission - -The searcher submits a bid via the OevAuctionHouse contract on the OEV Network. -The auction is dApp-specific. For their bid to be eligible, they need to have -enough collateral locked in the OevAuctionHouse contract at the time of award. - -### Start of the Award Phase - -The award phase starts immediately after the end of the bidding phase. -Auctioneer determines the auction winner and awards them a signature providing -them with exclusive update rights. - -Performance is critical here because the longer it takes to award the bid, the -less time the auction winner has to capture the OEV before the data becomes -public. Both bidding phase and award phase periods are chosen with this in mind, -allowing both Auctioneer and the auction winner sufficient time. - -### Finding the Winning Bid - -If there are multiple eligible bids, Auctioneer selects the one with the highest -bid amount. - -### Awarding the Winning Bid - -After the winning bid is determined, Auctioneer creates a cryptographic -signature and submits it on the OEV Network. The signature is to be used on the -target chain while capturing the OEV opportunity by the auction winner. This -signature is only usable by the auction winner. - -### Polling for Awarded Bid - -Searchers should monitor the OEV Network for the winning bid transaction to make -use of the award as soon as possible. - -### Capturing the OEV Opportunity - -The auction winner uses the award signature to pay for the OEV bid on the target -chain and pays the bid amount announced in the bid submission. In return, they -are allowed to perform data feed updates. - -Finally, after updating the data feed values, the searcher is able to capture -the OEV opportunity. It is assumed that the searcher performs all of these steps -atomically in a single transaction. - -### Reporting Fulfillment - -After paying for the OEV bid, the searcher needs to report the fulfillment back -to the OEV network. They do so by submitting the transaction hash in which -they've paid for the winning bid. - -The searcher is given a sufficiently long period to report the fulfillment. It's -advised to submit the fulfillment only once the transaction on the target chain -has reached sufficient finality. - -### Fulfillment Verification - -Once the fulfillment is submitted, Auctioneer verifies it, and there are two -possible outcomes: - -1. The fulfillment is confirmed - The collateral for this bid is released and - the protocol fee is charged. -2. The fulfillment is contradicted - The full collateral for this bid is - slashed. - -## Get Involved with OEV +## Get started with OEV Here are resources to help you get started with OEV: 1. Dive deeper into OEV by reading the [OEV Litepaper](https://raw.githubusercontent.com/api3dao/oev-litepaper/main/oev-litepaper.pdf). -2. Check out our detailed [Searchers guide](/oev-searchers/in-depth/) to see how +2. Check out the [Getting started](/oev-searchers/in-depth/) section to see how to start searching. 3. Connect with other developers and OEV enthusiasts in our [OEV Discord channel](https://discord.com/channels/758003776174030948/1062909222347603989). diff --git a/docs/oev-searchers/sidebar.js b/docs/oev-searchers/sidebar.js index 1c58a36b..5f4e3337 100644 --- a/docs/oev-searchers/sidebar.js +++ b/docs/oev-searchers/sidebar.js @@ -14,12 +14,12 @@ module.exports = [ collapsed: false, items: [ { - text: 'Searchers', + text: 'Getting started', link: '/oev-searchers/in-depth/', }, { - text: 'dAPIs', - link: '/oev-searchers/in-depth/dapis/', + text: 'Data feeds', + link: '/oev-searchers/in-depth/data-feeds/', }, { text: 'MEV with Signed APIs', @@ -34,13 +34,9 @@ module.exports = [ link: '/oev-searchers/in-depth/oev-auctioneer', }, { - text: 'OEV Searching', + text: 'OEV searching', link: '/oev-searchers/in-depth/oev-searching', }, - { - text: 'Examples', - link: '/oev-searchers/in-depth/examples', - }, ], }, { diff --git a/libs/link-validator.js b/libs/link-validator.js index e8a9fa6e..f8a7888f 100644 --- a/libs/link-validator.js +++ b/libs/link-validator.js @@ -1,8 +1,3 @@ -/** - * USAGE: see the usage instructions at - * https://docs.api3.org/dev/link-validation.html - */ - const { readFileSync } = require('fs'); var file = require('file'); var colors = require('colors');