diff --git a/content/changelog/active-notifications/enforcement-of-slippage-validation.mdx b/content/changelog/active-notifications/enforcement-of-slippage-validation.mdx new file mode 100644 index 000000000..713343ea8 --- /dev/null +++ b/content/changelog/active-notifications/enforcement-of-slippage-validation.mdx @@ -0,0 +1,20 @@ +--- +title: 'Enforcement of Slippage Validation' +description: 'Posted: September 4, 2026 | Effective: October 4, 2026' +type: changelog +datePublished: '2026-09-04' +--- + +On October 4, 2026, we will begin enforcing that every `/quote` request include either `autoSlippage` or `slippageTolerance`. + +**What is changing?** + +The [API Reference](/docs/api-reference/aggregator_quote) already documents that every `/quote` request must include either a `slippageTolerance` or an `autoSlippage` field. That requirement has not been enforced. Starting October 4, 2026, requests that omit both fields will be rejected. + +**Why is this changing?** + +This change ensures that integrators or their end users explicitly choose a slippage setting, rather than relying on an implicit default that may not match their intent. + +**What do I need to do?** + +If your `/quote` requests do not currently set `slippageTolerance` or `autoSlippage`, you must start setting one of them, as described in the [`/quote` API Reference](/docs/api-reference/aggregator_quote). If you already set one of these fields on each request, no change is required. diff --git a/content/changelog/active-notifications/improved-api-error-codes.mdx b/content/changelog/active-notifications/improved-api-error-codes.mdx new file mode 100644 index 000000000..087641823 --- /dev/null +++ b/content/changelog/active-notifications/improved-api-error-codes.mdx @@ -0,0 +1,42 @@ +--- +title: 'Improved API Error Codes' +description: 'Posted: August 20, 2026 | Effective: September 4, 2026' +type: changelog +datePublished: '2026-08-20' +--- + +Additional HTTP 404 error codes that provide more informative error reasons are being added to the `/quote` endpoint of the API. + +**What is changing?** + +When a `/quote` request returns an HTTP 404, the response will include more specific `errorCode` values and a `detail` field. + +| `errorCode` | Meaning | Retry? | +| --- | --- | --- | +| `QuoteAmountTooLowError` | Below the minimum quotable size for the requested protocol (e.g. UniswapX per-chain minimums) | No | +| `NoRouteFoundError` | Routing completed, but no viable route was found | No | +| `UnsupportedTokenError` | Token is not routable (e.g. unknown, blocklisted, or on the wrong chain) | No | +| `UnsupportedChainError` | Chain is not supported for the requested operation | No | +| `UniswapXNotSupportedOnChainError` | The requested UniswapX variant is not supported on this chain | No | +| `UpstreamTimeoutError` | A routing dependency timed out or errored; it is unknown whether a route exists | Yes | +| `ResourceNotFound` (fallback) | Unclassified failure | Yes (conditionally) | + +For clarity, the HTTP 404 error structure is not changing and will continue to look like: + +```json +{ + "errorCode": "UnsupportedTokenError", + "detail": "Token not routable (unknown / blocklisted / wrong chain)", + "requestId": "a00382a5539523928a4f997974dd27eb" +} +``` + +**Why is this changing?** + +Except for field-level validation errors, the `/quote` endpoint usually returned an `errorCode` of `ResourceNotFound` when it could not return a quote. This catch-all error was not specific enough for integrators to tell users whether to retry the request or change its parameters. + +**What do I need to do?** + +If you parse the `errorCode` field for specific actions or display, add handling for the new error codes. We also recommend a default case so your integration can tolerate additional error codes in the future. + +If you pass through the `detail` field from an HTTP 404 response to your users or interface, no change is needed. diff --git a/content/changelog/active-notifications/meta.json b/content/changelog/active-notifications/meta.json index 9780d5b31..24f3a8778 100644 --- a/content/changelog/active-notifications/meta.json +++ b/content/changelog/active-notifications/meta.json @@ -1,13 +1,8 @@ { "title": "Active Notifications", "pages": [ - "uniswapx-live-on-robinhood-chain", - "sunset-of-blast-support", - "uniswapx-rfq-auctions-on-base-and-arbitrum", - "uniswapx-live-on-avalanche-base-bnb-and-tempo", - "recipient-parameter-on-trading-api", - "sunset-of-api-key-based-fees-and-fields", - "proxy-approval", - "setting-a-fee-through-the-api" + "sunset-of-universal-router-2-0-and-2-1-1", + "enforcement-of-slippage-validation", + "improved-api-error-codes" ] } diff --git a/content/changelog/active-notifications/proxy-approval.mdx b/content/changelog/active-notifications/proxy-approval.mdx deleted file mode 100644 index aeb21e846..000000000 --- a/content/changelog/active-notifications/proxy-approval.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: 'Proxy Approval' -description: 'Posted: March 11, 2026 | Effective: March 17, 2026' -type: changelog -datePublished: '2026-03-11' ---- - -We are introducing a new swap approval workflow that requires just two signatures. - -**What is changing?** - -Today, swap approval through Permit2 can require up to three signatures. Proxy Approval reduces that to two signatures. - -How it works: the user approves spending to a proxy contract (a thin wrapper around Universal Router), then signs the swap. Tokens move from the user's wallet to the proxy contract and are forwarded to Universal Router to complete the swap. - -**Why is this changing?** - -This swap approval workflow is being introduced as a compatibility option for integrators with workflows that expect the swapper to directly approve the router contract to spend the swapper's tokens. - -**What do I need to do?** - -If you already have a workflow using Permit2, you do not need to make any change. If you have struggled to integrate Permit2 approval, this new workflow may be for you. Read the full [integration guide](/docs/trading/swapping-api/concepts/no-permit2-workflow). - -We still highly recommend using Permit2 approval for maximum security for your end users. diff --git a/content/changelog/active-notifications/recipient-parameter-on-trading-api.mdx b/content/changelog/active-notifications/recipient-parameter-on-trading-api.mdx deleted file mode 100644 index f8a64ecef..000000000 --- a/content/changelog/active-notifications/recipient-parameter-on-trading-api.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: 'Custom Recipient on Trading API' -description: 'Posted: May 5, 2026 | Effective: May 6, 2026' -type: changelog -datePublished: '2026-05-05' ---- - -The Uniswap Trading API now supports an optional `recipient` parameter that routes swap output tokens to a different address than the swapper. - -**What changed?** - -The `/quote`, `/swap`, and `/order` endpoints now accept an optional `recipient` field. When provided, the output of the swap is delivered to the `recipient` address instead of the original swapper. Input tokens are still pulled from `swapper`. - -The new field is supported across all routing types currently offered by the Trading API, including UniswapX (DutchV2 and DutchV3 orders) and onchain AMM swaps via the Universal Router. - -**Why did this change?** - -This is a first step toward enabling payment flows through the Trading API, where an integrator may want the swap output to land on an address other than the wallet performing the swap. Beyond payments, it unlocks use cases such as funding a smart account, settling to a treasury address, or routing proceeds to a contract. - -**What do I need to do?** - -Nothing. The `recipient` field is optional and fully backwards-compatible. When omitted, swap output continues to go to the `swapper` address as before, so existing integrations require no changes. - -To use the new behavior, include `recipient` in your `/quote` request and the field will flow through the rest of the swap pipeline. See the [API reference](/docs/api-reference) for the updated request schema. - -The `/send` endpoint is unaffected because it already accepts a recipient. diff --git a/content/changelog/active-notifications/setting-a-fee-through-the-api.mdx b/content/changelog/active-notifications/setting-a-fee-through-the-api.mdx deleted file mode 100644 index 605b510c1..000000000 --- a/content/changelog/active-notifications/setting-a-fee-through-the-api.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: 'Setting A Fee Through the API' -description: 'Posted: March 6, 2026 | Effective: March 17, 2026' -type: changelog -datePublished: '2026-03-06' ---- - -API integrators can now set a fee for themselves directly in their API request. - -**What changed?** - -The `/quote` endpoint of the Uniswap API now supports [a new `integratorFee` field](/docs/api-reference/aggregator_quote) which permits setting one fee in basis points, and the recipient for that fee. Any fee provided in the `/quote` request will be included in the `/quote` response (`aggregatedOutputs` and all `portion` fields) and subsequently coded into the calldata returned by the `/swap` response. - -The integrator fee also supports setting a fee in fractional basis points, down to two decimal places of precision (for example, `"bps":10.25`). - -**Why did this change?** - -We have had strong demand from many integrators to give them more flexibility in establishing non-linear fee structures. Additionally, many builders have been slowed down by needing to contact us in order to establish a fee and fee recipient on an API key, which is traditionally how integrators would set fees. - -**What do I need to do?** - -If you set a fee through your API key, we strongly recommend now setting your fee through these fields and removing the fee from your API key. Contact your Uniswap Labs account manager to arrange removal of your static API key-based fee. - -If you want to set a fee with a fractional basis point value, you must ensure that you set the `x-universal-router-version` header to `2.1.1`. Only this newer version of universal router supports taking fractional basis points. diff --git a/content/changelog/active-notifications/sunset-of-api-key-based-fees-and-fields.mdx b/content/changelog/active-notifications/sunset-of-api-key-based-fees-and-fields.mdx deleted file mode 100644 index ba5f08fbd..000000000 --- a/content/changelog/active-notifications/sunset-of-api-key-based-fees-and-fields.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: 'Sunset of API Key-Based Fees and Fields' -description: 'Posted: March 17, 2026 | Effective: May 18, 2026' -type: changelog -datePublished: '2026-03-17' ---- - -We will be modifying how API integrators take fees from swappers, including the sunset of multiple features: - -- Uniswap setting fees for integrators on API keys -- The `portionBips`, `portionAmount`, and `portionRecipient` fields in the `/quote` response - -These features are superseded by the ability to [set fees in API requests](/docs/changelog/active-notifications/setting-a-fee-through-the-api), and by the introduction of a new `fee` field in the `/quote` response. - -**What is changing?** - -Uniswap Labs will remove all statically set fees and fee recipient addresses from its systems. Swapper fees paid to integrators will no longer be set through the integrator specifying a fee and recipient on the API key which made the request. - -The `portionBips`, `portionAmount`, and `portionRecipient` fields will be removed from the `/quote` response and no longer be required to make a `/swap` request. - -A new fee string field will be provided in each aggregatedOutputs object indicating whether the output is a fee (`INTEGRATOR`) or is not a fee (field not included in the object). - -**Why is this changing?** - -Removing fees on API keys prevents integrators from having conflicting fee information stored against the API key and in the swap message through the recently introduced `integratorFees` field. All fees to swappers are only set by the integrator directly through their own code in the `integratorFees` fields. This change is intended to provide more clarity and transparency to integrators and their swappers on what fees are applied to a swap. - -Removing the `portion` fields simplifies the `/quote` response by removing duplicate information. The `aggregatedOutputs` fields are better structured for programmatic consumption of multiple outputs but lacked a clear indicator of which field was a fee. These changes lay the groundwork for Uniswap to continue innovating on multi-output swaps. - -**What do I need to do?** - -If you currently set a fee through your API key and wish to continue receiving a fee from your customers, you must make a change to set that fee through the recently introduced `integratorFees` fields. - -If you currently consume any of the `portion` fields, you must update your logic to read from the `aggregatedOutputs` objects, and may optionally use the new `fee` indicator to identify which output is the fee versus the principal swap result. diff --git a/content/changelog/active-notifications/sunset-of-universal-router-2-0-and-2-1-1.mdx b/content/changelog/active-notifications/sunset-of-universal-router-2-0-and-2-1-1.mdx new file mode 100644 index 000000000..ec8562f19 --- /dev/null +++ b/content/changelog/active-notifications/sunset-of-universal-router-2-0-and-2-1-1.mdx @@ -0,0 +1,26 @@ +--- +title: 'Sunset of Universal Router 2.0 and 2.1.1' +description: 'Posted: September 21, 2026 | Effective: October 21, 2026' +type: changelog +datePublished: '2026-09-21' +--- + +We are introducing Universal Router 2.1.2 as of September 21, 2026, and sunsetting support for Universal Router 2.0 and 2.1.1 on October 21, 2026. + +**What is changing?** + +Universal Router 2.1.2 is deployed across the chains listed on [Supported Chains](/docs/trading/swapping-api/supported-chains), and the API already routes to it by default. Universal Router 2.1.2 is the new recommended version for all API integrators. Starting October 21, 2026, requests that pin 2.0 or 2.1.1 through the `x-universal-router-version` header will cause an error response from the API. + +**Why is this changing?** + +The new version of Universal Router carries important improvements and fixes, including all of the changes in Universal Router 2.1.1. To reduce operational complexity and to simplify the integration experience, we are sunsetting the older versions of Universal Router. + +**What do I need to do?** + +If you pin a router version with the `x-universal-router-version` header, set it to `2.1.2` or drop the header to take the API default. If you allowlist router addresses in a wallet or in a contract, add the 2.1.2 address for every chain you use. + +Moving from 2.1.1 to 2.1.2 does not require any change aside from accepting the new Universal Router 2.1.2 address. There are no calldata or ABI changes, so a 2.1.1 integration can repoint to the 2.1.2 addresses without requiring any SDK, parsing, or other changes in calldata processing. + +Moving from 2.0 to 2.1.2 does require changes beyond accepting the new Universal Router address, if you parse the calldata. New arguments and commands meaningfully change the calldata and may require that you update the SDK you use if you parse the calldata. See [SDK compatibility for decoding calldata](/docs/trading/swapping-api/supported-chains#sdk-compatibility-for-decoding-calldata) for the SDK release and `UniversalRouterVersion` to use. + +If you do not set the `x-universal-router-version` header, you will automatically receive Universal Router 2.1.2. diff --git a/content/changelog/active-notifications/uniswapx-live-on-avalanche-base-bnb-and-tempo.mdx b/content/changelog/active-notifications/uniswapx-live-on-avalanche-base-bnb-and-tempo.mdx deleted file mode 100644 index 98d9e59eb..000000000 --- a/content/changelog/active-notifications/uniswapx-live-on-avalanche-base-bnb-and-tempo.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: 'UniswapX Live on Avalanche, Base, BNB Smart Chain, and Tempo' -description: 'Posted: June 9, 2026 | Effective: June 9, 2026' -type: changelog -datePublished: '2026-06-09' ---- - -[UniswapX](/docs/liquidity/uniswapx/overview), Uniswap's intent-based execution layer, is now live on Avalanche, Base, BNB Smart Chain, and Tempo. The Uniswap API will [route swaps through UniswapX](/docs/trading/swapping-api/amm-vs-uniswapx-routing) on these chains when it offers the better priced route, bringing MEV protection, gasless swaps, and a competitive market maker network into the same API call you already make. - -**What changed?** - -UniswapX is available on Avalanche, Base, BNB Smart Chain, and Tempo through the Trading API, and the `/quote` request now accepts a new `UNISWAPX_LATEST` value in the `protocols` field. - -`UNISWAPX_LATEST` always resolves to the current UniswapX version on each chain. Requesting it means you receive UniswapX quotes on these chains today, and on future chains as UniswapX launches on them, without changing your request again. You can still pin a specific version by requesting `UNISWAPX_V2` or `UNISWAPX_V3`, although not every chain supports both versions. The newly launched chains currently offer `UNISWAPX_V3`, while `UNISWAPX_V2` remains relevant on other chains such as Mainnet. - -**Why did this change?** - -Expanding UniswapX to more chains gives swappers access to MEV protection, gasless swaps, and competitive filler pricing. - -We are rolling this out for 30 days as an explicit opt-in, where integrators must set `UNISWAPX_LATEST` in their `protocols` field if they want to try UniswapX on these new chains. After 30 days, requests that do not set `protocols` will receive UniswapX quotes on all chains where UniswapX is available, matching the behavior most integrators already expect. - -**What do I need to do?** - -If you set the `protocols` field in your `/quote` requests and want UniswapX quotes on these chains today, include `UNISWAPX_LATEST` along with any AMM protocols you already request (`V2`, `V3`, and/or `V4`). - -Because UniswapX quotes use different response shapes than AMM quotes, confirm your `/quote` parsing handles the routing types you may now receive. Check the top-level `routing` field on the response and parse the matching `quote` object: - -- If you request `UNISWAPX_V3`, handle `routing: "DUTCH_V3"` with a `DutchQuoteV3` quote. -- If you request `UNISWAPX_LATEST`, handle `routing: "DUTCH_V2"` (`DutchQuoteV2`), `routing: "DUTCH_V3"` (`DutchQuoteV3`), and `routing: "PRIORITY"` (`PriorityQuote`), depending on the chain. - -See the [integration guide](/docs/trading/swapping-api/integration-guide) for response handling details. - -Effective July 9, 2026, this becomes the default: requests that do not set a `protocols` field will receive UniswapX quotes for any chain where UniswapX is available. If you set `protocols` and do not include `UNISWAPX_LATEST` (or a specific UniswapX version such as `UNISWAPX_V2` or `UNISWAPX_V3`), you will not receive UniswapX quotes on these chains. - -If you set `protocols` explicitly and do not want UniswapX on a given chain, request only the AMM protocols you need (`V2`, `V3`, and/or `V4`) and omit `UNISWAPX_LATEST`, `UNISWAPX_V2`, and `UNISWAPX_V3`. diff --git a/content/changelog/active-notifications/uniswapx-live-on-robinhood-chain.mdx b/content/changelog/active-notifications/uniswapx-live-on-robinhood-chain.mdx deleted file mode 100644 index 8fa54a992..000000000 --- a/content/changelog/active-notifications/uniswapx-live-on-robinhood-chain.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: 'UniswapX Live on Robinhood Chain' -description: 'Posted: July 1, 2026 | Effective: July 1, 2026' -type: changelog -datePublished: '2026-07-01' ---- - -[UniswapX](/docs/liquidity/uniswapx/overview), Uniswap's intent-based execution layer, is now live on Robinhood Chain (chainId `4663`), alongside the Uniswap Protocol (v2, v3, v4), the Apps, and the API. The Uniswap API will [route swaps through UniswapX](/docs/trading/swapping-api/amm-vs-uniswapx-routing) on Robinhood Chain when it offers the better priced route, bringing MEV protection, gasless swaps, and a competitive market maker network into the same API call you already make. - -**What changed?** - -UniswapX is available on Robinhood Chain through the Trading API. Robinhood Chain uses the Dutch V3 reactor, so the `/quote` request accepts `UNISWAPX_LATEST` or `UNISWAPX_V3` in the `protocols` field. `UNISWAPX_LATEST` always resolves to the current UniswapX version on each chain, so requesting it returns UniswapX quotes on Robinhood Chain today and on future chains as UniswapX launches on them. - -Reactor, quoter, and Permit2 addresses are on the [UniswapX Deployments](/docs/liquidity/uniswapx/deployments) page, and the full contract set is on the [v3](/docs/protocols/v3/deployments/v3-robinhood-chain-deployments) and [v4](/docs/protocols/v4/deployments) deployments pages. - -**Why did this change?** - -Expanding UniswapX to Robinhood Chain gives swappers access to MEV protection, gasless swaps, and competitive filler pricing. - -**What do I need to do?** - -If you are a filler or quoter, Robinhood Chain serves UniswapX orders through the Dutch V3 reactor. Exclusive quoters onboarded to the RFQ have access to these orders immediately. See [Filling on Dutch V3 chains](/docs/liquidity/uniswapx/filling/dutch-v3-chains/filling-on-dutch-v3-chains) for the execution flow. - -Confirm your quoter inspects `tokenInChainId` on incoming requests so you do not quote on chains you do not support. Respond with HTTP status code `204` for any chain you do not want to quote. - -If you set the `protocols` field in your `/quote` requests and want UniswapX quotes on Robinhood Chain, include `UNISWAPX_LATEST` (or `UNISWAPX_V3`) along with any AMM protocols you already request (`V2`, `V3`, and/or `V4`). Because UniswapX quotes use different response shapes than AMM quotes, confirm your `/quote` parsing handles `routing: "DUTCH_V3"` with a `DutchQuoteV3` quote. See the [integration guide](/docs/trading/swapping-api/integration-guide) for response handling details. diff --git a/content/changelog/active-notifications/uniswapx-rfq-auctions-on-base-and-arbitrum.mdx b/content/changelog/active-notifications/uniswapx-rfq-auctions-on-base-and-arbitrum.mdx deleted file mode 100644 index 6aa5a2ad4..000000000 --- a/content/changelog/active-notifications/uniswapx-rfq-auctions-on-base-and-arbitrum.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: 'UniswapX RFQ Auctions on Base and Arbitrum' -description: 'Posted: June 13, 2026 | Effective: June 13, 2026' -type: changelog -datePublished: '2026-06-13' ---- - -[UniswapX](/docs/liquidity/uniswapx/overview), Uniswap's intent-based execution layer, now runs [RFQ auctions](/docs/liquidity/uniswapx/concepts/auction-types) on Base and Arbitrum. The Uniswap API will [route swaps through UniswapX](/docs/trading/swapping-api/amm-vs-uniswapx-routing) on these chains when it offers the better priced route. With RFQ, a quoter parameterizes each order and holds an exclusivity window to fill it before the order opens to permissionless fillers. - -**What changed?** - -RFQ is now available for Base and Arbitrum. - -- **Base** moves from Priority auctions to DutchV3 auctions. Fillers integrated against the `PriorityOrderReactor` need to update their integration to handle DutchV3 orders. -- **Arbitrum** moves from open Dutch auctions to RFQ. The winning quoter now holds an exclusivity window before the order becomes permissionless. - -Filling remains permissionless on both chains, but only after the exclusivity window. - -**What do I need to do?** - -**If you are a Uniswap API integrator** - -No action is required. You can keep requesting UniswapX by leaving the `protocols` field out of your `/quote` request, which is the existing default. To request UniswapX explicitly on these chains, include `UNISWAPX_V3` in the `protocols` field. - -**If you are a filler** - -To compete for order flow during the exclusivity window, join the quoter set: - -- Update your integration to handle DutchV3 orders. See [Filling Dutch V3 Auctions](/docs/liquidity/uniswapx/filling/dutch-v3-chains/filling-on-dutch-v3-chains) and the reactor addresses on the [deployments page](/docs/liquidity/uniswapx/deployments#base). -- To verify ownership of your filler address, sign a message with the EOA wallet that has been submitting your fills, and Uniswap confirms it against onchain UniswapX activity. - -If you have questions, you can reach out to the team here. diff --git a/content/changelog/completed-notifications/meta.json b/content/changelog/completed-notifications/meta.json index 5f6004029..e83b4a7d8 100644 --- a/content/changelog/completed-notifications/meta.json +++ b/content/changelog/completed-notifications/meta.json @@ -1,7 +1,8 @@ { "title": "Completed Notifications", "pages": [ - "sunset-of-legacy-routing-preference-options", + "removal-of-api-amm-slippage-cap", + "sunset-of-blast-support", "live-on-unichain-flashblocks-200ms-sub-blocks", "live-on-unichain-fair-transaction-ordering-and-mev-protection", "upgrade-13-opcm-and-incident-response-improvements", diff --git a/content/changelog/completed-notifications/removal-of-api-amm-slippage-cap.mdx b/content/changelog/completed-notifications/removal-of-api-amm-slippage-cap.mdx new file mode 100644 index 000000000..13e7fcdf8 --- /dev/null +++ b/content/changelog/completed-notifications/removal-of-api-amm-slippage-cap.mdx @@ -0,0 +1,22 @@ +--- +title: 'Removal of API AMM slippageTolerance Cap' +description: 'Posted: August 20, 2026 | Effective: August 21, 2026' +type: changelog +datePublished: '2026-08-20' +--- + +The `slippageTolerance` field will allow any value from 0 to 100, inclusive, with up to two decimal places of precision. This will be applied correctly to AMM orders. + +**What is changing?** + +The `slippageTolerance` field on the `/quote` request was previously capped at 20% (`20`) for AMM orders. `/quote` requests with slippage set higher than 20% would fail with "No quotes available," or would fall back to UniswapX if allowed by the request. After this change, you can set slippage as high as 100% and still receive an AMM response. + +Requests with slippage below 0, above 100, using more than 2 decimal places, or providing a non-number will continue to fail with a field validation error. + +**Why is this changing?** + +The silent failure behavior was misleading and prevented integrators from offering wider slippage ranges to their end users. + +**What do I need to do?** + +No change is required for existing integrators. You may continue to keep your own slippage caps in your interface, or allow users to set any slippage from 0% to 100%. diff --git a/content/changelog/active-notifications/sunset-of-blast-support.mdx b/content/changelog/completed-notifications/sunset-of-blast-support.mdx similarity index 100% rename from content/changelog/active-notifications/sunset-of-blast-support.mdx rename to content/changelog/completed-notifications/sunset-of-blast-support.mdx diff --git a/content/changelog/completed-notifications/sunset-of-legacy-routing-preference-options.mdx b/content/changelog/completed-notifications/sunset-of-legacy-routing-preference-options.mdx deleted file mode 100644 index a43891293..000000000 --- a/content/changelog/completed-notifications/sunset-of-legacy-routing-preference-options.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: 'Sunset of Legacy routingPreference Options' -description: 'Posted: July 18th, 2025 | Effective: February 11th, 2026' -type: changelog -datePublished: '2025-07-18' ---- - -Support for multiple legacy options for the *routingPreference* field in the /quote request has been sunset. - -**What changed?** - -The *routingPreference* field in the /quote request now only supports the values *BEST_PRICE* or *FASTEST*. The legacy values of *CLASSIC*, *BEST_PRICE_V2*, *UNISWAPX_V2*, *V3_ONLY*, and *V2_ONLY* have been removed. Submitting a request with one of these legacy values will result in an error. - -**Why did this change?** - -This change clarifies API request intent and allows Uniswap Labs to expand the options for routing in the future. The *routingPreference* field now only indicates the method of routing, whereas the *protocols* field indicates the protocols to be considered while executing the routing method. - -**What do I need to do?** - -If you are still specifying a deprecated *routingPreference* value, you **must** update your requests to use one of the supported values (*BEST_PRICE* or *FASTEST*). You **may** also use the *protocols* field to more narrowly limit which protocols are considered for your /quote requests. - -If you do not specify any value for *routingPreference*, the default is *BEST_PRICE*. - -## Legacy routingPreference to protocols Equivalency - -The following table maps deprecated *routingPreference* values to equivalent *protocols* field values: - -| Legacy `routingPreference` Value | Equivalent `protocols` Value | -| :------------------------------- | :--------------------------- | -| CLASSIC | V2, V3, V4 | -| UNISWAPX_V2 | UNISWAPX_V2 | -| BEST_PRICE_V2 | V2, V3, V4, UNISWAPX_V2 | -| V2_ONLY | V2 | -| V3_ONLY | V3 | diff --git a/content/changelog/index.mdx b/content/changelog/index.mdx index 2a5b600d2..18f4a6316 100644 --- a/content/changelog/index.mdx +++ b/content/changelog/index.mdx @@ -7,36 +7,24 @@ type: changelog-index # document identifiers, so using the production host on every environment keeps the # rich-result and citation graph consistent. Do NOT swap in a staging or preview URL. entries: - - name: UniswapX Live on Robinhood Chain - url: https://developers.uniswap.org/docs/changelog/active-notifications/uniswapx-live-on-robinhood-chain - datePublished: '2026-07-01' + - name: Sunset of Universal Router 2.0 and 2.1.1 + url: https://developers.uniswap.org/docs/changelog/active-notifications/sunset-of-universal-router-2-0-and-2-1-1 + datePublished: '2026-09-21' + - name: Enforcement of Slippage Validation + url: https://developers.uniswap.org/docs/changelog/active-notifications/enforcement-of-slippage-validation + datePublished: '2026-09-04' + - name: Improved API Error Codes + url: https://developers.uniswap.org/docs/changelog/active-notifications/improved-api-error-codes + datePublished: '2026-08-20' + - name: Removal of API AMM slippageTolerance Cap + url: https://developers.uniswap.org/docs/changelog/completed-notifications/removal-of-api-amm-slippage-cap + datePublished: '2026-08-20' - name: Sunset of Blast Support - url: https://developers.uniswap.org/docs/changelog/active-notifications/sunset-of-blast-support + url: https://developers.uniswap.org/docs/changelog/completed-notifications/sunset-of-blast-support datePublished: '2026-06-29' - - name: UniswapX RFQ Auctions on Base and Arbitrum - url: https://developers.uniswap.org/docs/changelog/active-notifications/uniswapx-rfq-auctions-on-base-and-arbitrum - datePublished: '2026-06-13' - - name: UniswapX Live on Avalanche, Base, BNB Smart Chain, and Tempo - url: https://developers.uniswap.org/docs/changelog/active-notifications/uniswapx-live-on-avalanche-base-bnb-and-tempo - datePublished: '2026-06-09' - - name: Custom Recipient on Trading API - url: https://developers.uniswap.org/docs/changelog/active-notifications/recipient-parameter-on-trading-api - datePublished: '2026-05-05' - - name: Sunset of API Key-Based Fees and Fields - url: https://developers.uniswap.org/docs/changelog/active-notifications/sunset-of-api-key-based-fees-and-fields - datePublished: '2026-03-17' - - name: Proxy Approval - url: https://developers.uniswap.org/docs/changelog/active-notifications/proxy-approval - datePublished: '2026-03-11' - - name: Setting A Fee Through the API - url: https://developers.uniswap.org/docs/changelog/active-notifications/setting-a-fee-through-the-api - datePublished: '2026-03-06' - name: 'Live on Unichain: Flashblocks 200ms Sub-Blocks' url: https://developers.uniswap.org/docs/changelog/completed-notifications/live-on-unichain-flashblocks-200ms-sub-blocks datePublished: '2025-08-14' - - name: 'Sunset of Legacy routingPreference Options' - url: https://developers.uniswap.org/docs/changelog/completed-notifications/sunset-of-legacy-routing-preference-options - datePublished: '2025-07-18' - name: 'Live on Unichain: Fair Transaction Ordering and MEV Protection' url: https://developers.uniswap.org/docs/changelog/completed-notifications/live-on-unichain-fair-transaction-ordering-and-mev-protection datePublished: '2025-05-01' diff --git a/content/community/learning/courses-and-books.mdx b/content/community/learning/courses-and-books.mdx index 31e020ac0..0d180a598 100644 --- a/content/community/learning/courses-and-books.mdx +++ b/content/community/learning/courses-and-books.mdx @@ -23,4 +23,4 @@ These resources are created and maintained independently. They are not official If you've created a course or book about Uniswap, we'd love to feature it. -Submit a request through our help center with the resource name, link, a short description, and your contact info. +Submit a request through our Help Center with the resource name, link, a short description, and your contact info. diff --git a/content/community/learning/hook-discovery.mdx b/content/community/learning/hook-discovery.mdx index 9bfd71164..ba7aee350 100644 --- a/content/community/learning/hook-discovery.mdx +++ b/content/community/learning/hook-discovery.mdx @@ -20,4 +20,4 @@ These directories index third-party hooks. Always verify hook contracts independ If you maintain a hook directory or catalog, we'd love to feature it. -Submit a request through our help center with the resource name, link, a short description, and your contact info. +Submit a request through our Help Center with the resource name, link, a short description, and your contact info. diff --git a/content/community/tooling/overview.mdx b/content/community/tooling/overview.mdx index 8e3209ab5..a9a5f6774 100644 --- a/content/community/tooling/overview.mdx +++ b/content/community/tooling/overview.mdx @@ -1,5 +1,6 @@ --- -title: Overview +title: Community Tooling Overview +sidebarTitle: Overview description: Community-built tools, libraries, and integrations for the Uniswap ecosystem. --- @@ -24,4 +25,4 @@ The tools listed here are community-maintained and not officially supported by U If you've built a tool, library, or integration for the Uniswap ecosystem, we'd love to feature it. -Submit a request through our help center with the project name, link, a short description, and your contact info. +Submit a request through our Help Center with the project name, link, a short description, and your contact info. diff --git a/content/ecosystem/builder-support/build-with-us.mdx b/content/ecosystem/builder-support/build-with-us.mdx new file mode 100644 index 000000000..fb9b954e6 --- /dev/null +++ b/content/ecosystem/builder-support/build-with-us.mdx @@ -0,0 +1,75 @@ +--- +title: Build with Us +description: Get your hooks and quoters allowlisted for routing, work with Uniswap Labs on custom hooks, and bring permissioned assets onchain. +--- + +Programs for teams building on Uniswap: routing allowlists for hooks and quoters, and a direct line to Uniswap Labs for hook development. + +## Uniswap v4 Hooks Routing Allowlist + +Eligible integrators building with custom hooks can apply for inclusion in the hook routing allowlist. + +You only need to fill in this form if your hook: + +- Has a deployment address starting with `0x91` +- Uses any of the following flags: `beforeSwapReturnsDelta`, `afterSwapReturnsDelta`, or `dynamicFees` + +If your hook meets neither of these criteria, it is already automatically allowlisted and you do not need to fill in this form. + +The contract deployed at the hook address must have its source code verified on the chain's block explorer, matching the deployed bytecode. Submissions with unverified contracts are rejected. A public repository does not substitute for explorer verification. + +**What you get** + +- Your hooks allowlisted for routing in the Labs interface +- Swap order flow from the Labs interface routed through your hook-enabled pools + +[Learn how custom hooks work in the Labs interface](https://support.uniswap.org/hc/en-us/articles/33829289869965-How-do-custom-hooks-work-in-the-Labs-interface) + +[Review the full allowlisting criteria](https://support.uniswap.org/hc/en-us/articles/48291859140621-Routing-for-hooked-pools) + +Submit your hook + +## UniswapX Quoters Allowlist + +Apply to become a quoter for UniswapX on mainnet. Quoters source liquidity for UniswapX orders and participate in competitive auction-based execution. + +**What you get** + +- Access to UniswapX order flow on mainnet +- Direct integration with Uniswap's auction infrastructure + +For questions or to discuss eligibility, reach out at [quoters@uniswap.org](mailto:quoters@uniswap.org). + +Apply as a Quoter + +## Uniswap Labs Custom Hooks + +Uniswap Labs builds v4 hooks with asset issuers, liquidity providers, and protocols. If your use case needs bespoke infrastructure or support for a new asset class, tell us what you are building and the team will follow up. + +**What you get** + +- A direct line to the Uniswap Labs hooks team to scope your use case +- Guidance on adapting an existing Labs hook or building a new one + +Register your interest + +## Uniswap v4 Permissioned Pools + +Bring a tokenized or permissioned asset onchain with Uniswap v4 permissioned pools, where an onchain allowlist controls who can trade and provide liquidity. + +**What you get** + +- A direct line to the team to discuss your asset and integration +- Support allowlisting your permissioned pool with Uniswap Labs to be eligible for routing in the Uniswap interface and API + +If you are exploring and want the team to follow up, register your interest. If you are an issuer with a deployed, verified permissioned token, request allowlisting for routing. + +
Register your interest
+ +
Request allowlisting
+ +## Hackathon Feedback + +Built with Uniswap at a hackathon? We want to keep improving the docs, tools, and support we offer builders, and your experience tells us where to focus. It takes a few minutes. + +Share your hackathon feedback diff --git a/content/ecosystem/builder-support/get-funded.mdx b/content/ecosystem/builder-support/get-funded.mdx index 873aa4c27..7fbb8917b 100644 --- a/content/ecosystem/builder-support/get-funded.mdx +++ b/content/ecosystem/builder-support/get-funded.mdx @@ -1,6 +1,6 @@ --- title: Funding -description: Explore grants, incubators, and funding programs available to Uniswap ecosystem builders. +description: Explore grants and funding programs available to Uniswap ecosystem builders. --- [The Uniswap Foundation](https://www.uniswapfoundation.org/) and ecosystem contributors provide funding pathways for research, tooling, and product development. @@ -22,42 +22,6 @@ The Uniswap Foundation funds projects across protocols, tooling, research, gover [Apply for Uniswap Foundation Grants](https://share.hsforms.com/1fxQjPQTgTYmPwlYxxKlSGQsdca9) -## Unichain Grants - -Unichain Grants support teams building applications, infrastructure, and ecosystem tooling on Unichain. - -**What you get** - -- Funding support aligned to project scope and milestones -- Ecosystem support for teams building on Unichain -- Access to technical and builder resources - -[Apply for Unichain Grants](https://share.hsforms.com/18Kv3hTvDSt-x1wK9va0OYwsdca9) - -## Uniswap Hook Incubator - -The Uniswap Hook Incubator is an async program focused on Uniswap v4 hook development. - -**Who it is for** - -- Experienced Solidity developers -- Teams with DeFi experience -- Builders exploring new hook-based primitives - -**What you get** - -- Fully covered tuition -- Up to $40k in prizes -- Access to DeFi experts and a Uniswap v4 builder community - -[Apply for the Uniswap Hook Incubator](https://atrium.academy/uniswap) - -## Uniswap v4 Hooks Support - -This program provides support for building and shipping Uniswap v4 hooks. - -[Apply for Uniswap v4 Hooks Support](/v4-hooks-support) - ## UFSF Audit Subsidies The Uniswap Foundation Security Fund (UFSF) provides access to security audits at reduced or no cost through a vetted provider process. diff --git a/content/ecosystem/builder-support/get-reach.mdx b/content/ecosystem/builder-support/get-reach.mdx deleted file mode 100644 index 23c7b2736..000000000 --- a/content/ecosystem/builder-support/get-reach.mdx +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: GTM Support -description: Explore co-marketing and allowlist programs to amplify your Uniswap integration. ---- - -Apply to programs that help your project gain visibility, traction, and direct integration across the Uniswap ecosystem. - -## Uniswap Labs Co-Marketing - -Co-marketing opportunities for teams that have shipped Uniswap-powered features or integrations. - -**What you get** - -- Co-announcements, social media amplification, and cross-promotion across Uniswap channels -- Joint blog posts, case studies, and developer spotlights -- Visibility at Uniswap-sponsored events and hackathons - -Apply for Co-Marketing - -## Uniswap v4 Hooks Routing Allowlist - -Eligible integrators building with custom hooks can apply for inclusion in the hook routing allowlist. - -You only need to submit this form if your hook: - -- Uses a delta flag -- Has a deployment address starting with `0x91` -- Is intended for pools with major token pairs (e.g. ETH/USDC) - -If your hook does not meet one of these criteria, it is automatically allowlisted and you do not need to fill in this form. - -**What you get** - -- Your hooks whitelisted for routing in the Labs interface -- Swap order flow from the Labs interface routed through your hook-enabled pools - -[Learn how custom hooks work in the Labs interface](https://support.uniswap.org/hc/en-us/articles/33829289869965-How-do-custom-hooks-work-in-the-Labs-interface) - -Submit your hook - -## UniswapX Quoters Allowlist - -Apply to become a quoter for UniswapX on mainnet. Quoters source liquidity for UniswapX orders and participate in competitive auction-based execution. - -**What you get** - -- Access to UniswapX order flow on mainnet -- Direct integration with Uniswap's auction infrastructure - -For questions or to discuss eligibility, reach out at [quoters@uniswap.org](mailto:quoters@uniswap.org). - -Apply as a Quoter diff --git a/content/ecosystem/builder-support/meta.json b/content/ecosystem/builder-support/meta.json index b47fabd83..deb9ecf90 100644 --- a/content/ecosystem/builder-support/meta.json +++ b/content/ecosystem/builder-support/meta.json @@ -1,4 +1,4 @@ { "title": "Builder Support", - "pages": ["get-funded", "get-reach","security-resources"] + "pages": ["build-with-us", "get-funded", "security-resources"] } diff --git a/content/ecosystem/builder-support/security-resources.mdx b/content/ecosystem/builder-support/security-resources.mdx index 083370ad8..ee4bd25c5 100644 --- a/content/ecosystem/builder-support/security-resources.mdx +++ b/content/ecosystem/builder-support/security-resources.mdx @@ -1,5 +1,6 @@ --- -title: Security +title: Security Resources +sidebarTitle: Security description: Access security audits, emergency response, and safe harbor programs for Uniswap ecosystem builders. --- diff --git a/content/ecosystem/governance/faqs.mdx b/content/ecosystem/governance/faqs.mdx new file mode 100644 index 000000000..e15b08dd4 --- /dev/null +++ b/content/ecosystem/governance/faqs.mdx @@ -0,0 +1,42 @@ +--- +title: Governance FAQs +description: Answers to common questions about the UNI token, protocol fees, the UNI burn mechanism, and DUNI membership. +--- + +## UNI Token + +### What is UNI? + +UNI is the governance token of the Uniswap Protocol. For supply, distribution, and contract addresses, see the [UNI token](/docs/ecosystem/governance/uni) page. + +### Will the total supply of UNI ever increase? + +While governance has the authority to mint up to 2% of total supply annually, governance has not exercised this authority to date. Any future minting would require a governance vote. + +### What is UNI's current circulating supply? + +Total supply has been declining since the burn mechanism went live in December 2025. As of July 6, 2026, 892,876,000 UNI remains in circulation. You can review data on the protocol fee and UNI circulating supply via [this Dune dashboard](https://dune.com/uniswaplabs/uni-burn-tracker-l1l2/183143e7-2210-4b4d-82df-41220958a26b). + +## Protocol Fees and UNI Burn + +### Do UNI holders earn a share of protocol fees? + +No. Protocol fees are only used to permanently burn UNI, reducing supply over time. UNI holders have no individual or pro-rata claim on protocol revenue and there are no direct distributions of any kind. + +### How does the burn mechanism work? + +Protocol fees collected onchain are routed into a collector contract (TokenJar) on each active network. These fees are claimed by external participants, often called Searchers, who pay in UNI to receive them. The UNI they pay is then permanently burned, reducing total supply. + +### On which products and chains are protocol fees currently active? + +Protocol fee rollout began in December 2025 with v2 and v3 on Ethereum mainnet. Protocol fees are currently active on all Uniswap v2 and v3 pools across the 12 chains listed in the [UNI contract addresses tables](/docs/ecosystem/governance/uni#contract-addresses). Any future protocol fee activation on a different Uniswap version or product (v4, UniswapX, etc.) requires a governance vote. + +## Participation and DUNI + +### What is DUNI, and how does it relate to UNI? + +DUNI is Uniswap Governance's implementation of the Wyoming DUNA, a legal entity that represents UNI holders in the governance process. Notably, DUNI provides limited liability protections for its members. To be a member of DUNI, you must hold UNI tokens (more than 0 UNI) and engage in Uniswap Governance (for example, you delegate your votes, post a proposal, or vote on a proposal). For a full description of its structure and authority, see [DUNI](/docs/ecosystem/governance/overview#duni). + +### How do I use UNI to participate in governance? + +UNI can be used to vote on proposals during active governance processes. In order to vote, UNI needs to be delegated, which you can learn more about in the [guide to voting](/docs/ecosystem/governance/guide-to-voting). For a breakdown of the full governance process, see [Governance Process](/docs/ecosystem/governance/governance-process). diff --git a/content/ecosystem/governance/glossary.mdx b/content/ecosystem/governance/glossary.mdx index f13df3d45..5a4d47c64 100644 --- a/content/ecosystem/governance/glossary.mdx +++ b/content/ecosystem/governance/glossary.mdx @@ -1,6 +1,6 @@ --- -id: glossary -title: Glossary +title: Governance Glossary +sidebarTitle: Glossary description: Key terms and definitions for Uniswap governance, including UNI delegation, proposals, quorum, and voting. type: glossary terms: diff --git a/content/ecosystem/governance/governance-process.mdx b/content/ecosystem/governance/governance-process.mdx index a880f7802..0068d2138 100644 --- a/content/ecosystem/governance/governance-process.mdx +++ b/content/ecosystem/governance/governance-process.mdx @@ -1,5 +1,4 @@ --- -id: process title: Governance Process description: Understand the three-phase Uniswap governance lifecycle, including RFC, Temperature Check, and Onchain Vote. --- diff --git a/content/ecosystem/governance/guide-to-voting.mdx b/content/ecosystem/governance/guide-to-voting.mdx index ef7095ab9..e5a6896cf 100644 --- a/content/ecosystem/governance/guide-to-voting.mdx +++ b/content/ecosystem/governance/guide-to-voting.mdx @@ -1,5 +1,4 @@ --- -id: guide-to-voting title: Guide to Voting description: Learn how to delegate UNI on Agora or Tally and vote on Uniswap governance proposals. --- diff --git a/content/ecosystem/governance/meta.json b/content/ecosystem/governance/meta.json index d6816e602..a4c5eb68f 100644 --- a/content/ecosystem/governance/meta.json +++ b/content/ecosystem/governance/meta.json @@ -1,4 +1,4 @@ { "title": "Governance", - "pages": ["overview", "governance-process", "guide-to-voting", "technical-reference", "glossary"] + "pages": ["overview", "governance-process", "guide-to-voting", "uni", "technical-reference", "faqs", "glossary"] } diff --git a/content/ecosystem/governance/overview.mdx b/content/ecosystem/governance/overview.mdx index 7bc6950d9..e2c84959c 100644 --- a/content/ecosystem/governance/overview.mdx +++ b/content/ecosystem/governance/overview.mdx @@ -1,5 +1,6 @@ --- title: Governance Overview +sidebarTitle: Overview description: Learn how UNI holders govern Uniswap, what DUNI is, and where to continue with governance process and voting. --- @@ -33,6 +34,7 @@ Learn more about [DUNI](https://www.uniswapfoundation.org/duni). ## Where to Go Next +- Learn about supply, distribution, and the burn mechanism on the [UNI token](/docs/ecosystem/governance/uni) page. - Review proposal phases in the [governance process](/docs/ecosystem/governance/governance-process). - Follow delegation and voting steps in the [guide to voting](/docs/ecosystem/governance/guide-to-voting). - Find contract addresses and ABI links in [governance technical reference](/docs/ecosystem/governance/technical-reference). diff --git a/content/ecosystem/governance/uni.mdx b/content/ecosystem/governance/uni.mdx new file mode 100644 index 000000000..70edc324a --- /dev/null +++ b/content/ecosystem/governance/uni.mdx @@ -0,0 +1,92 @@ +--- +title: UNI Token +description: Learn what the UNI token is, its supply and initial distribution, contract addresses, and how protocol fees burn UNI. +--- + +UNI is the governance token of the Uniswap Protocol. UNI holders have governance rights and are represented through [DUNI](/docs/ecosystem/governance/overview#duni). Since December 2025, [protocol fees](/docs/protocols/protocol-fee/overview) collected across Uniswap's products are used to burn UNI, reducing its total supply over time. + +## Token Details + +| Property | Value | +| :---- | :---- | +| Token standard | ERC-20 | +| Total supply at launch | 1,000,000,000 UNI | +| Inflation | No active inflation. Governance has authority to mint up to 2% of total supply annually but has not exercised this to date. | +| Decimals | 18 | + +## Initial Distribution + +At genesis in September 2020, 1 billion UNI were minted and allocated as follows: + +| Recipient | Allocation | Amount | +| :---- | :---- | :---- | +| Community treasury | 43.00% | 430,000,000 UNI | +| Historical users and LPs (immediate airdrop) | 15.00% | 150,000,000 UNI | +| Team and future employees | 21.27% | 212,660,000 UNI | +| Investors | 18.04% | 180,440,000 UNI | +| Advisors | 0.69% | 6,900,000 UNI | + +The remaining 2.00% (20,000,000 UNI) was allocated to an initial liquidity mining program that ran from September to November 2020, per the [UNI genesis announcement](https://blog.uniswap.org/uni). + +The 15% airdrop was immediately claimable by historical liquidity providers, users of Uniswap v1 or v2, and [SOCKS](https://socks.uniswap.org/) token holders, based on a snapshot taken September 1, 2020. + +The community treasury vested over four years on the following schedule, with governance gaining access to vested UNI beginning October 18, 2020: + +| Year | Treasury release | +| :---- | :---- | +| Year 1 | 172,000,000 UNI | +| Year 2 | 129,000,000 UNI | +| Year 3 | 86,000,000 UNI | +| Year 4 | 43,000,000 UNI | + +Team, investor, and advisor allocations vested on the same four-year schedule. All vesting concluded in September 2025. + +## Contract Addresses + +### Ethereum mainnet + +| Contract | Address | +| :---- | :---- | +| UNI Token | [0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984](https://etherscan.io/address/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984) | +| GovernorBravo | [0x408ED6354d4973f66138C91495F2f2FCbd8724C3](https://etherscan.io/address/0x408ED6354d4973f66138C91495F2f2FCbd8724C3) | +| Timelock | [0x1a9C8182C09F50C8318d769245beA52c32BE35BC](https://etherscan.io/address/0x1a9C8182C09F50C8318d769245beA52c32BE35BC) | + +### Other networks + +UNI is available as a bridged token on several networks. Below are the contract addresses for UNI on chains where the protocol fee is active, matching the `releaserUni` values in [govkit](https://github.com/Uniswap/govkit/blob/main/src/types/Uniswap.sol). + +| Network | Address | +| :---- | :---- | +| Arbitrum One | [0xFa7F8980b0f1E64A2062791cc3b0871572f1F7f0](https://arbiscan.io/address/0xFa7F8980b0f1E64A2062791cc3b0871572f1F7f0) | +| OP Mainnet | [0x6fd9d7AD17242c41f7131d257212c54A0e816691](https://optimistic.etherscan.io/address/0x6fd9d7AD17242c41f7131d257212c54A0e816691) | +| Polygon | [0x06e8bdE95BE4ce5cB1134BD47aD18a79fFB35822](https://polygonscan.com/address/0x06e8bdE95BE4ce5cB1134BD47aD18a79fFB35822) | +| Base | [0xc3De830EA07524a0761646a6a4e4be0e114a3C83](https://basescan.org/address/0xc3De830EA07524a0761646a6a4e4be0e114a3C83) | +| BNB Chain | [0x06e8bdE95BE4ce5cB1134BD47aD18a79fFB35822](https://bscscan.com/address/0x06e8bdE95BE4ce5cB1134BD47aD18a79fFB35822) | +| Celo | [0xd7493e84a060292CDca6B67619402F7702336bF4](https://celoscan.io/address/0xd7493e84a060292CDca6B67619402F7702336bF4) | +| Unichain | [0x8f187aA05619a017077f5308904739877ce9eA21](https://uniscan.xyz/address/0x8f187aA05619a017077f5308904739877ce9eA21) | +| World Chain | [0x6fD31f56eb971113bEA12C5883deC68337b3B7b5](https://worldscan.org/address/0x6fD31f56eb971113bEA12C5883deC68337b3B7b5) | +| Soneium | [0x8f187aA05619a017077f5308904739877ce9eA21](https://soneium.blockscout.com/address/0x8f187aA05619a017077f5308904739877ce9eA21) | +| X Layer | [0x57FB37d035e6Ad0E687E0a50dC3F515691deB815](https://www.oklink.com/xlayer/address/0x57FB37d035e6Ad0E687E0a50dC3F515691deB815) | +| Zora | [0xE7798f023fC62146e8Aa1b36Da45fb70855a77Ea](https://explorer.zora.energy/address/0xE7798f023fC62146e8Aa1b36Da45fb70855a77Ea) | + +## How UNI Is Used + +### Governance + +UNI holders govern the Uniswap Protocol through onchain voting. Governance authority includes: + +- Setting and modifying protocol fee parameters +- Approving treasury allocations +- Minting additional UNI, up to 2% of total supply annually + +For the full governance process, see [Governance Process](/docs/ecosystem/governance/governance-process). + +### Protocol fee and UNI burn + +Protocol fees can be collected across Uniswap's products and are currently active only on Uniswap v2 and v3. Fees are routed into an onchain collector on each network where they are claimed by external participants in exchange for UNI, which is then permanently burned. UNI holders have no individual or pro-rata claim on protocol revenue; value accrual is mediated entirely through this burn mechanism and any other distribution mechanism governance may subsequently authorize. + +For a full description of the fee flow and burn mechanics, see [Protocol Fees](/docs/protocols/protocol-fee/overview). + +## FAQs + +Common questions about UNI, the protocol fee and burn mechanism, and DUNI are answered in the [Governance FAQs](/docs/ecosystem/governance/faqs). diff --git a/content/ecosystem/subgraphs/overview.mdx b/content/ecosystem/subgraphs/overview.mdx index 03275e832..d9f4542ad 100644 --- a/content/ecosystem/subgraphs/overview.mdx +++ b/content/ecosystem/subgraphs/overview.mdx @@ -1,5 +1,6 @@ --- title: Subgraphs Overview +sidebarTitle: Overview description: Query Uniswap onchain data using subgraphs hosted on The Graph across v2, v3, and v4. --- diff --git a/content/get-started/concepts/ecosystem-participants.mdx b/content/get-started/concepts/ecosystem-participants.mdx index e9484b956..2bd2d1dba 100644 --- a/content/get-started/concepts/ecosystem-participants.mdx +++ b/content/get-started/concepts/ecosystem-participants.mdx @@ -1,5 +1,4 @@ --- -id: ecosystem-participants title: Ecosystem Participants description: Explore liquidity providers, traders, and developers and their roles in the Uniswap ecosystem. --- diff --git a/content/get-started/concepts/fees.mdx b/content/get-started/concepts/fees.mdx index 47b29eea7..3c971e73f 100644 --- a/content/get-started/concepts/fees.mdx +++ b/content/get-started/concepts/fees.mdx @@ -1,5 +1,4 @@ --- -id: fees title: Fees description: Learn how swap fees, protocol fees, and fee tiers work across Uniswap v2, v3, and v4. --- diff --git a/content/get-started/concepts/glossary.mdx b/content/get-started/concepts/glossary.mdx index f90e0f277..e50047253 100644 --- a/content/get-started/concepts/glossary.mdx +++ b/content/get-started/concepts/glossary.mdx @@ -1,6 +1,6 @@ --- -id: glossary -title: Glossary +title: Uniswap Protocol Glossary +sidebarTitle: Glossary description: Common terms for the Uniswap protocol, its AMM design, permissionless architecture, and protocol versions. type: glossary terms: diff --git a/content/get-started/concepts/hooks.mdx b/content/get-started/concepts/hooks.mdx index b632a3e83..09a1740a4 100644 --- a/content/get-started/concepts/hooks.mdx +++ b/content/get-started/concepts/hooks.mdx @@ -1,6 +1,6 @@ --- -id: hooks -title: Hooks +title: Understanding Uniswap v4 Hooks +sidebarTitle: Hooks description: Discover Uniswap v4 hooks and how custom smart contract logic extends pool behavior. --- diff --git a/content/get-started/concepts/how-uniswap-works.mdx b/content/get-started/concepts/how-uniswap-works.mdx index a4e569c20..2f20d1126 100644 --- a/content/get-started/concepts/how-uniswap-works.mdx +++ b/content/get-started/concepts/how-uniswap-works.mdx @@ -1,5 +1,4 @@ --- -id: how-uniswap-works title: How Uniswap Works description: Learn how Uniswap AMMs work across all protocol versions. --- diff --git a/content/get-started/concepts/liquidity-providers/concentrated-liquidity.mdx b/content/get-started/concepts/liquidity-providers/concentrated-liquidity.mdx index 461f12755..4eb3e9730 100644 --- a/content/get-started/concepts/liquidity-providers/concentrated-liquidity.mdx +++ b/content/get-started/concepts/liquidity-providers/concentrated-liquidity.mdx @@ -1,5 +1,4 @@ --- -id: concentrated-liquidity title: Concentrated Liquidity description: Understand concentrated liquidity in Uniswap v3 and v4 and how price ranges improve capital efficiency. --- diff --git a/content/get-started/concepts/liquidity-providers/lp-calculations.mdx b/content/get-started/concepts/liquidity-providers/lp-calculations.mdx index d467a1084..9317694ff 100644 --- a/content/get-started/concepts/liquidity-providers/lp-calculations.mdx +++ b/content/get-started/concepts/liquidity-providers/lp-calculations.mdx @@ -1,5 +1,4 @@ --- -id: lp-calculations title: LP Calculations description: Find Uniswap v2 to v4 liquidity calculation tools for position math, fee estimation, and liquidity modeling. --- diff --git a/content/get-started/concepts/liquidity-providers/range-orders.mdx b/content/get-started/concepts/liquidity-providers/range-orders.mdx index eca9f2d46..ca5b6c914 100644 --- a/content/get-started/concepts/liquidity-providers/range-orders.mdx +++ b/content/get-started/concepts/liquidity-providers/range-orders.mdx @@ -1,6 +1,6 @@ --- -id: range-orders -title: Range Orders +title: Understanding Range Orders +sidebarTitle: Range Orders description: Learn how range orders approximate limit orders using single-sided liquidity in Uniswap AMMs. --- diff --git a/content/get-started/concepts/traders/swaps.mdx b/content/get-started/concepts/traders/swaps.mdx index 6bd13435c..eb526c25f 100644 --- a/content/get-started/concepts/traders/swaps.mdx +++ b/content/get-started/concepts/traders/swaps.mdx @@ -1,6 +1,6 @@ --- -id: swaps -title: Swaps +title: Understanding Swaps on Uniswap +sidebarTitle: Swaps description: Learn how swaps work on Uniswap, including price impact, liquidity pools, and trade execution. --- @@ -77,3 +77,5 @@ In practice, hooks let teams customize how swaps behave at the pool level withou - Build your first swap integration in the [trading guides](/docs/trading/overview). - Learn LP mechanics in the [liquidity section](/docs/liquidity/overview). - Explore advanced swap customization with [hooks](/docs/protocols/v4/concepts/hooks). + +For developer support, reach out to our team through the Help Center. diff --git a/content/get-started/quickstart.mdx b/content/get-started/quickstart.mdx index b502497dd..285e5b5e8 100644 --- a/content/get-started/quickstart.mdx +++ b/content/get-started/quickstart.mdx @@ -102,8 +102,7 @@ Your app still handles nonce strategy, error handling, and status tracking. ### Where to go next - [Get started with API swap flows](/docs/trading/swapping-api/getting-started) -- [Set up API integration prerequisites](/docs/trading/swapping-api/building-prerequisites) -- [Implement the end-to-end integration guide](/docs/trading/swapping-api/integration-guide) +- [Implement the end-to-end integration guide](/docs/trading/swapping-api/start-building/integration-guide) @@ -333,3 +332,5 @@ Hooks can run logic at key lifecycle points such as: + +For developer support, reach out to our team through the Help Center. diff --git a/content/liquidity/liquidity-launchpad/concepts/cca.mdx b/content/liquidity/liquidity-launchpad/concepts/cca.mdx index 6ca0edbfa..e5b72984d 100644 --- a/content/liquidity/liquidity-launchpad/concepts/cca.mdx +++ b/content/liquidity/liquidity-launchpad/concepts/cca.mdx @@ -1,5 +1,4 @@ --- -id: CCA title: Continuous Clearing Auction description: Understand the Continuous Clearing Auction mechanism used by Uniswap Liquidity Launchpad for token price discovery. --- diff --git a/content/liquidity/liquidity-launchpad/concepts/instant-launch.mdx b/content/liquidity/liquidity-launchpad/concepts/instant-launch.mdx new file mode 100644 index 000000000..83a6aa750 --- /dev/null +++ b/content/liquidity/liquidity-launchpad/concepts/instant-launch.mdx @@ -0,0 +1,52 @@ +--- +title: Instant Launch +description: Learn how Instant Launch creates a Uniswap v4 pool with the entire token supply as a single-sided position. +--- + +## How It Works + +[InstantLaunchStrategy](https://github.com/Uniswap/liquidity-launcher/blob/main/src/strategies/InstantLaunchStrategy.sol) is called via `LiquidityLauncher.distributeToken()` like other strategies. In a single transaction, it: + +1. pulls the full token supply from [Liquidity Launcher](https://github.com/Uniswap/liquidity-launcher/blob/main/src/LiquidityLauncher.sol) into the strategy +2. initializes a hookless Uniswap v4 pool pairing native ETH with the token, using the strategy's fixed parameters +3. mints a single position holding the entire token supply as a single-sided position +4. if a [BeneficiaryVault](https://github.com/Uniswap/liquidity-launcher/blob/main/src/periphery/BeneficiaryVault.sol) address was provided during the deployment of that Instant Launch strategy contract, it registers the fee beneficiary provided via the `InstantLaunchConfig` struct inside the `configData`. +5. transfers the position to the [FeeSplitter](https://github.com/Uniswap/liquidity-launcher/blob/main/src/periphery/FeeSplitter.sol), which holds it permanently and allows only to collect fees or to increase the position's size. + +The pool allows the token to be traded instantly after the launch. + +## Fixed Token and Launch Parameters + +The strategy calls `token.totalSupply()` and `token.decimals()` to verify they match the required launch parameters, before proceeding to create a pool. All pool parameters are fixed during the strategy's deployment to ensure every launch from a specific deployment of Instant Launch shares these parameters. + +| Parameter | Value | +| -------------- | ----------------------------------- | +| Total supply | 1,000,000,000 (18 decimals) | +| Pool | native ETH / token, no hook | +| LP fee | 0.25% (`2500`) | +| Tick spacing | 25 | +| Position range | `MIN_LAUNCH_TICK` to `initialTick` | +| `initialTick` | fixed at deployment of the strategy | + +## LP Fees + +LP fees accrue to the launch position, which the `FeeSplitter` owns and cannot transfer out. Collection is permissionless, and collected amounts are split by immutable shares set at deployment, with separate basis points for the native and the token side. + +- **[UERC20BeneficiaryVault](https://github.com/Uniswap/liquidity-launcher/blob/main/src/periphery/UERC20BeneficiaryVault.sol)** holds the creator's share. It mints a transferable ERC-721 at registration; only its holder can claim. Registration does not have to happen at launch: a claim on an unregistered position registers it, provided the caller matches the token's graffiti. +- **[CompoundingClaimRecipient](https://github.com/Uniswap/liquidity-launcher/blob/main/src/periphery/CompoundingClaimRecipient.sol)** allows any caller to compound collected swap fees back into the locked position, via a contract implementing [IClaimExecutor](https://github.com/Uniswap/liquidity-launcher/blob/main/src/interfaces/IClaimExecutor.sol). See [Collect and Compound Fees](/docs/liquidity/liquidity-launchpad/guides/collect-and-compound-fees). +- **[BuybackAndBurnClaimRecipient](https://github.com/Uniswap/liquidity-launcher/blob/main/src/periphery/BuybackAndBurnClaimRecipient.sol)** accumulates the fee share routed to it and releases it to any caller who burns a fixed amount of the token. See [Buyback and Burn](/docs/liquidity/liquidity-launchpad/guides/buyback-and-burn). + +## Compared to CCA + +| | Instant Launch | CCA | +| ----------------- | ------------------------- | ---------------------------------------- | +| Price | fixed at deployment | discovered by the auction | +| Capital to launch | token only | the currency raised by the auction | +| Supply | all of it, into the pool | split between auction and LP | +| Positions | exactly one, single-sided | weighted plan plus a full-range fallback | + +## Where to Go Next + +- [Collect and Compound Fees](/docs/liquidity/liquidity-launchpad/guides/collect-and-compound-fees) +- [Liquidity Strategies](/docs/liquidity/liquidity-launchpad/concepts/liquidity-strategies) +- [Deployments](/docs/liquidity/liquidity-launchpad/deployments) diff --git a/content/liquidity/liquidity-launchpad/concepts/liquidity-strategies.mdx b/content/liquidity/liquidity-launchpad/concepts/liquidity-strategies.mdx index 3d3026bc3..2ab47ccd7 100644 --- a/content/liquidity/liquidity-launchpad/concepts/liquidity-strategies.mdx +++ b/content/liquidity/liquidity-launchpad/concepts/liquidity-strategies.mdx @@ -1,5 +1,4 @@ --- -id: Strategies title: Strategies description: Learn how Liquidity Launchpad strategy contracts deploy auctions and migrate proceeds into Uniswap v4 liquidity. --- diff --git a/content/liquidity/liquidity-launchpad/concepts/meta.json b/content/liquidity/liquidity-launchpad/concepts/meta.json index d186ef0a7..9f95367df 100644 --- a/content/liquidity/liquidity-launchpad/concepts/meta.json +++ b/content/liquidity/liquidity-launchpad/concepts/meta.json @@ -1,4 +1,9 @@ { "title": "Concepts", - "pages": ["liquidity-strategies", "cca", "token-factory"] + "pages": [ + "liquidity-strategies", + "cca", + "instant-launch", + "token-factory" + ] } diff --git a/content/liquidity/liquidity-launchpad/concepts/token-factory.mdx b/content/liquidity/liquidity-launchpad/concepts/token-factory.mdx index c70a8d3d9..3dd0c5230 100644 --- a/content/liquidity/liquidity-launchpad/concepts/token-factory.mdx +++ b/content/liquidity/liquidity-launchpad/concepts/token-factory.mdx @@ -1,5 +1,4 @@ --- -id: TokenFactories title: Token Factories description: Token factories for creating new UERC20 and Superchain-compatible USUPERC20 tokens within the Uniswap Liquidity Launchpad flow. --- diff --git a/content/liquidity/liquidity-launchpad/deployments.mdx b/content/liquidity/liquidity-launchpad/deployments.mdx index 6153d2c8a..6c0fd0c05 100644 --- a/content/liquidity/liquidity-launchpad/deployments.mdx +++ b/content/liquidity/liquidity-launchpad/deployments.mdx @@ -1,98 +1,235 @@ --- -id: Deployments -title: Deployments +title: Liquidity Launchpad Deployments +sidebarTitle: Deployments description: Find Uniswap Liquidity Launchpad, CCA, and strategy contract deployments across supported chains. --- -View the changelogs for more details on differences between contract deployments: [continuous-clearing-auction](https://github.com/Uniswap/continuous-clearing-auction/blob/main/CHANGELOG.md) and [liquidity-launcher](https://github.com/Uniswap/liquidity-launcher/blob/main/CHANGELOG.md). + + All Liquidity Launchpad deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + +Prior liquidity-launcher deployment addresses are retained for reference, marked deprecated, in the [Deployment Guide](https://github.com/Uniswap/liquidity-launcher/blob/main/docs/DeploymentGuide.md#legacy-deployments-deprecated). ## ContinuousClearingAuctionFactory -The CCA factory has no constructor parameters so it can be deployed to the same address across all compatible chains. v2.0.0 is deployed on all currently supported chains. -| Address | Commit Hash | Version | -| ------------------------------------------ | ---------------------------------------- | ----------------- | -| 0x00cCa200BF124dBfA848937c553864f4B4CE0632 | | v2.0.0 | -| 0xCCccCcCAE7503Cac057829BF2811De42E16e0bD5 | 87b2546a298f691c095b06ec077ceef25ba56007 | v1.1.0 | -| 0x0000ccaDF55C911a2FbC0BB9d2942Aa77c6FAa1D | 154fd189022858707837112943c09346869c964f | v1.0.0-candidate\* | +The CCA factory has no constructor parameters so it is deployed to the same address across all compatible chains: Ethereum, Unichain, Base, Arbitrum, Robinhood Chain, and Sepolia. Versions before v2.0.0 should no longer be used or integrated with. - - \*v1.0.0-candidate is the initial version of CCA and is NOT recommended for production use. See the [Changelog](https://github.com/Uniswap/continuous-clearing-auction/blob/main/CHANGELOG.md) for more details. - +| Version | Address | Commit Hash | +| ------- | ------------------------------------------ | ---------------------------------------- | +| v2.1.0 | 0x000000001F26a0044BaA66024e7b6599c61963F8 | 7d7602d257733315434570f2a0c2f94f1c7b207a | +| v2.0.0 | 0x00cCa200BF124dBfA848937c553864f4B4CE0632 | aee9bca51c92c24eb24a00d75ad98e678bac61d3 | ## LiquidityLauncher -The LiquidityLauncher is a singleton contract deployed to the same address across all networks with the canonical Permit2 deployment address (0x000000000022D473030F116dDEE9F6B43aC78BA3). -| Version | Address | Commit Hash | -| -------- | ------------------------------------------ | ---------------------------------------- | -| v3.0.0 | 0x00004c4ccc709Ef590F7C81102C0689F0263D4e9 | 3a3103543f50a13a0ae52a253bb98a925d72146f | -| v1.0.0 | 0x00000008412db3394C91A5CbD01635c6d140637C | fd5be9b7a918ca3d925d985dff9bcde82b3b8a9d | +The LiquidityLauncher is a singleton contract deployed at the same address, via CREATE2, on every chain the Liquidity Launchpad supports: Ethereum, Base, Unichain, Arbitrum, Avalanche, X Layer, Robinhood Chain, Arc, Ink, Sepolia, and Base Sepolia. Each of these chains carries the canonical Permit2 deployment (0x000000000022D473030F116dDEE9F6B43aC78BA3). -## LBP Strategies -LBP strategies are deployed via factory contracts which are deployed to different addresses on different chains. Make sure to use the correct factory contract for the chain in question. +| Version | Address | Commit Hash | +| ------- | ------------------------------------------ | ---------------------------------------- | +| v3.2.0 | 0x0000FffFBE8efE702c8703aE3477FF5dE3d319C0 | dd8769cd45c0e9450e928513ee129b0af74f7f32 | -### FullRangeLBPStrategyFactory -The FullRangeLBPStrategyFactory is a factory contract for the [FullRangeLBPStrategy](https://github.com/Uniswap/liquidity-launcher/blob/main/src/strategies/lbp/FullRangeLBPStrategy.sol). +## LBPStrategy -| Version | Chain | Address | Commit Hash | -|---------|-------|---------|------------| -| v2.0.0 | Mainnet | 0x65aF3B62EE79763c704f04238080fBADD005B332 | 610603eed7c35ff504e23ec87cd18ec3f701e746 | -| v2.0.0 | Unichain | 0xAa56d4d68646B4858A5A3a99058169D0100b38e2 | 610603eed7c35ff504e23ec87cd18ec3f701e746 | -| v2.0.0 | Base | 0x39E5eB34dD2c8082Ee1e556351ae660F33B04252 | 610603eed7c35ff504e23ec87cd18ec3f701e746 | -| v2.0.0 | Sepolia | 0x89Dd5691e53Ea95d19ED2AbdEdCf4cBbE50da1ff | 610603eed7c35ff504e23ec87cd18ec3f701e746 | +The LBPStrategy contract is deployed to a different address on each chain because it must land on a valid v4 hook address. -### AdvancedLBPStrategyFactory -The AdvancedLBPStrategyFactory is a factory contract for the [AdvancedLBPStrategy](https://github.com/Uniswap/liquidity-launcher/blob/main/src/strategies/lbp/AdvancedLBPStrategy.sol). - -| Version | Chain | Address | Commit Hash | -|---------|-------|---------|------------| -| v2.0.0 | Mainnet | 0x982DC187cbeB4E21431C735B01Ecbd8A606129C5 | 610603eed7c35ff504e23ec87cd18ec3f701e746 | -| v2.0.0 | Unichain | 0xeB44195e1847F23D4ff411B7d501b726C7620529 | 610603eed7c35ff504e23ec87cd18ec3f701e746 | -| v2.0.0 | Base | 0x9C5A6fb9B0D9A60e665d93a3e6923bDe428c389a | 610603eed7c35ff504e23ec87cd18ec3f701e746 | -| v2.0.0 | Sepolia | 0xdC3553B7Cea1ad3DAB35cBE9d40728C4198BCBb6 | 610603eed7c35ff504e23ec87cd18ec3f701e746 | - -### LBPStrategy -The LBPStrategy contract is deployed to a different address on each chain. It must be deployed to a valid v4 hook address. - -| Version | Chain | Address | Commit Hash | -|---------|-------|---------|------------| -| v3.0.0 | Mainnet | 0xb98766A35cdc28415be0767D4EA41e39fBA3e000 | 3a3103543f50a13a0ae52a253bb98a925d72146f | -| v3.0.0 | Base | 0x5bB4bAfafEc57BEd50D864AAA9D1ef992611e000 | 3a3103543f50a13a0ae52a253bb98a925d72146f | -| v3.0.0 | Unichain | 0x824A3eCDe463DD45cC156b64CEfA132596C9A000 | 3a3103543f50a13a0ae52a253bb98a925d72146f | -| v3.0.0 | Arbitrum | 0x18608AD558dcD233F7854242bbAef73988Bee000 | 3a3103543f50a13a0ae52a253bb98a925d72146f | -| v3.0.0 | Sepolia | 0x3f37838651B5AD71D4e01Ec9745862A5D9DF2000 | 3a3103543f50a13a0ae52a253bb98a925d72146f | -| v3.0.0 | Base Sepolia | 0x0e1793a989c682117fcBfB3a9aA8e451D37D2000 | 3a3103543f50a13a0ae52a253bb98a925d72146f | - -## Previous Deployments -The following contracts are deprecated and are not recommended for production use. See the [Changelog](https://github.com/Uniswap/liquidity-launcher/blob/main/CHANGELOG.md) for more details. +### Current + +| Version | Chain | Address | Commit Hash | +| ------- | --------------- | ------------------------------------------ | ---------------------------------------- | +| v3.3.0 | Ethereum | 0x2EEF0e2a9a652d755AccAD95a24541A98B5CA000 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | Base | 0xf10124B01E9fa88b0a2eF3fA95a53B3310446000 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | Unichain | 0x48F55E7E8ac229aA4e2f3F2d44aa9284D86da000 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | Arbitrum | 0xc80f3f4497CD9ae41bf8cB5C8809620182B6E000 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | Robinhood Chain | 0xbf1aB81f7d534b2CC0Da76fcf4d541322bB0e000 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | Avalanche | 0x7575c9488AB7913e7749B9F5e02789355699E000 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | X Layer | 0xde758D7B3202b7f4f842E8313Fc04Bf19c6Be000 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | Ink | 0x0cB98d78be96D5119E49664a9F24fDA22f83E000 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | Arc | 0x542BCDA1015485ef0B1cD11B835DC58DF5102000 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | Sepolia | 0x95434E898Af471945Cab33D5064d2aC1A6Ba2000 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | Base Sepolia | 0x73ad52384798AdADfBe19fCfD28ff09D2CC82000 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | -### LBPStrategyBasicFactory -The LBPStrategyBasicFactory is a factory contract for the [LBPStrategyBasic](https://github.com/Uniswap/liquidity-launcher/blob/v1.0.0-candidate/src/distributionContracts/LBPStrategyBasic.sol). +### v3.1.x (deprecated) -| Network | Address | Commit Hash | Version | -|---------|---------|------------|---------| -| Mainnet | 0xbbbb6FFaBCCb1EaFD4F0baeD6764d8aA973316B6 | fd5be9b7a918ca3d925d985dff9bcde82b3b8a9d | v1.0.0-candidate | -| Base | 0xC46143aE2801b21B8C08A753f9F6b52bEaD9C134 | fd5be9b7a918ca3d925d985dff9bcde82b3b8a9d | v1.0.0-candidate | -| Unichain | 0x435DDCFBb7a6741A5Cc962A95d6915EbBf60AE24 | fd5be9b7a918ca3d925d985dff9bcde82b3b8a9d | v1.0.0-candidate | +| Version | Chain | Address | +| ------- | --------------- | ------------------------------------------ | +| v3.1.0 | Ethereum | 0x49380c4EfaB1b491006aF7FabAB8B3459F0E6000 | +| v3.1.0 | Base | 0x34385dD739FE5464892BF0bA4CC42492804dA000 | +| v3.1.0 | Unichain | 0x298eA05D0356B2Ae5cCAa3169E471783ee9EA000 | +| v3.1.0 | Arbitrum | 0x8Af0775a70Cc94D71DFc0fE809435e833F2Fe000 | +| v3.1.1 | Robinhood Chain | 0x05d552391067389EE44fec3924157ed33F976000 | +| v3.1.0 | Avalanche | 0x57BD0A9Cd933c89Ba55e086D53031367b6406000 | +| v3.1.0 | X Layer | 0x58DF162fF41e5cB42B8515f75F90C1841938A000 | +| v3.1.0 | Ink | 0xd749FAe4D01E8fd85B9e26555cB300018aFEA000 | +| v3.1.0 | Sepolia | 0x96641d91e223c766F45b19d09494F5925C3cE000 | +| v3.1.0 | Base Sepolia | 0xB06428b62c259eE982cE3D9BED47391dC9A5E000 | -### VirtualLBPStrategyFactory +### v3.0.0 (deprecated) + +| Chain | Address | +| --------------- | ------------------------------------------ | +| Avalanche | 0xcAcd77134b072b4AD5621f585b0b422C6Da4E000 | +| X Layer | 0x95bcb80e3804a085d23778F2956c305d6488e000 | +| Robinhood Chain | 0x095e38a2135aeBcfFa98A5B6911591937f912000 | + +## InstantLaunchStrategy + +The InstantLaunchStrategy launches a fixed-supply token directly into a hookless native-currency Uniswap v4 pool (ETH on most chains; USDC on Arc) as a single-sided LP position. + +Deployments that support creator fees split the fees from the pool position between auto-compounding and the creator; deployments without creator fees do not share funds with a creator. The Creator Fees column marks each deployment: launches that select a creator fee in the interface use a deployment marked Yes, and launches without one use a deployment marked No. + +| Version | Chain | Creator Fees | Address | FeeSplitter | Initial Tick | Commit Hash | +| ------- | --------------- | ------------ | ------------------------------------------ | ------------------------------------------ | ------------ | ---------------------------------------- | +| v3.3.0 | Robinhood Chain | Yes | 0x7c48DDe3B447381F4d986334679b3Afc7F2D35C2 | [0x9411fa7F956f64aa7981AA27cB3bC6eC0415449C](#feesplitter) | 198,050 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | Robinhood Chain | No | 0xC9566675b1Ea42861546f3c5B74Ace2c79c49572 | [0x882Ae5e2095435A62Fd1BBDEfcb637f5CeAFc0ee](#feesplitter) | 198,050 | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | Arc | No | 0x36F8c87047b212589eD66524Bb69cE62B1f00B2d | [0xE8113a9a9CddD6d13fe8A3E32eAA687e108C4616](#feesplitter) | 122,050 | 81fc34ce3e2dd9a48199485edc5cbf81bdeaec76 | +| v3.2.0 | Robinhood Chain | Yes | 0x23f8209572b4a1C2AD88A42749E830791Fb027f1 | 0xeFF166AAf189323c58dc27eD1206EB2C37FaACDf | | dd8769cd45c0e9450e928513ee129b0af74f7f32 | +| v3.2.0 | Robinhood Chain | No | 0xAD44D55E7f8337C3cE113fBb591486E85be104b2 | 0x222D6d4f1ce59b0d48D5505114eC8Addc90A4359 | | dd8769cd45c0e9450e928513ee129b0af74f7f32 | + +## UniversalRouterStrategy + +The UniversalRouterStrategy runs a caller-supplied Universal Router route, so a launch and a buy fit in one transaction. + +| Version | Chain | Address | Commit Hash | +| ------- | --------------- | ------------------------------------------ | ---------------------------------------- | +| v3.3.0 | Robinhood Chain | 0x0A122717bc36E3C7A7958128a5C789E0b070b3Ae | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.3.0 | Arc | 0x0A122717bc36E3C7A7958128a5C789E0b070b3Ae | 1c5904912aefceaceb89c24528cd5e25d0b61597 | +| v3.2.0 | Robinhood Chain | 0x1242c9439d589cAE85E121B1f79f2aF51e91DCEE | dd8769cd45c0e9450e928513ee129b0af74f7f32 | + +## InitializerHook + +The InitializerHook is a base hook that restricts pool initialization to a preset address. Caller-specified hooks must inherit it to be used in LBPStrategy. + +| Version | Chain | Address | LBPStrategy | Salt | Commit Hash | +| ------- | --------------- | ------------------------------------------ | ------------------------------------------ | ------------------------------------------------------------------ | ---------------------------------------- | +| v3.3.0 | Ethereum | 0xcDf73dEddE5e8C2FdC9c01C18607e0B40380E000 | [0x2EEF0e2a9a652d755AccAD95a24541A98B5CA000](#lbpstrategy) | 0x00000000000000000000000000000000000000000000000000000000000010a4 | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.3.0 | Unichain | 0xF44Ba9c854Ec0ad6a899864bdfF560AAD4002000 | [0x48F55E7E8ac229aA4e2f3F2d44aa9284D86da000](#lbpstrategy) | 0x0000000000000000000000000000000000000000000000000000000000001046 | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.3.0 | Robinhood Chain | 0x5fB5229FBA341dFE5a7e6A14d4809D6Cf887a000 | [0xbf1aB81f7d534b2CC0Da76fcf4d541322bB0e000](#lbpstrategy) | 0x000000000000000000000000000000000000000000000000000000000000247f | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.3.0 | Avalanche | 0x602bd3e53b5e80f732b0859E90564CFCAcb52000 | [0x7575c9488AB7913e7749B9F5e02789355699E000](#lbpstrategy) | 0x0000000000000000000000000000000000000000000000000000000000000d67 | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.3.0 | X Layer | 0xcaf0443A5F171DC1dd5574eE50dD2c45274da000 | [0xde758D7B3202b7f4f842E8313Fc04Bf19c6Be000](#lbpstrategy) | 0x000000000000000000000000000000000000000000000000000000000000df03 | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.3.0 | Ink | 0x47AFDD2D8591275E9dF688FCacb8Cf5C772Ee000 | [0x0cB98d78be96D5119E49664a9F24fDA22f83E000](#lbpstrategy) | 0x000000000000000000000000000000000000000000000000000000000000ae2a | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.3.0 | Arc | 0x0A2Bf52DA5D72fd1B1cDB21ABd4Bd8672b512000 | [0x542BCDA1015485ef0B1cD11B835DC58DF5102000](#lbpstrategy) | 0x000000000000000000000000000000000000000000000000000000000000403b | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.3.0 | Sepolia | 0x1600059B95A80d500fC42400ea9a88A9C29D2000 | [0x95434E898Af471945Cab33D5064d2aC1A6Ba2000](#lbpstrategy) | 0x0000000000000000000000000000000000000000000000000000000000000edf | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.3.0 | Base Sepolia | 0xE09e0D23097B08443C09F2AE23e7201601422000 | [0x73ad52384798AdADfBe19fCfD28ff09D2CC82000](#lbpstrategy) | 0x0000000000000000000000000000000000000000000000000000000000011e77 | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.1.1 | Robinhood Chain | 0xD462a559337859369EF271814851A18F496ba000 | | | 5ef0262b8e191360a212aac864a525dcf7a06605 | + +v3.3.0 InitializerHook addresses for Base and Arbitrum are not yet published in the liquidity-launcher release notes. + +## TokenSplitter + +The TokenSplitter is a minimal strategy that splits a token distribution across multiple recipients, such as EOAs or multisigs, pulling tokens directly from the caller so it never holds funds. The v3.0.0 deployment shares one address across the networks listed below; Robinhood Chain runs the newer v3.2.0 deployment at its own address. + +| Version | Chain | Address | Commit Hash | +| ------- | --------------- | ------------------------------------------ | ---------------------------------------- | +| v3.0.0 | Ethereum, Base, Unichain, Arbitrum, Avalanche, X Layer, Arc, Sepolia, Base Sepolia | 0x8B7DCeb5639DB986FCf86606C74e6300C40FE3cd | 3a3103543f50a13a0ae52a253bb98a925d72146f | +| v3.2.0 | Robinhood Chain | 0x4F5E3FBb9745358A92Da5674305FAb8D2B8a73cE | dd8769cd45c0e9450e928513ee129b0af74f7f32 | + +## FeeSplitter + +The FeeSplitter permanently holds v4 native-currency LP positions, permissionlessly collects their fees, and pushes independent fixed splits for the native-currency and token side, set immutably at deployment. Multiple deployments may exist on the same chain. + +| Version | Chain | Address | Fee Splits | Commit Hash | +| ------- | --------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| v3.3.0 | Robinhood Chain | 0x9411fa7F956f64aa7981AA27cB3bC6eC0415449C | [UERC20BeneficiaryVault](#uerc20beneficiaryvault): 40% native ETH; [CompoundingClaimRecipient](#compoundingclaimrecipient): 60% native ETH, 100% token | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.3.0 | Robinhood Chain | 0x882Ae5e2095435A62Fd1BBDEfcb637f5CeAFc0ee | [CompoundingClaimRecipient](#compoundingclaimrecipient): 100% native ETH, 100% token | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.3.0 | Arc | 0xE8113a9a9CddD6d13fe8A3E32eAA687e108C4616 | [BuybackAndBurnClaimRecipient](#buybackandburnclaimrecipient): 100% native, 100% token | 81fc34ce3e2dd9a48199485edc5cbf81bdeaec76 | +| v3.2.0 | Robinhood Chain | 0xeFF166AAf189323c58dc27eD1206EB2C37FaACDf | [UERC20BeneficiaryVault](#uerc20beneficiaryvault): 40% native ETH; [CompoundingClaimRecipient](#compoundingclaimrecipient): 60% native ETH, 100% token | dd8769cd45c0e9450e928513ee129b0af74f7f32 | +| v3.2.0 | Robinhood Chain | 0x222D6d4f1ce59b0d48D5505114eC8Addc90A4359 | [CompoundingClaimRecipient](#compoundingclaimrecipient): 100% native ETH, 100% token | dd8769cd45c0e9450e928513ee129b0af74f7f32 | + +## UERC20BeneficiaryVault + +The UERC20BeneficiaryVault is a BeneficiaryVault that holds fee shares for registered beneficiaries. Registration mints a transferable ERC-721 whose holder can claim, and the creator of a UERC20 token can register an unregistered position via the token's graffiti. -| Network | Address | Commit Hash | Version | -|---------|---------|------------|---------| -| Mainnet | 0x00000010F37b6524617b17e66796058412bbC487 | fd5be9b7a918ca3d925d985dff9bcde82b3b8a9d | v1.0.0-candidate | -| Sepolia | 0xC695ee292c39Be6a10119C70Ed783d067fcecfA4 | fd5be9b7a918ca3d925d985dff9bcde82b3b8a9d | v1.0.0-candidate | +| Version | Chain | Address | Commit Hash | +| ------- | --------------- | ------------------------------------------ | ---------------------------------------- | +| v3.3.0 | Robinhood Chain | 0x26d2F7AcB07707034406a0dC458351Bb63C02553 | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.2.0 | Robinhood Chain | 0xd35E9CA72F64C7F93BE30fad67524323396B36D7 | dd8769cd45c0e9450e928513ee129b0af74f7f32 | +## CompoundingClaimRecipient + +The CompoundingClaimRecipient pays claimed fee amounts to an executor contract, which must compound them back into the claimed position as liquidity. + +| Version | Chain | Address | Commit Hash | +| ------- | --------------- | ------------------------------------------ | ---------------------------------------- | +| v3.3.0 | Robinhood Chain | 0xf585b5D728A8fdE743027307BF5F3556E3B9C58D | 7ea523c9d75a51cb2f497be5e49bacdaeb80a342 | +| v3.2.0 | Robinhood Chain | 0xf9526Dd3361fe0ba6b7a99533ed471D3E808E99a | dd8769cd45c0e9450e928513ee129b0af74f7f32 | + +## BuybackAndBurnClaimRecipient + +The BuybackAndBurnClaimRecipient pays claimed fee amounts to an executor contract, then pulls a fixed amount of the position's token from that executor and sends it to the burn address. The burn amount is fixed at deployment and the same for every call; read the live value from `minCurrency1BurnAmount()`. See [Buyback and Burn](/docs/liquidity/liquidity-launchpad/guides/buyback-and-burn). + +| Version | Chain | Address | Burn Amount | Commit Hash | +| ------- | --------------- | ------------------------------------------ | -------------------------------- | ---------------------------------------- | +| v3.2.0 | Robinhood Chain | 0xa1ba4CC12654D2b188e3ba77dc86c75cA47f1A4e | 500,000 tokens (0.05% of supply) | 0b5ee0527af94a8c635b6af5b334a7d17c5ed719 | +| v3.3.0 | Arc | 0x5cEe9852d136833aE26c9E36a96fC02Cdfc9C40C | 500,000 tokens (0.05% of supply) | 81fc34ce3e2dd9a48199485edc5cbf81bdeaec76 | + +## VestingClaimRecipient + +The VestingClaimRecipient holds the beneficiary NFT for a renounced position, claims that position's fees from an allowlisted beneficiary vault, and releases them to a downstream recipient at a capped rate per block. Both the rate and the downstream recipient are fixed at deployment. See [Buyback and Burn](/docs/liquidity/liquidity-launchpad/guides/buyback-and-burn). + +| Chain | Address | Releases To | Commit Hash | +| --------------- | ------------------------------------------ | ----------------------------------------------------------------- | ---------------------------------------- | +| Robinhood Chain | 0xeF451B293ED8C61d20f7d13ef336a496F0cc2c26 | [BuybackAndBurnClaimRecipient](#buybackandburnclaimrecipient) | 0b5ee0527af94a8c635b6af5b334a7d17c5ed719 | ## UERC20Factory + The UERC20Factory is a factory contract for new UERC20 tokens. -| Network | Address | Commit Hash | Version | -| ------- | ------------------------------------------ | ---------------------------------------- | ---------------- | -| Mainnet | 0x0cde87c11b959e5eb0924c1abf5250ee3f9bd1b5 | 9705debfea9e6a641bc04352398f9e549055ac44 | v1.0.0-candidate | -| Sepolia | 0x0cde87c11b959e5eb0924c1abf5250ee3f9bd1b5 | 9705debfea9e6a641bc04352398f9e549055ac44 | v1.0.0-candidate | +| Network | Address | Commit Hash | Version | +| ------- | ------------------------------------------ | ---------------------------------------- | ------- | +| Ethereum | 0x000000e200088D55C39a11F609E5F667729ad49b | de5bacd215f6aae50e524297c18fcf78b69b6312 | v2.0.0 | +| Sepolia | 0x000000e200088D55C39a11F609E5F667729ad49b | de5bacd215f6aae50e524297c18fcf78b69b6312 | v2.0.0 | ## USUPERC20Factory -The USUPERC20Factory is a factory contract for new Superchain compatible UERC20 tokens. It is deployed to the same address across all Superchain compatible L2s. -| Network | Address | Commit Hash | Version | -| ---------------- | ------------------------------------------ | ---------------------------------------- | ---------------- | -| Unichain | 0x24016ed99a69e9b86d16d84351e1661266b7ac6a | 9705debfea9e6a641bc04352398f9e549055ac44 | v1.0.0-candidate | -| Unichain Sepolia | 0x24016ed99a69e9b86d16d84351e1661266b7ac6a | 9705debfea9e6a641bc04352398f9e549055ac44 | v1.0.0-candidate | +The USUPERC20Factory is a factory contract for Superchain compatible UERC20 tokens, deployed to the same address across Superchain compatible L2s. + +| Network | Address | Commit Hash | Version | +| ---------------- | ------------------------------------------ | ---------------------------------------- | ------- | +| Base | 0xeEeeEEE204Afb6BABb1287ffed52cCD6BA0b0fb2 | de5bacd215f6aae50e524297c18fcf78b69b6312 | v2.0.0 | +| Base Sepolia | 0xeEeeEEE204Afb6BABb1287ffed52cCD6BA0b0fb2 | de5bacd215f6aae50e524297c18fcf78b69b6312 | v2.0.0 | +| Unichain | 0xeEeeEEE204Afb6BABb1287ffed52cCD6BA0b0fb2 | de5bacd215f6aae50e524297c18fcf78b69b6312 | v2.0.0 | +| Unichain Sepolia | 0xeEeeEEE204Afb6BABb1287ffed52cCD6BA0b0fb2 | de5bacd215f6aae50e524297c18fcf78b69b6312 | v2.0.0 | + +## Deprecated Strategy Factories + +The following LBP strategy factories are superseded by LBPStrategy v3 and are not recommended for new launches. Addresses are retained for reference. + +### FullRangeLBPStrategyFactory + +| Chain | Address | +| ------------ | ------------------------------------------ | +| Ethereum | 0x65aF3B62EE79763c704f04238080fBADD005B332 | +| Unichain | 0xAa56d4d68646B4858A5A3a99058169D0100b38e2 | +| Base | 0x39E5eB34dD2c8082Ee1e556351ae660F33B04252 | +| Sepolia | 0x89Dd5691e53Ea95d19ED2AbdEdCf4cBbE50da1ff | +| Base Sepolia | 0xa3A236647c80BCD69CAD561ACf863c29981b6fbC | + +### AdvancedLBPStrategyFactory + +| Chain | Address | +| ------------ | ------------------------------------------ | +| Ethereum | 0x982DC187cbeB4E21431C735B01Ecbd8A606129C5 | +| Unichain | 0xeB44195e1847F23D4ff411B7d501b726C7620529 | +| Base | 0x9C5A6fb9B0D9A60e665d93a3e6923bDe428c389a | +| Sepolia | 0xdC3553B7Cea1ad3DAB35cBE9d40728C4198BCBb6 | +| Base Sepolia | 0x67E24586231D4329AfDbF1F4Ac09E081cFD1e6a6 | + +### GovernedLBPStrategyFactory + +| Chain | Address | +| ------------ | ------------------------------------------ | +| Base | 0xBc869216dAD02E1A95c1478a459D064b16F41B24 | +| Base Sepolia | 0xB460228ACa3bbf8FaDB781d22Cf051f55e7460A9 | + +### LBPStrategyBasicFactory + +| Chain | Address | +| -------- | ------------------------------------------ | +| Ethereum | 0xbbbb6FFaBCCb1EaFD4F0baeD6764d8aA973316B6 | +| Base | 0xC46143aE2801b21B8C08A753f9F6b52bEaD9C134 | +| Unichain | 0x435DDCFBb7a6741A5Cc962A95d6915EbBf60AE24 | + +### VirtualLBPStrategyFactory + +| Chain | Address | +| -------- | ------------------------------------------ | +| Ethereum | 0x00000010F37b6524617b17e66796058412bbC487 | +| Sepolia | 0xC695ee292c39Be6a10119C70Ed783d067fcecfA4 | diff --git a/content/liquidity/liquidity-launchpad/guides/buyback-and-burn.mdx b/content/liquidity/liquidity-launchpad/guides/buyback-and-burn.mdx new file mode 100644 index 000000000..e11e6a9e0 --- /dev/null +++ b/content/liquidity/liquidity-launchpad/guides/buyback-and-burn.mdx @@ -0,0 +1,89 @@ +--- +title: Buyback and Burn +description: Run a searcher against the Uniswap buyback and burn recipient, which pays out accumulated creator fees in exchange for burning a fixed amount of the token. +keywords: + - buyback and burn + - BuybackAndBurnClaimRecipient + - searcher + - creator fees + - token burn + - Uniswap v4 + - MEV + - IClaimExecutor +--- + +The Uniswap buyback and burn recipient pays out accumulated creator fees to anyone willing to burn a fixed amount of the pool's token. Calling it is permissionless and it pays the caller, so third parties compete to run it. + +Some creator fee streams are routed to this contract instead of to a creator. It accumulates those fees per position and releases them only against a burn: the caller takes what has accumulated and sends a fixed amount of the pool's token to the burn address in the same transaction. This page is the searcher side, covering what the calls require and when they are worth making. + +Fees reach the burn recipient through a fee splitter and then a vesting contract that releases them gradually, so several calls are in play. All but the last are permissionless plumbing that anyone can run, and the last is the one that pays. + +## Collect Fees Into the Splitter + + + Swap fees do not appear in any recipient's accounting until someone collects them. A searcher that + only polls `amounts(tokenId)` will watch a mapping that never moves and conclude there is nothing + to do. + + +Launch positions are held permanently by the [FeeSplitter](https://github.com/Uniswap/liquidity-launcher/blob/main/src/periphery/FeeSplitter.sol), and fees sit in the PoolManager until `collectFees(tokenIds)` pulls them out and pushes each recipient its immutable share. It is permissionless and takes an array, so a searcher can sweep several positions in one call. + +Three things make it revert: an empty array, with `NoTokenIds`; a position the splitter does not own, with `NotOwner`; and being called while the PoolManager is already unlocked, with `PoolManagerAlreadyUnlocked`, so collection cannot be nested inside an existing unlock. A recipient that reverts its notification reverts the whole call and leaves those fees in the pool, so exclude a token ID that behaves that way rather than retrying the batch. + +## Release Fees From Vesting + +[VestingClaimRecipient](https://github.com/Uniswap/liquidity-launcher/blob/main/src/periphery/VestingClaimRecipient.sol) holds the beneficiary NFT for a renounced position and meters the fee stream out over time. Its downstream `recipient` is immutable, set at deployment, so everything it releases goes to the same place. + +Two calls move fees through it, both permissionless: + +`claimFrom(beneficiaryVault, tokenId, minCurrency0Amount, minCurrency1Amount)` pulls whatever the vault has attributed to the position into the vesting contract. The vault must be one of the allowlisted ones fixed at deployment, and the vesting contract must already hold that position's beneficiary NFT, otherwise it reverts with `NotPositionOwner`. The first successful call starts the clock for that position and emits `VestingStarted`. + +`claim(tokenId, minCurrency0Amount, minCurrency1Amount)` then releases the vested portion into the buyback and burn recipient and registers it there. The amount released is capped at `maxCurrency0PerBlock` and `maxCurrency1PerBlock` multiplied by the blocks elapsed since the last claim, so calling it twice in the same block releases nothing the second time. Both caps are immutable and rejected at deployment if zero. + +Neither call pays the caller. They exist so the ETH is sitting in the burn recipient when the trade below becomes worth making. + +## Claim Accumulated Fees + +[BuybackAndBurnClaimRecipient](https://github.com/Uniswap/liquidity-launcher/blob/main/src/periphery/BuybackAndBurnClaimRecipient.sol) is a singleton that holds the amounts attributed to each position and releases them only against a burn. It can hold either side of the pair. Today it holds ETH, because creator fees accrue in ETH, but the accounting is per currency and may carry the token side in future launches. + +`claim(tokenId, minCurrency0Amount, minCurrency1Amount)` runs in this order: + +1. transfers the amounts attributed to `tokenId` to the caller +2. reverts unless the position's `currency0` is native ETH, with `InvalidCurrency` +3. calls `onClaimed(poolKey, tokenId, currency0Received, currency1Received)` on the caller +4. pulls `minCurrency1BurnAmount` of the position's `currency1` from the caller, sends it to `0x000000000000000000000000000000000000dEaD`, and emits `TokensBurned` + +The whole sequence is one transaction, so a failure at any step reverts the payout as well. + +The callback is not optional. The caller of `claim` must be a contract implementing [IClaimExecutor](https://github.com/Uniswap/liquidity-launcher/blob/main/src/interfaces/IClaimExecutor.sol), and it must have approved the recipient for at least `minCurrency1BurnAmount` of `currency1` by the time the callback returns. `claim` is non-reentrant, and the `minCurrency0Amount` and `minCurrency1Amount` arguments let the caller abort when less than expected is attributed. + +The burn amount is fixed and the same for every call, so it does not scale with what has accumulated. Read it from `minCurrency1BurnAmount()`. The payout is whatever has accrued since the last claim, which means the trade becomes profitable once the attributed amount is worth more than the cost of acquiring the burn amount. A searcher watches for that crossing rather than for a schedule. + +## Running a Searcher + +Index the contracts above, then loop: + +1. call `collectFees(tokenIds)` on the fee splitter so accrued swap fees leave the PoolManager and reach the recipients +2. call `claimFrom` and then `claim` on the vesting contract to move the released portion into the burn recipient +3. read `amounts(tokenId)` on the burn recipient for what is attributed to the position, and `minCurrency1BurnAmount()` for the burn cost +4. when the attributed value exceeds what it costs to acquire the burn amount, call `claim` on the burn recipient from your executor + +Steps 1 and 2 cost gas and pay nothing, so in practice whoever intends to take step 4 runs them. + +### What the executor has to do + +The contract you call `claim` from has to satisfy everything the recipient enforces during that single transaction: + +- **Implement `IClaimExecutor`.** The recipient calls `onClaimed` on the caller unconditionally, so a plain EOA cannot claim. +- **Accept native ETH.** The payout is sent before the callback runs, so a contract that cannot receive ETH reverts the whole claim. +- **Hold `minCurrency1BurnAmount` of the pool's token and approve the recipient for it before the callback returns.** The recipient pulls that exact amount immediately afterwards. Where the tokens come from is up to you: a swap funded by the ETH just received, existing inventory, or any other route. +- **Account for the token side already paid out.** `onClaimed` reports both currencies received. If the position carried a token amount, you only need to source the difference. +- **Have a way to withdraw.** Whatever is left after funding the burn is your profit, and it stays in the contract until you move it out. + +Bound the price you are willing to pay when you source the burn amount. `minCurrency0Amount` only floors the payout, so a claim that clears it can still settle at a loss if the token has appreciated. + +## Where to Go Next + +- [Deployments](/docs/liquidity/liquidity-launchpad/deployments) for the recipient address +- [Collect and Compound Fees](/docs/liquidity/liquidity-launchpad/guides/collect-and-compound-fees) for the compounding recipient, a different mechanism +- [Instant Launch](/docs/liquidity/liquidity-launchpad/concepts/instant-launch) diff --git a/content/liquidity/liquidity-launchpad/guides/collect-and-compound-fees.mdx b/content/liquidity/liquidity-launchpad/guides/collect-and-compound-fees.mdx new file mode 100644 index 000000000..da6a5c237 --- /dev/null +++ b/content/liquidity/liquidity-launchpad/guides/collect-and-compound-fees.mdx @@ -0,0 +1,45 @@ +--- +title: Collect and Compound Fees +description: Trigger fee collection on an Instant Launch position and compound part of the fees back into it. +--- + +An [Instant Launch](/docs/liquidity/liquidity-launchpad/concepts/instant-launch) position is held permanently by the [FeeSplitter](https://github.com/Uniswap/liquidity-launcher/blob/main/src/periphery/FeeSplitter.sol). Two permissionless actions apply to it: **collecting** fees from the pool and pushing each recipient its share, and **increasing** a position in its custody. + +## Collect Fees + +`collectFees` collects the accrued fees of each position from the PoolManager and distributes them to the recipients. The splits are immutable, so the caller cannot redirect them. + +Recipients that have a callback receive the token ID and the information about the share of the fees sent to them, so they can be attributed per position. + +## Compound Fees + +The share of fees to be compounded accrues to a `CompoundingClaimRecipient`. + +For a handful of Crowd Launch pools, `claim` must be called on an alternative entrypoint rather than the `CompoundingClaimRecipient` listed against the FeeSplitter. Those positions can be located from the `PositionGuarded` event emitted by that entrypoint contract, at `0x2EB0b14814dCa26Df8b8AD729F8F70aD3399E89e` on Robinhood Chain. + +```solidity +event PositionGuarded(uint256 indexed guardedTokenId, address indexed compounder); +``` + +Any address implementing `IClaimExecutor` can call `claim`, which: + +1. transfers the full token and native amounts attributed to that position to `msg.sender` +2. calls `onClaimed` back on `msg.sender` +3. requires that the position's liquidity has grown by at least `minLiquidityIncrease`, otherwise reverting with `NotEnoughLiquidityAdded` + + + Collect the position before compounding it. `increaseLiquidity` reverts with + `UncollectedFees` while fees are still pending, so a single transaction should + call `collectFees` before `claim`. + + +## Caller tip + +A call to `claim` transfers the caller all balances attributed with the position, while the liquidity it must add is fixed. + +`amounts(tokenId)` returns what is currently claimable for a position (not including available fees inside the PoolManager); `minLiquidityIncrease()` returns the minimum liquidity units that the call must add + +## Where to Go Next + +- [Instant Launch](/docs/liquidity/liquidity-launchpad/concepts/instant-launch) +- [Deployments](/docs/liquidity/liquidity-launchpad/deployments) diff --git a/content/liquidity/liquidity-launchpad/guides/example-configuration.mdx b/content/liquidity/liquidity-launchpad/guides/example-configuration.mdx index b124cefc0..4b44fa5d3 100644 --- a/content/liquidity/liquidity-launchpad/guides/example-configuration.mdx +++ b/content/liquidity/liquidity-launchpad/guides/example-configuration.mdx @@ -1,5 +1,4 @@ --- -id: example-configuration title: Example Configuration description: Configure Uniswap Continuous Clearing Auction parameters and deploy an example auction with a local script. --- diff --git a/content/liquidity/liquidity-launchpad/guides/exit-bid.mdx b/content/liquidity/liquidity-launchpad/guides/exit-bid.mdx index b4e695ad6..eb143f643 100644 --- a/content/liquidity/liquidity-launchpad/guides/exit-bid.mdx +++ b/content/liquidity/liquidity-launchpad/guides/exit-bid.mdx @@ -1,5 +1,4 @@ --- -id: exit-bid title: Exit and Claim Tokens description: Exit outbid positions and claim purchased tokens in a Uniswap Continuous Clearing Auction lifecycle. --- diff --git a/content/liquidity/liquidity-launchpad/guides/local-deployment.mdx b/content/liquidity/liquidity-launchpad/guides/local-deployment.mdx index 646f7d2ab..e322e7c4d 100644 --- a/content/liquidity/liquidity-launchpad/guides/local-deployment.mdx +++ b/content/liquidity/liquidity-launchpad/guides/local-deployment.mdx @@ -1,5 +1,4 @@ --- -id: local-deployment title: Create a Local Deployment description: Deploy a Uniswap Continuous Clearing Auction locally with Foundry using the factory-based deployment flow. --- diff --git a/content/liquidity/liquidity-launchpad/guides/meta.json b/content/liquidity/liquidity-launchpad/guides/meta.json index da8b72798..7dab5d579 100644 --- a/content/liquidity/liquidity-launchpad/guides/meta.json +++ b/content/liquidity/liquidity-launchpad/guides/meta.json @@ -1,4 +1,13 @@ { "title": "Guides", - "pages": ["setup", "local-deployment", "example-configuration", "submit-bid", "price-discovery", "exit-bid"] + "pages": [ + "setup", + "local-deployment", + "example-configuration", + "submit-bid", + "price-discovery", + "exit-bid", + "collect-and-compound-fees", + "buyback-and-burn" + ] } diff --git a/content/liquidity/liquidity-launchpad/guides/price-discovery.mdx b/content/liquidity/liquidity-launchpad/guides/price-discovery.mdx index ae1ef3617..397f4075a 100644 --- a/content/liquidity/liquidity-launchpad/guides/price-discovery.mdx +++ b/content/liquidity/liquidity-launchpad/guides/price-discovery.mdx @@ -1,5 +1,4 @@ --- -id: price-discovery title: Price Discovery description: Learn how a Uniswap Continuous Clearing Auction discovers clearing prices as new bids enter each block. --- diff --git a/content/liquidity/liquidity-launchpad/guides/setup.mdx b/content/liquidity/liquidity-launchpad/guides/setup.mdx index 06752c45d..9d44418cc 100644 --- a/content/liquidity/liquidity-launchpad/guides/setup.mdx +++ b/content/liquidity/liquidity-launchpad/guides/setup.mdx @@ -1,5 +1,4 @@ --- -id: setup title: Setup CCA Environment description: Set up a local Continuous Clearing Auction development environment for Uniswap Liquidity Launchpad with Foundry. --- diff --git a/content/liquidity/liquidity-launchpad/guides/submit-bid.mdx b/content/liquidity/liquidity-launchpad/guides/submit-bid.mdx index ab367f163..b2bdced28 100644 --- a/content/liquidity/liquidity-launchpad/guides/submit-bid.mdx +++ b/content/liquidity/liquidity-launchpad/guides/submit-bid.mdx @@ -1,5 +1,4 @@ --- -id: submit-bid title: Submitting a Bid description: Submit your first bid in a Uniswap Continuous Clearing Auction and verify execution from onchain logs. --- diff --git a/content/liquidity/liquidity-launchpad/overview.mdx b/content/liquidity/liquidity-launchpad/overview.mdx index 84fe87eae..121f097ae 100644 --- a/content/liquidity/liquidity-launchpad/overview.mdx +++ b/content/liquidity/liquidity-launchpad/overview.mdx @@ -1,7 +1,29 @@ --- -id: Overview -title: CCA Overview +title: Liquidity Launchpad (CCA) Overview +sidebarTitle: Overview description: Learn how Uniswap Liquidity Launchpad uses CCA auctions and strategies to bootstrap liquidity for Uniswap v4 pools. +keywords: + - continuous clearing auction + - liquidity launchpad + - price discovery + - submitBid + - liquidity bootstrapping +faqs: + - question: What is a Continuous Clearing Auction (CCA)? + answer: |- + A Continuous Clearing Auction is the price discovery mechanism behind the Uniswap Liquidity Launchpad. It generalizes the uniform-price auction into continuous time: tokens are sold over the auction window to the current set of active participants, and every block a portion of supply (set by the release schedule) is allocated to bids with higher max prices first. Because bids spread automatically over time, no participant can concentrate demand at a single moment, which reduces timing games and sniping. See the CCA concept page for details. + - question: How do I submit a bid in a CCA? + answer: |- + You submit a bid by calling submitBid on the auction contract. A bid has two main parts: a max price (the highest price you are willing to pay, which must be strictly above the current clearing price) and an amount of currency you are bidding. The owner address receives any purchased tokens or refunded currency. See the Submitting a Bid guide for a full walkthrough. + - question: How does price discovery work in a CCA? + answer: |- + Each bid is willing to buy tokens up to a maximum price, so there is a clearing price at which total demand can purchase all of the tokens being sold. That equilibrium only changes when a new bid enters. Each time a bid is submitted, the auction iterates through price ticks to find the highest price at which there is still enough demand to buy the full supply. That price becomes the clearing price for the block, and all active participants in that block pay it. See the Price Discovery guide for a worked example. + - question: What is the clearing price and who pays it? + answer: |- + The clearing price is the single price that all active bidders in a given block pay, the same concept used in uniform-price auctions. In a CCA it is discovered gradually over time rather than in one shot: each time a bid enters, the auction settles at the highest price at which demand still covers the full supply. A bid is removed from the auction once its max price falls below the clearing price. + - question: What happens to the funds raised after a CCA auction ends? + answer: |- + After the auction finalizes its clearing state and raised funds, a liquidity strategy migrates the proceeds into a Uniswap v4 pool. In the example flow, you call migrate after the configured migration block to initialize the pool and its liquidity positions, and participants then claim their tokens after the claim block. This is what moves a completed auction from price discovery into active v4 trading with initial depth. See the Liquidity Strategies concept page for details. --- ## What Is the Uniswap Liquidity Launchpad? @@ -63,9 +85,87 @@ If you want to manually configure and deploy the contracts, use this sample flow 4. **Seeding Liquidity**: call `migrate()` after `migrationBlock` to initialize the Uniswap v4 pool and liquidity positions. 5. **After Migration**: participants claim tokens after `claimBlock`, and strategy/auction balances are swept by configuration. +## FAQ + +
+ What is a Continuous Clearing Auction (CCA)? + + + + A [Continuous Clearing Auction](/docs/liquidity/liquidity-launchpad/concepts/cca) is the price discovery mechanism behind the Uniswap Liquidity Launchpad. It generalizes the uniform-price auction into continuous time: tokens are sold over the auction window to the current set of active participants, and every block a portion of supply (set by the release schedule) is allocated to bids with higher max prices first. + + Because bids spread automatically over time: + + * No participant can concentrate demand at a single moment. + * Timing of bid submission matters less than valuation. + * Sniping and last-minute gaming become ineffective. + + + +
+ +
+ How do I submit a bid in a CCA? + + + + You submit a bid by calling `submitBid` on the auction contract. A bid has two main parts: + + * `maxPrice`: the highest price you are willing to pay. It must be strictly above the current clearing price. + * `amount`: the amount of currency you are bidding. + + The `owner` address receives any purchased tokens or refunded currency. See the [Submitting a Bid](/docs/liquidity/liquidity-launchpad/guides/submit-bid) guide for a full walkthrough, including the function signature and an example script. + + + +
+ +
+ How does price discovery work in a CCA? + + + + Each bid is willing to buy tokens up to a maximum price, so there is a clearing price at which total demand can purchase all of the tokens being sold. That equilibrium only changes when a new bid enters. + + Each time a bid is submitted, the auction iterates through price ticks to find the highest price at which there is still enough demand to buy the full supply. That price becomes the clearing price for the block, and all active participants in that block pay it. See the [Price Discovery](/docs/liquidity/liquidity-launchpad/guides/price-discovery) guide for a worked example. + + + +
+ +
+ What is the clearing price and who pays it? + + + + The clearing price is the single price that all active bidders in a given block pay, the same concept used in uniform-price auctions. In a CCA it is discovered gradually over time rather than in one shot. + + Each time a bid enters, the auction settles at the highest price at which demand still covers the full supply. A bid is removed from the auction once its max price falls below the clearing price. + + + +
+ +
+ What happens to the funds raised after a CCA auction ends? + + + + After the auction finalizes its clearing state and raised funds, a [liquidity strategy](/docs/liquidity/liquidity-launchpad/concepts/liquidity-strategies) migrates the proceeds into a Uniswap v4 pool. In the example flow: + + * Call `migrate()` after the configured `migrationBlock` to initialize the pool and its liquidity positions. + * Participants claim their tokens after the `claimBlock`. + + This is what moves a completed auction from price discovery into active v4 trading with initial depth. + + + +
+ ## Where to Go Next - Read the [CCA whitepaper](/whitepaper_cca.pdf) - Learn about the [Continuous Clearing Auction](/docs/liquidity/liquidity-launchpad/concepts/cca) mechanism +- Create a pool without an auction with [Instant Launch](/docs/liquidity/liquidity-launchpad/concepts/instant-launch) - Create a token via the [Token Factories](/docs/liquidity/liquidity-launchpad/concepts/token-factory) (UERC20 and Superchain-compatible USUPERC20) - For full address tables and versions, see [Deployments](/docs/liquidity/liquidity-launchpad/deployments) diff --git a/content/liquidity/liquidity-provisioning-api/getting-started.mdx b/content/liquidity/liquidity-provisioning-api/getting-started.mdx index 1dc48acd8..a2e02ea46 100644 --- a/content/liquidity/liquidity-provisioning-api/getting-started.mdx +++ b/content/liquidity/liquidity-provisioning-api/getting-started.mdx @@ -19,4 +19,6 @@ The following diagram illustrates how an integrator starting with no liquidity p 1. Commonly, liquidity providers will want to claim their earned fees from the pool using the [`/claim_fees`](/docs/api-reference/claim_fees) request. 2. Integrators may want to change the allocation of tokens they have made to a pool. Integrators can add additional tokens to a pool using the [`/increase`](/docs/api-reference/increase_position) request and can reduce or fully withdraw their position using the [`/decrease`](/docs/api-reference/decrease_position) endpoint. -If you are ready to build, you can grab an API key from the [Uniswap Developer Platform](https://developers.uniswap.org/dashboard/welcome?utm_medium=eco&utm_source=platform&utm_campaign=20260428-liquidity-api&utm_content=getting-started&utm_term=self-serve). \ No newline at end of file +If you are ready to build, you can grab an API key from the [Uniswap Developer Platform](https://developers.uniswap.org/dashboard/welcome?utm_medium=eco&utm_source=platform&utm_campaign=20260428-liquidity-api&utm_content=getting-started&utm_term=self-serve). + +For developer support, reach out to our team through the Help Center. \ No newline at end of file diff --git a/content/liquidity/liquidity-provisioning-api/integration-guide.mdx b/content/liquidity/liquidity-provisioning-api/integration-guide.mdx index e2379bdc6..5e229ec35 100644 --- a/content/liquidity/liquidity-provisioning-api/integration-guide.mdx +++ b/content/liquidity/liquidity-provisioning-api/integration-guide.mdx @@ -73,8 +73,6 @@ Your application handles: - **Gas Payment**: Actual gas costs - **Transaction Error Handling**: Handle reverts and surface errors to users -See the [Build Prerequisites](/docs/trading/swapping-api/building-prerequisites) for more details. - ### Required infrastructure Your integration must include: @@ -82,6 +80,7 @@ Your integration must include: - **RPC Provider**: Connection to blockchain nodes (e.g. Infura, Alchemy, or self-hosted) - **Web3 Library**: ethers.js, viem, or web3.js for transaction signing - **Wallet Integration**: Uniswap Wallet, MetaMask, or similar for user signing +- **API Key Handling**: Store your Uniswap API key server-side and attach it to requests over HTTPS. Do not ship it in front-end code; proxy calls through your own backend so the key is never exposed to users. ### Data flow @@ -156,7 +155,7 @@ const { transactions } = await approvalResponse.json(); ```ts // transactions is a list of ApprovalTransactionRequest objects. -// If empty, all approvals are already in place — proceed to the LP action. +// If empty, all approvals are already in place. Proceed to the LP action. for (const item of transactions) { validateTransaction(item.transaction); const signedTx = await wallet.signTransaction(item.transaction); @@ -206,7 +205,7 @@ For Uniswap v3 positions, `/lp/check_approval` may return `v3NftPermitData` for ## Creating a Position -### Uniswap v3 and Uniswap v4 — `/lp/create` +### Uniswap v3 and Uniswap v4: `/lp/create` The caller specifies a price range and the amount of one token. The API computes the corresponding amount of the second token based on current pool state. @@ -214,15 +213,15 @@ The caller specifies a price range and the amount of one token. The API computes Provide exactly one of: -- **`existingPool`** — For an existing pool. Includes `token0address`, `token1address`, and `poolReference` (pool address for Uniswap v3, pool ID for Uniswap v4). The API fetches live pool state to compute the dependent token amount. -- **`newPool`** — For initializing a new pool. Includes token addresses, `fee`, `tickSpacing`, optional `hooks` (Uniswap v4 only), and `initialPrice` as a `sqrtRatioX96` string. The API uses the initial price to compute the dependent amount. +- **`existingPool`**: For an existing pool. Includes `token0address`, `token1address`, and `poolReference` (pool address for Uniswap v3, pool ID for Uniswap v4). The API fetches live pool state to compute the dependent token amount. +- **`newPool`**: For initializing a new pool. Includes token addresses, `fee`, `tickSpacing`, optional `hooks` (Uniswap v4 only), and `initialPrice` as a `sqrtRatioX96` string. The API uses the initial price to compute the dependent amount. #### Price range Provide exactly one of: -- **`priceBounds`** — Human-readable decimal price strings (`minPrice`, `maxPrice`). The API converts to ticks, snaps to valid tick spacing, and returns the adjusted prices in the response. -- **`tickBounds`** — Raw tick integers (`tickLower`, `tickUpper`). Skips price conversion. The API computes the corresponding decimal prices for the response. +- **`priceBounds`**: Human-readable decimal price strings (`minPrice`, `maxPrice`). The API converts to ticks, snaps to valid tick spacing, and returns the adjusted prices in the response. +- **`tickBounds`**: Raw tick integers (`tickLower`, `tickUpper`). Skips price conversion. The API computes the corresponding decimal prices for the response. #### Example request @@ -268,7 +267,7 @@ interface CreatePositionResponse { } ``` -### Uniswap v2 — `/lp/create_classic` +### Uniswap v2: `/lp/create_classic` Uniswap v2 positions always span the full price range (0 to ∞). The caller provides an `independentToken` amount; the API computes the `dependentToken` amount from current pair reserves. If creating a new pool, the `independentToken` and `dependentToken` fields are both required. @@ -298,7 +297,7 @@ curl --location 'https://liquidity.api.uniswap.org/lp/create_classic' \ If `dependentToken` is omitted, the API computes the optimal amount from current pool reserves. -## Increasing Liquidity — `/lp/increase` +## Increasing Liquidity: `/lp/increase` Adds liquidity to an existing Uniswap v2, v3, or v4 position. Provide one token amount; the API computes the other. @@ -337,7 +336,7 @@ For Uniswap v4 permit-based approvals, include `v4BatchPermitData` and `signatur | `independentToken` | Token address and amount the user wants to add | | `slippageTolerance` | Optional. Decimal slippage tolerance (e.g., `0.5` for 0.5%) | -## Decreasing Liquidity — `/lp/decrease` +## Decreasing Liquidity: `/lp/decrease` Removes a percentage of liquidity from a Uniswap v2, v3, or v4 position. The API computes the token amounts to be returned and generates the withdrawal transaction. @@ -367,7 +366,7 @@ curl --location 'https://liquidity.api.uniswap.org/lp/decrease' \ > **v3 fee collection**: For Uniswap v3, uncollected fees are included in the withdrawal automatically via the SDK's `removeCallParameters`. You do not need to call `/lp/claim_fees` separately. -## Collecting Fees — `/lp/claim_fees` +## Collecting Fees: `/lp/claim_fees` Collects accumulated trading fees from a Uniswap v3 or Uniswap v4 position. Not available for Uniswap v2; Uniswap v2 fees are embedded in LP token value and are realized upon liquidity removal. @@ -545,7 +544,7 @@ If a transaction reverts onchain: 1. **Check `data` field**: Verify it is not empty before broadcasting 2. **Verify token balances**: User has sufficient token balances at broadcast time -3. **Check approvals**: Run `/lp/check_approval` again — a prior approval may have been consumed or revoked +3. **Check approvals**: Run `/lp/check_approval` again, since a prior approval may have been consumed or revoked 4. **Check slippage**: Pool price moved beyond the slippage tolerance between quote and broadcast 5. **Check deadline**: Transaction was not broadcast before the deadline encoded in the calldata 6. **Nonce collision**: Another transaction used the same nonce @@ -592,7 +591,7 @@ async function validateBeforeBroadcast( ### Always check approvals first -Call `/lp/check_approval` before every LP action — even for positions where approvals were previously granted, since allowances can be revoked or consumed. +Call `/lp/check_approval` before every LP action, even for positions where approvals were previously granted, since allowances can be revoked or consumed. ```ts async function approveAndExecute( @@ -624,7 +623,7 @@ async function approveAndExecute( ### Price range guidance -When using `priceBounds`, note that the API snaps prices to valid tick spacing boundaries. Always display the **adjusted prices** returned in the response to the user — not the original input values. +When using `priceBounds`, note that the API snaps prices to valid tick spacing boundaries. Always display the **adjusted prices** returned in the response to the user, not the original input values. ```ts const { adjustedMinPrice, adjustedMaxPrice, tickLower, tickUpper } = createResponse; @@ -754,12 +753,12 @@ function logLpAttempt( - Verify the amount is in the correct units (wei, not ether) - Confirm token decimals match the onchain contract -- If using `priceBounds`, check the returned `adjustedMinPrice` / `adjustedMaxPrice` in the response — the server may have snapped to different tick boundaries than expected +- If using `priceBounds`, check the returned `adjustedMinPrice` / `adjustedMaxPrice` in the response. The server may have snapped to different tick boundaries than expected - For new pools, confirm `initialPrice` is a valid `sqrtRatioX96` value **Problem**: Transaction reverts after a successful create response -- Re-check token approvals via `/lp/check_approval` — another transaction may have consumed the allowance +- Re-check token approvals via `/lp/check_approval`. Another transaction may have consumed the allowance - Confirm the quote has not gone stale (price moved significantly since the transaction was built) - Verify slippage tolerance is appropriate for the pair's volatility @@ -774,7 +773,7 @@ function logLpAttempt( **Problem**: `/lp/decrease` does not return expected amounts - Confirm `liquidityPercentageToDecrease` is between 1 and 100 -- For Uniswap v3, note that uncollected fees are bundled into the withdrawal — the returned amounts may be higher than the pro-rata liquidity alone +- For Uniswap v3, note that uncollected fees are bundled into the withdrawal. The returned amounts may be higher than the pro-rata liquidity alone ### Fee collection issues @@ -786,7 +785,7 @@ function logLpAttempt( **Problem**: Uniswap v2 claim attempt returns a validation error -- This is expected behavior. Uniswap v2 fees are not claimable independently — use `/lp/decrease` to realize accumulated fees along with liquidity. +- This is expected behavior. Uniswap v2 fees are not claimable independently. Use `/lp/decrease` to realize accumulated fees along with liquidity. ### Approval issues diff --git a/content/liquidity/overview.mdx b/content/liquidity/overview.mdx index f93b54e99..6696c4d8d 100644 --- a/content/liquidity/overview.mdx +++ b/content/liquidity/overview.mdx @@ -1,7 +1,30 @@ --- -id: Overview title: Liquidity Overview +sidebarTitle: Overview description: "Explore all liquidity-related workflows in the Uniswap ecosystem: providing liquidity, filling UniswapX orders, and bootstrapping new markets." +keywords: + - liquidity provisioning + - concentrated liquidity + - full-range liquidity + - fee collection + - v3 to v4 migration + - token ratio +faqs: + - question: How much of each token do I deposit when adding liquidity? + answer: |- + The token ratio depends on where the current pool price sits relative to your chosen range. When the price is inside your range, you deposit both tokens, and the split shifts as the price moves toward either bound. When the price is at or beyond one bound, your position is single-sided and you deposit only one token. A full-range position always takes both tokens at the current price ratio. When you use the API, you provide one token amount and the API computes the dependent amount from live pool state. + - question: How do fees accrue on my Uniswap v3 or v4 position, and how do I collect them? + answer: |- + Fees accrue to your position as swaps cross the price range where your liquidity is active, and you collect them manually as a separate action, for example the claim_fees endpoint in the Uniswap Liquidity Provisioning API or, onchain, a decrease with zero liquidity change on the v4 Position Manager, which has no dedicated collect command. A position only earns fees while the current price is inside its range; once the price moves out of range, that position stops earning until the price returns. Accrued fees are not auto-compounded back into your position, and you can collect fees without withdrawing your principal liquidity. + - question: What is the difference between full-range and concentrated liquidity? + answer: |- + Full-range liquidity spreads your capital evenly across all possible prices, from 0 to infinity, the way Uniswap v2 works. It stays active at any price but uses capital less efficiently because most of it sits at prices that rarely trade. Concentrated liquidity, available in v3 and v4, lets you allocate capital to a chosen price band. This can earn more fees from the same capital, but the position stops earning when the price leaves the band, so it needs more active management. + - question: What happens when the price moves outside my range in a Uniswap v3 or v4 position? + answer: |- + When the price exits the bounds of a concentrated position, that position's liquidity becomes inactive and stops earning fees. As the price moves toward one bound, your position converts increasingly into a single token, and once the price is fully out of range it holds only one of the two tokens. If the price later reenters your range, the liquidity becomes active again and resumes earning fees. Full-range positions avoid this because they remain active across the entire price interval. + - question: How do I move a Uniswap v3 position to Uniswap v4? + answer: |- + Moving a v3 position to v4 means removing the liquidity from your v3 position and minting a new position in a v4 pool, since the two versions use separate contracts. You can do this in steps, or in a single transaction. The Universal Router can compose the v3 withdrawal and the v4 mint into one transaction through its command-based encoding, and the Uniswap Liquidity Provisioning API supports the migration flow through the MIGRATE action on its check_approval endpoint. --- There are three principal ways to participate in Uniswap as a liquidity provider or market maker. Each serves a different purpose and appeals to a different type of builder. @@ -31,12 +54,11 @@ You can build LP workflows at three different levels of abstraction: | Endpoint | Purpose | | :--- | :--- | -| `/approve` | Check and obtain token approvals | +| `/check_approval` | Check and obtain token approvals | | `/create` | Create a pool (if needed) and mint a new position | | `/increase` | Add liquidity to an existing position | | `/decrease` | Remove liquidity (partial or full withdrawal) | -| `/claim` | Collect accrued fees | -| `/migrate` | Move a position from v3 to v4 | +| `/claim_fees` | Collect accrued fees | **Via the SDK**: The v4 SDK (`@uniswap/v4-sdk`) provides TypeScript classes for constructing positions and encoding transaction calldata locally. You manage RPC connections and submit transactions yourself using a library like Ethers.js or Viem. [Manage liquidity via the SDK](/docs/sdks/v4/guides/managing-liquidity/position-minting). @@ -124,3 +146,80 @@ This is designed for projects that need to go from "no market exists" to "deep o ### How to integrate The Liquidity Launchpad is accessed via **smart contract interactions** with the Liquidity Launcher and strategy contracts onchain. The architecture is modular and permissionless, so anyone can deploy an auction and bootstrap liquidity without gatekeepers. + +## FAQ + +
+ How much of each token do I deposit when adding liquidity? + + + + The token ratio depends on where the current pool price sits relative to your chosen range: + + * **Price inside your range**: you deposit both tokens, and the split shifts as the price moves toward either bound. + * **Price at or beyond a bound**: the position is single-sided, so you deposit only one token. + * **Full-range position**: always takes both tokens at the current price ratio. + + When you use the [Liquidity Provisioning API](/docs/liquidity/liquidity-provisioning-api/getting-started), you provide one token amount and the API computes the dependent amount from live pool state. + + + +
+ +
+ How do fees accrue on my Uniswap v3 or v4 position, and how do I collect them? + + + + Fees accrue to your position as swaps cross the price range where your liquidity is active, and you collect them manually as a separate action. A position only earns fees while the current price is inside its range; once the price moves out of range, it stops earning until the price returns. + + Accrued fees are not auto-compounded back into your position. Collect them via: + + * **[Liquidity Provisioning API](/docs/liquidity/liquidity-provisioning-api/getting-started)**: the `/lp/claim_fees` endpoint + * **Smart contracts**: a decrease with zero liquidity change on the v4 `PositionManager` (there is no dedicated collect command) + + You can collect fees without withdrawing your principal liquidity. + + + +
+ +
+ What is the difference between full-range and concentrated liquidity? + + + + Full-range liquidity spreads your capital evenly across all possible prices, from 0 to infinity, the way Uniswap v2 works. It stays active at any price but uses capital less efficiently, because most of it sits at prices that rarely trade. + + [Concentrated liquidity](/docs/get-started/concepts/liquidity-providers/concentrated-liquidity), available in v3 and v4, lets you allocate capital to a chosen price band. This can earn more fees from the same capital, but the position stops earning when the price leaves the band, so it needs more active management. + + + +
+ +
+ What happens when the price moves outside my range in a Uniswap v3 or v4 position? + + + + When the price exits the bounds of a concentrated position, that position's liquidity becomes inactive and stops earning fees. As the price moves toward one bound, your position converts increasingly into a single token, and once the price is fully out of range it holds only one of the two tokens. + + If the price later reenters your range, the liquidity becomes active again and resumes earning fees. Full-range positions avoid this because they remain active across the entire price interval. + + + +
+ +
+ How do I move a Uniswap v3 position to Uniswap v4? + + + + Moving a v3 position to v4 means removing the liquidity from your v3 position and minting a new position in a v4 pool, since the two versions use separate contracts. You can do this in steps, or in a single transaction: + + * **[Liquidity Provisioning API](/docs/liquidity/liquidity-provisioning-api/getting-started)**: the `MIGRATE` action on `/lp/check_approval` returns the approvals needed to migrate a position. + * **[Universal Router](/docs/protocols/universal-router/overview)**: composes the v3 withdrawal and the v4 mint into one transaction through its command-based encoding. + + + +
diff --git a/content/liquidity/uniswapx/concepts/architecture.mdx b/content/liquidity/uniswapx/concepts/architecture.mdx index b7998e7b5..6190d80f0 100644 --- a/content/liquidity/uniswapx/concepts/architecture.mdx +++ b/content/liquidity/uniswapx/concepts/architecture.mdx @@ -1,6 +1,6 @@ --- -id: architecture -title: Architecture +title: UniswapX Architecture +sidebarTitle: Architecture description: Understand UniswapX reactors, fill contracts, and direct fill settlement paths across supported order formats. --- diff --git a/content/liquidity/uniswapx/concepts/auction-types.mdx b/content/liquidity/uniswapx/concepts/auction-types.mdx index 6dd446416..ce6a19b62 100644 --- a/content/liquidity/uniswapx/concepts/auction-types.mdx +++ b/content/liquidity/uniswapx/concepts/auction-types.mdx @@ -1,5 +1,4 @@ --- -id: auctiontypes title: Auction Types description: Compare UniswapX auction mechanisms across chains using chain-specific timing models. --- @@ -13,7 +12,7 @@ The following table summarizes the auction mechanisms on each chain. | Chain | Auction Type | Reactor | Timing Mechanism | |-------|-------------|---------|------------------| | **Ethereum** | RFQ + Exclusive Dutch Auction | Dutch V2 | Time-based: exclusivity window, then decay (`decayStartTime`) | -| **Arbitrum, Avalanche, Base, BNB Smart Chain, Robinhood Chain, Tempo, Unichain** | RFQ + Exclusive Dutch Auction | Dutch V3 | Block-based: exclusivity window, then decay (`decayStartBlock`) | +| **Arbitrum, Arc, Avalanche, Base, BNB Smart Chain, Ink, Monad, Robinhood Chain, Tempo, Unichain** | RFQ + Exclusive Dutch Auction | Dutch V3 | Block-based: exclusivity window, then decay (`decayStartBlock`) | UniswapX uses the same RFQ and exclusive Dutch auction model on every supported chain. The only difference is how timing is measured: Ethereum measures the exclusivity window and decay in time, while the other chains measure them in block numbers. @@ -81,7 +80,7 @@ Currently, the Uniswap Interface and Uniswap API set the cosigner to Uniswap Lab The same RFQ and exclusive Dutch auction as Ethereum, with exclusivity and decay measured in block numbers instead of time. -Arbitrum, Avalanche, Base, BNB Smart Chain, Robinhood Chain, Tempo, and Unichain run the same model described above for Ethereum: a winning quoter from the RFQ holds an exclusivity window, and the order then decays in an open Dutch auction. These chains settle through the [DutchV3 reactor](https://github.com/Uniswap/UniswapX/blob/main/src/reactors/V3DutchOrderReactor.sol), and both the exclusivity window and the decay are measured in **block numbers** rather than timestamps. +Arbitrum, Arc, Avalanche, Base, BNB Smart Chain, Ink, Monad, Robinhood Chain, Tempo, and Unichain run the same model described above for Ethereum: a winning quoter from the RFQ holds an exclusivity window, and the order then decays in an open Dutch auction. These chains settle through the [DutchV3 reactor](https://github.com/Uniswap/UniswapX/blob/main/src/reactors/V3DutchOrderReactor.sol), and both the exclusivity window and the decay are measured in **block numbers** rather than timestamps. ### How the decay curve works @@ -98,7 +97,7 @@ The exclusive filler has a short exclusivity window before decay begins. After i | Reactor | Block time | Exclusivity window | Decay | |---|---|---|---| | Dutch V2 (Ethereum) | ~12 seconds | ~24 seconds (2 blocks) | Time-based, about 1 minute, then expiry | -| Dutch V3 (Arbitrum, Avalanche, Base, BNB Smart Chain, Robinhood Chain, Tempo, Unichain) | ~1 second | ~2 to 4 seconds | Block-based, about 1 minute, then expiry | +| Dutch V3 (Arbitrum, Arc, Avalanche, Base, BNB Smart Chain, Ink, Monad, Robinhood Chain, Tempo, Unichain) | Varies by chain, sub-second to a couple of seconds | ~2 to 4 seconds | Block-based, about 1 minute, then expiry | The cosigner sets the exclusivity window per order, so these values can change. On the DutchV3 chains the window and decay are counted in blocks, and the wall-clock duration follows each chain's block time. diff --git a/content/liquidity/uniswapx/deployments.mdx b/content/liquidity/uniswapx/deployments.mdx index 0fd17f9a4..1faaf70a6 100644 --- a/content/liquidity/uniswapx/deployments.mdx +++ b/content/liquidity/uniswapx/deployments.mdx @@ -3,6 +3,10 @@ title: Deployment description: Find UniswapX reactor, quoter, and Permit2 deployment addresses across supported chains. --- + + All UniswapX deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + ## Mainnet | Contract | Contract Address | Source Code | Example Filler Implementation | @@ -72,3 +76,27 @@ Base supports both Priority and DutchV3 orders. | DutchV3OrderReactor | [0x000000007A1C8e570011EeDF86A2A35593013cBA](https://robinhoodchain.blockscout.com/address/0x000000007A1C8e570011EeDF86A2A35593013cBA) | [V3DutchOrderReactor](https://github.com/Uniswap/UniswapX/blob/main/src/reactors/V3DutchOrderReactor.sol) | [dutchv3_strategy](https://github.com/Uniswap/uniswapx-artemis/blob/main/src/strategies/dutchv3_strategy.rs) | | OrderQuoter| [0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58](https://robinhoodchain.blockscout.com/address/0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58) | [OrderQuoter](https://github.com/Uniswap/UniswapX/blob/main/src/lens/OrderQuoter.sol)| N/A | | Permit2| [0x000000000022D473030F116dDEE9F6B43aC78BA3](https://robinhoodchain.blockscout.com/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | [Permit2](https://github.com/Uniswap/permit2)| N/A| + +## Monad + +| Contract | Contract Address | Source Code | Example Filler Implementation | +|-----------|------------------|----------------------|------------------------------| +| DutchV3OrderReactor | [0x000000000Ac008F7e07210CFb6648e40249232c2](https://monadvision.com/address/0x000000000Ac008F7e07210CFb6648e40249232c2) | [V3DutchOrderReactor](https://github.com/Uniswap/UniswapX/blob/main/src/reactors/V3DutchOrderReactor.sol) | [dutchv3_strategy](https://github.com/Uniswap/uniswapx-artemis/blob/main/src/strategies/dutchv3_strategy.rs) | +| OrderQuoter| [0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58](https://monadvision.com/address/0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58) | [OrderQuoter](https://github.com/Uniswap/UniswapX/blob/main/src/lens/OrderQuoter.sol)| N/A | +| Permit2| [0x000000000022D473030F116dDEE9F6B43aC78BA3](https://monadvision.com/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | [Permit2](https://github.com/Uniswap/permit2)| N/A| + +## Ink + +| Contract | Contract Address | Source Code | Example Filler Implementation | +|-----------|------------------|----------------------|------------------------------| +| DutchV3OrderReactor | [0x000000007A1C8e570011EeDF86A2A35593013cBA](https://explorer.inkonchain.com/address/0x000000007A1C8e570011EeDF86A2A35593013cBA) | [V3DutchOrderReactor](https://github.com/Uniswap/UniswapX/blob/main/src/reactors/V3DutchOrderReactor.sol) | [dutchv3_strategy](https://github.com/Uniswap/uniswapx-artemis/blob/main/src/strategies/dutchv3_strategy.rs) | +| OrderQuoter| [0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58](https://explorer.inkonchain.com/address/0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58) | [OrderQuoter](https://github.com/Uniswap/UniswapX/blob/main/src/lens/OrderQuoter.sol)| N/A | +| Permit2| [0x000000000022D473030F116dDEE9F6B43aC78BA3](https://explorer.inkonchain.com/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | [Permit2](https://github.com/Uniswap/permit2)| N/A| + +## Arc + +| Contract | Contract Address | Source Code | Example Filler Implementation | +|-----------|------------------|----------------------|------------------------------| +| DutchV3OrderReactor | [0x0000000015134054eA82AE0bb9fda66b36402C36](https://explorer.arc.io/address/0x0000000015134054eA82AE0bb9fda66b36402C36) | [V3DutchOrderReactor](https://github.com/Uniswap/UniswapX/blob/main/src/reactors/V3DutchOrderReactor.sol) | [dutchv3_strategy](https://github.com/Uniswap/uniswapx-artemis/blob/main/src/strategies/dutchv3_strategy.rs) | +| OrderQuoter| [0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58](https://explorer.arc.io/address/0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58) | [OrderQuoter](https://github.com/Uniswap/UniswapX/blob/main/src/lens/OrderQuoter.sol)| N/A | +| Permit2| [0x000000000022D473030F116dDEE9F6B43aC78BA3](https://explorer.arc.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | [Permit2](https://github.com/Uniswap/permit2)| N/A| diff --git a/content/liquidity/uniswapx/filling/dutch-v3-chains/filling-on-dutch-v3-chains.mdx b/content/liquidity/uniswapx/filling/dutch-v3-chains/filling-on-dutch-v3-chains.mdx index 762710c16..d3e1d8b4f 100644 --- a/content/liquidity/uniswapx/filling/dutch-v3-chains/filling-on-dutch-v3-chains.mdx +++ b/content/liquidity/uniswapx/filling/dutch-v3-chains/filling-on-dutch-v3-chains.mdx @@ -1,12 +1,11 @@ --- -id: fillingondutchv3chains title: Filling Dutch V3 Auctions description: Fill UniswapX orders on chains that use the DutchV3 reactor, where exclusivity and decay are measured in block numbers. --- Ethereum uses the Dutch V2 reactor. Every other UniswapX chain that runs a Dutch auction uses the [DutchV3 reactor](https://github.com/Uniswap/UniswapX/blob/main/src/reactors/V3DutchOrderReactor.sol), so the execution flow is the same across them. This guide covers: -- **Arbitrum, Avalanche, Base, BNB Smart Chain, Robinhood Chain, Tempo, and Unichain**: RFQ with exclusive filling, the same model as [Ethereum mainnet](/docs/liquidity/uniswapx/filling/mainnet/filling-on-mainnet) but with block-based timing. +- **Arbitrum, Arc, Avalanche, Base, BNB Smart Chain, Ink, Monad, Robinhood Chain, Tempo, and Unichain**: RFQ with exclusive filling, the same model as [Ethereum mainnet](/docs/liquidity/uniswapx/filling/mainnet/filling-on-mainnet) but with block-based timing. Find reactor, quoter, and Permit2 addresses on the [Deployments](/docs/liquidity/uniswapx/deployments) page. @@ -24,10 +23,12 @@ On all of these chains, the exclusivity window and the auction decay are measure All signed Dutch orders created through the Uniswap interface are available via the UniswapX Orders Endpoint. [Swagger documentation](https://api.uniswap.org/v2/uniswapx/docs) is available. Pass the chain ID of the chain you want to fill: ```bash -GET https://api.uniswap.org/v2/orders?orderStatus=open&chainId=42161&limit=1000&orderType=Dutch_V3 +GET https://api.uniswap.org/v2/orders?orderStatus=open&chainId=42161&limit=50&orderType=Dutch_V3 ``` -Use one of the following chain IDs: Arbitrum `42161`, Avalanche `43114`, Base `8453`, BNB Smart Chain `56`, Robinhood Chain `4663`, Tempo `4217`, Unichain `130`. Quote requests include a `tokenInChainId` field that identifies the chain of the intent. If you are not interested in quoting for a given chain, respond with HTTP status code `204`. +The endpoint serves cached responses and returns at most the last 50 orders, ordered by most recent. Poll at no more than 4 RPS; requests above that return `429`. + +Use one of the following chain IDs: Arbitrum `42161`, Arc `5042`, Avalanche `43114`, Base `8453`, BNB Smart Chain `56`, Ink `57073`, Monad `143`, Robinhood Chain `4663`, Tempo `4217`, Unichain `130`. Quote requests include a `tokenInChainId` field that identifies the chain of the intent. If you are not interested in quoting for a given chain, respond with HTTP status code `204`. Decode the `encodedOrder` field returned from the endpoint with the [UniswapX SDK](https://github.com/Uniswap/sdks/tree/main/sdks/uniswapx-sdk). Each order represents a fillable user trade. @@ -75,7 +76,8 @@ If you already fill on mainnet, the integration is the same with the following a - **Block-based timing**: The reactor uses block numbers for both exclusivity and decay. Cosigner data carries only `decayStartBlock`; there is no separate end time, since the decay end is implied by the curve. See [`dutchBlockDecay.ts`](https://github.com/Uniswap/sdks/blob/main/sdks/uniswapx-sdk/src/utils/dutchBlockDecay.ts). - **Cosignature digest includes the chain ID**: The digest hashes in `chainid` as `orderHash || chainid || cosignerData`. See `cosignerDigest()` in [`V3DutchOrder.ts`](https://github.com/Uniswap/sdks/blob/main/sdks/uniswapx-sdk/src/order/V3DutchOrder.ts). - **Base fee adjustment is unused for now**: DutchV3 supports a dynamic base fee adjustment on inputs and outputs. It is not used today, so set `startingBaseFee` and `adjustmentPerGweiBaseFee` to zero on every input and output to keep it a no-op. -- **Faster quote responses**: Quote responses for any chain other than Ethereum must be returned within 250ms (compared to 500ms on Ethereum). +- **Same quote response budget**: Quote responses must be returned within 500ms, the same budget as Ethereum. +- **No timeouts**: Answer every quote request, including the ones you do not want to quote. See [Become a Quoter](/docs/liquidity/uniswapx/filling/mainnet/become-a-quoter#performance-expectations) for the full response expectations. Build orders with [`V3DutchOrderBuilder.ts`](https://github.com/Uniswap/sdks/blob/main/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.ts) (compare against `V2DutchOrderBuilder.ts`). diff --git a/content/liquidity/uniswapx/filling/faq.mdx b/content/liquidity/uniswapx/filling/faq.mdx index 305e8032d..867c9f16b 100644 --- a/content/liquidity/uniswapx/filling/faq.mdx +++ b/content/liquidity/uniswapx/filling/faq.mdx @@ -4,9 +4,16 @@ description: Resolve UniswapX filler and quoter issues, including native ETH inp type: faq faqs: - question: How do I get orders? - answer: Fillers should start with polling for orders and rate limit at 6 RPS. + answer: Fillers should start with polling for orders and rate limit at 4 RPS. The orders endpoint serves cached responses, and requests above 4 RPS return 429. Each response returns at most the last 50 orders, ordered by most recent. + - question: Do I need an API key to poll for orders? + answer: No. The orders API is a separate service from the Trading API, and polling for open orders requires no API key. Raising a Trading API key's rate limit does not increase your polling throughput. + - question: Which orders endpoint should I use? + answer: |- + Three different endpoints are called "orders", and fillers want the first one. GET /v2/orders on api.uniswap.org polls for open orders to fill and is the filler endpoint. POST /v1/order on trade-api.gateway.uniswap.org submits a signed order, and GET /v1/orders on the same host checks the status of a submitted order; both are for swappers and integrators and require an API key. + - question: What should I do if I get a 429? + answer: Back off and stop polling until the limit clears. Do not retry. Throttled requests return HTTP 429 with error code TOO_MANY_REQUESTS. Blocked requests still count toward the rolling five-minute window, so retrying while throttled keeps the window full and extends the block. - question: Are webhooks still supported? - answer: Webhooks were deprecated on UniswapX due to degraded performance, and we are no longer onboarding new webhook integrations. Existing webhook integrations will continue to work, but new fillers should start with polling orders on the API and rate limit at 6 RPS. We are exploring WebSocket connections going forward. + answer: Webhooks were deprecated on UniswapX due to degraded performance, and we are no longer onboarding new webhook integrations. Existing webhook integrations will continue to work, but new fillers should start with polling orders on the API and rate limit at 4 RPS. We are exploring WebSocket connections going forward. - question: Which IPs do I need to whitelist to receive quote requests? answer: 'Whitelist the UniswapX quote-request source IPs so your quoting server can receive RFQ requests. Beta test environment: 3.135.148.114. Production environment: 3.138.88.28.' - question: Why don't I get quote requests for all chains? @@ -14,29 +21,31 @@ faqs: - question: How do I know which chain I need to quote on? answer: Quote requests include the tokenInChainId field, which identifies the chain of the intent. If you are not interested in quoting for a given chain, respond with HTTP status code 204. - question: How quickly do I need to quote? - answer: Quote responses must be returned within 500ms on Ethereum, or 250ms on any other chain, to be considered. + answer: Quote responses must be returned within 500ms to be considered. The budget is the same on every chain. - question: What's the expected RPS for quoting on Ethereum? answer: 1 RPS. - question: Which tokens are supported in RFQ? answer: All tokens are supported, except those on the unsupported token list at unsupportedtokens.uniswap.org. - question: I'm getting 404, no quotes available? answer: |- - There are several reasons why you might receive this error. Price Impact: UniswapX has filters that route trades to the AMM when direct AMM execution would be superior. If the price impact is too high or the benefit of routing through UniswapX isn't significant enough, no quote will be returned for this pair. Order Size: Very small orders may not be economical to fill through UniswapX due to gas costs. Similarly, extremely large orders might exceed available liquidity from quoters. Response Latency: If your filler responds but takes longer than 500ms on Ethereum, or 250ms on any other chain, your quote will be rejected. Ensure your infrastructure can consistently respond within this latency requirement. The quote server is located in AWS US-EAST-2 if you wish to co-locate to reduce latency. + There are several reasons why you might receive this error. Price Impact: UniswapX has filters that route trades to the AMM when direct AMM execution would be superior. If the price impact is too high or the benefit of routing through UniswapX isn't significant enough, no quote will be returned for this pair. Order Size: Very small orders may not be economical to fill through UniswapX due to gas costs. Similarly, extremely large orders might exceed available liquidity from quoters. Response Latency: If your filler responds but takes longer than 500ms, on any chain, your quote will be rejected. Ensure your infrastructure can consistently respond within this latency requirement. The quote server is located in AWS US-EAST-2 if you wish to co-locate to reduce latency. - question: The transaction is reverting for a certain reason (e.g. DeadlineReached). What does this mean? answer: UniswapX reactors revert with custom errors such as DeadlineReached, InvalidCosignerInput, and InvalidCosignerOutput. Look up the revert selector against the reactor and base contracts in the UniswapX repository to find the cause. Custom errors defined under src/v4 (for example IntentAlreadyCancelled and ChunkSizeBelowMin) belong to the v4 DCA hook, not the production Dutch reactors, so do not confuse them with live order reverts. - question: Why did my server stop receiving quote requests? - answer: Your server may be temporarily blocked due to the fade-rate monitor. If you win an RFQ but don't fill the order, this counts as a "fade." After too many fades, RFQ requests are temporarily paused. You'll know you're blocked when quote requests include a blockUntilTimestamp field indicating when you'll start receiving requests again. Handle this field in your code so your service backs off until the block clears, and log it so you can detect and debug circuit breaker events. + answer: There are two reasons. The first is a fade-rate block. Your server may be temporarily blocked by the fade-rate monitor. If you win an RFQ but don't fill the order, this counts as a "fade." After too many fades, RFQ requests are temporarily paused. You'll know you're blocked when quote requests include a blockUntilTimestamp field indicating when you'll start receiving requests again. Handle this field in your code so your service backs off until the block clears, and log it so you can detect and debug circuit breaker events. The second is timeouts. Uniswap Labs may disable a quote endpoint that times out on a meaningful share of quote requests, at its discretion, until the issue is fixed. - question: Why does my fill transaction fail the Permit2 nonce check? answer: |- A Permit2 nonce check failure typically means the order has already been filled by another filler, the user cancelled the order, or the signature has expired. Before attempting to fill, verify the order is still valid. See "How do I know if an order is still fillable?". - question: What is ERC20ETH? answer: ERC20ETH is a minimal ERC-20 wrapper for native ETH that lets EIP-7702 smart wallets use ETH in ERC-20-based flows like UniswapX and Permit2. + - question: How does ERC20ETH work? + answer: ERC20ETH is built on Solady's ERC-20 implementation, supports EIP-2612 permit, and automatically gives Permit2 an infinite allowance. It keeps no internal balances and relies on actual native ETH balances, with balanceOf intentionally reverting to prevent double-entry-point balance-check bugs. On transfer and transferFrom it calls ERC-7914's transferFromNative on the sender, pulls native ETH, forwards it to the recipient, and emits standard ERC-20 events for tooling compatibility. The contract was audited by OpenZeppelin. - question: How do fillers handle orders with ERC20ETH as the input token? answer: Special-case the ERC20ETH address in routing logic and treat it as native ETH. There are no ERC20ETH liquidity pools, and the reactor delivers actual native ETH to the filler when Permit2 pulls the input. - question: What setup does a swapper need before using native ETH input? answer: The swapper needs an EIP-7702 wallet with ERC-7914 support and a one-time native ETH allowance to ERC20ETH. After setup, each swap only requires the usual offchain Permit2 signature. - question: Where is ERC20ETH deployed? - answer: ERC20ETH is deployed at 0x00000000e20E49e6dCeE6e8283A0C090578F0fb9, the same address across supported chains. + answer: ERC20ETH is deployed at 0x00000000e20E49e6dCeE6e8283A0C090578F0fb9, the same address on the chains that carry it. It is not deployed on every UniswapX chain, so check the Deployments page or deployments.json for a given chain before relying on it. - question: How do I know if an order is still fillable? answer: The simulation using UniswapXOrderQuoter (sdks/uniswapx-sdk/src/utils/OrderQuoter.ts) will tell you whether the order is still fillable. - question: How is orderHash generated? Is it guaranteed to be unique? @@ -44,7 +53,7 @@ faqs: - question: Why do I receive inverse requests for every quote (e.g. USDC<>ETH and ETH<>USDC)? answer: Two quote requests are performed per actual quote to obfuscate the swapper's actual request and reduce the chances of front-running. - question: How long is the exclusivity period after a winning quote? Is it fixed or dynamic? - answer: The exclusivity period on mainnet is currently 24 seconds (2 blocks) and is set by the cosigner when it cosigns the order. It is not a fixed protocol constant and could change in the future. On chains that use the DutchV3 reactor (Arbitrum, Avalanche, Base, BNB Smart Chain, Robinhood Chain, Tempo, and Unichain), the exclusivity window is measured in block numbers rather than seconds and is currently about 2 to 4 seconds, likewise set by the cosigner per order. Block times on these chains are roughly 1 second. + answer: The exclusivity period on mainnet is currently 24 seconds (2 blocks) and is set by the cosigner when it cosigns the order. It is not a fixed protocol constant and could change in the future. On chains that use the DutchV3 reactor (Arbitrum, Arc, Avalanche, Base, BNB Smart Chain, Ink, Monad, Robinhood Chain, Tempo, and Unichain), the exclusivity window is measured in block numbers rather than seconds and is currently about 2 to 4 seconds, likewise set by the cosigner per order. Block times vary by chain, from sub-second to a couple of seconds. - question: Why do some orders not have exclusive fillers? answer: The Order Service gets a soft quote to decide between UniswapX and Classic routing. If UniswapX is chosen and the hard quote comes back a certain amount lower than the soft quote, the Order Service cannot assign exclusivity. We call this missing exclusivity. The order then goes straight to decay. - question: What counts as a fade? @@ -60,7 +69,7 @@ faqs: - question: Do simulation failures count as fades? answer: No. Fades are only counted when a quoter wins exclusivity but fails to fill the order onchain before the exclusivity window expires. Offchain simulation failures (for example quote validation or gas estimation) do not trigger the circuit breaker. - question: How do I submit a ticket? - answer: Use the UniswapX filler help form to reach the team without leaving this page. + answer: Use the Help Center to reach the team without leaving this page. - question: How do I stay up to date? answer: Subscribe to the Telegram channel at t.me/UniswapXdiscussion for UniswapX announcements. --- @@ -72,7 +81,46 @@ faqs:
- Fillers should start with polling for orders and rate limit at 6 RPS. + Fillers should start with polling for orders and rate limit at 4 RPS. The orders endpoint serves cached responses, and requests above 4 RPS return `429`. Each response returns at most the last 50 orders, ordered by most recent. + +
+ + + +
+ Do I need an API key to poll for orders? + +
+ + No. The orders API is a separate service from the Trading API, and polling for open orders requires no API key. Raising a Trading API key's rate limit does not increase your polling throughput. + +
+ +
+ +
+ Which `orders` endpoint should I use? + +
+ + Three different endpoints are called "orders". Fillers want the first one. + + - `GET /v2/orders` on `api.uniswap.org`: poll for open orders to fill. This is the filler endpoint. + - `POST /v1/order` on `trade-api.gateway.uniswap.org`: submit a signed order. For swappers and integrators; requires an API key. + - `GET /v1/orders` on `trade-api.gateway.uniswap.org`: check the status of a submitted order; requires an API key. + +
+ +
+ +
+ What should I do if I get a 429? + +
+ + Back off and stop polling until the limit clears. Do not retry. + + Throttled requests return HTTP `429` with error code `TOO_MANY_REQUESTS`. Blocked requests still count toward the rolling five-minute window, so retrying while throttled keeps the window full and extends the block.
@@ -83,7 +131,7 @@ faqs:
- Webhooks were deprecated on UniswapX due to degraded performance, and we are no longer onboarding new webhook integrations. Existing webhook integrations will continue to work, but new fillers should start with polling orders on the API and rate limit at 6 RPS. We are exploring WebSocket connections going forward. + Webhooks were deprecated on UniswapX due to degraded performance, and we are no longer onboarding new webhook integrations. Existing webhook integrations will continue to work, but new fillers should start with polling orders on the API and rate limit at 4 RPS. We are exploring WebSocket connections going forward.
@@ -134,7 +182,7 @@ faqs:
- Quote responses must be returned within 500ms on Ethereum, or 250ms on any other chain, to be considered. + Quote responses must be returned within 500ms to be considered. The budget is the same on every chain.
@@ -175,7 +223,7 @@ faqs: - **Order Size**: Very small orders may not be economical to fill through UniswapX due to gas costs. Similarly, extremely large orders might exceed available liquidity from quoters. - - **Response Latency**: If your filler responds but takes longer than 500ms on Ethereum, or 250ms on any other chain, your quote will be rejected. Ensure your infrastructure can consistently respond within this latency requirement. The quote server is located in AWS `US-EAST-2` if you wish to co-locate to reduce latency. + - **Response Latency**: If your filler responds but takes longer than 500ms, on any chain, your quote will be rejected. Ensure your infrastructure can consistently respond within this latency requirement. The quote server is located in AWS `US-EAST-2` if you wish to co-locate to reduce latency. @@ -199,12 +247,16 @@ faqs:
- Your server may be temporarily blocked due to the fade-rate monitor. If you win an RFQ but don't fill the order, this counts as a "fade." After too many fades, RFQ requests are temporarily paused. + There are two reasons. + + **Fade-rate block**: your server may be temporarily blocked by the fade-rate monitor. If you win an RFQ but don't fill the order, this counts as a "fade." After too many fades, RFQ requests are temporarily paused. You'll know you're blocked when quote requests include a `blockUntilTimestamp` field indicating when you'll start receiving requests again. Handle this field in your code so your service backs off until the block clears, and log it so you can detect and debug circuit breaker events. + **Timeouts**: Uniswap Labs may disable a quote endpoint that times out on a meaningful share of quote requests, at its discretion, until the issue is fixed. See [Become a Quoter](/docs/liquidity/uniswapx/filling/mainnet/become-a-quoter#performance-expectations) for the full response expectations. +
@@ -268,7 +320,7 @@ faqs: The exclusivity period on mainnet is currently **24 seconds (2 blocks)** and is set by the cosigner when it cosigns the order. It is not a fixed protocol constant and could change in the future. - On chains that use the DutchV3 reactor (Arbitrum, Avalanche, Base, BNB Smart Chain, Robinhood Chain, Tempo, and Unichain), the exclusivity window is measured in **block numbers** rather than seconds and is currently about 2 to 4 seconds, likewise set by the cosigner per order. Block times on these chains are roughly 1 second. + On chains that use the DutchV3 reactor (Arbitrum, Arc, Avalanche, Base, BNB Smart Chain, Ink, Monad, Robinhood Chain, Tempo, and Unichain), the exclusivity window is measured in **block numbers** rather than seconds and is currently about 2 to 4 seconds, likewise set by the cosigner per order. Block times vary by chain, from sub-second to a couple of seconds. @@ -355,7 +407,7 @@ faqs:
- `ERC20ETH` is deployed at `0x00000000e20E49e6dCeE6e8283A0C090578F0fb9`. The address is the same across supported chains through deterministic CREATE2 deployment and a mined vanity address. + `ERC20ETH` is deployed at `0x00000000e20E49e6dCeE6e8283A0C090578F0fb9`, the same address on the chains that carry it through deterministic CREATE2 deployment and a mined vanity address. It is not deployed on every UniswapX chain, so check the [Deployments](/docs/liquidity/uniswapx/deployments) page or deployments.json for a given chain before relying on it. References: @@ -450,7 +502,7 @@ faqs:
- Use the UniswapX filler help form to reach the team without leaving this page. + Use the Help Center to reach the team without leaving this page.
diff --git a/content/liquidity/uniswapx/filling/mainnet/become-a-quoter.mdx b/content/liquidity/uniswapx/filling/mainnet/become-a-quoter.mdx index 3d0a340fa..a6fe9d377 100644 --- a/content/liquidity/uniswapx/filling/mainnet/become-a-quoter.mdx +++ b/content/liquidity/uniswapx/filling/mainnet/become-a-quoter.mdx @@ -1,5 +1,4 @@ --- -id: becomequoter title: Become a Quoter description: Set up a UniswapX quoter on Ethereum mainnet, meet performance requirements, and move from beta to production. --- @@ -16,8 +15,14 @@ To participate as a quoter, you must host a service that adheres to the UniswapX ## Performance Expectations To ensure a smooth experience for swappers and a fair auction process for quoters, participants are held to the following performance standards: - -Your server must respond to a request for a quote within 500ms. If you cannot provide a quote, respond with a `204` status code. Consistent failure to meet this standard may result in suspension from the system. + + +Your server must respond to every quote request within 500ms. The budget is the same on every chain. + +If you cannot quote, return a `204` with an empty body. + +Do not let quote requests time out. Endpoints that time out on a meaningful share of requests may be disabled at Uniswap Labs' discretion until the issue is fixed. + ## Handling Fades & the Circuit Breaker @@ -71,7 +76,7 @@ If you can fulfill the quote request, your server should respond with status `20 } ``` -If you do not wish to respond to a quote request, you must return an empty response with status code `204`. +A `204` with an empty body is the expected signal when you cannot or will not quote. ### Schema when disabled due to circuit breaker If you are an onboarded quoter who is currently disabled by the circuit breaker, your server will receive the following message on the same quote endpoint: diff --git a/content/liquidity/uniswapx/filling/mainnet/filling-on-mainnet.mdx b/content/liquidity/uniswapx/filling/mainnet/filling-on-mainnet.mdx index 51195c478..a385568dd 100644 --- a/content/liquidity/uniswapx/filling/mainnet/filling-on-mainnet.mdx +++ b/content/liquidity/uniswapx/filling/mainnet/filling-on-mainnet.mdx @@ -1,5 +1,4 @@ --- -id: createfiller title: Filling on Mainnet description: Integrate a UniswapX filler on Ethereum mainnet, retrieve open orders, and execute Dutch and limit fills safely. --- @@ -56,6 +55,8 @@ All signed Dutch Orders created through the Uniswap UI are available via the Uni GET https://api.uniswap.org/v2/orders?orderStatus=open&chainId=1&limit=1 ``` +The endpoint serves cached responses and returns at most the last 50 orders, ordered by most recent. Poll at no more than 4 RPS; requests above that return `429`. + It’s up to the individual filler to architect their own systems for finding and executing profitable orders, but the basic flow is as follows: 1. Call `GET` on the `/orders` of the UniswapX Orders Endpoint as written above, to retrieve open signed orders. This page covers Dutch V2 orders on Mainnet (`chainId=1`). For the DutchV3 chains, see [Filling Dutch V3 Auctions](/docs/liquidity/uniswapx/filling/dutch-v3-chains/filling-on-dutch-v3-chains). diff --git a/content/liquidity/uniswapx/filling/overview.mdx b/content/liquidity/uniswapx/filling/overview.mdx index c45922e81..ab760f450 100644 --- a/content/liquidity/uniswapx/filling/overview.mdx +++ b/content/liquidity/uniswapx/filling/overview.mdx @@ -1,5 +1,4 @@ --- -id: filleroverview title: Fillers Overview description: Learn how UniswapX fillers and quoters compete to settle swaps across chains. --- @@ -9,11 +8,11 @@ description: Learn how UniswapX fillers and quoters compete to settle swaps acro | Chain | Auction type | Reactor | Guide | |---|---|---|---| | Ethereum | RFQ + Exclusive Dutch Auction | Dutch V2 | [Filling on Mainnet](/docs/liquidity/uniswapx/filling/mainnet/filling-on-mainnet), [Become a Quoter](/docs/liquidity/uniswapx/filling/mainnet/become-a-quoter) | -| Arbitrum, Avalanche, Base, BNB Smart Chain, Robinhood Chain, Tempo, Unichain | RFQ + Exclusive Dutch Auction (block-based decay) | Dutch V3 | [Filling Dutch V3 Auctions](/docs/liquidity/uniswapx/filling/dutch-v3-chains/filling-on-dutch-v3-chains) | +| Arbitrum, Arc, Avalanche, Base, BNB Smart Chain, Ink, Monad, Robinhood Chain, Tempo, Unichain | RFQ + Exclusive Dutch Auction (block-based decay) | Dutch V3 | [Filling Dutch V3 Auctions](/docs/liquidity/uniswapx/filling/dutch-v3-chains/filling-on-dutch-v3-chains) | UniswapX fillers compete to settle swaps through permissionless auctions. Use this section to choose a chain, ingest orders, and fill. -UniswapX now uses RFQ and the exclusive Dutch auction model on every supported chain. Priority gas auctions are no longer a separate integration path. Fillers previously integrated against a Priority reactor should migrate to DutchV3. See the [changelog entry](/docs/changelog/active-notifications/uniswapx-rfq-auctions-on-base-and-arbitrum) for the Base and Arbitrum transition. +UniswapX now uses RFQ and the exclusive Dutch auction model on every supported chain. Priority gas auctions are no longer a separate integration path. Fillers previously integrated against a Priority reactor should migrate to DutchV3. See the [changelog entry](/docs/changelog/completed-notifications/uniswapx-rfq-auctions-on-base-and-arbitrum) for the Base and Arbitrum transition. ## Filler Roles @@ -23,7 +22,7 @@ UniswapX has one permissioned role (quoter) and one permissionless role (filler) |---|---|---|---|---| | **Quoter** | Permissioned, vetted by Uniswap Labs | Responds to the off-chain RFQ; if it wins the hard quote, it gets the exclusivity window | Yes: if it wins exclusivity and does not fill, it triggers the circuit breaker | Receives quote requests from the parameterization service | | **Exclusive filler** | The quoter that won the RFQ | During the exclusivity window (about 24 seconds, or 2 blocks, on mainnet) | Yes | It is the RFQ winner | -| **Non-exclusive filler** | Permissionless, no vetting | After exclusivity expires in the open Dutch auction, or during exclusivity through a soft-exclusivity override (`exclusivityOverrideBps` greater than zero) | No: it never held exclusivity, so it cannot fade and is not subject to the circuit breaker | Polls the orders API at 6 RPS | +| **Non-exclusive filler** | Permissionless, no vetting | After exclusivity expires in the open Dutch auction, or during exclusivity through a soft-exclusivity override (`exclusivityOverrideBps` greater than zero) | No: it never held exclusivity, so it cannot fade and is not subject to the circuit breaker | Polls the orders API at 4 RPS | A non-exclusive filler carries no fade risk and is never subject to the circuit breaker, because it never commits to an exclusivity it could fail to honor. @@ -46,17 +45,22 @@ Retrieve open orders from the UniswapX Orders Endpoint. The [Swagger documentati |---|---|---| | Ethereum | `1` | `Dutch_V2` | | Arbitrum | `42161` | `Dutch_V3` | +| Arc | `5042` | `Dutch_V3` | | Avalanche | `43114` | `Dutch_V3` | | Base | `8453` | `Dutch_V3` | | BNB Smart Chain | `56` | `Dutch_V3` | +| Ink | `57073` | `Dutch_V3` | +| Monad | `143` | `Dutch_V3` | | Robinhood Chain | `4663` | `Dutch_V3` | | Tempo | `4217` | `Dutch_V3` | | Unichain | `130` | `Dutch_V3` | ```bash -GET https://api.uniswap.org/v2/orders?orderStatus=open&chainId=1&orderType=Dutch_V2&limit=1000 +GET https://api.uniswap.org/v2/orders?orderStatus=open&chainId=1&orderType=Dutch_V2&limit=50 ``` +The endpoint serves cached responses and returns at most the last 50 orders, ordered by most recent. Poll at no more than 4 RPS; requests above that return `429`. + ## Native ETH Input UniswapX supports native ETH input from EIP-7702 smart wallets through `ERC20ETH`. Fillers may see orders where `inputTokenAddress` is the `ERC20ETH` deployment address; route those orders as native ETH, not as a pool-backed ERC-20. @@ -69,5 +73,5 @@ For common RFQ and execution issues, see the [Filler FAQ](/docs/liquidity/uniswa ## Support -- Submit a ticket via the UniswapX filler help form. +- Submit a ticket via the Help Center. - Subscribe to the [Telegram channel](http://t.me/UniswapXdiscussion) for announcements. diff --git a/content/liquidity/uniswapx/filling/priority-chain/filling-on-op-stack.mdx b/content/liquidity/uniswapx/filling/priority-chain/filling-on-op-stack.mdx index 74b96ed68..6599514a5 100644 --- a/content/liquidity/uniswapx/filling/priority-chain/filling-on-op-stack.mdx +++ b/content/liquidity/uniswapx/filling/priority-chain/filling-on-op-stack.mdx @@ -1,5 +1,4 @@ --- -id: priorityorderreactor title: Filling Priority Auctions description: Fill UniswapX Priority orders using priority-fee bidding and reactor execution patterns. --- diff --git a/content/liquidity/uniswapx/overview.mdx b/content/liquidity/uniswapx/overview.mdx index f7e6d09c3..cd79475e0 100644 --- a/content/liquidity/uniswapx/overview.mdx +++ b/content/liquidity/uniswapx/overview.mdx @@ -1,6 +1,6 @@ --- -id: overview title: UniswapX Overview +sidebarTitle: Overview description: Learn how UniswapX's intent-based infrastructure uses competitive auctions to route swaps across public and private liquidity sources, all gasless with no cost for failed swaps. --- diff --git a/content/protocols/meta.json b/content/protocols/meta.json index 3c97600f8..ae10e3fb4 100644 --- a/content/protocols/meta.json +++ b/content/protocols/meta.json @@ -5,6 +5,7 @@ "overview", "[Deployments](/deployments)", "v4", + "uniswap-labs-hooks", "v3", "v2", "smart-wallet", diff --git a/content/protocols/overview.mdx b/content/protocols/overview.mdx index 9a978d654..13f3adab7 100644 --- a/content/protocols/overview.mdx +++ b/content/protocols/overview.mdx @@ -1,7 +1,30 @@ --- -id: overview -title: Protocols Overview +title: Uniswap Protocols Overview +sidebarTitle: Overview description: Navigate the Uniswap protocol documentation, from the core AMM versions to supporting infrastructure contracts. +keywords: + - Uniswap protocols + - AMM versions + - Universal Router + - Permit2 + - The Compact + - protocol fees +faqs: + - question: Which Uniswap protocol version should I use for a new integration? + answer: |- + Uniswap v4 is the current and recommended version for new integrations. It consolidates all pools into a single PoolManager contract, supports hooks that customize pool behavior across the pool lifecycle, and uses flash accounting to defer token transfers until the end of a transaction, which reduces gas for multi-step operations. Use v3 for existing concentrated liquidity integrations and v2 for legacy constant product workflows. + - question: What is the difference between the Uniswap AMM and its supporting protocols? + answer: |- + The AMM contracts are the pool contracts that hold liquidity and execute swaps, versioned as Uniswap v2, v3, and v4. The supporting protocols are infrastructure contracts used across versions: the Universal Router composes swaps across v2, v3, and v4 in a single transaction, Permit2 handles signature-based token transfers and time-bound allowances, Fee Adapter and TokenJar contracts collect protocol fees, The Compact provides ERC-6909 resource locks for cross-chain coordination, and Calibur powers smart wallet delegation through EIP-7702. + - question: Which contract should I use to execute Uniswap swaps programmatically? + answer: |- + The Universal Router is the recommended entry point for executing swaps programmatically. It is an unowned, non-upgradeable contract that composes swaps across Uniswap v2, v3, and v4 in a single transaction using command-based encoding, and it integrates with Permit2 for signature-controlled token approvals. + - question: Are the Uniswap protocol contracts audited? + answer: |- + Yes. The Uniswap v4 core and periphery repositories publish their audit reports, and Uniswap Labs maintains an active bug bounty program on Cantina for eligible vulnerability disclosures. + - question: Where do I find Uniswap contract deployment addresses? + answer: |- + The unified deployments page at developers.uniswap.org/deployments lists Uniswap contract addresses across all protocols and chains. Each protocol section of the docs also has its own deployments page; for example, Uniswap v4 addresses are on the v4 deployments page, and the smart wallet deployments page lists the Calibur address across supported networks. --- ## Protocols @@ -85,3 +108,68 @@ Uniswap smart wallet features are powered by Calibur, a non-upgradeable contract Uniswap Labs maintains an active bug bounty program on Cantina for eligible vulnerability disclosures. [Uniswap Bug Bounty Program](https://cantina.xyz/bounties/f9df94db-c7b1-434b-bb06-d1360abdd1be) + +## FAQ + +
+ Which Uniswap protocol version should I use for a new integration? + + + + Uniswap v4 is the current and recommended version for new integrations. It consolidates all pools into a single `PoolManager` contract, supports [hooks](/docs/protocols/v4/concepts/hooks) that customize pool behavior across the pool lifecycle, and uses [flash accounting](/docs/protocols/v4/concepts/flash-accounting) to defer token transfers until the end of a transaction, which reduces gas for multi-step operations. + + Use [Uniswap v3](/docs/protocols/v3/overview) for existing concentrated liquidity integrations and [Uniswap v2](/docs/protocols/v2/overview) for legacy constant product workflows. + + + +
+ +
+ What is the difference between the Uniswap AMM and its supporting protocols? + + + + The AMM contracts are the pool contracts that hold liquidity and execute swaps, versioned as Uniswap v2, v3, and v4. The supporting protocols are infrastructure contracts used across versions: + + * [Universal Router](/docs/protocols/universal-router/overview): composes swaps across v2, v3, and v4 in a single transaction. + * [Permit2](/docs/protocols/permit2/overview): signature-based token transfers and time-bound allowances. + * [Protocol Fees](/docs/protocols/protocol-fee/overview): Fee Adapter and TokenJar contracts that collect protocol fees. + * [The Compact](/docs/protocols/the-compact/overview): ERC-6909 resource locks for cross-chain coordination. + * [Smart wallet (Calibur)](/docs/protocols/smart-wallet/overview): EIP-7702 delegation for smart wallet features. + + + +
+ +
+ Which contract should I use to execute Uniswap swaps programmatically? + + + + The [Universal Router](/docs/protocols/universal-router/overview) is the recommended entry point for executing swaps programmatically. It is an unowned, non-upgradeable contract that composes swaps across Uniswap v2, v3, and v4 in a single transaction using command-based encoding, and it integrates with [Permit2](/docs/protocols/permit2/overview) for signature-controlled token approvals. + + + +
+ +
+ Are the Uniswap protocol contracts audited? + + + + Yes. The Uniswap v4 [core audits](https://github.com/Uniswap/v4-core/tree/main/docs/security/audits) and [periphery audits](https://github.com/Uniswap/v4-periphery/tree/main/audits) are published in their repositories, and Uniswap Labs maintains an active [bug bounty program on Cantina](https://cantina.xyz/bounties/f9df94db-c7b1-434b-bb06-d1360abdd1be) for eligible vulnerability disclosures. + + + +
+ +
+ Where do I find Uniswap contract deployment addresses? + + + + The [unified deployments page](/deployments) lists Uniswap contract addresses across all protocols and chains. Each protocol section of the docs also has its own deployments page; for example, [Uniswap v4 addresses](/docs/protocols/v4/deployments) are on the v4 deployments page, and the [smart wallet deployments page](/docs/protocols/smart-wallet/deployments) lists the Calibur address across supported networks. + + + +
diff --git a/content/protocols/permit2/concepts/allowance-transfer.mdx b/content/protocols/permit2/concepts/allowance-transfer.mdx index 1937d018a..0a7faf399 100644 --- a/content/protocols/permit2/concepts/allowance-transfer.mdx +++ b/content/protocols/permit2/concepts/allowance-transfer.mdx @@ -1,5 +1,4 @@ --- -id: allowance-transfer title: Allowance Transfer description: Understand Uniswap Permit2 allowance-based approvals, permits, and `transferFrom` flows with nonce safety. --- diff --git a/content/protocols/permit2/overview.mdx b/content/protocols/permit2/overview.mdx index e9d9da3dd..7074e30a0 100644 --- a/content/protocols/permit2/overview.mdx +++ b/content/protocols/permit2/overview.mdx @@ -1,6 +1,30 @@ --- -title: Overview +title: Permit2 Overview +sidebarTitle: Overview description: Learn how Uniswap Permit2 combines signature-based transfers and time-bound allowances for token spending. +keywords: + - permit2 + - allowance-transfer + - signature-transfer + - token-approvals + - eip-2612 + - nonces +faqs: + - question: What is the difference between AllowanceTransfer and SignatureTransfer? + answer: |- + Permit2 exposes two independent modules. AllowanceTransfer stores a standing, time-bound allowance inside the Permit2 contract: you set an amount and an expiration for a spender, and that spender can call transferFrom repeatedly until the allowance is exhausted or expires. This suits recurring flows such as repeated swaps or subscriptions. SignatureTransfer authorizes a single, nonce-scoped transfer through one signature; the permission does not persist after the transaction, so it leaves no standing allowance. Use it when a contract needs tokens infrequently and you want to avoid lingering approvals. + - question: Do I still need a per-token approval to use Permit2? + answer: |- + Yes, but only once per token. Before Permit2 can move a token on a user's behalf, the user makes a one-time standard ERC-20 approval of the Permit2 contract on that token, commonly for the maximum uint256 amount. After that, Permit2 manages granular, per-spender, time-bound permissions through signatures or its own approve function, so integrators no longer trigger a separate onchain approval for every spender. + - question: How is Permit2 different from an EIP-2612 permit? + answer: |- + EIP-2612 adds a permit function to a token itself, so it only works for tokens that implement it. Permit2 is a separate contract that works with any ERC-20, including tokens that will never add EIP-2612 support. After the one-time approval of the Permit2 contract, users get signature-based approvals for every such token, plus batching, expirations, and unordered nonces that a bare EIP-2612 permit does not provide. + - question: How do Permit2 nonces and expiration work? + answer: |- + The two modules use different nonce schemes. AllowanceTransfer packs an incrementing nonce per owner, token, and spender alongside the amount and an expiration timestamp, so two permits with the same nonce do not cancel each other as long as the token or spender differ. SignatureTransfer uses unordered nonces tracked in a bitmap, so signatures can be spent in any order and each nonce is single-use. Both carry a signature deadline, and AllowanceTransfer allowances also carry their own expiration after which the permission is invalid. + - question: What is the Permit2 contract address, and has it been audited? + answer: |- + Permit2 is deployed at the same address on every chain Uniswap supports except zkSync: 0x000000000022D473030F116dDEE9F6B43aC78BA3. On zkSync it is 0x0000000000225e31D15943971F47aD3022F714Fa. The contracts are open source in the Uniswap/permit2 repository, which also publishes the third-party audit reports. --- [Permit2](https://github.com/Uniswap/permit2) is a unification of 2 contracts, `SignatureTransfer` and `AllowanceTransfer`. The `SignatureTransfer` contract handles all signature-based transfers, meaning that an allowance on the token is bypassed and permissions to the spender only last for the duration of the transaction that the one-time signature is spent. The `AllowanceTransfer` contract handles setting allowances on tokens, giving permissions to spenders on a specified amount for a specified duration of time. Any transfers that then happen through the `AllowanceTransfer` contract will only succeed if the proper permissions have been set. @@ -22,6 +46,81 @@ To maximize Permit2 utility, users can choose a max approval on the contract whe totalAmount = type(uint256).max; ``` +## FAQ + +
+ What is the difference between AllowanceTransfer and SignatureTransfer? + + + + Permit2 exposes two independent modules: + + * **[AllowanceTransfer](/docs/protocols/permit2/concepts/allowance-transfer)** stores a standing, time-bound allowance inside the Permit2 contract. You set an amount and an expiration for a spender, and that spender can call `transferFrom` repeatedly until the allowance is exhausted or expires. This suits recurring flows such as repeated swaps or subscriptions. + * **[SignatureTransfer](/docs/protocols/permit2/concepts/signature-transfer)** authorizes a single, nonce-scoped transfer through one signature. The permission does not persist after the transaction, so it leaves no standing allowance. Use it when a contract needs tokens infrequently and you want to avoid lingering approvals. + + + +
+ +
+ Do I still need a per-token approval to use Permit2? + + + + Yes, but only once per token. Before Permit2 can move a token on a user's behalf, the user makes a one-time standard ERC-20 approval of the Permit2 contract on that token, commonly for the maximum `uint256` amount: + + ```solidity + USDC.approve(permit2Address, type(uint256).max); + ``` + + After that, Permit2 manages granular, per-spender, time-bound permissions through signatures or its own `approve` function, so integrators no longer trigger a separate onchain approval for every spender. + + + +
+ +
+ How is Permit2 different from an EIP-2612 permit? + + + + [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612) adds a `permit` function to a token itself, so it only works for tokens that implement it. Permit2 is a separate contract that works with any ERC-20, including tokens that will never add EIP-2612 support. After the one-time approval of the Permit2 contract, users get signature-based approvals for every such token, plus batching, expirations, and unordered nonces that a bare EIP-2612 permit does not provide. + + + +
+ +
+ How do Permit2 nonces and expiration work? + + + + The two modules use different nonce schemes: + + * **AllowanceTransfer** packs an incrementing nonce per owner, token, and spender alongside the amount and an expiration timestamp. Two permits with the same nonce do not cancel each other as long as the token or spender differ. + * **SignatureTransfer** uses unordered nonces tracked in a bitmap, so signatures can be spent in any order and each nonce is single-use. + + Both carry a signature deadline, and AllowanceTransfer allowances also carry their own `expiration` after which the permission is invalid. + + + +
+ +
+ What is the Permit2 contract address, and has it been audited? + + + + Permit2 is deployed at the same address on every chain Uniswap supports **except** zkSync: `0x000000000022D473030F116dDEE9F6B43aC78BA3`. + + On zkSync it is `0x0000000000225e31D15943971F47aD3022F714Fa`. + + The contracts are open source in the [Uniswap/permit2](https://github.com/Uniswap/permit2) repository, which also publishes the third-party audit reports. + + + +
+ ## Where to Go Next - Learn allowance flows in [Allowance Transfer](/docs/protocols/permit2/concepts/allowance-transfer) diff --git a/content/protocols/protocol-fee/deployments.mdx b/content/protocols/protocol-fee/deployments.mdx index 288ceb7e5..a25c70791 100644 --- a/content/protocols/protocol-fee/deployments.mdx +++ b/content/protocols/protocol-fee/deployments.mdx @@ -1,27 +1,159 @@ --- -title: Deployments +title: Protocol Fee Deployments +sidebarTitle: Deployments description: Find Uniswap Protocol Fee deployment addresses and governance-controlled deployment flow details. --- -## Ethereum Mainnet +## Ethereum: 1 | Contract | Address | |----------|---------| -| MainnetDeployer | [0xd3Aa12B99892b7D95BBAA27AEf222A8E2a038C0C](https://etherscan.io/address/0xd3Aa12B99892b7D95BBAA27AEf222A8E2a038C0C) | -| TokenJar (AssetSink) | [0xf38521f130fcCF29dB1961597bc5d2B60F995f85](https://etherscan.io/address/0xf38521f130fcCF29dB1961597bc5d2B60F995f85) | -| Releaser (Firepit) | [0x0D5Cd355e2aBEB8fb1552F56c965B867346d6721](https://etherscan.io/address/0x0D5Cd355e2aBEB8fb1552F56c965B867346d6721) | -| V3FeeAdapter | [0x5E74C9f42EEd283bFf3744fBD1889d398d40867d](https://etherscan.io/address/0x5E74C9f42EEd283bFf3744fBD1889d398d40867d) | -| UNI | [0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984](https://etherscan.io/address/0x1f9840a85d5af5bf1d1762f925bdaddc4201f984) | +| MainnetDeployer | [`0xd3Aa12B99892b7D95BBAA27AEf222A8E2a038C0C`](https://etherscan.io/address/0xd3Aa12B99892b7D95BBAA27AEf222A8E2a038C0C) | +| TokenJar | [`0xf38521f130fcCF29dB1961597bc5d2B60F995f85`](https://etherscan.io/address/0xf38521f130fcCF29dB1961597bc5d2B60F995f85) | +| Releaser (Firepit) | [`0x0D5Cd355e2aBEB8fb1552F56c965B867346d6721`](https://etherscan.io/address/0x0D5Cd355e2aBEB8fb1552F56c965B867346d6721) | +| V3FeeAdapter | [`0x5E74C9f42EEd283bFf3744fBD1889d398d40867d`](https://etherscan.io/address/0x5E74C9f42EEd283bFf3744fBD1889d398d40867d) | +| V3OpenFeeAdapter | [`0xf2371551Fe3937Db7c750f4DfABe5c2fFFdcBf5A`](https://etherscan.io/address/0xf2371551Fe3937Db7c750f4DfABe5c2fFFdcBf5A) | +| UNI Vesting | [`0xCa046A83EDB78F74aE338bb5A291bF6FdAc9e1D2`](https://etherscan.io/address/0xCa046A83EDB78F74aE338bb5A291bF6FdAc9e1D2) | +| Agreement Anchor 1 | [`0xC707467e7fb43Fe7Cc55264F892Dd2D7f8Fc27C8`](https://etherscan.io/address/0xC707467e7fb43Fe7Cc55264F892Dd2D7f8Fc27C8) | +| Agreement Anchor 2 | [`0x33A56942Fe57f3697FE0fF52aB16cb0ba9b8eadd`](https://etherscan.io/address/0x33A56942Fe57f3697FE0fF52aB16cb0ba9b8eadd) | +| Agreement Anchor 3 | [`0xF9F85a17cC6De9150Cd139f64b127976a1dE91D1`](https://etherscan.io/address/0xF9F85a17cC6De9150Cd139f64b127976a1dE91D1) | +| NttManager | [`0x6569925Aac77D6B8Bb085F31F9828ff80D5a0c44`](https://etherscan.io/address/0x6569925Aac77D6B8Bb085F31F9828ff80D5a0c44) | +| WormholeTransceiver | [`0x7597C40Fd3df66b750C14ad4D90524e247499011`](https://etherscan.io/address/0x7597C40Fd3df66b750C14ad4D90524e247499011) | +| V4FeeAdapter | [`0x89A5D5bF00a27D55c02951E49078a5C5771051dB`](https://etherscan.io/address/0x89A5D5bF00a27D55c02951E49078a5C5771051dB) | +| V4FeePolicy | [`0x1cd822b70a0591420F65E94b9B3A0D0b0fB3a314`](https://etherscan.io/address/0x1cd822b70a0591420F65E94b9B3A0D0b0fB3a314) | +| UNI | [`0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984`](https://etherscan.io/address/0x1f9840a85d5af5bf1d1762f925bdaddc4201f984) | -## Unichain +## Unichain: 130 | Contract | Address | |----------|---------| -| UnichainDeployer | [0xD16c47bf3ae22e0B2BAc5925D990b81416f18dea](https://uniscan.xyz/address/0xD16c47bf3ae22e0B2BAc5925D990b81416f18dea) | -| TokenJar | [0xD576BDF6b560079a4c204f7644e556DbB19140b5](https://uniscan.xyz/address/0xD576BDF6b560079a4c204f7644e556DbB19140b5) | -| Releaser (OptimismBridgedResourceFirepit) | [0xe0A780E9105aC10Ee304448224Eb4A2b11A77eeB](https://uniscan.xyz/address/0xe0A780E9105aC10Ee304448224Eb4A2b11A77eeB) | +| UnichainDeployer | [`0xD16c47bf3ae22e0B2BAc5925D990b81416f18dea`](https://uniscan.xyz/address/0xD16c47bf3ae22e0B2BAc5925D990b81416f18dea) | +| TokenJar | [`0xD576BDF6b560079a4c204f7644e556DbB19140b5`](https://uniscan.xyz/address/0xD576BDF6b560079a4c204f7644e556DbB19140b5) | +| Releaser (OptimismBridgedResourceFirepit) | [`0xe0A780E9105aC10Ee304448224Eb4A2b11A77eeB`](https://uniscan.xyz/address/0xe0A780E9105aC10Ee304448224Eb4A2b11A77eeB) | -### Deployment process +## Optimism: 10 + +| Contract | Address | +|----------|---------| +| Deployer | [`0x3398783D2ffE6F79B56dade84CEAea888C400da4`](https://optimistic.etherscan.io/address/0x3398783D2ffE6F79B56dade84CEAea888C400da4) | +| TokenJar | [`0xb13285DF724ea75f3f1E9912010B7e491dCd5EE3`](https://optimistic.etherscan.io/address/0xb13285DF724ea75f3f1E9912010B7e491dCd5EE3) | +| Releaser (OptimismBridgedResourceFirepit) | [`0x94460443Ca27FFC1baeCa61165fde18346C91AbD`](https://optimistic.etherscan.io/address/0x94460443Ca27FFC1baeCa61165fde18346C91AbD) | +| V3OpenFeeAdapter | [`0xec23Cf5A1db3dcC6595385D28B2a4D9B52503Be4`](https://optimistic.etherscan.io/address/0xec23Cf5A1db3dcC6595385D28B2a4D9B52503Be4) | +| V4FeeAdapter | [`0xd85393784234fB2ee4f077867A8B78E1aD4cE56B`](https://optimistic.etherscan.io/address/0xd85393784234fB2ee4f077867A8B78E1aD4cE56B) | +| V4FeePolicy | [`0x13d9D19802660b8167B3c84C1fcDCD0163672eB8`](https://optimistic.etherscan.io/address/0x13d9D19802660b8167B3c84C1fcDCD0163672eB8) | + +## BNB Chain: 56 + +| Contract | Address | +|----------|---------| +| SyntheticNttUni | [`0x06e8bdE95BE4ce5cB1134BD47aD18a79fFB35822`](https://bscscan.com/address/0x06e8bdE95BE4ce5cB1134BD47aD18a79fFB35822) | +| NttManager | [`0x9226AEb835487dD2ed6700A967A8AD25BEE1Dc0E`](https://bscscan.com/address/0x9226AEb835487dD2ed6700A967A8AD25BEE1Dc0E) | +| WormholeTransceiver | [`0xB89780a55d15CAcA4F5c8828b5B5cf95442C2716`](https://bscscan.com/address/0xB89780a55d15CAcA4F5c8828b5B5cf95442C2716) | +| TokenJar | [`0xc6Ae6373CEcc9e595A6C8b9fe581925a8c84f70A`](https://bscscan.com/address/0xc6Ae6373CEcc9e595A6C8b9fe581925a8c84f70A) | +| WormholeReleaser | [`0xa59FfbB55D91Fc32b44A06F0b9cc6036a4afbcE2`](https://bscscan.com/address/0xa59FfbB55D91Fc32b44A06F0b9cc6036a4afbcE2) | +| V3OpenFeeAdapter | [`0x3F07F08b45912dCd6691C5B9412975D5113B2910`](https://bscscan.com/address/0x3F07F08b45912dCd6691C5B9412975D5113B2910) | +| V4FeeAdapter | [`0x66276D2e80784180E4B9b859e4327b9C5646B87c`](https://bscscan.com/address/0x66276D2e80784180E4B9b859e4327b9C5646B87c) | +| V4FeePolicy | [`0x020B1Ad79037f02feC357Ec4601fFbe5f7ED6872`](https://bscscan.com/address/0x020B1Ad79037f02feC357Ec4601fFbe5f7ED6872) | + +## Polygon: 137 + +| Contract | Address | +|----------|---------| +| SyntheticNttUni | [`0x06e8bdE95BE4ce5cB1134BD47aD18a79fFB35822`](https://polygonscan.com/address/0x06e8bdE95BE4ce5cB1134BD47aD18a79fFB35822) | +| NttManager | [`0x9226AEb835487dD2ed6700A967A8AD25BEE1Dc0E`](https://polygonscan.com/address/0x9226AEb835487dD2ed6700A967A8AD25BEE1Dc0E) | +| WormholeTransceiver | [`0xB89780a55d15CAcA4F5c8828b5B5cf95442C2716`](https://polygonscan.com/address/0xB89780a55d15CAcA4F5c8828b5B5cf95442C2716) | +| TokenJar | [`0xc6Ae6373CEcc9e595A6C8b9fe581925a8c84f70A`](https://polygonscan.com/address/0xc6Ae6373CEcc9e595A6C8b9fe581925a8c84f70A) | +| WormholeReleaser | [`0xa59FfbB55D91Fc32b44A06F0b9cc6036a4afbcE2`](https://polygonscan.com/address/0xa59FfbB55D91Fc32b44A06F0b9cc6036a4afbcE2) | +| V3OpenFeeAdapter | [`0x3F07F08b45912dCd6691C5B9412975D5113B2910`](https://polygonscan.com/address/0x3F07F08b45912dCd6691C5B9412975D5113B2910) | +| V4FeeAdapter | [`0x59e84309Afa65F084F9c03668583d231afB12cc6`](https://polygonscan.com/address/0x59e84309Afa65F084F9c03668583d231afB12cc6) | +| V4FeePolicy | [`0x600c29d3Ce95Ce503FAb43753cbcb5Fa87EE6093`](https://polygonscan.com/address/0x600c29d3Ce95Ce503FAb43753cbcb5Fa87EE6093) | + +## X Layer: 196 + +| Contract | Address | +|----------|---------| +| CrossChainAccount | [`0x044aAF330d7fD6AE683EEc5c1C1d1fFf5196B6b7`](https://www.oklink.com/xlayer/address/0x044aAF330d7fD6AE683EEc5c1C1d1fFf5196B6b7) | +| Deployer | [`0xC943dd90D459dB082D9e9C1baBf89D4Afe79E7E0`](https://www.oklink.com/xlayer/address/0xC943dd90D459dB082D9e9C1baBf89D4Afe79E7E0) | +| TokenJar | [`0x8Dd8B6D56e4a4A158EDbBfE7f2f703B8FFC1a754`](https://www.oklink.com/xlayer/address/0x8Dd8B6D56e4a4A158EDbBfE7f2f703B8FFC1a754) | +| Releaser (OptimismBridgedResourceFirepit) | [`0xe122E231cb52aea99690963Fd73E91e33E97468f`](https://www.oklink.com/xlayer/address/0xe122E231cb52aea99690963Fd73E91e33E97468f) | +| V3OpenFeeAdapter | [`0x6A88EF2e6511CAFfE2D006e260e7A5d1E7D4d7D7`](https://www.oklink.com/xlayer/address/0x6A88EF2e6511CAFfE2D006e260e7A5d1E7D4d7D7) | + +## World Chain: 480 + +| Contract | Address | +|----------|---------| +| Deployer | [`0x4E524DAbf30A1D6e87261c804991119181F65bb8`](https://worldscan.org/address/0x4E524DAbf30A1D6e87261c804991119181F65bb8) | +| TokenJar | [`0xbDb82c2dE7D8748A3e499e771604ef8ef8544918`](https://worldscan.org/address/0xbDb82c2dE7D8748A3e499e771604ef8ef8544918) | +| Releaser (OptimismBridgedResourceFirepit) | [`0x455e844D286631566cF98D6cb2996149734618C6`](https://worldscan.org/address/0x455e844D286631566cF98D6cb2996149734618C6) | +| V3OpenFeeAdapter | [`0x1CE9d4DfB474Ef9ea7dc0e804a333202e40d6201`](https://worldscan.org/address/0x1CE9d4DfB474Ef9ea7dc0e804a333202e40d6201) | + +## Soneium: 1868 + +| Contract | Address | +|----------|---------| +| CrossChainAccount | [`0x044aAF330d7fD6AE683EEc5c1C1d1fFf5196B6b7`](https://soneium.blockscout.com/address/0x044aAF330d7fD6AE683EEc5c1C1d1fFf5196B6b7) | +| Deployer | [`0xD63fFE536bE3f44AE8f33C5f9c81581f9C94d1C8`](https://soneium.blockscout.com/address/0xD63fFE536bE3f44AE8f33C5f9c81581f9C94d1C8) | +| TokenJar | [`0x85aeb792b94a9d79741002FC871423Ec5dAD29e9`](https://soneium.blockscout.com/address/0x85aeb792b94a9d79741002FC871423Ec5dAD29e9) | +| Releaser (OptimismBridgedResourceFirepit) | [`0xc9CC50A75cE2a5f88fa77B43e3b050480c731b6e`](https://soneium.blockscout.com/address/0xc9CC50A75cE2a5f88fa77B43e3b050480c731b6e) | +| V3OpenFeeAdapter | [`0x47Cf920815344Fd684A48BBEFcbfbed9C7AE09CF`](https://soneium.blockscout.com/address/0x47Cf920815344Fd684A48BBEFcbfbed9C7AE09CF) | + +## Robinhood Chain: 4663 + +| Contract | Address | +|----------|---------| +| Deployer | [`0x81405C50595f09175d282ccEc657e090EE54AB2E`](https://robinhoodchain.blockscout.com/address/0x81405C50595f09175d282ccEc657e090EE54AB2E) | +| TokenJar | [`0x2aC03e14Cfe755426DaAEe0a4994184Ce81482F8`](https://robinhoodchain.blockscout.com/address/0x2aC03e14Cfe755426DaAEe0a4994184Ce81482F8) | +| Releaser | [`0x7a8f74C2585F84c781F951B7f2FF21337D5b630b`](https://robinhoodchain.blockscout.com/address/0x7a8f74C2585F84c781F951B7f2FF21337D5b630b) | +| V3OpenFeeAdapter | [`0x05C420bC4823e039AA4dA645eDde743486dAAA25`](https://robinhoodchain.blockscout.com/address/0x05C420bC4823e039AA4dA645eDde743486dAAA25) | +| V4FeeAdapter | [`0x6d0009504D129CF5002Dba61D9Ae8575AA79314c`](https://robinhoodchain.blockscout.com/address/0x6d0009504D129CF5002Dba61D9Ae8575AA79314c) | +| V4FeePolicy | [`0x6ee984309ba26c224f12Bb85D6F7f3C019483DFc`](https://robinhoodchain.blockscout.com/address/0x6ee984309ba26c224f12Bb85D6F7f3C019483DFc) | + +## Base: 8453 + +| Contract | Address | +|----------|---------| +| Deployer | [`0x076f84717f3601B8Cd177bb84b217A2679B38b7d`](https://basescan.org/address/0x076f84717f3601B8Cd177bb84b217A2679B38b7d) | +| TokenJar | [`0x9bD25e67bF390437C8fAF480AC735a27BcF6168c`](https://basescan.org/address/0x9bD25e67bF390437C8fAF480AC735a27BcF6168c) | +| Releaser (OptimismBridgedResourceFirepit) | [`0xFf77c0ED0B6b13A20446969107E5867abc46f53a`](https://basescan.org/address/0xFf77c0ED0B6b13A20446969107E5867abc46f53a) | +| V3OpenFeeAdapter | [`0xaBEA76658b205696d49B5F91b2a03536cB8A3bE1`](https://basescan.org/address/0xaBEA76658b205696d49B5F91b2a03536cB8A3bE1) | +| V4FeeAdapter | [`0xc53DD825dedBE7814562528A1A30e8e5BCbB4b55`](https://basescan.org/address/0xc53DD825dedBE7814562528A1A30e8e5BCbB4b55) | +| V4FeePolicy | [`0xf963bdbe8BA2aABBB3190fF2268F3d833393ab71`](https://basescan.org/address/0xf963bdbe8BA2aABBB3190fF2268F3d833393ab71) | + +## Arbitrum: 42161 + +| Contract | Address | +|----------|---------| +| Deployer | [`0x3Ac66e1bfC79032C9deFCB23aE4DEe3F8c1630eb`](https://arbiscan.io/address/0x3Ac66e1bfC79032C9deFCB23aE4DEe3F8c1630eb) | +| TokenJar | [`0x95E337C5B155385945D407f5396387D0c2a3A263`](https://arbiscan.io/address/0x95E337C5B155385945D407f5396387D0c2a3A263) | +| Releaser | [`0xB8018422bcE25D82E70cB98FdA96a4f502D89427`](https://arbiscan.io/address/0xB8018422bcE25D82E70cB98FdA96a4f502D89427) | +| V3OpenFeeAdapter | [`0xFF7aD5dA31fECdC678796c88B05926dB896b0699`](https://arbiscan.io/address/0xFF7aD5dA31fECdC678796c88B05926dB896b0699) | +| V4FeeAdapter | [`0x66276D2e80784180E4B9b859e4327b9C5646B87c`](https://arbiscan.io/address/0x66276D2e80784180E4B9b859e4327b9C5646B87c) | +| V4FeePolicy | [`0x8F6a5A19Ff1adc6AA9456d6b201fA4FC7589BD0B`](https://arbiscan.io/address/0x8F6a5A19Ff1adc6AA9456d6b201fA4FC7589BD0B) | + +## Celo: 42220 + +| Contract | Address | +|----------|---------| +| CrossChainAccount | [`0x044aAF330d7fD6AE683EEc5c1C1d1fFf5196B6b7`](https://celoscan.io/address/0x044aAF330d7fD6AE683EEc5c1C1d1fFf5196B6b7) | +| Deployer | [`0x91Df768dF14E94a3fCa42badBF1907E3a3b0240f`](https://celoscan.io/address/0x91Df768dF14E94a3fCa42badBF1907E3a3b0240f) | +| TokenJar | [`0x190c22c5085640D1cB60CeC88a4F736Acb59bb6B`](https://celoscan.io/address/0x190c22c5085640D1cB60CeC88a4F736Acb59bb6B) | +| Releaser (OptimismBridgedResourceFirepit) | [`0x2758FbaA228D7d3c41dD139F47dab1a27bF9bc25`](https://celoscan.io/address/0x2758FbaA228D7d3c41dD139F47dab1a27bF9bc25) | +| V3OpenFeeAdapter | [`0xB9952C01830306ea2fAAe1505f6539BD260Bfc48`](https://celoscan.io/address/0xB9952C01830306ea2fAAe1505f6539BD260Bfc48) | +| V4FeeAdapter | [`0xfd39ac616e630e9db03EFB2c9a4Fe63eDB949233`](https://celoscan.io/address/0xfd39ac616e630e9db03EFB2c9a4Fe63eDB949233) | +| V4FeePolicy | [`0xe1Adf3f130Abf616a7aB04AEeBf8D0470F6B6a16`](https://celoscan.io/address/0xe1Adf3f130Abf616a7aB04AEeBf8D0470F6B6a16) | + +## Zora: 7777777 + +| Contract | Address | +|----------|---------| +| Deployer | [`0x71F14F2A8b827cD29453498d5AF24F605caee931`](https://explorer.zora.energy/address/0x71F14F2A8b827cD29453498d5AF24F605caee931) | +| TokenJar | [`0x4753C137002D802f45302b118E265c41140e73C2`](https://explorer.zora.energy/address/0x4753C137002D802f45302b118E265c41140e73C2) | +| Releaser (OptimismBridgedResourceFirepit) | [`0x2f98eD4D04e633169FbC941BFCc54E785853b143`](https://explorer.zora.energy/address/0x2f98eD4D04e633169FbC941BFCc54E785853b143) | +| V3OpenFeeAdapter | [`0xbfc49b47637a4DC9b7B8dE8E71BF41E519103B95`](https://explorer.zora.energy/address/0xbfc49b47637a4DC9b7B8dE8E71BF41E519103B95) | + +## Deployment process + +The `AssetSink` contract described below is listed as `TokenJar` in the tables above. To enable fees for v2 and v3 on *mainnet*, the Deployer handles the entire set up in one transaction. Subsequent transactions will be required to set the initial fee values. diff --git a/content/protocols/protocol-fee/guides/best-practices.mdx b/content/protocols/protocol-fee/guides/best-practices.mdx index 1c4759b78..e9e1a8533 100644 --- a/content/protocols/protocol-fee/guides/best-practices.mdx +++ b/content/protocols/protocol-fee/guides/best-practices.mdx @@ -1,5 +1,6 @@ --- -title: Best Practices +title: Protocol Fee Best Practices +sidebarTitle: Best Practices description: Apply practical safeguards when integrating with the Uniswap Protocol Fee contracts and release flow. --- diff --git a/content/protocols/protocol-fee/guides/getting-started.mdx b/content/protocols/protocol-fee/guides/getting-started.mdx index 51d6162f0..cb2134f42 100644 --- a/content/protocols/protocol-fee/guides/getting-started.mdx +++ b/content/protocols/protocol-fee/guides/getting-started.mdx @@ -1,5 +1,6 @@ --- -title: Get Started +title: Get Started with the Protocol Fee System +sidebarTitle: Get Started description: Follow a complete step-by-step flow to call `Firepit.release()` in the Uniswap Protocol Fee system. --- diff --git a/content/protocols/protocol-fee/overview.mdx b/content/protocols/protocol-fee/overview.mdx index 85017a4bb..974d1e17b 100644 --- a/content/protocols/protocol-fee/overview.mdx +++ b/content/protocols/protocol-fee/overview.mdx @@ -1,5 +1,6 @@ --- title: Uniswap Protocol Fees +sidebarTitle: Overview description: Understand how protocol fees flow from Uniswap products into TokenJar and through releaser contracts. --- @@ -25,20 +26,20 @@ Each protocol component that generates fees (v2, v3, v4, UniswapX, Unichain, and Immutable contract that receives all tokens from fee sources on a given chain. Only the active Releaser can withdraw from it. -See the TokenJar contract source for more. +See the [TokenJar contract source](https://github.com/Uniswap/protocol-fees/blob/main/src/TokenJar.sol) for more. ### Fee adapters Adapters that connect specific protocol versions or products to the TokenJar. They define how and when fees are collected. -See the Fee Adapter contract source for more. +See the [Fee Adapter contract sources](https://github.com/Uniswap/protocol-fees/tree/main/src/feeAdapters) for more. ### Releasers Contracts that convert collected fees into protocol value according to defined logic. Examples include the Firepit Releaser, which burns UNI in return for assets. -See the Releaser contract source for more. +See the [Releaser contract sources](https://github.com/Uniswap/protocol-fees/tree/main/src/releasers) for more. ## Real-World Example diff --git a/content/protocols/smart-wallet/concepts/batched-transactions.mdx b/content/protocols/smart-wallet/concepts/batched-transactions.mdx index 0cc88c89a..ed85775a9 100644 --- a/content/protocols/smart-wallet/concepts/batched-transactions.mdx +++ b/content/protocols/smart-wallet/concepts/batched-transactions.mdx @@ -1,5 +1,4 @@ --- -id: batched-transactions title: Batched Transactions description: Understand how Uniswap smart wallet supports batched actions and ERC-7821-compatible execution flows. --- diff --git a/content/protocols/smart-wallet/concepts/delegation.mdx b/content/protocols/smart-wallet/concepts/delegation.mdx index f86e9e825..a33a27197 100644 --- a/content/protocols/smart-wallet/concepts/delegation.mdx +++ b/content/protocols/smart-wallet/concepts/delegation.mdx @@ -1,5 +1,4 @@ --- -id: delegation title: Delegation description: Learn how EIP-7702 delegation enables Uniswap smart wallet account behavior while preserving EOA addresses. --- diff --git a/content/protocols/smart-wallet/concepts/hooks.mdx b/content/protocols/smart-wallet/concepts/hooks.mdx index 231ec01f0..dc02401dd 100644 --- a/content/protocols/smart-wallet/concepts/hooks.mdx +++ b/content/protocols/smart-wallet/concepts/hooks.mdx @@ -1,6 +1,6 @@ --- -id: hooks -title: Hooks +title: Smart Wallet Hooks +sidebarTitle: Hooks description: Understand validation and execution hooks in Uniswap smart wallet, including call sites and integration cautions. --- diff --git a/content/protocols/smart-wallet/deployments.mdx b/content/protocols/smart-wallet/deployments.mdx index 6cd28f881..c1639fac6 100644 --- a/content/protocols/smart-wallet/deployments.mdx +++ b/content/protocols/smart-wallet/deployments.mdx @@ -1,10 +1,12 @@ --- -id: deployments -title: Deployments +title: Smart Wallet Deployments +sidebarTitle: Deployments description: View Uniswap smart wallet Calibur deployment addresses, versions, and repository references. --- - + + All Smart Wallet deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + ## Deployment Addresses diff --git a/content/protocols/smart-wallet/guides/best-practices.mdx b/content/protocols/smart-wallet/guides/best-practices.mdx index 0d4599932..e0eff1ba3 100644 --- a/content/protocols/smart-wallet/guides/best-practices.mdx +++ b/content/protocols/smart-wallet/guides/best-practices.mdx @@ -1,5 +1,6 @@ --- -title: Best Practices +title: Smart Wallet Best Practices +sidebarTitle: Best Practices description: Apply practical security best practices when integrating Uniswap smart wallet Calibur features into production flows. --- diff --git a/content/protocols/smart-wallet/overview.mdx b/content/protocols/smart-wallet/overview.mdx index 18c16ee04..9294bcbff 100644 --- a/content/protocols/smart-wallet/overview.mdx +++ b/content/protocols/smart-wallet/overview.mdx @@ -1,7 +1,33 @@ --- -id: overview title: Smart Wallet Overview +sidebarTitle: Overview description: Learn how Uniswap smart wallet uses the Calibur implementation with EIP-7702 delegation across supported networks. +keywords: + - smart wallet + - EIP-7702 + - delegation + - gas abstraction + - batched transactions + - ERC-7739 +faqs: + - question: What is EIP-7702 delegation, and does it change my account address? + answer: |- + No. Your address and onchain history stay the same. Delegation is the EIP-7702 process where an Externally Owned Account (EOA) points to code deployed at a remote smart contract address, called the implementation. After the Pectra fork, an EOA can internalize that code and execute transactions using the implementation logic while keeping its original address and onchain history. Uniswap smart wallet uses the Calibur implementation for this. + - question: Can I delegate to more than one implementation at a time? + answer: |- + No. A user can only be delegated to one contract at a time on a given chain. You can, however, have separate delegations on different chains, since delegation state is tracked per chain. To move to a different implementation on the same chain, you replace the existing delegation rather than adding a second one. + - question: What are batched transactions, and when would I use them? + answer: |- + Batched transactions combine multiple actions in the same execution flow. A common example is approving an ERC-20 token and then swapping that token in a single batched flow, rather than sending two separate transactions. Uniswap smart wallet supports simple batch calls and the ERC-7821 Minimal Batch Executor Interface, which improves interoperability between dapps and contract implementations. + - question: How does gas abstraction let someone else pay for gas? + answer: |- + Gas abstraction allows a user to transact without holding ETH to pay for gas. A third party called a bundler can cover or manage those fees on the user's behalf. Uniswap smart wallet implements ERC-4337, Account Abstraction Using Alt Mempool. By default, EntryPoint v0.8 is enabled on the account; see the gas abstraction concept page for the address. The root signer can disable or change this, but doing so incorrectly can lead to loss of funds. + - question: What is ERC-7739, and which signatures does it apply to? + answer: |- + ERC-7739 defines a defensive rehashing model for external signers on smart contract accounts. In Uniswap smart wallet it is enforced for all alternative keys added to an account, but does not apply to signatures from the root EOA, the account delegated to the implementation. It protects signatures from being replayed across accounts by binding the signed data to the account and chain. The standard is still in draft. + - question: What does Calibur add on top of a plain EOA? + answer: |- + Calibur is the contract implementation that a user delegates to through EIP-7702. Once delegated, the account can batch multiple actions into one flow, use gas abstraction so a third party can pay fees, and apply custom permission controls through alternative signers. Calibur is deployed to the same address across supported networks, is non-upgradeable, and has no owner. --- Uniswap smart wallet features are powered by [Calibur](/docs/protocols/smart-wallet/deployments), a contract implementation designed for [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702). @@ -14,6 +40,90 @@ Uniswap smart wallet features are powered by [Calibur](/docs/protocols/smart-wal Users delegate to the implementation through EIP-7702 and then use smart wallet features while keeping the same EOA address. +## FAQ + +
+ What is EIP-7702 delegation, and does it change my account address? + + + + No. Your address and onchain history stay the same. [Delegation](/docs/protocols/smart-wallet/concepts/delegation) is the [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) process where an Externally Owned Account (EOA) points to code deployed at a remote smart contract address, called the *implementation*. After the Pectra fork, an EOA can internalize that code and execute transactions using the implementation logic while keeping its original address and onchain history. + + Uniswap smart wallet uses the [Calibur](/docs/protocols/smart-wallet/deployments) implementation for this. + + + +
+ +
+ Can I delegate to more than one implementation at a time? + + + + No. A user can only be delegated to one contract at a time on a given chain. You can, however, have separate delegations on different chains, since delegation state is tracked per chain. + + To move to a different implementation on the same chain, you replace the existing delegation rather than adding a second one. + + + +
+ +
+ What are batched transactions, and when would I use them? + + + + [Batched transactions](/docs/protocols/smart-wallet/concepts/batched-transactions) combine multiple actions in the same execution flow. A common example is approving an ERC-20 token and then swapping that token in a single batched flow, rather than sending two separate transactions. + + Uniswap smart wallet supports simple batch calls and [ERC-7821](https://eips.ethereum.org/EIPS/eip-7821), the Minimal Batch Executor Interface, which improves interoperability between dapps and contract implementations. + + + +
+ +
+ How does gas abstraction let someone else pay for gas? + + + + [Gas abstraction](/docs/protocols/smart-wallet/concepts/gas-abstraction) allows a user to transact without holding ETH to pay for gas. A third party called a [bundler](https://www.alchemy.com/overviews/what-is-a-bundler) can cover or manage those fees on the user's behalf. Uniswap smart wallet implements [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337), Account Abstraction Using Alt Mempool. + + By default, EntryPoint v0.8 is enabled on the account; see [Gas Abstraction](/docs/protocols/smart-wallet/concepts/gas-abstraction) for the address. The root signer can disable or change this, but doing so incorrectly can lead to loss of funds. + + + +
+ +
+ What is ERC-7739, and which signatures does it apply to? + + + + [ERC-7739](/docs/protocols/smart-wallet/concepts/erc-7739) defines a defensive rehashing model for external signers on smart contract accounts. In Uniswap smart wallet it is enforced for all alternative keys added to an account, but does not apply to signatures from the root EOA, the account delegated to the implementation. + + It protects signatures from being replayed across accounts by binding the signed data to the account and chain. The [standard](https://eips.ethereum.org/EIPS/eip-7739) is still in draft. + + + +
+ +
+ What does Calibur add on top of a plain EOA? + + + + [Calibur](/docs/protocols/smart-wallet/deployments) is the contract implementation that a user delegates to through EIP-7702. Once delegated, the account can: + + * Batch multiple actions into one flow. + * Use gas abstraction so a third party can pay fees. + * Apply custom permission controls through alternative signers. + + Calibur is deployed to the same address across supported networks, is non-upgradeable, and has no owner. + + + +
+ ## Where to Go Next - Explore core smart wallet patterns in [Concepts](/docs/protocols/smart-wallet/concepts/delegation). diff --git a/content/protocols/the-compact/concepts/arbiters.mdx b/content/protocols/the-compact/concepts/arbiters.mdx index 14a56a47a..60f33409a 100644 --- a/content/protocols/the-compact/concepts/arbiters.mdx +++ b/content/protocols/the-compact/concepts/arbiters.mdx @@ -1,5 +1,4 @@ --- -id: arbiters title: Arbiters description: Learn how arbiters verify conditions and submit claims for Uniswap The Compact single-chain and multichain compacts. --- diff --git a/content/protocols/the-compact/concepts/compacts.mdx b/content/protocols/the-compact/concepts/compacts.mdx index dd80431b1..2ee4fa36d 100644 --- a/content/protocols/the-compact/concepts/compacts.mdx +++ b/content/protocols/the-compact/concepts/compacts.mdx @@ -1,5 +1,4 @@ --- -id: compacts-eip712 title: Compacts & EIP-712 description: Understand Uniswap The Compact agreement formats, witness data, and EIP-712 signing or registration workflows. --- diff --git a/content/protocols/the-compact/concepts/core-interfaces.mdx b/content/protocols/the-compact/concepts/core-interfaces.mdx index 86bcc0f31..cbd4075a9 100644 --- a/content/protocols/the-compact/concepts/core-interfaces.mdx +++ b/content/protocols/the-compact/concepts/core-interfaces.mdx @@ -1,5 +1,4 @@ --- -id: core-interfaces title: Core Interfaces description: Reference key Uniswap The Compact interfaces for deposits, registration, claims, allocator checks, and emissary verification. --- diff --git a/content/protocols/the-compact/concepts/periphery-contracts.mdx b/content/protocols/the-compact/concepts/periphery-contracts.mdx index 0e0fd0e0d..8d92037cb 100644 --- a/content/protocols/the-compact/concepts/periphery-contracts.mdx +++ b/content/protocols/the-compact/concepts/periphery-contracts.mdx @@ -1,5 +1,4 @@ --- -id: Periphery Contracts title: Periphery Contracts description: Understand emissaries and Tribunal as peripheral patterns that integrate with Uniswap The Compact claim verification flows. --- diff --git a/content/protocols/the-compact/overview.mdx b/content/protocols/the-compact/overview.mdx index 91cb4951a..b15b27090 100644 --- a/content/protocols/the-compact/overview.mdx +++ b/content/protocols/the-compact/overview.mdx @@ -1,6 +1,6 @@ --- -id: overview title: The Compact Overview +sidebarTitle: Overview description: Learn how Uniswap The Compact coordinates resource locks, compacts, and claims across single-chain and multichain flows. --- diff --git a/content/protocols/uniswap-labs-hooks/index.mdx b/content/protocols/uniswap-labs-hooks/index.mdx new file mode 100644 index 000000000..d6867ee5a --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/index.mdx @@ -0,0 +1,15 @@ +--- +title: Overview +description: This is the technical repository for production-ready v4 hooks designed and maintained by Uniswap Labs. Every hook is open source and ready to be deployed. +keywords: ["Uniswap Labs Hooks", "v4 hooks", "production-ready hooks"] +--- + +| Hook | Core Mechanism | Primary Technology | Get Started | +| :--- | :--- | :--- | :--- | +| **LitePSM** | Facilitates gas-efficient USDC <> USDS conversions in a hook. | Peg Stability Module | [Link](https://github.com/Uniswap/v4-hooks-public/blob/main/src/aggregator-hooks/implementations/LitePSM/LitePSMAggregator.sol) | +| **Permissioned Pools** | Restricts swaps and liquidity provision to allowlisted addresses. | ERC6909 Wrapped Token Proxy | [Link](/docs/protocols/uniswap-labs-hooks/permissioned-pools/overview) | +| **StablePair Hook** | Concentrates liquidity around a reference price for assets that should trade at a fixed rate. | Custom Pricing Logic | [Link](/docs/protocols/uniswap-labs-hooks/stable-pair/overview) | +| **WETH <> ETH** | Facilitates WETH <> ETH conversions in a hook. | Wraps core conversion contract | [Link](https://github.com/Uniswap/v4-hooks-public/blob/main/src/WETHHook.sol) | +| **wstETH <> stETH** | Facilitates wstETH <> stETH conversions in a hook. | Wraps core conversion contract | [Link](https://github.com/Uniswap/v4-hooks-public/blob/main/src/WstETHHook.sol) | + +For bespoke infrastructure or custom asset class support, [get in touch](/uniswap-labs-hooks) with our team. diff --git a/content/protocols/uniswap-labs-hooks/meta.json b/content/protocols/uniswap-labs-hooks/meta.json new file mode 100644 index 000000000..24c8d591d --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Uniswap Labs Hooks", + "pages": ["index", "permissioned-pools", "stable-pair"] +} diff --git a/content/protocols/uniswap-labs-hooks/permissioned-pools/architecture.mdx b/content/protocols/uniswap-labs-hooks/permissioned-pools/architecture.mdx new file mode 100644 index 000000000..1ecc69b84 --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/permissioned-pools/architecture.mdx @@ -0,0 +1,89 @@ +--- +title: Permissioned Pools Architecture +sidebarTitle: Architecture +description: Explore the contracts behind Uniswap v4 permissioned pools, including the Permissions Adapter, hooks, position manager, and routing. +--- + +Permissioned pools are built from four contracts that work together to enforce an issuer's allowlist while keeping the permissioned token compatible with the standard `PoolManager`. + +## The Permissions Adapter + +The Permissions Adapter is the ERC-20 contract at the center of this design. It holds the underlying permissioned token and mints a virtual version of it that the pool trades, so the underlying token never enters the `PoolManager` directly. The adapter and the virtual token are the same contract. + +Creating the virtual token and converting it back to the original are handled automatically. Swappers and liquidity providers interact with the token as usual, and the router and position manager perform these conversions behind the scenes, so end users never manage the virtual token themselves. The virtual token is necessary for two reasons: + +- **The `PoolManager` allowlist cannot be enforced directly.** The `PoolManager` is a single shared contract, so it cannot be added to every issuer's allowlist. The adapter acts as the approved holder of the underlying token and keeps the raw asset out of the `PoolManager`. +- **Direct holding would expose the token as a freely tradable claim.** A permissioned token held directly by the `PoolManager` could be minted into an ERC-6909 claim and traded without the allowlist. The adapter prevents this by restricting minting to authorized periphery contracts, such as the position manager, router, and quoters the issuer approves. + +See the [`PermissionsAdapter` source](https://github.com/Uniswap/v4-periphery/blob/main/src/hooks/permissionedPools/PermissionsAdapter.sol) in `v4-periphery`. + +- **Pool manager exclusivity:** only the `PoolManager` can hold the virtual token. When it is transferred out of the pool, the adapter burns it and releases the underlying token in the same call. +- **Pluggable allowlist:** the adapter delegates permission checks to an allowlist checker that the issuer implements and deploys. + +![Creating a virtual version of the token mints the virtual token to the PoolManager; on exit the virtual token is burned and the underlying token is released](./images/permissioned-pools-virtual-token.png) + +The adapter exposes several administrative functions for the permissioned token issuer: + +- **`updateAllowListChecker`:** update the pluggable validation contract that decides who is authorized to swap the token or provide liquidity. +- **`updateAllowedWrapper`:** approve or revoke a contract, such as a router, position manager, or quoter, that can create a virtual version of the token. +- **`updateSwappingEnabled`:** enable, pause, or resume swapping for the token. Swapping is disabled by default on a new adapter. +- **`updateAllowedHook`:** allow or revoke a hook for the adapter. Position mints and liquidity increases revert with `InvalidHook` unless the pool's hook is allowed. The position manager and the router both read this from the adapter, so one call covers every periphery contract. + +## Permissioned Hooks + +The permissioned hook enforces the allowlist on every interaction. Like any v4 hook, it is attached to a pool at initialization through the `PoolKey`. It activates four callbacks: + +- `beforeInitialize` queries the `PermissionsAdapterFactory`, requires at least one pool currency to be a factory-verified adapter, and rejects any currency that is an unverified adapter, so a pool cannot be created around an unverified Permissions Adapter. +- `beforeSwap` checks the `SWAP_ALLOWED` flag for the swapper, and also reverts while the issuer has swapping paused via `updateSwappingEnabled`. +- `afterSwap` emits a `Swap` event so indexers can track activity on permissioned pools. +- `beforeAddLiquidity` checks the `LIQUIDITY_ALLOWED` flag before a position is minted. + +Permissions are expressed as flags: `SWAP_ALLOWED` (`0x0001`) and `LIQUIDITY_ALLOWED` (`0x0002`). The hook also confirms that the calling router or position manager is approved to create virtual versions of the token (via `updateAllowedWrapper`), which is why the issuer must approve the contracts that can interact with the pool. + +## Permissioned Position Manager + +The Permissioned Position Manager extends the standard `PositionManager`, adding allowlist enforcement and automatic creation of the virtual token. + +- **Non-transferable NFTs:** position transfers revert, which prevents an allowlisted holder from handing a position to a disallowed address. +- **Position unwinding:** the owner of either Permissions Adapter in the pool can call `unwindPosition` to burn a position NFT, remove its liquidity, and route each asset back to the holder. Any asset the holder can no longer receive falls back to that asset's own issuer (as tokens, or as an ERC-6909 claim if delivery fails), so unwinding never lets one issuer receive the other's asset. +- **Automatic conversion:** the position manager creates a virtual version of the permissioned token before interacting with the pool and validates the holder against the allowlist on mint and increase. + + +When building a pool key, supply the **adapter address** as the currency, not the underlying permissioned token. The same applies when settling and taking. + + +![An allowlisted holder mints a non-transferable position NFT; an issuer admin can unwind it, removing the liquidity and returning assets to the holder](./images/permissioned-pools-liquidity.png) + + +When a position is unwound, each asset routes to the holder first. An asset the holder can no longer receive falls back to its own issuer, never to the other issuer. + + +## Swap Routing + +Swaps go through the [Universal Router](/docs/trading/swapping-api/supported-chains#universal-router-version), which converts permissioned tokens to and from their virtual versions. The router identifies the permissioned token in the swap path, creates a virtual version of it before the pool interaction, executes the swap with the virtual token, and converts back to the original token automatically on exit. The allowlist is enforced twice: by the router when it creates the virtual version of the input token, and by the hook on `beforeSwap`, so the restriction cannot be bypassed. + + +Permissioned swap routing requires [Universal Router](/docs/trading/swapping-api/supported-chains#universal-router-version) 2.2.0 or higher. + + +![Permissioned swap flow: approve, trigger transfer to the Permissions Adapter, create a representation inside Uniswap v4, then settle](./images/permissioned-pools-swap-flow.png) + +## Adapter Verification + +A factory deploys and verifies adapters. Verification confirms that an adapter is allowed to hold its underlying token: the issuer seeds the adapter with a minimal balance, as little as 1 wei, which is only possible if the adapter is on the token's allowlist. See [Step 3](/docs/protocols/uniswap-labs-hooks/permissioned-pools/deploy-a-permissioned-pool#step-3-allowlist-and-fund-the-adapter) and [Step 4](/docs/protocols/uniswap-labs-hooks/permissioned-pools/deploy-a-permissioned-pool#step-4-verify-the-adapter) for the mechanics. The factory records a mapping from each adapter to its underlying token, never the reverse. + +Factory verification is separate from the ERC-165 check on the allowlist checker. Factory verification proves the adapter holds a real balance of its token, while ERC-165 only confirms that a checker implements `IAllowlistChecker`. + +## Security Considerations + +- **Issuer recall:** if a holder loses permissions, the Permissions Adapter owner can call `unwindPosition` to remove their liquidity and route the assets back. Assets that cannot be delivered to the holder fall back to the issuer, so an issuer can always reclaim exposure to a permissioned token when required. +- **Non-custodial design:** user funds can only leave the pool through `PoolManager` settlement flows: swaps, position withdrawals, and claim redemptions. They never leave through the virtual token directly. +- **Access control:** the Permissions Adapter owner can change the allowlist checker, approve or revoke the contracts that can create virtual tokens, and pause swapping. The owner cannot transfer positions or pull funds directly through the virtual token; unwinding routes assets to the holder first, and the issuer receives an asset only when the holder can no longer hold it. The factory and hook are shared contracts that Uniswap deploys, and they are not issuer-controlled. +- **Reverse mapping:** the factory maps each adapter to its underlying token, never the reverse, which stops anyone from registering an arbitrary allowlist check against an existing ERC-20. +- **Unwinding in dual-permissioned pools:** pools with two permissioned tokens from different issuers, for example two tokenized funds in the same sector, are fully supported. Either Permissions Adapter owner can unwind a position, and each asset routes to the holder first. An asset the holder can no longer receive falls back to its own issuer only, so one issuer cannot seize the other's asset. + +## Where to Go Next + +- Onboard a token in [Deploy a Permissioned Pool](/docs/protocols/uniswap-labs-hooks/permissioned-pools/deploy-a-permissioned-pool). +- Integrate permissioned tokens in an app with [Swapping through Permissioned Pools](/docs/trading/swapping-api/swapping-permissioned-pools). +- Review hook fundamentals in [Hooks](/docs/protocols/v4/concepts/hooks). diff --git a/content/protocols/uniswap-labs-hooks/permissioned-pools/deploy-a-permissioned-pool.mdx b/content/protocols/uniswap-labs-hooks/permissioned-pools/deploy-a-permissioned-pool.mdx new file mode 100644 index 000000000..c1cd2d0e8 --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/permissioned-pools/deploy-a-permissioned-pool.mdx @@ -0,0 +1,253 @@ +--- +title: Deploy a Permissioned Pool +description: Deploy a permissioned pool on Uniswap v4 by creating an allowlist checker and a Permissions Adapter. +--- + +This guide walks a permissioned asset issuer through onboarding a permissioned token so it can trade in a Uniswap v4 permissioned pool. Rather than building custom infrastructure, you use the shared `PermissionsAdapterFactory` and `PermissionedHooks` that Uniswap deploys and maintains, while keeping direct administrative control over your compliance rules. + + + You will need contract addresses throughout this guide. They are listed under [Deployment + Addresses](#deployment-addresses) below, and on the unified [Deployments](/deployments) page and + its [deployments.json](/deployments.json) feed. Permissioned pools use their own Universal Router + build, so use the address listed there rather than the standard one. + + +At a high level, onboarding is seven steps: + +1. **Implement an allowlist checker.** Define the compliance logic that decides who is authorized to swap or provide liquidity. +2. **Create the Permissions Adapter.** Use the factory to deploy the contract that issues the virtual version of your token and acts as its pool-facing proxy. +3. **Allowlist and fund the adapter.** Add the adapter to your token's allowlist and seed it with at least 1 wei so it can be verified. +4. **Verify the adapter.** Register it with the factory so the protocol recognizes it as a legitimate adapter. +5. **Approve virtual token contracts.** Authorize the position manager, router, and quoters that are allowed to create the virtual version of your token, and allow the permissioned hook on the adapter. +6. **Create the pool.** Initialize the pool with the adapter as a currency and the permissioned hook, then enable swapping on the adapter. +7. **Allowlist your pool for routing.** Register with Uniswap Labs so the pool is eligible for routing in the Uniswap interface and API. + +The steps below walk through each in detail. + +![Issuer onboarding flow: implement allowlist checker, create adapter, allowlist and fund it, verify, approve virtual token contracts, create pool, register for app and API](./images/permissioned-pools-onboarding.png) + + +A permissioned pool does not by itself restrict who can hold the token. The token's allowlist does that, and the pool enforces those rules onchain for swaps and liquidity. Make sure your allowlist reflects any requirements that apply to your asset before deploying. + + +## Prerequisites + +- A deployed ERC-20 permissioned token. The virtual token is always named `Uniswap v4 ` with symbol `v4`, read from your token's `name()`, `symbol()`, and `decimals()`. When those are missing, it falls back to `Uniswap v4 Permissioned Token`, `v4PT`, and `18` decimals, so exposing them is recommended. +- A way to determine which addresses are allowed to swap or provide liquidity. +- The address of the `PermissionsAdapterFactory` and `PermissionedHooks` for your target network. See [Deployment Addresses](#deployment-addresses). + +Developing with Uniswap v4 _requires [foundry](https://book.getfoundry.sh)_. The permissioned pools contracts are not in a published npm release yet — the latest `@uniswap/v4-periphery` on npm predates them — so install them from source with the commit pinned: + +```bash +forge install Uniswap/v4-periphery@3245c3cb99c48fa1dc2459c3b60abc37d4294aba +forge install OpenZeppelin/openzeppelin-contracts@v5.0.2 +``` + +In the `remappings.txt`, add the following: + +``` +@uniswap/v4-periphery/=lib/v4-periphery/ +@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ +``` + +`v4-periphery` has no release tags, so pinning the commit is what keeps the import paths below resolving to the code this guide describes. + +## Step 1: Implement an Allowlist Checker + +The adapter delegates permission checks to a contract you implement. It must satisfy the [`IAllowlistChecker`](https://github.com/Uniswap/v4-periphery/blob/3245c3cb99c48fa1dc2459c3b60abc37d4294aba/src/hooks/permissionedPools/interfaces/IAllowlistChecker.sol) interface, which is an `IERC165`. The `checkAllowlist` function returns a `PermissionFlag` for a given account and token. A single checker can therefore serve multiple assets. + +```solidity +import {IAllowlistChecker} from "@uniswap/v4-periphery/src/hooks/permissionedPools/interfaces/IAllowlistChecker.sol"; +import {PermissionFlag, PermissionFlags} from "@uniswap/v4-periphery/src/hooks/permissionedPools/libraries/PermissionFlags.sol"; +import {ERC165, IERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; + +contract MyAllowlistChecker is IAllowlistChecker, ERC165 { + // Map each approved account to its granted permissions. + mapping(address account => PermissionFlag) public permissions; + + // Return the permissions granted to `account` for `tokenAddress`. + // PermissionFlags.SWAP_ALLOWED and PermissionFlags.LIQUIDITY_ALLOWED can be combined. + function checkAllowlist(address account, address tokenAddress) + external + view + returns (PermissionFlag) + { + return permissions[account]; + } + + // Owner-controlled setter to manage the allowlist (access control omitted for brevity). + function setPermissions(address account, PermissionFlag permission) external { + permissions[account] = permission; + } + + // ERC-165 lets the adapter confirm this is a valid allowlist checker. + // This is separate from factory verification of the adapter itself. + function supportsInterface(bytes4 interfaceId) + public + view + override(ERC165, IERC165) + returns (bool) + { + return interfaceId == type(IAllowlistChecker).interfaceId || super.supportsInterface(interfaceId); + } +} +``` + +## Step 2: Create a Permissions Adapter + +Call `createPermissionsAdapter` on the factory with your permissioned token, the admin address that will own the adapter, and your allowlist checker. The factory deploys an adapter scoped to your token. + +```solidity +address adapter = factory.createPermissionsAdapter( + IERC20(permissionedToken), + issuerAdmin, // adapter owner: holds admin control over the pool + IAllowlistChecker(myChecker) +); +``` + + +The admin address becomes the adapter owner and holds admin control over the pool. It can change the allowlist checker, approve or revoke the contracts that can create virtual tokens, pause swapping, and unwind positions. This is a high-leverage key, so secure it accordingly, for example with a multisig. + + +## Step 3: Allowlist and Fund the Adapter + +The adapter must be able to hold your permissioned token. Add the adapter address to your token's allowlist, then transfer a small balance so the factory can verify it. The amount can be as little as 1 wei. + +```solidity +// 1. On your permissioned token, allow the adapter to hold the token. +// 2. Seed the adapter so it holds a non-zero balance. +PermissionsAdapter(adapter).depositForVerification(1); +``` + +## Step 4: Verify the Adapter + +Verification confirms the adapter is allowed to hold your token. It succeeds only when the adapter holds a non-zero balance of the permissioned token. + +```solidity +factory.verifyPermissionsAdapter(adapter); +``` + +## Step 5: Approve Virtual Token Contracts + +Approve the contracts that are allowed to create the virtual version of your token and redeem the original: the Permissioned Position Manager, the Universal Router, and both quoters (`V4Quoter` and `MixedRouteQuoterV2`) used for pricing. Onchain, these are called *allowed wrappers*, which is why the function below is named `updateAllowedWrapper`. All four addresses are listed in [Deployment Addresses](#deployment-addresses) below. + +```solidity +PermissionsAdapter(adapter).updateAllowedWrapper(permissionedPositionManager, true); +PermissionsAdapter(adapter).updateAllowedWrapper(universalRouter, true); +PermissionsAdapter(adapter).updateAllowedWrapper(v4Quoter, true); +PermissionsAdapter(adapter).updateAllowedWrapper(mixedRouteQuoterV2, true); +``` + +Then, allow `PermissionedHooks` on the adapter itself. Only the adapter owner can call this, and without it every attempt to mint a liquidity position reverts with `InvalidHook`. + +```solidity +PermissionsAdapter(adapter).updateAllowedHook(IHooks(permissionedHooks), true); +``` + +## Step 6: Create the Pool + +Create the pool with the **adapter address** as the currency and `PermissionedHooks` as the hook. The hook reverts on initialization unless at least one currency is a verified adapter. + +```solidity +PoolKey memory key = PoolKey({ + currency0: Currency.wrap(adapter), // the adapter, not the underlying token + currency1: Currency.wrap(weth), + fee: 3000, + tickSpacing: 60, + hooks: IHooks(permissionedHooks) +}); +``` + +Finally, enable swapping on the adapter. Swapping is disabled by default on a new adapter, so swaps revert with `SwappingDisabled` until the owner turns it on. + +```solidity +PermissionsAdapter(adapter).updateSwappingEnabled(true); +``` + +## Step 7: Allowlist Your Pool for Routing + +To be eligible for routing in the Uniswap interface and API, your permissioned pool must be allowlisted with Uniswap Labs. Once your adapter is verified, [request allowlisting](/permissioned-pools-allowlist) with the details below, and the team follows up to complete onboarding. + +Uniswap Labs reviews this request manually. It is not self-serve, and submitting the form does not enable routing by itself. + +Allowlisting is required on every network, including mainnet and Sepolia. One request can cover several networks, so list them all in the Chain(s) field. + + +This form is for issuers with a deployed, verified permissioned token. If you are still exploring and want the team to reach out, use the [Uniswap Labs Hooks interest form](/uniswap-labs-hooks) instead. + + + + +Requests are reviewed as they are received, but they may take varying time to consider. Submit your request as soon as your adapter is verified onchain, to give the request the most time possible before your intended launch date. Uniswap cannot guarantee that a review or an allowlisting takes place before any given launch date, but we get back to you as quickly as we can. + + + +### What the form asks for + +Have these ready before you open the form. Every field is required except last name and notes. You also must accept the terms and privacy notice. + +- First name and last name. +- Email and Telegram handle. +- Company and company location. +- Token issuer. +- The chain or chains you want routing on. +- A CoinGecko API link for your token logo. +- Permissioned token address, verified adapter address, and KYC URL. +- Notes. + +A monitored Telegram handle matters, because the team uses it to reach you with any questions about your submission. Uniswap does not work with CoinGecko to make sure logos are available and accurate, so contact CoinGecko and get your logo set before you submit this form. + +During onboarding, the following values are added to the backend configuration: + +- **Permissioned token address** (the token wallets hold). +- **Verified adapter address** (the Permissions Adapter created in Step 2 and verified in Step 4). +- **KYC URL** (where unapproved users complete verification). + +The configuration entry looks like this: + +```typescript +// Keyed by the permissioned token address, lowercased. +'0x...permissionedtokenaddress': { + adapterTokenAddress: '0x...verifiedadapteraddress', + kycUrl: 'https://your-kyc-provider.example/verify', + issuer: 'Your Issuer Name', +}, +``` + + +Addresses must be lowercase. When the adapter and the permissioned token share an address, the token already behaves as its own adapter. + + +## Deployment Addresses + +The Permissions Adapter Factory, the Permissioned Position Manager, the hook, and the Universal Router are builds specific to permissioned pools, so use these addresses rather than the standard v4 equivalents. The two quoters are the standard Uniswap deployments, unchanged for permissioned pools. + +### Ethereum mainnet + +| Contract | Address | +| --- | --- | +| `PermissionsAdapterFactory` | 0x7DA911490Ca4663E572eA9C8154f3CdEbCE16452 | +| `PermissionedPositionManager` | 0x63Bd7e5D4EcfAA74d82AE1dE98F476C935a81973 | +| `PermissionedHooks` | 0x499a724Ab630549f14C995EC41a8E04fA3fd28c0 | +| Universal Router | 0xab863E752Bf67D8DCDD929EaAe9Be9dc83Fb3BbB | +| `V4Quoter` | 0x52F0E24D1c21C8A0cB1e5a5dD6198556BD9E1203 | +| `MixedRouteQuoterV2` | 0xE63C5F5005909E96b5aA9CE10744CCE70eC16CC3 | + +### Sepolia testnet + +| Contract | Address | +| --- | --- | +| `PermissionsAdapterFactory` | 0xE6B0d96919334C33d06266d1420F97f6f434fA2B | +| `PermissionedPositionManager` | 0xf99D553912084c99F6299291b75Fe9B7119Aa1A7 | +| `PermissionedHooks` | 0x51247E2291d290d17C08813A175AC86465EdE8c0 | +| Universal Router | 0x5093f1CDED83d99FfEd6602dA6260672ae16787c | +| `V4Quoter` | 0x61B3f2011A92d183C7dbaDBdA940a7555Ccf9227 | +| `MixedRouteQuoterV2` | 0x4745F77b56a0E2294426E3936dc4Fab68d9543Cd | + +Swaps involving a permissioned token route through the Universal Router rather than a standalone router. + +## Where to Go Next + +- Understand the contracts in [Architecture](/docs/protocols/uniswap-labs-hooks/permissioned-pools/architecture). +- Add liquidity as an allowlisted LP in [Provide Liquidity](/docs/protocols/uniswap-labs-hooks/permissioned-pools/provide-liquidity). +- Integrate the token in an app with [Swapping through Permissioned Pools](/docs/trading/swapping-api/swapping-permissioned-pools). diff --git a/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-architecture.png b/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-architecture.png new file mode 100644 index 000000000..f2dca2525 Binary files /dev/null and b/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-architecture.png differ diff --git a/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-liquidity.png b/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-liquidity.png new file mode 100644 index 000000000..f2f3f179a Binary files /dev/null and b/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-liquidity.png differ diff --git a/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-onboarding.png b/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-onboarding.png new file mode 100644 index 000000000..7a6a1e688 Binary files /dev/null and b/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-onboarding.png differ diff --git a/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-swap-flow.png b/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-swap-flow.png new file mode 100644 index 000000000..387104ac9 Binary files /dev/null and b/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-swap-flow.png differ diff --git a/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-virtual-token.png b/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-virtual-token.png new file mode 100644 index 000000000..4a03a38d8 Binary files /dev/null and b/content/protocols/uniswap-labs-hooks/permissioned-pools/images/permissioned-pools-virtual-token.png differ diff --git a/content/protocols/uniswap-labs-hooks/permissioned-pools/meta.json b/content/protocols/uniswap-labs-hooks/permissioned-pools/meta.json new file mode 100644 index 000000000..5c38c30af --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/permissioned-pools/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Permissioned Pools Hook", + "pages": ["overview", "architecture", "deploy-a-permissioned-pool", "provide-liquidity"] +} diff --git a/content/protocols/uniswap-labs-hooks/permissioned-pools/overview.mdx b/content/protocols/uniswap-labs-hooks/permissioned-pools/overview.mdx new file mode 100644 index 000000000..7e1d882b8 --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/permissioned-pools/overview.mdx @@ -0,0 +1,42 @@ +--- +title: Permissioned Pools Overview +sidebarTitle: Overview +description: Understand Uniswap v4 permissioned pools, which restrict swaps and liquidity to allowlisted holders of a permissioned asset. +--- + +The Permissioned Pools hook lets a Uniswap v4 pool support tokens that can only be held or traded by approved addresses, such as tokenized or crypto-native assets that must restrict who can hold them. It combines an onchain allowlist with a virtual version of the token that keeps the permissioned token compatible with the standard `PoolManager`. The protocol stays permissionless: anyone can create a pool, but only allowlisted holders can swap or provide liquidity. + +## Use Cases + +Potential use cases for the Permissioned Pools hook include: + +- **Tokenized assets** that require holders to pass identity verification before trading. +- **Regulated assets** where an issuer must be able to restrict who gains exposure. +- **Compliance-gated liquidity** where both swappers and liquidity providers must be on an allowlist. + +## How It Works + +With permissioned pools, a verified contract, the **Permissions Adapter**, holds the underlying permissioned token and issues a virtual version of it, and the pool trades that virtual token. When assets enter the pool, a virtual version of the token is created; when they leave, the virtual token is converted back to the original, so the holder always ends up with the underlying permissioned token. A **permissioned hook** checks the issuer's allowlist on every swap and liquidity addition, and the Permissioned Position Manager and the Universal Router handle these conversions automatically so integrations need minimal changes. + +The Permissions Adapter is verified through a factory: before a pool can use it, the issuer proves the adapter is authorized to hold the underlying token by seeding it with a minimal balance, which is only possible if the adapter is on the token's allowlist. See [Architecture](/docs/protocols/uniswap-labs-hooks/permissioned-pools/architecture) for the details. + +![Permissioned pool architecture: the Universal Router and Permissioned Position Manager create virtual versions of tokens through the Permissions Adapter for the PoolManager, where Permissioned Hooks enforce the allowlist](./images/permissioned-pools-architecture.png) + +## Core Invariants + +- Only allowlisted addresses can swap or provide liquidity. +- Disallowed addresses cannot gain exposure to the permissioned token, including through multi-hop routes. +- The issuer can halt swapping and can unwind liquidity positions. +- Liquidity position NFTs are non-transferable, so allowlist checks cannot be bypassed. +- The system is non-custodial: funds leave the pool only through swaps, position withdrawals, and claim redemptions, never through the virtual token directly. + + +If you are considering bringing an asset onchain and want the team to follow up, [register your interest](/uniswap-labs-hooks). +If you already have a permissioned token deployed, [request allowlisting for routing](/permissioned-pools-allowlist) instead. + + +## Where to Go Next + +- Learn how the contracts fit together in [Architecture](/docs/protocols/uniswap-labs-hooks/permissioned-pools/architecture). +- Onboard a token in [Deploy a Permissioned Pool](/docs/protocols/uniswap-labs-hooks/permissioned-pools/deploy-a-permissioned-pool). +- Integrate permissioned tokens in an app with [Swapping through Permissioned Pools](/docs/trading/swapping-api/swapping-permissioned-pools). diff --git a/content/protocols/uniswap-labs-hooks/permissioned-pools/provide-liquidity.mdx b/content/protocols/uniswap-labs-hooks/permissioned-pools/provide-liquidity.mdx new file mode 100644 index 000000000..6ae019266 --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/permissioned-pools/provide-liquidity.mdx @@ -0,0 +1,108 @@ +--- +title: Provide Liquidity in Permissioned Pools +sidebarTitle: Provide Liquidity +description: Add liquidity to a Uniswap v4 permissioned pool with the Permissioned Position Manager, including minting a position, viewing it, and how issuer recall works. +--- + +This guide walks allowlisted liquidity providers through the process of adding liquidity to a Uniswap v4 permissioned pool. It assumes familiarity with the standard Uniswap v4 liquidity provisioning flow and focuses specifically on the technical and operational differences introduced by the permissioned hook. For the deep dive into the contract details, please refer to [Architecture](/docs/protocols/uniswap-labs-hooks/permissioned-pools/architecture) first. + + +You must hold the `LIQUIDITY_ALLOWED` permission for the token. This is separate from `SWAP_ALLOWED`: a wallet allowed to swap is not automatically allowed to provide liquidity. + + +## Prerequisites + +- The connected wallet is allowlisted with `LIQUIDITY_ALLOWED` for the permissioned token. +- You use the `PermissionedPositionManager`, not the standard `PositionManager`. See [Deployment Addresses](/docs/protocols/uniswap-labs-hooks/permissioned-pools/deploy-a-permissioned-pool#deployment-addresses). +- You know the token's verified **Permissions Adapter** address. The pool uses the adapter as its currency, not the underlying token. +- The `PermissionedHooks` contract is allowed on the adapter by the adapter admin through `updateAllowedHook`, part of [Step 5 of onboarding](/docs/protocols/uniswap-labs-hooks/permissioned-pools/deploy-a-permissioned-pool#step-5-approve-virtual-token-contracts). Mints and increases revert with `InvalidHook` otherwise. + +## How Liquidity Differs From Standard v4 + +- You interact with the `PermissionedPositionManager`, which converts the token into its virtual version through the Permissions Adapter before touching the pool. +- The pool currency is the adapter address, not the underlying token. +- Minting and increasing check `LIQUIDITY_ALLOWED` twice: the position manager checks the recipient, and the hook's `beforeAddLiquidity` checks the caller. +- Position NFTs are non-transferable. `transferFrom` and `safeTransferFrom` revert with `TransferDisabled`. +- Decreasing and burning are never gated, so you can always exit, even after losing permission. +- The adapter admin can force-close your position with `unwindPosition`. + +## Step 1: Approve the Position Manager + +The position manager pulls the underlying token through Permit2, so approvals are on the **underlying permissioned token**, not the adapter. Approve Permit2 on the token, then approve the position manager as a Permit2 spender. + +```solidity +// 1. Approve Permit2 to move the underlying permissioned token. +IERC20(permissionedToken).approve(address(permit2), type(uint256).max); + +// 2. Approve the Permissioned Position Manager as a Permit2 spender. +permit2.approve(permissionedToken, address(permissionedPositionManager), type(uint160).max, type(uint48).max); +``` + +When the position manager settles, it pulls the underlying token into the Permissions Adapter, which creates the virtual version for the pool, so you never handle the virtual token yourself. + +## Step 2: Build the Pool Key + +Use the **adapter address** as the currency and `PermissionedHooks` as the hook, the same key the pool was created with. + +```solidity +PoolKey memory key = PoolKey({ + currency0: Currency.wrap(adapter), // the Permissions Adapter, not the underlying token + currency1: Currency.wrap(weth), + fee: 3000, + tickSpacing: 60, + hooks: IHooks(permissionedHooks) +}); +``` + +## Step 3: Mint a Position + +Minting uses the standard `modifyLiquidities` batch flow. Encode a `MINT_POSITION` action followed by `SETTLE_PAIR` to pay what the mint owes. The recipient must hold `LIQUIDITY_ALLOWED`, or the call reverts. + +```solidity +bytes memory actions = abi.encodePacked(uint8(Actions.MINT_POSITION), uint8(Actions.SETTLE_PAIR)); + +bytes[] memory params = new bytes[](2); +params[0] = abi.encode(key, tickLower, tickUpper, liquidity, amount0Max, amount1Max, recipient, hookData); +params[1] = abi.encode(key.currency0, key.currency1); + +PermissionedPositionManager(permissionedPositionManager).modifyLiquidities( + abi.encode(actions, params), + block.timestamp + 60 +); +``` + +On settlement, the position manager pulls the underlying token from your wallet through Permit2, deposits it into the Permissions Adapter, and the adapter mints the virtual token to the `PoolManager`. The position NFT is minted to `recipient`. + +## Step 4: Increase or Decrease Liquidity + +Use `INCREASE_LIQUIDITY` and `DECREASE_LIQUIDITY` on the same position, exactly as on standard v4. Increases check `LIQUIDITY_ALLOWED` for the position owner. Decreases and burns are never gated, so you can always withdraw, even if the wallet later loses permission or the hook is revoked. + +## Step 5: View a Position + +Positions are read through the inherited `PositionManager` accessors. + +```solidity +(PoolKey memory poolKey, PositionInfo info) = + PermissionedPositionManager(permissionedPositionManager).getPoolAndPositionInfo(tokenId); + +uint128 liquidity = PermissionedPositionManager(permissionedPositionManager).getPositionLiquidity(tokenId); +address owner = PermissionedPositionManager(permissionedPositionManager).ownerOf(tokenId); +``` + +Read raw pool state with `StateView`, the same as any v4 pool. + +## Non-Transferable Positions + +Position NFTs cannot be moved. `transferFrom` and both `safeTransferFrom` overloads revert with `TransferDisabled`. This prevents an allowlisted holder from handing a position to a disallowed address, which would bypass the allowlist. + +## Issuer Recall + +The owner of either Permissions Adapter in the pool can call `unwindPosition(tokenId)` to force-close a position. It burns the NFT, removes the liquidity, and routes each asset back to the holder. Any asset the holder can no longer receive falls back to that asset's own adapter owner (as tokens, or as an ERC-6909 claim if delivery fails), regardless of which issuer called. You can always exit a position yourself through a decrease or burn, so recall does not trap your funds. + +![An allowlisted holder mints a non-transferable position NFT; an issuer admin can unwind it, removing the liquidity and returning assets to the holder](./images/permissioned-pools-liquidity.png) + +## Where to Go Next + +- Understand the contracts in [Architecture](/docs/protocols/uniswap-labs-hooks/permissioned-pools/architecture). +- Onboard a token in [Deploy a Permissioned Pool](/docs/protocols/uniswap-labs-hooks/permissioned-pools/deploy-a-permissioned-pool). +- Integrate swaps in an app with [Swapping through Permissioned Pools](/docs/trading/swapping-api/swapping-permissioned-pools). diff --git a/content/protocols/uniswap-labs-hooks/stable-pair/concepts/block-price-caching.mdx b/content/protocols/uniswap-labs-hooks/stable-pair/concepts/block-price-caching.mdx new file mode 100644 index 000000000..d7597e614 --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/stable-pair/concepts/block-price-caching.mdx @@ -0,0 +1,27 @@ +--- +title: Block Price Caching +description: Learn why StablePair prices every swap in a block from the same cached pool price, and what that means for integrators. +--- + +On the first swap of each block, the hook reads the pool price and stores it. Every other swap in that block is priced from that same stored value, not from the live price. + +## Why + +Without the cache, a corrective swap could be split into legs, each leg facing a price slightly closer to the reference rate and paying a slightly smaller fee than the last. The split trade would pay less in total than the single trade. Caching the price at the start of the block removes the advantage: every leg sees the same inputs and pays the same rate. + +This behavior was introduced in response to a finding in the OpenZeppelin review of the fee mechanism. See [StablePair Security](/docs/protocols/uniswap-labs-hooks/stable-pair/security). + +## What it means for integrators + +- **Splitting a swap gains nothing.** Same-direction corrective swaps within a block all pay the same rate. +- **The fee does not move within a block.** A quote taken at the top of a block holds for the rest of it, even as other swaps move the actual pool price. The next block reads a fresh price and reprices. +- **The cached price can go stale inside a block.** Later swaps in a heavily traded block may see a fee derived from a price the pool has already moved away from. For pairs trading near parity the gap is small, and it is bounded to a single block. + + +While a pool is outside its band, the cached price also decides which direction counts as corrective. If a swap pushes the price across the reference rate mid-block, the fee directions invert for the remainder of that block: the newly corrective direction is charged zero and the newly adverse direction pays the decaying fee. The next block restores the correct assignment. + + +## Where to Go Next + +- [Dynamic Fees](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/dynamic-fees) +- [Swap Against a StablePair Pool](/docs/protocols/uniswap-labs-hooks/stable-pair/guides/swap) diff --git a/content/protocols/uniswap-labs-hooks/stable-pair/concepts/dynamic-fees.mdx b/content/protocols/uniswap-labs-hooks/stable-pair/concepts/dynamic-fees.mdx new file mode 100644 index 000000000..189f83d86 --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/stable-pair/concepts/dynamic-fees.mdx @@ -0,0 +1,38 @@ +--- +title: Dynamic Fees +description: Learn how StablePair sets the LP fee from the pool's distance from its reference rate and the direction of the swap. +--- + +StablePair sets the LP fee dynamically instead of charging one fixed number. Each pool is configured with a reference rate (the price the pair is expected to hold) and a narrow band around it. The hook derives the fee from that reference rate and the pool's price at the start of the block. + +## Inside the band + +Within the band, the hook sets the fee so that every buy clears at one price and every sell at another, regardless of where the spot price sits inside the band. Two swappers arriving at different moments in the band see the same quote. + + +These are pre-impact prices. The hook derives the fee from the pool price as it stands before the swap executes, so a quoted rate never includes the price impact of the swap itself. A large swap still walks the curve and realizes a worse average price than a small one. The consistency guarantee is about the fee, not the execution. + + +At exactly the reference rate, both directions are charged the configured band width. As the price drifts toward one edge, the fee for swaps pushing toward that edge falls toward zero, while the fee in the opposite direction rises toward roughly twice the band width. + +The band is defined symmetrically in price terms, so a buy-then-sell roundtrip at the two edges costs the same percentage in either direction. + +## Outside the band + +Once the price leaves the band, the hook switches regime and the fee depends on the direction of the swap. + +| Swap direction | Fee | +| :--- | :--- | +| Toward the reference rate (corrective) | A decaying fee. It starts at the far edge of the band and falls each block toward a target. See [Fee Decay](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/fee-decay). | +| Away from the reference rate (adverse) | Zero. | + +Adverse swaps pay nothing because they bring volume without extracting from the mispricing. Charging them would cost the pool activity and gain liquidity providers nothing. + + +The fee never depends on swap size. StablePair reads the pool price and the swap direction, never the amount, so a quote holds for any size. + + +## Where to Go Next + +- [Fee Decay](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/fee-decay) +- [Swap Against a StablePair Pool](/docs/protocols/uniswap-labs-hooks/stable-pair/guides/swap) diff --git a/content/protocols/uniswap-labs-hooks/stable-pair/concepts/fee-decay.mdx b/content/protocols/uniswap-labs-hooks/stable-pair/concepts/fee-decay.mdx new file mode 100644 index 000000000..14f454798 --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/stable-pair/concepts/fee-decay.mdx @@ -0,0 +1,31 @@ +--- +title: Fee Decay +description: Understand how StablePair lowers the fee on corrective swaps over time to create a progressively stronger arbitrage incentive. +--- + +When the pool price sits outside its band, the pool is mispriced against the wider market and there is an arbitrage opportunity. StablePair auctions that opportunity off rather than fixing a price for it. + +## The auction + +When the hook reads a price outside the band, the fee on corrective swaps resets to the far edge of the band (the same price an ordinary in-band swap would get) and decays from there, one step per block. As blocks pass and nobody takes it, the fee falls until someone does, and the pool collects whatever the fee is at that moment. + +Two configured parameters shape how much that turns out to be: a per-block decay factor, controlling how quickly the fee falls, and a target multiplier, controlling how low it can go. + +## The target and the incentive + +The target the fee decays toward is set by the target multiplier, applied to the pool's distance outside the band. At the maximum multiplier the target settles near twice the band width and stays roughly there however far the price has drifted. At lower multipliers the target scales up with the mispricing, so the fee is not permitted to fall as far. + +At the maximum setting this makes larger mispricings clear sooner: the floor stays put while the arbitrage on offer grows, so the fee becomes worth taking in fewer blocks. + +## Adjustment before decay + +Between blocks, the price itself moves, and the fee is adjusted before decay is applied: + +- **The price moved further out.** The fee is raised to preserve the same quoted price it would have produced at the previous, better pool price. A worsening pool price never lowers the fee. +- **The price moved back toward the reference.** The fee is capped so it can never exceed what the far edge of the band would produce at the new price, then decays from there. +- **The price crossed the reference rate, or re-entered the band and left again.** The fee resets to the far edge of the band. There is no meaningful prior fee to carry forward. + +## Where to Go Next + +- [Block Price Caching](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/block-price-caching) +- [StablePair Security](/docs/protocols/uniswap-labs-hooks/stable-pair/security) diff --git a/content/protocols/uniswap-labs-hooks/stable-pair/concepts/meta.json b/content/protocols/uniswap-labs-hooks/stable-pair/concepts/meta.json new file mode 100644 index 000000000..c78755f67 --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/stable-pair/concepts/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Concepts", + "pages": ["dynamic-fees", "fee-decay", "block-price-caching", "pool-creation"] +} diff --git a/content/protocols/uniswap-labs-hooks/stable-pair/concepts/pool-creation.mdx b/content/protocols/uniswap-labs-hooks/stable-pair/concepts/pool-creation.mdx new file mode 100644 index 000000000..64b41e013 --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/stable-pair/concepts/pool-creation.mdx @@ -0,0 +1,59 @@ +--- +title: Pool Creation and Configuration +description: Understand why StablePair pools are created only by Uniswap Labs, and where each pool's fee parameters live. +--- + +## What identifies a pool + +Every Uniswap v4 pool is identified by five values, which together form its pool key: the two currencies, a fee field, a tick spacing, and the hook. Change any one of them and it is a different pool. + +For a dynamic fee hook the fee field does not hold a rate. It holds a flag meaning that the fee is set by the hook at swap time. + +## Fee parameters are not part of pool identity + +The parameters StablePair uses to compute a fee live in the hook's own storage, keyed by pool ID, not in the pool key: + +| Parameter | What it controls | +| :--- | :--- | +| Reference rate | The price the pair is expected to hold. The fee is derived from how far the pool sits from it. | +| Optimal fee | How wide the band around the reference rate is. | +| Decay factor | How quickly the corrective fee falls each block once the price is outside the band. | +| Target multiplier | How far the corrective fee is allowed to fall. | + +Because configuration sits outside the pool key, two pools on the same pair, tick spacing, and hook cannot differ by configuration. They would be the same pool. + +## Why creation is permissioned + +That has a direct consequence: whoever creates the pool for a given pair first occupies the identity permanently, and v4 rejects creating a pool that already exists. Under open creation, anyone could create the pool for a pair ahead of its launch and fix its parameters, with a governance vote as the only remedy. + +So creation is restricted structurally. The hook's `beforeInitialize` callback reverts unconditionally, which makes `PoolManager.initialize` unusable against it. Pools are created only through the hook's own `initializePool`, restricted to a role held by a Uniswap Labs Safe, which validates and stores the fee configuration atomically with creation. + +Two guarantees follow: + +- No pool on this hook can exist without a valid fee configuration. +- No fee configuration can exist without a live pool. + +Support for a new pair is therefore a request rather than a transaction. + +## Who controls what + +| Action | Who | +| :--- | :--- | +| Create a pool and set its opening parameters | Uniswap Labs Safe | +| Change a live pool's parameters | Uniswap governance | +| Upgrade the hook | Uniswap governance | + +See [StablePair Security](/docs/protocols/uniswap-labs-hooks/stable-pair/security) for the full trust model. + +## One hook serves every pool + +Every hook entry point takes a pool key, so a single deployment handles every pair. There is one canonical StablePair hook address per chain to integrate against, listed in [Deployments](/docs/protocols/uniswap-labs-hooks/stable-pair/deployments). + + +Permissioned creation is a property of this deployment rather than of the fee mechanism. Governance is the role admin and can change who may create pools. + + +## Where to Go Next + +- [Dynamic Fees](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/dynamic-fees) +- [StablePair Deployments](/docs/protocols/uniswap-labs-hooks/stable-pair/deployments) diff --git a/content/protocols/uniswap-labs-hooks/stable-pair/deployments.mdx b/content/protocols/uniswap-labs-hooks/stable-pair/deployments.mdx new file mode 100644 index 000000000..f77a5d4b6 --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/stable-pair/deployments.mdx @@ -0,0 +1,55 @@ +--- +title: StablePair Deployments +sidebarTitle: Deployments +description: Find StablePair hook addresses and live pool parameters on Ethereum and Sepolia. +--- + +The registered v4 hook is an ERC1967 proxy. Its address is permanent and encodes the hook permission flags; the implementation behind it changes on a governance upgrade. Always integrate against the hook address. + +## Mainnet Deployments + +### Ethereum: 1 + +| Contract | Address | +| :--- | :--- | +| StablePairHook (hook) | [`0x0000113dCf4ADd69999Fad8F20F2b63F979bfcC0`](https://etherscan.io/address/0x0000113dCf4ADd69999Fad8F20F2b63F979bfcC0) | +| StablePairHook (implementation) | [`0x5f216d21b1C81346938EDDc1Df7e0111A0F64000`](https://etherscan.io/address/0x5f216d21b1C81346938EDDc1Df7e0111A0F64000) | + +## Testnet Deployments + +### Sepolia: 11155111 + +| Contract | Address | +| :--- | :--- | +| StablePairHook (hook) | [`0x2F45A94782d3e187BaB5F72448bb85d6d1d67CC0`](https://sepolia.etherscan.io/address/0x2F45A94782d3e187BaB5F72448bb85d6d1d67CC0) | +| StablePairHook (implementation) | [`0xDBc81fFadaB5ee9c9fB1c2D43Bef547EB9c64000`](https://sepolia.etherscan.io/address/0xDBc81fFadaB5ee9c9fB1c2D43Bef547EB9c64000) | + +## Pool Parameters + +Two pools are live on Ethereum. + +### USDC / USDT + +| Parameter | Value | +| :--- | :--- | +| Pool ID | `0x2b21c65d9a7dc6926ee330a1c6e5a8037fd81774f3dc066536f800128e39f634` | +| currency0 | USDC [`0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`](https://etherscan.io/address/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48) | +| currency1 | USDT [`0xdAC17F958D2ee523a2206206994597C13D831ec7`](https://etherscan.io/address/0xdAC17F958D2ee523a2206206994597C13D831ec7) | +| Fee | Dynamic (`0x800000`) | +| Tick spacing | 1 | +| Reference rate | 1 USDC = 1 USDT | + +### USDC / USDG + +| Parameter | Value | +| :--- | :--- | +| Pool ID | `0xeda62d2906d0edf26d40c793d581609552a44a87f618a98ff76ebe8dde4b7edb` | +| currency0 | USDC [`0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`](https://etherscan.io/address/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48) | +| currency1 | USDG [`0xe343167631d89B6Ffc58B88d6b7fB0228795491D`](https://etherscan.io/address/0xe343167631d89B6Ffc58B88d6b7fB0228795491D) | +| Fee | Dynamic (`0x800000`) | +| Tick spacing | 1 | +| Reference rate | 1 USDC = 1 USDG | + + +Do not hardcode pool IDs. Derive them from the pool key, and read each pool's live fee configuration from the hook rather than from this page. Parameters can be changed by governance. + diff --git a/content/protocols/uniswap-labs-hooks/stable-pair/guides/meta.json b/content/protocols/uniswap-labs-hooks/stable-pair/guides/meta.json new file mode 100644 index 000000000..a1100826b --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/stable-pair/guides/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Guides", + "pages": ["swap", "provide-liquidity"] +} diff --git a/content/protocols/uniswap-labs-hooks/stable-pair/guides/provide-liquidity.mdx b/content/protocols/uniswap-labs-hooks/stable-pair/guides/provide-liquidity.mdx new file mode 100644 index 000000000..ea741b07a --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/stable-pair/guides/provide-liquidity.mdx @@ -0,0 +1,25 @@ +--- +title: Provide Liquidity on StablePair +description: Add and remove liquidity in StablePair pools using the standard Uniswap v4 position flow. +--- + +Liquidity in a StablePair pool works exactly as it does in any Uniswap v4 pool. Use `PositionManager` as normal. There is no hook-specific calldata, no allowlist, and no deposit wrapper. + +## What the hook can and cannot do + +StablePair deliberately claims almost no power over liquidity: + +- Its remove-liquidity callbacks are switched off entirely, so it cannot block or interfere with an exit. +- It holds none of v4's return-delta permissions, so it cannot alter the amounts on a mint or a burn. +- Its add-liquidity callbacks are enabled but inert. + +The hook's only active role in a live pool is overriding the LP fee on swaps. + +## Creating pools is permissioned + +Liquidity is open to anyone, but pool creation is not. Calling `PoolManager.initialize` against this hook reverts; pools are created only by Uniswap Labs, which sets each pool's fee parameters atomically with creation. See [Pool Creation and Configuration](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/pool-creation) for why. + +## Where to Go Next + +- [StablePair Deployments](/docs/protocols/uniswap-labs-hooks/stable-pair/deployments) +- [StablePair Security](/docs/protocols/uniswap-labs-hooks/stable-pair/security) diff --git a/content/protocols/uniswap-labs-hooks/stable-pair/guides/swap.mdx b/content/protocols/uniswap-labs-hooks/stable-pair/guides/swap.mdx new file mode 100644 index 000000000..ccdaaffaa --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/stable-pair/guides/swap.mdx @@ -0,0 +1,52 @@ +--- +title: Swap Against a StablePair Pool +description: Quote and execute swaps against StablePair pools, including how to read the current dynamic fee. +--- + +Swapping against a StablePair pool uses the standard v4 swap path. The only difference is the fee: it is set by the hook at swap time, so it cannot be read from the pool key. + +## Build the pool key + +The pool uses v4's dynamic fee flag rather than a fixed fee tier. Code that assumes a static tier will not find the pool. + +```solidity +PoolKey memory key = PoolKey({ + currency0: Currency.wrap(USDC), + currency1: Currency.wrap(USDT), + fee: LPFeeLibrary.DYNAMIC_FEE_FLAG, // 0x800000, not a fee tier + tickSpacing: 1, + hooks: IHooks(0x0000113dCf4ADd69999Fad8F20F2b63F979bfcC0) +}); +``` + +## Read the current fee + +`PoolKey.fee` holds the dynamic flag, not a rate. Instead, the hook exposes a view function returning the exact LP fee a swap will be charged in the current block, per direction: + +```solidity +function getFee(PoolKey calldata key) external view returns (uint24 feeE6ZeroForOne, uint24 feeE6OneForZero); +``` + +Both values are returned in 1e6 precision, matching v4's own fee units. + +For routers and aggregators this makes quoting substantially cheaper: the fee can be computed locally rather than simulated per size. Two properties are why. + +- **Size-independent.** The fee never depends on the swap amount, so the same value applies to every size. `getFee` never reads a swap amount, and so never reverts on the basis of one. +- **Fixed for the block.** Both values are computed from the start-of-block price the next swap will see, so one read per pool per block covers every quote in that block. See [Block Price Caching](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/block-price-caching). + +The two directions differ, often substantially (outside the band one of them is zero), so quote the direction being swapped. + +`getFee` reverts with `PoolNotInitialized` if the pool was not initialized through the hook. + + +Two things the returned value is not. It is the LP fee only: if the pool has a protocol fee enabled, v4 compounds the two, taking the protocol fee from the input first and the LP fee from the remainder, and rounds the combined rate up to a whole pip. And it is pre price impact: the fee is exact, but the execution price still depends on the liquidity the swap traverses. + + +## Execute the swap + +Swap through the standard v4 router or `PoolManager` unlock flow. StablePair holds no return-delta permissions, so it never alters swap amounts. It only overrides the fee. + +## Where to Go Next + +- [Dynamic Fees](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/dynamic-fees) +- [Provide Liquidity on StablePair](/docs/protocols/uniswap-labs-hooks/stable-pair/guides/provide-liquidity) diff --git a/content/protocols/uniswap-labs-hooks/stable-pair/meta.json b/content/protocols/uniswap-labs-hooks/stable-pair/meta.json new file mode 100644 index 000000000..f3b8aca9b --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/stable-pair/meta.json @@ -0,0 +1,4 @@ +{ + "title": "StablePair Hook", + "pages": ["overview", "concepts", "guides", "deployments", "security"] +} diff --git a/content/protocols/uniswap-labs-hooks/stable-pair/overview.mdx b/content/protocols/uniswap-labs-hooks/stable-pair/overview.mdx new file mode 100644 index 000000000..94033ef53 --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/stable-pair/overview.mdx @@ -0,0 +1,37 @@ +--- +title: StablePair Overview +sidebarTitle: Overview +description: Understand StablePair, a Uniswap v4 hook that computes LP fees dynamically for pairs expected to trade at the same price. +--- + +StablePair is a dynamic fee hook built on Uniswap v4, for pools whose two assets are expected to trade at the same price: USDC/USDT, or WBTC/cbBTC. Rather than charging one static fee, the hook sets the LP fee on every swap from how far the pool price has drifted from a configured reference rate and which direction the swap pushes it. + +Inside a narrow band around that reference rate, where the pool sits under normal conditions, both directions pay a small fee, set so that every buy is quoted at one price and every sell at another, before the price impact of the swap itself. Once the price leaves the band the regime changes: swaps pushing it back toward the reference are charged a fee that starts high and decays each block until an arbitrageur takes it, and swaps pushing it further away pay nothing. + + +StablePair pools cannot be created permissionlessly. Calling `PoolManager.initialize` against this hook reverts; pools are created only by Uniswap Labs, which sets each pool's fee parameters atomically with creation. See [Pool Creation and Configuration](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/pool-creation). + + +## Concepts + +- [Dynamic Fees](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/dynamic-fees): how the fee is chosen for any given swap +- [Fee Decay](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/fee-decay): how corrective swaps get cheaper over time +- [Block Price Caching](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/block-price-caching): why the fee is fixed for a whole block +- [Pool Creation and Configuration](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/pool-creation): who can create pools, and where fee parameters live + +## Guides + +- [Swap Against a StablePair Pool](/docs/protocols/uniswap-labs-hooks/stable-pair/guides/swap): quote and execute swaps +- [Provide Liquidity on StablePair](/docs/protocols/uniswap-labs-hooks/stable-pair/guides/provide-liquidity): deposit and withdraw + +## Repositories + +- [Uniswap/v4-hooks-public](https://github.com/Uniswap/v4-hooks-public): hook source and tests + +## Deployments + +See [StablePair Deployments](/docs/protocols/uniswap-labs-hooks/stable-pair/deployments) for hook addresses and live pool parameters. + +## Security + +See [StablePair Security](/docs/protocols/uniswap-labs-hooks/stable-pair/security) for the trust model, protocol invariants, and audit history. diff --git a/content/protocols/uniswap-labs-hooks/stable-pair/security.mdx b/content/protocols/uniswap-labs-hooks/stable-pair/security.mdx new file mode 100644 index 000000000..45082c6d7 --- /dev/null +++ b/content/protocols/uniswap-labs-hooks/stable-pair/security.mdx @@ -0,0 +1,58 @@ +--- +title: StablePair Security +sidebarTitle: Security +description: Review StablePair's trust model, protocol invariants, and audit history. +--- + +## Audit + +OpenZeppelin reviewed the StablePair fee mechanism from February 9 to February 13, 2026. One high-severity finding, that splitting a corrective swap into legs produced a cheaper aggregate price, was resolved by caching the pool price once per block, the behavior described in [Block Price Caching](/docs/protocols/uniswap-labs-hooks/stable-pair/concepts/block-price-caching). + +The review covered the fee mechanism as implemented in the hook's non-upgradeable predecessor, which shares StablePair's core fee math. The upgradeability and role model described below postdate that review. + +## Trust Model + +### Governance + +The hook sits behind an upgradeable proxy controlled by Uniswap Governance, so the implementation can change over time as new research identifies opportunities to increase LP value capture. Even so, governance can never change the permissions that protect LP funds. + +In Uniswap v4, a hook's permissions are encoded in its address, and that address is permanent. A hook's permissions are strictly scoped, so upgrades cannot expand them. Because the flags for the remove-liquidity callbacks and for returning custom accounting deltas are switched off, no upgrade can let the hook block LP withdrawals or alter swap amounts to skim additional fees. + +A fee configuration change also resets the pool's decay state, so the next swap starts from a fresh price reading. + +### Pool creation + +A Uniswap Labs Safe holds the role that can create pools. It cannot change fee configurations, upgrade the implementation, or grant roles. + +### Roles + +| Capability | Holder | +| :--- | :--- | +| Upgrade the implementation; grant and revoke all roles | [Uniswap Governance Timelock](https://etherscan.io/address/0x1a9C8182C09F50C8318d769245beA52c32BE35BC) | +| Change a pool's fee configuration | [Uniswap Governance Timelock](https://etherscan.io/address/0x1a9C8182C09F50C8318d769245beA52c32BE35BC) | +| Create pools and set initial pool fee configuration | [Uniswap Labs Safe](https://etherscan.io/address/0xFc43582532E90Fa8726FE9cdb5FAd48f4e487d27) | + +Neither operational role can grant or revoke roles. Because the hook sits behind a proxy, the pool address survives upgrades: no liquidity migration and no re-integration when the implementation changes. + +## Core Invariants + +- The decaying fee always sits between its target and its starting value. +- Inside the band, every buy is quoted at one price and every sell at another, before price impact, for every pool price in the band. +- The swap callback never reverts. +- While a pool is outside its band, a worsening price can only raise the corrective fee, never lower it. +- Splitting a corrective swap within a block yields no fee advantage. +- No pool can exist without a valid fee configuration, and no fee configuration can exist without a live pool. +- The hook cannot block or alter a liquidity withdrawal. + +## Known Limitations + +The cached start-of-block price is intentionally stale within a block. Two consequences are accepted rather than fixed, because resolving either would restore the swap-splitting advantage the cache exists to remove: + +- Later swaps in a heavily traded block may be priced from a pool price that has already moved. +- A swap that pushes the price across the reference rate mid-block inverts the fee directions for the remainder of that block. + +Both are bounded to a single block and self-correct on the next one. + +## Quote Semantics + +`getFee` returns the LP fee a swap would pay right now, in both directions, computed from the same start-of-block price the next swap will see. It is size-independent, excludes any protocol fee, and does not account for price impact: the realized execution price of a large swap will differ from the quoted rate according to the depth of the liquidity it traverses. diff --git a/content/protocols/universal-router/concepts/commands.mdx b/content/protocols/universal-router/concepts/commands.mdx index c8f391683..0bdb3ca65 100644 --- a/content/protocols/universal-router/concepts/commands.mdx +++ b/content/protocols/universal-router/concepts/commands.mdx @@ -1,5 +1,4 @@ --- -id: technical-reference title: Universal Router Commands description: Reference Uniswap Universal Router command encoding, supported v2 commands, and composition patterns for execute flows. --- diff --git a/content/protocols/universal-router/overview.mdx b/content/protocols/universal-router/overview.mdx index 5be2d4d93..eeda6ff9f 100644 --- a/content/protocols/universal-router/overview.mdx +++ b/content/protocols/universal-router/overview.mdx @@ -1,6 +1,29 @@ --- -title: Overview +title: Universal Router Overview +sidebarTitle: Overview description: Learn how Uniswap Universal Router composes v2, v3, and v4 swaps with Permit2-based approvals in one transaction. +keywords: + - universal-router + - swaprouter + - command-encoding + - permit2 + - router-address +faqs: + - question: How does Universal Router command encoding work? + answer: |- + You call execute(commands, inputs), optionally with a deadline. The commands argument is a byte string where each byte is one operation, and inputs is a parallel array holding the ABI-encoded parameters for each command. The router walks the command stream in order and dispatches each byte to its module, so a single transaction can chain swaps across v2, v3, and v4, Permit2 permits, ETH wrapping, payments, and position-manager calls. The low 7 bits of each byte select the command, and the high bit is an allow-revert flag. + - question: How is Universal Router different from SwapRouter? + answer: |- + SwapRouter (SwapRouter02) exposed fixed functions tightly coupled to v2 and v3, so each call ran a scripted sequence. Universal Router is command-based: the caller composes an arbitrary ordered list of operations, so it aggregates v2, v3, and v4 swaps, Permit2 approvals, ETH wrapping, and position-manager actions in one transaction, and it supports splitting, interleaving, and partial fills. It is unowned and non-upgradeable. New integrations should target Universal Router rather than the legacy SwapRouter. + - question: Which Universal Router address should I use for each chain? + answer: |- + Universal Router is deployed at a different address on each chain and per router version, so do not hardcode a single address. The current per-chain addresses are published in Supported Chains and Tokens, and the canonical source of truth is maintained in the universal-router-sdk constants on GitHub. Whitelist the address for the specific chain and version you integrate. + - question: How do I enable partial fills with Universal Router? + answer: |- + Set the high bit (0x80) on a command byte to mark it allow-revert. If that command fails, the rest of the transaction still executes, which is how partial fills work. For example, 0x80 combined with 0x00 is a V3_SWAP_EXACT_IN that is allowed to revert. When you use allow-revert, include a cleanup command such as SWEEP so no funds are stranded in the router. + - question: Do I need Permit2 to use Universal Router? + answer: |- + Universal Router pulls a user's ERC-20 tokens through Permit2, so the user first approves the Permit2 contract once per token and then authorizes the router by signature. Native ETH does not require Permit2. See the Permit2 documentation for allowance and signature-transfer patterns. --- The `UniversalRouter` is an ETH and ERC20 swap router that aggregates trades across Uniswap v2, v3, and v4. It is unowned and non-upgradeable. @@ -26,6 +49,71 @@ You call `execute(...)` with a `commands` byte string and a parallel `inputs` ar See [Permit2 documentation](/docs/protocols/permit2/overview) for allowance and signature-transfer patterns. +## FAQ + +
+ How does Universal Router command encoding work? + + + + You call `execute(commands, inputs)`, optionally with a `deadline`. The `commands` argument is a byte string where each byte is one operation, and `inputs` is a parallel array holding the ABI-encoded parameters for each command. The router walks the command stream in order and dispatches each byte to its module, so a single transaction can chain swaps across v2, v3, and v4, Permit2 permits, ETH wrapping, payments, and position-manager calls. The low 7 bits of each byte select the command, and the high bit is an allow-revert flag. + + See [Universal Router Commands](/docs/protocols/universal-router/concepts/commands) for the full command table. + + + +
+ +
+ How is Universal Router different from SwapRouter? + + + + `SwapRouter` (SwapRouter02) exposed fixed functions tightly coupled to v2 and v3, so each call ran a scripted sequence. Universal Router is command-based: the caller composes an arbitrary ordered list of operations, so it aggregates v2, v3, and v4 swaps, Permit2 approvals, ETH wrapping, and position-manager actions in one transaction, and it supports splitting, interleaving, and partial fills. It is unowned and non-upgradeable. New integrations should target Universal Router rather than the legacy `SwapRouter`. + + + +
+ +
+ Which Universal Router address should I use for each chain? + + + + Universal Router is deployed at a different address on each chain and per router version, so do not hardcode a single address. The current per-chain addresses are published in [Supported Chains & Tokens](/docs/trading/swapping-api/supported-chains#supported-chains-for-swapping), and the canonical source of truth is maintained in the [universal-router-sdk constants](https://github.com/Uniswap/sdks/blob/main/sdks/universal-router-sdk/src/utils/constants.ts) on GitHub. Whitelist the address for the specific chain and version you integrate. + + + +
+ +
+ How do I enable partial fills with Universal Router? + + + + Set the high bit (`0x80`) on a command byte to mark it allow-revert. If that command fails, the rest of the transaction still executes, which is how partial fills work: + + ```solidity + command = 0x80 | 0x00; // V3_SWAP_EXACT_IN with allow-revert + ``` + + When you use allow-revert, include a cleanup command such as `SWEEP` so no funds are stranded in the router. + + + +
+ +
+ Do I need Permit2 to use Universal Router? + + + + Universal Router pulls a user's ERC-20 tokens through Permit2, so the user first approves the Permit2 contract once per token and then authorizes the router by signature. Native ETH does not require Permit2. See the [Permit2 documentation](/docs/protocols/permit2/overview) for allowance and signature-transfer patterns. + + + +
+ ## Where to Go Next - Review command encoding in [Universal Router Commands](/docs/protocols/universal-router/concepts/commands) diff --git a/content/protocols/v2/audits.mdx b/content/protocols/v2/audits.mdx index d24aaa7e8..86cf16b0b 100644 --- a/content/protocols/v2/audits.mdx +++ b/content/protocols/v2/audits.mdx @@ -1,5 +1,6 @@ --- -title: Audits +title: Uniswap v2 Audits +sidebarTitle: Audits description: Learn about the audits for Uniswap v2 --- diff --git a/content/protocols/v2/concepts/architecture.mdx b/content/protocols/v2/concepts/architecture.mdx index 6d7700012..204b20194 100644 --- a/content/protocols/v2/concepts/architecture.mdx +++ b/content/protocols/v2/concepts/architecture.mdx @@ -1,5 +1,6 @@ --- -title: Architecture +title: Uniswap v2 Architecture +sidebarTitle: Architecture description: Understand Uniswap v2 core and periphery contracts and the design decisions behind pair behavior and routing. --- diff --git a/content/protocols/v2/concepts/flash-swap.mdx b/content/protocols/v2/concepts/flash-swap.mdx index 26a510994..80ed72dc8 100644 --- a/content/protocols/v2/concepts/flash-swap.mdx +++ b/content/protocols/v2/concepts/flash-swap.mdx @@ -1,5 +1,6 @@ --- -title: Flash Swaps +title: Uniswap v2 Flash Swaps +sidebarTitle: Flash Swaps description: Withdraw up to the full reserves of any ERC20 token on Uniswap v2 and execute arbitrary logic at no upfront cost. --- diff --git a/content/protocols/v2/concepts/meta-transactions.mdx b/content/protocols/v2/concepts/meta-transactions.mdx index 77c110f8a..f6fc92126 100644 --- a/content/protocols/v2/concepts/meta-transactions.mdx +++ b/content/protocols/v2/concepts/meta-transactions.mdx @@ -1,5 +1,4 @@ --- -id: supporting-meta-transactions title: Supporting meta transactions description: Understand meta-transaction approvals in Uniswap v2 with permit, domain separators, and EIP-712 signatures. --- diff --git a/content/protocols/v2/concepts/oracles.mdx b/content/protocols/v2/concepts/oracles.mdx index aef49c78d..e3bd0a70b 100644 --- a/content/protocols/v2/concepts/oracles.mdx +++ b/content/protocols/v2/concepts/oracles.mdx @@ -1,5 +1,6 @@ --- -title: Oracles +title: Uniswap v2 Oracles +sidebarTitle: Oracles description: Understand Uniswap v2 oracle design and use cumulative prices to build manipulation-resistant TWAP feeds. --- diff --git a/content/protocols/v2/concepts/pools.mdx b/content/protocols/v2/concepts/pools.mdx index 6775c940a..13162c0ea 100644 --- a/content/protocols/v2/concepts/pools.mdx +++ b/content/protocols/v2/concepts/pools.mdx @@ -1,5 +1,4 @@ --- -id: pools title: Pools description: Understand Uniswap v2 pools, LP shares, and how reserve balances and fees affect liquidity outcomes. --- diff --git a/content/protocols/v2/concepts/pricing.mdx b/content/protocols/v2/concepts/pricing.mdx index 38e16a619..cbb8b2ab9 100644 --- a/content/protocols/v2/concepts/pricing.mdx +++ b/content/protocols/v2/concepts/pricing.mdx @@ -1,6 +1,6 @@ --- -id: pricing -title: Pricing +title: Uniswap v2 Pricing +sidebarTitle: Pricing description: Understand Uniswap v2 pricing mechanics, oracle-safe quoting, and exact input and output trade calculations. --- diff --git a/content/protocols/v2/concepts/swapping.mdx b/content/protocols/v2/concepts/swapping.mdx index 7767aaeda..b7a803617 100644 --- a/content/protocols/v2/concepts/swapping.mdx +++ b/content/protocols/v2/concepts/swapping.mdx @@ -1,5 +1,6 @@ --- -title: Swaps +title: Uniswap v2 Swaps +sidebarTitle: Swaps description: Understand how Uniswap v2 swaps move reserves and how token transfers are validated during execution. --- diff --git a/content/protocols/v2/concepts/understanding-returns.mdx b/content/protocols/v2/concepts/understanding-returns.mdx index 6beed2273..773dc3155 100644 --- a/content/protocols/v2/concepts/understanding-returns.mdx +++ b/content/protocols/v2/concepts/understanding-returns.mdx @@ -1,5 +1,4 @@ --- -id: understanding-returns title: Understanding Returns description: Understand Uniswap v2 LP return drivers, including fee income, divergence loss, and market volatility effects. --- @@ -46,7 +45,7 @@ So let’s look at the impact of a price change on a liquidity provider. To keep "Of course, if the price were to return to the same value as when the liquidity provider added their liquidity, this loss would disappear. **For this reason, we can call it an **impermanent loss**.** Using the equations above, we can derive a formula for the size of the impermanent loss in terms of the price ratio between when liquidity was supplied and now. We get the following:" -- "`impermanent_loss = 2 * sqrt(price_ratio) / (1+price_ratio) — 1`" +- "`impermanent_loss = 2 * sqrt(price_ratio) / (1+price_ratio) - 1`" - "Which we can plot out to get a general sense of the scale of the impermanent loss at different price ratios:" ![](https://firebasestorage.googleapis.com/v0/b/firescript-577a2.appspot.com/o/imgs%2Fapp%2Fdnazarov%2FOscQ_nmzbA.png?alt=media&token=4dff866e-a740-4121-9da4-9c9105baa404) diff --git a/content/protocols/v2/deployments.mdx b/content/protocols/v2/deployments.mdx index 1ec5aea21..4d7d78465 100644 --- a/content/protocols/v2/deployments.mdx +++ b/content/protocols/v2/deployments.mdx @@ -1,8 +1,13 @@ --- -title: Deployments +title: Uniswap v2 Deployments +sidebarTitle: Deployments description: Find Uniswap v2 factory and router deployment addresses across supported networks. --- + + All Uniswap v2 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + Contract addresses for the [`Uniswap v2 Factory`](https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Factory.sol) and the [`Uniswap v2 Router02`](https://github.com/Uniswap/v2-periphery/blob/master/contracts/UniswapV2Router02.sol). | Network | Factory Contract Address | V2Router02 Contract Address | @@ -23,3 +28,4 @@ Contract addresses for the [`Uniswap v2 Factory`](https://github.com/Uniswap/v2- | MegaETH | `0xbf56488c857a881ae7e3bed27cf99c10a7ab7e50` | `0xb73055db2b3a3eae87a331dd88e4a80b43602690` | | Tempo | `0xf9ec577a4e45b5278bb7cf60fcbc20c3acaef68f` | `0x0fbac3c46f6f83b44c7fb4ea986d7309c701d73e` | | Robinhood Chain | `0x8bceaa40b9acdfaedf85adf4ff01f5ad6517937f` | `0x89e5db8b5aa49aa85ac63f691524311aeb649eba` | +| HyperEVM | `0x89e5DB8B5aA49aA85AC63f691524311AEB649eba` | `0x1f7d7550B1b028f7571E69A784071F0205FD2EfA` | diff --git a/content/protocols/v2/guides/building-an-oracle.mdx b/content/protocols/v2/guides/building-an-oracle.mdx index bd91e627d..e7a688553 100644 --- a/content/protocols/v2/guides/building-an-oracle.mdx +++ b/content/protocols/v2/guides/building-an-oracle.mdx @@ -1,5 +1,4 @@ --- -id: building-an-oracle title: Building an Oracle description: Build a Uniswap v2 TWAP oracle using cumulative prices, observation windows, and resilient maintenance patterns. --- diff --git a/content/protocols/v2/guides/flash-swaps.mdx b/content/protocols/v2/guides/flash-swaps.mdx index 3441e1320..ccd35ace8 100644 --- a/content/protocols/v2/guides/flash-swaps.mdx +++ b/content/protocols/v2/guides/flash-swaps.mdx @@ -1,6 +1,6 @@ --- -id: using-flash-swaps -title: Flash Swaps +title: Implementing Flash Swaps on Uniswap v2 +sidebarTitle: Flash Swaps description: Implement Uniswap v2 flash swaps by handling callbacks, validating pair context, and repaying with required fees. --- diff --git a/content/protocols/v2/guides/getting-pair-addresses.mdx b/content/protocols/v2/guides/getting-pair-addresses.mdx index 6a93911a3..c86253220 100644 --- a/content/protocols/v2/guides/getting-pair-addresses.mdx +++ b/content/protocols/v2/guides/getting-pair-addresses.mdx @@ -1,6 +1,6 @@ --- -id: getting-pair-addresses -title: Pair Addresses +title: Uniswap v2 Pair Addresses +sidebarTitle: Pair Addresses description: Compute deterministic Uniswap v2 pair addresses with CREATE2 and verify pair ordering and factory inputs. --- diff --git a/content/protocols/v2/guides/providing-liquidity.mdx b/content/protocols/v2/guides/providing-liquidity.mdx index fb3615a25..de1c2c76e 100644 --- a/content/protocols/v2/guides/providing-liquidity.mdx +++ b/content/protocols/v2/guides/providing-liquidity.mdx @@ -1,5 +1,4 @@ --- -id: providing-liquidity title: Providing Liquidity description: Provide Uniswap v2 liquidity safely by matching reserve ratios and applying slippage-aware minting logic. --- diff --git a/content/protocols/v2/guides/swapping.mdx b/content/protocols/v2/guides/swapping.mdx index 796f6b68e..bf4e064cf 100644 --- a/content/protocols/v2/guides/swapping.mdx +++ b/content/protocols/v2/guides/swapping.mdx @@ -1,5 +1,4 @@ --- -id: trading-from-a-smart-contract title: Implement a Swap description: Implement Uniswap v2 swaps from smart contracts using router functions and external price safety checks. --- diff --git a/content/protocols/v2/guides/troubleshooting.mdx b/content/protocols/v2/guides/troubleshooting.mdx index e7334bb14..ef8a3204d 100644 --- a/content/protocols/v2/guides/troubleshooting.mdx +++ b/content/protocols/v2/guides/troubleshooting.mdx @@ -64,3 +64,5 @@ The transaction deadline elapsed before inclusion onchain. ### Unable To Approve Transaction On The Front End Some tokens block direct allowance increases. Setting allowance to zero first, then setting the target amount, usually resolves this. + +For developer support, reach out to our team through the Help Center. diff --git a/content/protocols/v2/overview.mdx b/content/protocols/v2/overview.mdx index 4671ddcfe..53d61e347 100644 --- a/content/protocols/v2/overview.mdx +++ b/content/protocols/v2/overview.mdx @@ -1,5 +1,6 @@ --- -title: Overview +title: Uniswap v2 Protocol Overview +sidebarTitle: Overview description: Get started with Uniswap v2 concepts, guides, deployments, and security references for protocol integrations. --- diff --git a/content/protocols/v3/audits.mdx b/content/protocols/v3/audits.mdx index 57e9a9e7a..7479a699e 100644 --- a/content/protocols/v3/audits.mdx +++ b/content/protocols/v3/audits.mdx @@ -1,5 +1,6 @@ --- -title: Audits +title: Uniswap v3 Audits +sidebarTitle: Audits description: Learn about the audits for Uniswap v3 --- diff --git a/content/protocols/v3/concepts/architecture.mdx b/content/protocols/v3/concepts/architecture.mdx index d4e94922f..01076817c 100644 --- a/content/protocols/v3/concepts/architecture.mdx +++ b/content/protocols/v3/concepts/architecture.mdx @@ -1,6 +1,6 @@ --- -id: overview -title: Architecture +title: Uniswap v3 Architecture +sidebarTitle: Architecture description: Understand Uniswap v3 architecture, including core contracts, factory design, and pool interaction patterns. --- @@ -38,6 +38,29 @@ Pools primarily serve as automated market makers for the paired assets. Addition Source code: [UniswapV3Pool.sol](https://github.com/Uniswap/uniswap-v3-core/blob/main/contracts/UniswapV3Pool.sol)
+### Core libraries + +The pool contract delegates most of its arithmetic to a set of libraries. They are the contracts a v3 integration reads most often when reasoning about ticks, prices and liquidity, and each one is small enough to read end to end. + +| Library | What it does | +| --- | --- | +| [TickMath](https://github.com/Uniswap/uniswap-v3-core/blob/main/contracts/libraries/TickMath.sol) | Computes sqrt prices from ticks and vice versa, for ticks of size 1.0001 | +| [SqrtPriceMath](https://github.com/Uniswap/uniswap-v3-core/blob/main/contracts/libraries/SqrtPriceMath.sol) | Price and amount functions based on Q64.96 sqrt price and liquidity | +| [SwapMath](https://github.com/Uniswap/uniswap-v3-core/blob/main/contracts/libraries/SwapMath.sol) | Computes the result of a swap within a single tick | +| [FullMath](https://github.com/Uniswap/uniswap-v3-core/blob/main/contracts/libraries/FullMath.sol) | 512-bit multiply and divide without loss of precision | +| [LiquidityMath](https://github.com/Uniswap/uniswap-v3-core/blob/main/contracts/libraries/LiquidityMath.sol) | Adds a signed liquidity delta to liquidity | +| [TickBitmap](https://github.com/Uniswap/uniswap-v3-core/blob/main/contracts/libraries/TickBitmap.sol) | Packed record of which ticks are initialized | +| [Tick](https://github.com/Uniswap/uniswap-v3-core/blob/main/contracts/libraries/Tick.sol) | Per-tick state, including liquidity and fee growth | +| [Position](https://github.com/Uniswap/uniswap-v3-core/blob/main/contracts/libraries/Position.sol) | Per-position state, keyed by owner and tick range | + +Alongside these sit the numeric helpers the pool uses internally: `BitMath`, `FixedPoint96`, `FixedPoint128`, `LowGasSafeMath`, `SafeCast`, `UnsafeMath` and `TransferHelper`. + +Every library carries natspec on each function, so the source is the reference. + + +Source code: [libraries/](https://github.com/Uniswap/uniswap-v3-core/tree/main/contracts/libraries) + + ## Periphery The periphery is a constellation of smart contracts designed to support domain-specific interactions with the core. As the Uniswap protocol is a permissionless system, the contracts described below have no special privileges and are only a small subset of possible periphery-like contracts. diff --git a/content/protocols/v3/concepts/unsupported-tokens.mdx b/content/protocols/v3/concepts/unsupported-tokens.mdx index 2a736e6f4..7e416fcba 100644 --- a/content/protocols/v3/concepts/unsupported-tokens.mdx +++ b/content/protocols/v3/concepts/unsupported-tokens.mdx @@ -1,5 +1,4 @@ --- -id: integration-issues title: Token Integration Issues description: Understand Uniswap v3 token integration issues and how non-standard token behavior affects pool interactions. --- diff --git a/content/protocols/v3/deployments/index.mdx b/content/protocols/v3/deployments/index.mdx index 9ade174b5..20ef2c843 100644 --- a/content/protocols/v3/deployments/index.mdx +++ b/content/protocols/v3/deployments/index.mdx @@ -1,9 +1,13 @@ --- -id: deployments -title: Deployments +title: Uniswap v3 Deployments +sidebarTitle: Deployments description: Find official Uniswap v3 deployment addresses across supported networks and chain-specific references. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + ## Uniswap v3 Contract Deployments The Uniswap Protocol is made up of multiple contracts on many networks. @@ -27,6 +31,7 @@ Please do not assume contracts are deployed to the same addresses across chains, - [`MegaETH`](./v3-megaeth-deployments) - [`Tempo`](./v3-tempo-deployments) - [`Robinhood Chain`](./v3-robinhood-chain-deployments) +- [`HyperEVM`](./v3-hyperevm-deployments) These addresses are final and were deployed from these npm package versions: diff --git a/content/protocols/v3/deployments/meta.json b/content/protocols/v3/deployments/meta.json index ebe8f8dd9..bc18ab647 100644 --- a/content/protocols/v3/deployments/meta.json +++ b/content/protocols/v3/deployments/meta.json @@ -8,6 +8,7 @@ "v3-bnb-deployments", "v3-celo-deployments", "v3-ethereum-deployments", + "v3-hyperevm-deployments", "v3-megaeth-deployments", "v3-monad-deployments", "v3-tempo-deployments", diff --git a/content/protocols/v3/deployments/v3-arbitrum-deployments.mdx b/content/protocols/v3/deployments/v3-arbitrum-deployments.mdx index 78046d505..72c458428 100644 --- a/content/protocols/v3/deployments/v3-arbitrum-deployments.mdx +++ b/content/protocols/v3/deployments/v3-arbitrum-deployments.mdx @@ -1,9 +1,12 @@ --- -id: arbitrum-deployments title: Arbitrum Deployments description: Review Uniswap v3 deployment addresses and contract references for Arbitrum integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | Arbitrum Addresses | Arbitrum Sepolia Addresses | diff --git a/content/protocols/v3/deployments/v3-avalanche-deployments.mdx b/content/protocols/v3/deployments/v3-avalanche-deployments.mdx index 5a3d5d601..14daeb978 100644 --- a/content/protocols/v3/deployments/v3-avalanche-deployments.mdx +++ b/content/protocols/v3/deployments/v3-avalanche-deployments.mdx @@ -1,9 +1,12 @@ --- -id: avalanche-deployments title: Avalanche Deployments description: Review Uniswap v3 deployment addresses and contract references for Avalanche integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | AVAX Avalanche C-Chain Addresses | diff --git a/content/protocols/v3/deployments/v3-base-deployments.mdx b/content/protocols/v3/deployments/v3-base-deployments.mdx index ca9a638b1..f241de092 100644 --- a/content/protocols/v3/deployments/v3-base-deployments.mdx +++ b/content/protocols/v3/deployments/v3-base-deployments.mdx @@ -1,9 +1,12 @@ --- -id: base-deployments title: Base Deployments description: Review Uniswap v3 deployment addresses and contract references for Base integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | Base Address | Base Sepolia Address | diff --git a/content/protocols/v3/deployments/v3-bnb-deployments.mdx b/content/protocols/v3/deployments/v3-bnb-deployments.mdx index 595a6ab7b..069b7375d 100644 --- a/content/protocols/v3/deployments/v3-bnb-deployments.mdx +++ b/content/protocols/v3/deployments/v3-bnb-deployments.mdx @@ -3,6 +3,10 @@ title: BNB Deployments description: Uniswap v3 contract deployment addresses on BNB Smart Chain. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | BNB Address | diff --git a/content/protocols/v3/deployments/v3-celo-deployments.mdx b/content/protocols/v3/deployments/v3-celo-deployments.mdx index 9fe6ad52b..a3a970239 100644 --- a/content/protocols/v3/deployments/v3-celo-deployments.mdx +++ b/content/protocols/v3/deployments/v3-celo-deployments.mdx @@ -1,9 +1,12 @@ --- -id: celo-deployments title: CELO Deployments description: Review Uniswap v3 deployment addresses and contract references for Celo integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | CELO Address | Alfajores Address | diff --git a/content/protocols/v3/deployments/v3-ethereum-deployments.mdx b/content/protocols/v3/deployments/v3-ethereum-deployments.mdx index 8b2e67aae..c28bf9432 100644 --- a/content/protocols/v3/deployments/v3-ethereum-deployments.mdx +++ b/content/protocols/v3/deployments/v3-ethereum-deployments.mdx @@ -1,9 +1,12 @@ --- -id: ethereum-deployments title: Ethereum Deployments description: Review Uniswap v3 deployment addresses and contract references for Ethereum mainnet integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | Mainnet | Ethereum Sepolia Addresses | @@ -11,8 +14,8 @@ The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap | [UniswapV3Factory](https://github.com/Uniswap/uniswap-v3-core/blob/v1.0.0/contracts/UniswapV3Factory.sol) | `0x1F98431c8aD98523631AE4a59f267346ea31F984` | `0x0227628f3F023bb0B980b67D528571c95c6DaC1c` | | [Multicall](https://etherscan.io/address/0x1F98415757620B543A52E61c46B32eB19261F984#code) | `0x1F98415757620B543A52E61c46B32eB19261F984` | `` | | [Multicall2](https://etherscan.io/address/0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696#code) | `0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696` | `0xD7F33bCdb21b359c8ee6F0251d30E94832baAd07` | -| [ProxyAdmin](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.1-solc-0.7-2/contracts/proxy/ProxyAdmin.sol) | `0xB753548F6E010e7e680BA186F9Ca1BdAB2E90cf2` | `0x0b343475d44EC2b4b8243EBF81dc888BF0A14b36` | -| [TickLens](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/lens/TickLens.sol) | `0xbfd8137f7d1516D3ea5cA83523914859ec47F573` | `` | +| [ProxyAdmin](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.1-solc-0.7-2/contracts/proxy/ProxyAdmin.sol) | `0xB753548F6E010e7e680BA186F9Ca1BdAB2E90cf2` | `0x5d3ceBAb8fbA22B48d725a40452e874F24E537f4` | +| [TickLens](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/lens/TickLens.sol) | `0xbfd8137f7d1516D3ea5cA83523914859ec47F573` | `0x0b343475d44EC2b4b8243EBF81dc888BF0A14b36` | | [Quoter](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/lens/Quoter.sol) | `0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6` | `` | | [SwapRouter](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/SwapRouter.sol) | `0xE592427A0AEce92De3Edee1F18E0157C05861564` | `` | | [NFTDescriptor](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/libraries/NFTDescriptor.sol) | `0x42B24A95702b9986e82d421cC3568932790A48Ec` | `0x3B5E3c5E595D85fbFBC2a42ECC091e183E76697C` | diff --git a/content/protocols/v3/deployments/v3-hyperevm-deployments.mdx b/content/protocols/v3/deployments/v3-hyperevm-deployments.mdx new file mode 100644 index 000000000..200d5f45c --- /dev/null +++ b/content/protocols/v3/deployments/v3-hyperevm-deployments.mdx @@ -0,0 +1,54 @@ +--- +title: HyperEVM Deployments +description: Review Uniswap v3 deployment addresses and contract references for HyperEVM integrations. +--- + + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + +The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. + +HyperEVM is chainId `999` with HYPE as the gas token. Confirm any deployment on the [HyperEVM explorer](https://hyperevmscan.io). + +| Contract | HyperEVM Addresses | +| ---------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | +| [UniswapV3Factory](https://github.com/Uniswap/uniswap-v3-core/blob/v1.0.0/contracts/UniswapV3Factory.sol) | [`0xf0db7b58379503491d857dB50AC9ece64c653918`](https://hyperevmscan.io/address/0xf0db7b58379503491d857dB50AC9ece64c653918) | +| [UniswapInterfaceMulticall](https://github.com/Uniswap/v3-periphery/blob/main/contracts/lens/UniswapInterfaceMulticall.sol) | [`0x33e885eD0Ec9bF04EcfB19341582aADCb4c8A9E7`](https://hyperevmscan.io/address/0x33e885eD0Ec9bF04EcfB19341582aADCb4c8A9E7) | +| [TickLens](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/lens/TickLens.sol) | [`0x9EB8600665b55d10C1eB2316Ca5127A9cA6E2E76`](https://hyperevmscan.io/address/0x9EB8600665b55d10C1eB2316Ca5127A9cA6E2E76) | +| [Quoter](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/lens/Quoter.sol) | [`0xe29df26bce7F7e691F37f2313eA6726fc2b481B3`](https://hyperevmscan.io/address/0xe29df26bce7F7e691F37f2313eA6726fc2b481B3) | +| [QuoterV2](https://github.com/Uniswap/v3-periphery/blob/main/contracts/lens/QuoterV2.sol) | [`0x7DfD4F31be6814D2906BDE155c3e1B146EAc1468`](https://hyperevmscan.io/address/0x7DfD4F31be6814D2906BDE155c3e1B146EAc1468) | +| [MixedRouteQuoterV2](https://github.com/Uniswap/swap-router-contracts/blob/main/contracts/lens/MixedRouteQuoterV2.sol) | [`0xD6A1239f7d0A47420349a80a4406EAa7a1283576`](https://hyperevmscan.io/address/0xD6A1239f7d0A47420349a80a4406EAa7a1283576) | +| [NFTDescriptor](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/libraries/NFTDescriptor.sol) | [`0x2E9D45Bb7b30549F5216813aDA9a6b7982C5B3ED`](https://hyperevmscan.io/address/0x2E9D45Bb7b30549F5216813aDA9a6b7982C5B3ED) | +| [NonfungibleTokenPositionDescriptor](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/NonfungibleTokenPositionDescriptor.sol) | [`0x73991a25C818Bf1f1128dEAaB1492D45638DE0D3`](https://hyperevmscan.io/address/0x73991a25C818Bf1f1128dEAaB1492D45638DE0D3) | +| [NonfungiblePositionManager](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/NonfungiblePositionManager.sol) | [`0x39654A85A4C05127f5Fd6ED22CAeC077A0fB1377`](https://hyperevmscan.io/address/0x39654A85A4C05127f5Fd6ED22CAeC077A0fB1377) | +| [V3Migrator](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/V3Migrator.sol) | [`0x384461c47446324EC0D861aD902fc3935c969B5c`](https://hyperevmscan.io/address/0x384461c47446324EC0D861aD902fc3935c969B5c) | +| [SwapRouter](https://github.com/Uniswap/uniswap-v3-periphery/blob/v1.0.0/contracts/SwapRouter.sol) | [`0xfF8137B0E0B9EF7021850B5124987C51E5424A9E`](https://hyperevmscan.io/address/0xfF8137B0E0B9EF7021850B5124987C51E5424A9E) | +| [SwapRouter02](https://github.com/Uniswap/swap-router-contracts/blob/main/contracts/SwapRouter02.sol) | [`0x7AdF4701AbCDBc5Dcf5Cb58B526f897e048F0D11`](https://hyperevmscan.io/address/0x7AdF4701AbCDBc5Dcf5Cb58B526f897e048F0D11) | +| [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://hyperevmscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | +| [UniversalRouter](https://github.com/Uniswap/universal-router) | [`0x9aFe3C497e19501DB228F28CdBdD29bC98F65DBa`](https://hyperevmscan.io/address/0x9aFe3C497e19501DB228F28CdBdD29bC98F65DBa) | +| [UniversalRouter 2.1.2](https://github.com/Uniswap/universal-router) | [`0xeD270A1Bcdc63cf1356D695e7f40961d4819d6bF`](https://hyperevmscan.io/address/0xeD270A1Bcdc63cf1356D695e7f40961d4819d6bF) | + +These addresses are final and were deployed from these npm package versions: + +- [`@uniswap/v3-core@1.0.0`](https://github.com/Uniswap/uniswap-v3-core/tree/v1.0.0) +- [`@uniswap/v3-periphery@1.0.0`](https://github.com/Uniswap/uniswap-v3-periphery/tree/v1.0.0) +- [`@uniswap/swap-router-contracts@1.1.0`](https://github.com/Uniswap/swap-router-contracts/tree/v1.1.0) + +## Uniswap v3 Staker + +An up-to-date list of [deploy addresses by chain is hosted on GitHub](https://github.com/Uniswap/v3-staker/releases/tag/v1.0.2) for the `UniswapV3Staker` contract. + +## Universal Router + +The `UniversalRouter` contract is the current preferred entrypoint for ERC20 and NFT swaps, replacing, among other contracts, `SwapRouter02`. An up-to-date list of [deploy addresses by chain is hosted on GitHub](https://github.com/Uniswap/universal-router/tree/main/deploy-addresses). + +## Uniswap Pool Deployments + +Every Uniswap pool is a unique instance of the `UniswapV3Pool` contract and is deployed at its own unique address. The contract source code of the pool will be auto-verified on the explorer. You can browse [HyperEVM contracts on the explorer](https://hyperevmscan.io) to confirm any deployment. + +You can look up the address of an existing pool on [Uniswap Info](https://info.uniswap.org/#/) or by calling the `getPool` function on the `UniswapV3Factory` contract. + +```solidity +getPool("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", 3000) +``` diff --git a/content/protocols/v3/deployments/v3-megaeth-deployments.mdx b/content/protocols/v3/deployments/v3-megaeth-deployments.mdx index f305a0417..006744475 100644 --- a/content/protocols/v3/deployments/v3-megaeth-deployments.mdx +++ b/content/protocols/v3/deployments/v3-megaeth-deployments.mdx @@ -1,9 +1,12 @@ --- -id: megaeth-deployments title: MegaETH Deployments description: Review Uniswap v3 deployment addresses and contract references for MegaETH integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | MegaETH Addresses | diff --git a/content/protocols/v3/deployments/v3-monad-deployments.mdx b/content/protocols/v3/deployments/v3-monad-deployments.mdx index ff814f1b6..4346bfb30 100644 --- a/content/protocols/v3/deployments/v3-monad-deployments.mdx +++ b/content/protocols/v3/deployments/v3-monad-deployments.mdx @@ -1,9 +1,12 @@ --- -id: monad-deployments title: Monad Deployments description: Review Uniswap v3 deployment addresses and contract references for Monad integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | Monad Addresses | diff --git a/content/protocols/v3/deployments/v3-optimism-deployments.mdx b/content/protocols/v3/deployments/v3-optimism-deployments.mdx index 50afc8c7a..9e8856b3d 100644 --- a/content/protocols/v3/deployments/v3-optimism-deployments.mdx +++ b/content/protocols/v3/deployments/v3-optimism-deployments.mdx @@ -1,9 +1,12 @@ --- -id: optimism-deployments title: Optimism Deployments description: Review Uniswap v3 deployment addresses and contract references for Optimism integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | Optimism Addresses | OP Sepolia Addresses SDK-Core | OP Sepolia Addresses | diff --git a/content/protocols/v3/deployments/v3-polygon-deployments.mdx b/content/protocols/v3/deployments/v3-polygon-deployments.mdx index a0c0812b0..bdea29743 100644 --- a/content/protocols/v3/deployments/v3-polygon-deployments.mdx +++ b/content/protocols/v3/deployments/v3-polygon-deployments.mdx @@ -3,6 +3,10 @@ title: Polygon Deployments description: Uniswap v3 contract deployment addresses on Polygon. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | Polygon Address | diff --git a/content/protocols/v3/deployments/v3-robinhood-chain-deployments.mdx b/content/protocols/v3/deployments/v3-robinhood-chain-deployments.mdx index 0aa52b663..0c636d7cc 100644 --- a/content/protocols/v3/deployments/v3-robinhood-chain-deployments.mdx +++ b/content/protocols/v3/deployments/v3-robinhood-chain-deployments.mdx @@ -1,9 +1,12 @@ --- -id: robinhood-chain-deployments title: Robinhood Chain Deployments description: Review Uniswap v3 deployment addresses and contract references for Robinhood Chain integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. Robinhood Chain is an Arbitrum Orbit L2 (chainId `4663`) with ETH as the gas token. Confirm any deployment on the [Robinhood Chain explorer](https://robinhoodchain.blockscout.com/). diff --git a/content/protocols/v3/deployments/v3-tempo-deployments.mdx b/content/protocols/v3/deployments/v3-tempo-deployments.mdx index c6c9b1d1f..296e3fcbe 100644 --- a/content/protocols/v3/deployments/v3-tempo-deployments.mdx +++ b/content/protocols/v3/deployments/v3-tempo-deployments.mdx @@ -1,9 +1,12 @@ --- -id: tempo-deployments title: Tempo Deployments description: Review Uniswap v3 deployment addresses and contract references for Tempo integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | Tempo Addresses | diff --git a/content/protocols/v3/deployments/v3-unichain-deployments.mdx b/content/protocols/v3/deployments/v3-unichain-deployments.mdx index 00a91fedf..c80c5f290 100644 --- a/content/protocols/v3/deployments/v3-unichain-deployments.mdx +++ b/content/protocols/v3/deployments/v3-unichain-deployments.mdx @@ -1,9 +1,12 @@ --- -id: unichain-deployments title: Unichain Deployments description: Review Uniswap v3 deployment addresses and contract references for Unichain integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | Unichain Addresses | Unichain Sepolia Addresses | diff --git a/content/protocols/v3/deployments/v3-world-chain-deployments.mdx b/content/protocols/v3/deployments/v3-world-chain-deployments.mdx index 04457c9e5..3d2f76967 100644 --- a/content/protocols/v3/deployments/v3-world-chain-deployments.mdx +++ b/content/protocols/v3/deployments/v3-world-chain-deployments.mdx @@ -3,6 +3,10 @@ title: World Chain Deployments description: Review Uniswap v3 deployment addresses and contract references for World Chain integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | WorldChain | diff --git a/content/protocols/v3/deployments/v3-xlayer-deployments.mdx b/content/protocols/v3/deployments/v3-xlayer-deployments.mdx index 7450bcaca..3511a2381 100644 --- a/content/protocols/v3/deployments/v3-xlayer-deployments.mdx +++ b/content/protocols/v3/deployments/v3-xlayer-deployments.mdx @@ -1,9 +1,12 @@ --- -id: xlayer-deployments title: X Layer Deployments description: Review Uniswap v3 deployment addresses and contract references for X Layer integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | Address | | --- | --- | diff --git a/content/protocols/v3/deployments/v3-zksync-deployments.mdx b/content/protocols/v3/deployments/v3-zksync-deployments.mdx index 7984b3abf..ec1a922ca 100644 --- a/content/protocols/v3/deployments/v3-zksync-deployments.mdx +++ b/content/protocols/v3/deployments/v3-zksync-deployments.mdx @@ -1,9 +1,12 @@ --- -id: ZKsync-deployments title: ZKsync Deployments description: Review Uniswap v3 deployment addresses and contract references for ZKsync integrations. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | ZKsync Mainnet | diff --git a/content/protocols/v3/deployments/v3-zora-deployments.mdx b/content/protocols/v3/deployments/v3-zora-deployments.mdx index e5da9f335..bc32ec834 100644 --- a/content/protocols/v3/deployments/v3-zora-deployments.mdx +++ b/content/protocols/v3/deployments/v3-zora-deployments.mdx @@ -3,6 +3,10 @@ title: Zora Deployments description: Uniswap v3 contract deployment addresses on Zora and Zora Sepolia. --- + + All Uniswap v3 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The latest version of `@uniswap/v3-core`, `@uniswap/v3-periphery`, and `@uniswap/swap-router-contracts` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. | Contract | Zora | Zora Sepolia | diff --git a/content/protocols/v3/guides/flash-swaps/calling-flash.mdx b/content/protocols/v3/guides/flash-swaps/calling-flash.mdx index f2b3442d3..e6f97afbd 100644 --- a/content/protocols/v3/guides/flash-swaps/calling-flash.mdx +++ b/content/protocols/v3/guides/flash-swaps/calling-flash.mdx @@ -1,5 +1,4 @@ --- -id: calling-flash title: Calling Flash description: Call flash swap functions on Uniswap v3 and encode parameters for callback-driven execution. --- diff --git a/content/protocols/v3/guides/flash-swaps/final-contract.mdx b/content/protocols/v3/guides/flash-swaps/final-contract.mdx index eb6bdee36..5d5e4fd6d 100644 --- a/content/protocols/v3/guides/flash-swaps/final-contract.mdx +++ b/content/protocols/v3/guides/flash-swaps/final-contract.mdx @@ -1,5 +1,4 @@ --- -id: final-contract title: The Final Contract description: Review a complete Uniswap v3 flash swap contract with callback handling and settlement logic. --- diff --git a/content/protocols/v3/guides/flash-swaps/flash-callback.mdx b/content/protocols/v3/guides/flash-swaps/flash-callback.mdx index a0c5f4a96..dd247f7c0 100644 --- a/content/protocols/v3/guides/flash-swaps/flash-callback.mdx +++ b/content/protocols/v3/guides/flash-swaps/flash-callback.mdx @@ -1,5 +1,4 @@ --- -id: flash-callback title: The Flash Callback description: Implement the Uniswap v3 flash callback to settle borrowed amounts and fees correctly. --- diff --git a/content/protocols/v3/guides/flash-swaps/getting-started.mdx b/content/protocols/v3/guides/flash-swaps/getting-started.mdx index d9e296b35..7e78a5dbc 100644 --- a/content/protocols/v3/guides/flash-swaps/getting-started.mdx +++ b/content/protocols/v3/guides/flash-swaps/getting-started.mdx @@ -1,6 +1,6 @@ --- -id: inheritance-constructors -title: Get Started +title: Get Started with Uniswap v3 Flash Swaps +sidebarTitle: Get Started description: Set up a Uniswap v3 flash swap environment and prepare the contract workflow end to end. --- diff --git a/content/protocols/v3/guides/getting-started.mdx b/content/protocols/v3/guides/getting-started.mdx index 402efffd9..2cb4d2167 100644 --- a/content/protocols/v3/guides/getting-started.mdx +++ b/content/protocols/v3/guides/getting-started.mdx @@ -143,3 +143,5 @@ $ npx hardhat test --network localhost - [Managing Liquidity Getting Started](/docs/protocols/v3/guides/managing-liquidity/getting-started) - [Flash Swaps Getting Started](/docs/protocols/v3/guides/flash-swaps/getting-started) - [Troubleshooting](/docs/protocols/v3/guides/troubleshooting) + +For developer support, reach out to our team through the Help Center. diff --git a/content/protocols/v3/guides/managing-liquidity/collect-fees.mdx b/content/protocols/v3/guides/managing-liquidity/collect-fees.mdx index 547056790..299d6f000 100644 --- a/content/protocols/v3/guides/managing-liquidity/collect-fees.mdx +++ b/content/protocols/v3/guides/managing-liquidity/collect-fees.mdx @@ -1,6 +1,6 @@ --- -id: collect-fees -title: Collecting Fees +title: Collecting Fees on Uniswap v3 +sidebarTitle: Collecting Fees description: Collect accrued fees from Uniswap v3 positions using NonfungiblePositionManager flows. --- diff --git a/content/protocols/v3/guides/managing-liquidity/decrease-liquidity.mdx b/content/protocols/v3/guides/managing-liquidity/decrease-liquidity.mdx index 1559a6485..dc47a6bf9 100644 --- a/content/protocols/v3/guides/managing-liquidity/decrease-liquidity.mdx +++ b/content/protocols/v3/guides/managing-liquidity/decrease-liquidity.mdx @@ -1,5 +1,4 @@ --- -id: decrease-liquidity title: Decrease Liquidity (v3) description: Decrease an existing Uniswap v3 position and collect the returned token amounts with PositionManager. --- diff --git a/content/protocols/v3/guides/managing-liquidity/getting-started.mdx b/content/protocols/v3/guides/managing-liquidity/getting-started.mdx index b803e03e5..b46bb45a2 100644 --- a/content/protocols/v3/guides/managing-liquidity/getting-started.mdx +++ b/content/protocols/v3/guides/managing-liquidity/getting-started.mdx @@ -1,5 +1,4 @@ --- -id: setting-up title: Set Up Your Contract description: Set up a Uniswap v3 liquidity management contract workflow with position lifecycle prerequisites. --- diff --git a/content/protocols/v3/guides/managing-liquidity/increase-liquidity.mdx b/content/protocols/v3/guides/managing-liquidity/increase-liquidity.mdx index bbb9e0137..9dfd25070 100644 --- a/content/protocols/v3/guides/managing-liquidity/increase-liquidity.mdx +++ b/content/protocols/v3/guides/managing-liquidity/increase-liquidity.mdx @@ -1,5 +1,4 @@ --- -id: increase-liquidity title: Increase Liquidity (v3) description: Increase an existing Uniswap v3 position using PositionManager while preserving the position range. --- diff --git a/content/protocols/v3/guides/managing-liquidity/mint-a-position.mdx b/content/protocols/v3/guides/managing-liquidity/mint-a-position.mdx index 121553ba7..738799b72 100644 --- a/content/protocols/v3/guides/managing-liquidity/mint-a-position.mdx +++ b/content/protocols/v3/guides/managing-liquidity/mint-a-position.mdx @@ -1,5 +1,4 @@ --- -id: mint-a-position title: Mint a New Position description: Mint a new Uniswap v3 liquidity position with token approvals, ranges, and position parameters. --- diff --git a/content/protocols/v3/guides/managing-liquidity/the-full-contract.mdx b/content/protocols/v3/guides/managing-liquidity/the-full-contract.mdx index 004129b2e..48c9fb0b1 100644 --- a/content/protocols/v3/guides/managing-liquidity/the-full-contract.mdx +++ b/content/protocols/v3/guides/managing-liquidity/the-full-contract.mdx @@ -1,5 +1,4 @@ --- -id: the-full-contract title: The Full Contract description: Review a complete Uniswap v3 liquidity management contract covering mint, adjust, and collect flows. --- diff --git a/content/protocols/v3/guides/swapping/getting-started.mdx b/content/protocols/v3/guides/swapping/getting-started.mdx index 68a559ca5..ac40dc146 100644 --- a/content/protocols/v3/guides/swapping/getting-started.mdx +++ b/content/protocols/v3/guides/swapping/getting-started.mdx @@ -1,5 +1,6 @@ --- -title: Get Started +title: Get Started with Uniswap v3 Swapping +sidebarTitle: Get Started description: Start Uniswap v3 swap integrations with single-hop and multi-hop guide paths and implementation references. --- diff --git a/content/protocols/v3/guides/troubleshooting.mdx b/content/protocols/v3/guides/troubleshooting.mdx index 3039e5e80..ef74fffe7 100644 --- a/content/protocols/v3/guides/troubleshooting.mdx +++ b/content/protocols/v3/guides/troubleshooting.mdx @@ -55,3 +55,5 @@ Use this reference to map common Uniswap v3 error codes to likely failure causes - `L`: Liquidity in the pool must be greater than zero for a flash to execute - `F0`: Token0 balance before flash must be less than, or equal to, token0 balance after flash plus fee - `F1`: Token1 balance before flash must be less than, or equal to, token1 balance after flash plus fee + +For developer support, reach out to our team through the Help Center. diff --git a/content/protocols/v3/overview.mdx b/content/protocols/v3/overview.mdx index a9f752c5e..1c70b7d01 100644 --- a/content/protocols/v3/overview.mdx +++ b/content/protocols/v3/overview.mdx @@ -1,5 +1,6 @@ --- -title: Overview +title: Uniswap v3 Protocol Overview +sidebarTitle: Overview description: Get started with Uniswap v3 concepts, guides, and security references for protocol integrations. --- diff --git a/content/protocols/v4/concepts/architecture.mdx b/content/protocols/v4/concepts/architecture.mdx index e30ab0266..3d48e6f2f 100644 --- a/content/protocols/v4/concepts/architecture.mdx +++ b/content/protocols/v4/concepts/architecture.mdx @@ -1,5 +1,6 @@ --- -title: Architecture +title: Uniswap v4 Architecture +sidebarTitle: Architecture description: Understand the core design pillars of Uniswap v4, including hooks, singleton architecture, and flash accounting. --- @@ -43,3 +44,31 @@ Example use cases: - Custom curves, opting out of the concentrated liquidity curve in favor of an independent pricing mechanism - Hook swap fees, charging and collecting fees on swaps - Liquidity withdrawal fees, penalizing and/or redistributing fee revenue + +## Core libraries + +The `PoolManager` delegates most of its arithmetic and state handling to a set of libraries in `v4-core`. These are the contracts a v4 integration reads when reasoning about ticks, prices, deltas and hook permissions. + +| Library | What it does | +| --- | --- | +| [TickMath](https://github.com/Uniswap/v4-core/blob/main/src/libraries/TickMath.sol) | Computes sqrt prices from ticks and vice versa | +| [SqrtPriceMath](https://github.com/Uniswap/v4-core/blob/main/src/libraries/SqrtPriceMath.sol) | Price and amount functions based on Q64.96 sqrt price and liquidity | +| [SwapMath](https://github.com/Uniswap/v4-core/blob/main/src/libraries/SwapMath.sol) | Computes the result of a swap within a single tick | +| [Pool](https://github.com/Uniswap/v4-core/blob/main/src/libraries/Pool.sol) | Every action that can be performed on a pool | +| [Position](https://github.com/Uniswap/v4-core/blob/main/src/libraries/Position.sol) | Per-position state, keyed by owner and tick range | +| [CurrencyDelta](https://github.com/Uniswap/v4-core/blob/main/src/libraries/CurrencyDelta.sol) | Stores callers' currency deltas in transient storage, the basis of flash accounting | +| [TransientStateLibrary](https://github.com/Uniswap/v4-core/blob/main/src/libraries/TransientStateLibrary.sol) | Reads the transient state the manager keeps during a lock | +| [ProtocolFeeLibrary](https://github.com/Uniswap/v4-core/blob/main/src/libraries/ProtocolFeeLibrary.sol) | Packs and reads the protocol fee for each swap direction | +| [FullMath](https://github.com/Uniswap/v4-core/blob/main/src/libraries/FullMath.sol) | 512-bit multiply and divide without loss of precision | +| [LiquidityMath](https://github.com/Uniswap/v4-core/blob/main/src/libraries/LiquidityMath.sol) | Adds a signed liquidity delta to liquidity | +| [TickBitmap](https://github.com/Uniswap/v4-core/blob/main/src/libraries/TickBitmap.sol) | Packed record of which ticks are initialized | + +Three libraries have their own pages rather than a row here, because they carry concepts rather than arithmetic: [Hooks](/docs/protocols/v4/concepts/hooks), [LPFeeLibrary](/docs/protocols/v4/concepts/dynamic-fees) and [StateLibrary](/docs/protocols/v4/guides/state-view). + +Alongside these sit the numeric and encoding helpers: `BitMath`, `FixedPoint96`, `FixedPoint128`, `SafeCast`, `UnsafeMath`, `CustomRevert`, `ParseBytes`, `Lock`, `NonzeroDeltaCount` and `CurrencyReserves`. + +Every library carries natspec on each function, so the source is the reference. + + +Source code: [src/libraries/](https://github.com/Uniswap/v4-core/tree/main/src/libraries) + diff --git a/content/protocols/v4/concepts/erc-6909.mdx b/content/protocols/v4/concepts/erc-6909.mdx index 0fbe23014..7f97601d9 100644 --- a/content/protocols/v4/concepts/erc-6909.mdx +++ b/content/protocols/v4/concepts/erc-6909.mdx @@ -1,5 +1,6 @@ --- -title: ERC-6909 +title: ERC-6909 in Uniswap v4 +sidebarTitle: ERC-6909 description: Learn how ERC-6909 supports efficient token accounting flows in Uniswap v4. --- diff --git a/content/protocols/v4/concepts/flash-accounting.mdx b/content/protocols/v4/concepts/flash-accounting.mdx index 73b8d8e32..892cdd48d 100644 --- a/content/protocols/v4/concepts/flash-accounting.mdx +++ b/content/protocols/v4/concepts/flash-accounting.mdx @@ -1,5 +1,6 @@ --- -title: Flash Accounting +title: Uniswap v4 Flash Accounting +sidebarTitle: Flash Accounting description: Understand flash accounting in Uniswap v4 and how deltas reduce transfer overhead. --- diff --git a/content/protocols/v4/concepts/hook-routing.mdx b/content/protocols/v4/concepts/hook-routing.mdx index 4aa8e9cef..86099c4c4 100644 --- a/content/protocols/v4/concepts/hook-routing.mdx +++ b/content/protocols/v4/concepts/hook-routing.mdx @@ -17,7 +17,9 @@ For implementation details, check [UniswapX Documentation](/docs/liquidity/unisw ## Hook Allowlisting -If you have built a hook that you would like to have allowlisted, fill out the [hook allowlisting form](https://www.notion.so/uniswaplabs/1aec52b2548b80f78dbef8d2f0d7183e). +If you have built a hook that you would like to have allowlisted, fill out the [hook allowlisting form](/hook-allowlist). -You can review current allowlisted hooks in [Allowlisted Hooks](https://support.uniswap.org/hc/en-us/articles/41305283155597-Allowlisted-Hooks). +You can look up the current allowlisting criteria in [Routing for hooked pools](https://support.uniswap.org/hc/en-us/articles/48291859140621-Routing-for-hooked-pools). + +You can review current allowlisted hooks in [Allowlisted Hooks](https://github.com/Uniswap/uniroute-public/blob/main/src/lib/poolCaching/util/hooksAddressesAllowlist.ts). diff --git a/content/protocols/v4/concepts/hooks.mdx b/content/protocols/v4/concepts/hooks.mdx index cdeedd5a2..9137a03d7 100644 --- a/content/protocols/v4/concepts/hooks.mdx +++ b/content/protocols/v4/concepts/hooks.mdx @@ -1,6 +1,33 @@ --- -title: Hooks +title: Uniswap v4 Hooks +sidebarTitle: Hooks description: Learn how Uniswap v4 hooks extend pool behavior at key lifecycle execution points. +keywords: + - Uniswap v4 hooks + - hook permissions + - hook address flags + - HookMiner + - CREATE2 salt mining + - pool initialization +faqs: + - question: When do I need a hook in Uniswap v4? + answer: |- + Hooks are optional. A v4 pool works without one, using the same concentrated liquidity behavior as Uniswap v3. You need a hook only when you want to customize pool behavior at specific lifecycle points, such as running logic before or after a swap, gating who can add liquidity, applying dynamic fees, or building custom accounting. If your use case is a standard pool, you do not need to write or attach a hook. + - question: How do I deploy a hook to a valid hook address? + answer: |- + A hook contract must be deployed to an address whose low bits encode exactly the permissions it implements. Each hook function maps to a flag stored in a specific bit of the 20-byte address, so you cannot deploy a hook to an arbitrary address. To get a valid address you mine a CREATE2 salt that produces an address with the correct flag bits set, then deploy with that salt. The HookMiner helper library finds the salt, and the deployment script asserts that the deployed address matches the mined address. For local testing, Foundry's deployCodeTo cheatcode can place a hook at any address without mining. + - question: What hook permissions are available in Uniswap v4? + answer: |- + A hook declares its permissions through getHookPermissions, which returns a struct of boolean flags. The call permissions are beforeInitialize, afterInitialize, beforeAddLiquidity, afterAddLiquidity, beforeRemoveLiquidity, afterRemoveLiquidity, beforeSwap, afterSwap, beforeDonate, and afterDonate. There are also four return-delta permissions that let a hook adjust balances: beforeSwapReturnDelta, afterSwapReturnDelta, afterAddLiquidityReturnDelta, and afterRemoveLiquidityReturnDelta. A hook implements only the functions it needs, and those choices must match the flags encoded in its address. + - question: Can I add a hook to an existing pool? + answer: |- + No. The hook is part of the PoolKey and is set once when the pool is created through PoolManager.initialize. It cannot be added, removed, or swapped afterward. To use a different hook, or to add one to a pool that has none, you create a new pool with the desired hook in its key. A single hook contract can serve many pools, so you do not need to redeploy the hook itself. + - question: How do I test a Uniswap v4 hook? + answer: |- + Most hook development uses Foundry. The v4-template repository ships a preconfigured Foundry project with v4-core and v4-periphery already imported, so you can clone it, run forge test, and start from working examples. For unit tests you can deploy the hook to a valid address using the deployCodeTo cheatcode, which avoids mining during tests. You can also run a local Anvil node, deploy v4 and your hook with a Foundry script, and point the test suite at it with the rpc-url flag. + - question: What happens if the address flags do not match the implemented functions? + answer: |- + The address flags and the implemented functions must agree. If the address lacks a flag, the PoolManager never calls that hook function, so the logic silently does nothing. Permissions are also validated against the address at deployment, so declaring permissions that do not match the mined address makes the deployment fail. Mining the correct address and declaring matching permissions through getHookPermissions keeps the two in sync. --- Uniswap v4 introduces Hooks, a system that allows developers to customize and extend the behavior of liquidity pools. @@ -58,3 +85,119 @@ The introduction of hooks in Uniswap v4 opens up a world of possibilities for de - Lending hooks integrated with Uniswap v4 pools. As a hook developer you can easily bootstrap the codebase of an entirely new DeFi protocol through hook designs, which subsequently drives down your audit costs and allows you to develop faster. However, it's important to note that just because you made a hook, that does not mean you will get liquidity routed to your hook from the Uniswap frontend. + +## FAQ + +
+ When do I need a hook in Uniswap v4? + + + + Hooks are optional. A v4 pool works without one, using the same concentrated liquidity behavior as Uniswap v3. You need a hook only when you want to customize pool behavior at specific lifecycle points, such as: + + * Running logic before or after a swap + * Gating who can add or remove liquidity + * Applying dynamic fees + * Building custom accounting or a custom curve + + If your use case is a standard pool, you do not need to write or attach a hook. + + + +
+ +
+ How do I deploy a hook to a valid hook address? + + + + A hook contract must be deployed to an address whose low bits encode exactly the permissions it implements. Each hook function maps to a flag stored in a specific bit of the 20-byte address, so you cannot deploy a hook to an arbitrary address. + + To get a valid address you mine a `CREATE2` salt that produces an address with the correct flag bits set, then deploy with that salt. The [`HookMiner`](https://github.com/Uniswap/v4-periphery/blob/main/src/utils/HookMiner.sol) helper library finds the salt: + + ```solidity + uint160 flags = uint160(Hooks.AFTER_ADD_LIQUIDITY_FLAG | Hooks.AFTER_SWAP_FLAG); + bytes memory constructorArgs = abi.encode(POOLMANAGER); + (address hookAddress, bytes32 salt) = + HookMiner.find(CREATE2_DEPLOYER, flags, type(PointsHook).creationCode, constructorArgs); + ``` + + The deployment script then asserts that the deployed address matches the mined address. For local testing, Foundry's `deployCodeTo` cheatcode can place a hook at any address without mining. See [Hook Deployment](/docs/protocols/v4/guides/hooks/hook-deployment) for the full walkthrough. + + + +
+ +
+ What hook permissions are available in Uniswap v4? + + + + A hook declares its permissions through `getHookPermissions`, which returns a struct of boolean flags. The call permissions are: + + * `beforeInitialize` / `afterInitialize` + * `beforeAddLiquidity` / `afterAddLiquidity` + * `beforeRemoveLiquidity` / `afterRemoveLiquidity` + * `beforeSwap` / `afterSwap` + * `beforeDonate` / `afterDonate` + + There are also four return-delta permissions that let a hook adjust balances: `beforeSwapReturnDelta`, `afterSwapReturnDelta`, `afterAddLiquidityReturnDelta`, and `afterRemoveLiquidityReturnDelta`. A hook implements only the functions it needs, and those choices must match the flags encoded in its address. See the full flag list in [`Hooks.sol`](https://github.com/Uniswap/v4-core/blob/main/src/libraries/Hooks.sol). + + + +
+ +
+ Can I add a hook to an existing pool? + + + + No. The hook is part of the `PoolKey` and is set once when the pool is created through `PoolManager.initialize`. It cannot be added, removed, or swapped afterward. + + To use a different hook, or to add one to a pool that has none, you create a new pool with the desired hook in its key. A single hook contract can serve many pools, so you do not need to redeploy the hook itself. + + + +
+ +
+ How do I test a Uniswap v4 hook? + + + + Most hook development uses [Foundry](https://book.getfoundry.sh/). The [v4-template](https://github.com/uniswapfoundation/v4-template) repository ships a preconfigured project with `v4-core` and `v4-periphery` already imported: + + ```bash + git clone https://github.com/uniswapfoundation/v4-template.git + cd v4-template + forge install + forge test + ``` + + For unit tests you can deploy the hook to a valid address using the `deployCodeTo` cheatcode, which avoids mining during tests. You can also run a local [Anvil](https://book.getfoundry.sh/anvil/) node, deploy v4 and your hook with a Foundry script, and point the test suite at it: + + ```bash + forge test --rpc-url 127.0.0.1:8545 + ``` + + See [Hooks Overview](/docs/protocols/v4/guides/hooks/getting-started) for the full local setup. + + + +
+ +
+ What happens if the address flags do not match the implemented functions? + + + + The address flags and the implemented functions must agree: + + * If the address lacks a flag, the `PoolManager` never calls that hook function, so the logic silently does nothing. + * Permissions are validated against the address at deployment, so declaring permissions that do not match the mined address makes the deployment fail. + + Mining the correct address and declaring matching permissions through `getHookPermissions` keeps the two in sync. + + + +
diff --git a/content/protocols/v4/deployments.mdx b/content/protocols/v4/deployments.mdx index f582c3b29..c6add9ffb 100644 --- a/content/protocols/v4/deployments.mdx +++ b/content/protocols/v4/deployments.mdx @@ -1,9 +1,13 @@ --- -id: deployments -title: Deployments +title: Uniswap v4 Deployments +sidebarTitle: Deployments description: Find current Uniswap v4 core, periphery, and Universal Router deployment addresses by network. --- + + All Uniswap v4 deployment addresses are also available on the unified [Deployments](/deployments) page and its [deployments.json](/deployments.json) feed. + + The Uniswap Protocol is made up of multiple contracts on many networks. The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap/universal-router` are deployed at the addresses listed below. Integrators should **no longer assume that they are deployed to the same addresses across chains** and be extremely careful to confirm mappings below. @@ -21,6 +25,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://etherscan.io/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x66a9893cc07d91d95644aedd05d03f95e1dba8af`](https://etherscan.io/address/0x66a9893cc07d91d95644aedd05d03f95e1dba8af) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x4c82d1fbfe28c977cbb58d8c7ff8fcf9f70a2cca`](https://etherscan.io/address/0x4c82d1fbfe28c977cbb58d8c7ff8fcf9f70a2cca) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x23617e59A5925b2A4Bf75d73ff6711cD0b29De85`](https://etherscan.io/address/0x23617e59A5925b2A4Bf75d73ff6711cD0b29De85) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Unichain: 130 @@ -34,6 +39,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://uniscan.xyz/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xef740bf23acae26f6492b10de645d6b98dc8eaf3`](https://uniscan.xyz/address/0xef740bf23acae26f6492b10de645d6b98dc8eaf3) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7`](https://uniscan.xyz/address/0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xD1b797D92d87B688193A2B976eFc8D577D204343`](https://uniscan.xyz/address/0xD1b797D92d87B688193A2B976eFc8D577D204343) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://uniscan.xyz/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Optimism: 10 @@ -47,6 +53,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://optimistic.etherscan.io/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x851116d9223fabed8e56c0e6b8ad0c31d98b3507`](https://optimistic.etherscan.io/address/0x851116d9223fabed8e56c0e6b8ad0c31d98b3507) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8b844f885672f333bc0042cb669255f93a4c1e6b`](https://optimistic.etherscan.io/address/0x8b844f885672f333bc0042cb669255f93a4c1e6b) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xC09255D86DB563cBc11C2fCf4a0C512e160111B4`](https://optimistic.etherscan.io/address/0xC09255D86DB563cBc11C2fCf4a0C512e160111B4) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://optimistic.etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Base: 8453 @@ -60,6 +67,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://basescan.org/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x6ff5693b99212da76ad316178a184ab56d299b43`](https://basescan.org/address/0x6ff5693b99212da76ad316178a184ab56d299b43) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7`](https://basescan.org/address/0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xd6145b2D3F379919E8CdEda7B97e37c4b2Ca9c40`](https://basescan.org/address/0xd6145b2D3F379919E8CdEda7B97e37c4b2Ca9c40) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://basescan.org/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Arbitrum One: 42161 @@ -73,6 +81,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://arbiscan.io/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xa51afafe0263b40edaef0df8781ea9aa03e381a3`](https://arbiscan.io/address/0xa51afafe0263b40edaef0df8781ea9aa03e381a3) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8b844f885672f333bc0042cb669255f93a4c1e6b`](https://arbiscan.io/address/0x8b844f885672f333bc0042cb669255f93a4c1e6b) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x2d01411773c8C24805306E89A41F7855C3c4Fe65`](https://arbiscan.io/address/0x2d01411773c8C24805306E89A41F7855C3c4Fe65) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://arbiscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Polygon: 137 @@ -86,6 +95,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://polygonscan.com/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x1095692a6237d83c6a72f3f5efedb9a670c49223`](https://polygonscan.com/address/0x1095692a6237d83c6a72f3f5efedb9a670c49223) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8b844f885672f333bc0042cb669255f93a4c1e6b`](https://polygonscan.com/address/0x8b844f885672f333bc0042cb669255f93a4c1e6b) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xDc264714F68d84CF29BC605589405E78bDBE7C9f`](https://polygonscan.com/address/0xDc264714F68d84CF29BC605589405E78bDBE7C9f) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://polygonscan.com/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Zora: 7777777 @@ -99,6 +109,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://explorer.zora.energy/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x3315ef7ca28db74abadc6c44570efdf06b04b020`](https://explorer.zora.energy/address/0x3315ef7ca28db74abadc6c44570efdf06b04b020) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7`](https://explorer.zora.energy/address/0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xF025e0Fe9E331A0eF05c2ad3C4E9C64b625cda6f`](https://explorer.zora.energy/address/0xF025e0Fe9E331A0eF05c2ad3C4E9C64b625cda6f) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://explorer.zora.energy/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Worldchain: 480 @@ -112,6 +123,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://worldscan.org/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8ac7bee993bb44dab564ea4bc9ea67bf9eb5e743`](https://worldscan.org/address/0x8ac7bee993bb44dab564ea4bc9ea67bf9eb5e743) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8b844f885672f333bc0042cb669255f93a4c1e6b`](https://worldscan.org/address/0x8b844f885672f333bc0042cb669255f93a4c1e6b) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xF025e0Fe9E331A0eF05c2ad3C4E9C64b625cda6f`](https://worldscan.org/address/0xF025e0Fe9E331A0eF05c2ad3C4E9C64b625cda6f) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://worldscan.org/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### X Layer: 196 @@ -125,6 +137,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://www.oklink.com/x-layer/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xda00ae15d3a71466517129255255db7c0c0956d3`](https://www.oklink.com/x-layer/address/0xda00ae15d3a71466517129255255db7c0c0956d3) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8b844f885672f333bc0042cb669255f93a4c1e6b`](https://www.oklink.com/x-layer/address/0x8b844f885672f333bc0042cb669255f93a4c1e6b) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x1cd182C94fcF42277B80DBB9060F88024809E61E`](https://www.oklink.com/x-layer/address/0x1cd182C94fcF42277B80DBB9060F88024809E61E) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://www.oklink.com/x-layer/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Ink: 57073 @@ -137,6 +150,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [StateView](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/StateView.sol) | [`0x76fd297e2d437cd7f76d50f01afe6160f86e9990`](https://explorer.inkonchain.com/address/0x76fd297e2d437cd7f76d50f01afe6160f86e9990) | | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://explorer.inkonchain.com/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x112908dac86e20e7241b0927479ea3bf935d1fa0`](https://explorer.inkonchain.com/address/0x112908dac86e20e7241b0927479ea3bf935d1fa0) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x661E93cca42AfacB172121EF892830cA3b70F08d`](https://explorer.inkonchain.com/address/0x661E93cca42AfacB172121EF892830cA3b70F08d) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://explorer.inkonchain.com/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Soneium: 1868 @@ -150,6 +164,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://soneium.blockscout.com/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x4cded7edf52c8aa5259a54ec6a3ce7c6d2a455df`](https://soneium.blockscout.com/address/0x4cded7edf52c8aa5259a54ec6a3ce7c6d2a455df) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8b844f885672f333bc0042cb669255f93a4c1e6b`](https://soneium.blockscout.com/address/0x8b844f885672f333bc0042cb669255f93a4c1e6b) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x661E93cca42AfacB172121EF892830cA3b70F08d`](https://soneium.blockscout.com/address/0x661E93cca42AfacB172121EF892830cA3b70F08d) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://soneium.blockscout.com/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Avalanche: 43114 @@ -163,6 +178,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://snowscan.xyz/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x94b75331ae8d42c1b61065089b7d48fe14aa73b7`](https://snowscan.xyz/address/0x94b75331ae8d42c1b61065089b7d48fe14aa73b7) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8b844f885672f333bc0042cb669255f93a4c1e6b`](https://snowscan.xyz/address/0x8b844f885672f333bc0042cb669255f93a4c1e6b) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x661E93cca42AfacB172121EF892830cA3b70F08d`](https://snowscan.xyz/address/0x661E93cca42AfacB172121EF892830cA3b70F08d) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://snowscan.xyz/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### BNB Smart Chain: 56 @@ -176,6 +192,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://bscscan.com/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x1906c1d672b88cd1b9ac7593301ca990f94eae07`](https://bscscan.com/address/0x1906c1d672b88cd1b9ac7593301ca990f94eae07) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8b844f885672f333bc0042cb669255f93a4c1e6b`](https://bscscan.com/address/0x8b844f885672f333bc0042cb669255f93a4c1e6b) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xDc264714F68d84CF29BC605589405E78bDBE7C9f`](https://bscscan.com/address/0xDc264714F68d84CF29BC605589405E78bDBE7C9f) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://bscscan.com/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Celo: 42220 @@ -189,6 +206,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://celoscan.io/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xcb695bc5d3aa22cad1e6df07801b061a05a0233a`](https://celoscan.io/address/0xcb695bc5d3aa22cad1e6df07801b061a05a0233a) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8b844f885672f333bc0042cb669255f93a4c1e6b`](https://celoscan.io/address/0x8b844f885672f333bc0042cb669255f93a4c1e6b) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xe2023F3FA515cF070e07fD9d51c1d236e07843f4`](https://celoscan.io/address/0xe2023F3FA515cF070e07fD9d51c1d236e07843f4) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://celoscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Monad: 143 @@ -202,6 +220,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://monadvision.com/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x0d97dc33264bfc1c226207428a79b26757fb9dc3`](https://monadvision.com/address/0x0d97dc33264bfc1c226207428a79b26757fb9dc3) | | [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7`](https://monadvision.com/address/0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xa6CE4F10d83dBdDAc17E68e1837ca9cE6a1b596e`](https://monadvision.com/address/0xa6CE4F10d83dBdDAc17E68e1837ca9cE6a1b596e) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://monadvision.com/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### MegaETH: 4326 @@ -214,6 +233,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [StateView](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/StateView.sol) | [`0x726f84e1dfb8d375a365e0808282f40d52d3e4e8`](https://megaeth.blockscout.com/address/0x726f84e1dfb8d375a365e0808282f40d52d3e4e8) | | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://megaeth.blockscout.com/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x47837eb80db5908eabba9105626d9b348bea7b02`](https://megaeth.blockscout.com/address/0x47837eb80db5908eabba9105626d9b348bea7b02) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xAedd1CF4C14e833140A61E9C0d2b73a64795c823`](https://megaeth.blockscout.com/address/0xAedd1CF4C14e833140A61E9C0d2b73a64795c823) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://megaeth.blockscout.com/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | ### Tempo: 4217 @@ -226,6 +246,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [StateView](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/StateView.sol) | [`0x21b954fba3f5ddebe77ef2d47a3100c066908b2a`](https://explore.tempo.xyz/address/0x21b954fba3f5ddebe77ef2d47a3100c066908b2a?tab=contract) | | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://explore.tempo.xyz/address/0x0000001b173C3bbF3984D417d8614E3eed34865B?tab=contract) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xa2dc7d0266f0cc50b3eeaf36c9bfcecff1beea91`](https://explore.tempo.xyz/address/0xa2dc7d0266f0cc50b3eeaf36c9bfcecff1beea91?tab=contract) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x182a927119D56008d921126764bF884221b10f59`](https://explore.tempo.xyz/address/0x182a927119D56008d921126764bF884221b10f59) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://explore.tempo.xyz/address/0x000000000022D473030F116dDEE9F6B43aC78BA3?tab=contract) | ### Robinhood Chain: 4663 @@ -238,8 +259,35 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap | [StateView](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/StateView.sol) | [`0xf3334192d15450cdd385c8b70e03f9a6bd9e673b`](https://robinhoodchain.blockscout.com/address/0xf3334192d15450cdd385c8b70e03f9a6bd9e673b?tab=contract) | | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://robinhoodchain.blockscout.com/address/0x0000001b173C3bbF3984D417d8614E3eed34865B?tab=contract) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8876789976decbfcbbbe364623c63652db8c0904`](https://robinhoodchain.blockscout.com/address/0x8876789976decbfcbbbe364623c63652db8c0904?tab=contract) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x204FAca1764B154221e35c0d20aBb3c525710498`](https://robinhoodchain.blockscout.com/address/0x204FAca1764B154221e35c0d20aBb3c525710498) | | [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://robinhoodchain.blockscout.com/address/0x000000000022d473030f116ddee9f6b43ac78ba3?tab=contract) | +### Arc: 5042 +| Contract | Address | +|----------|---------| +| [PoolManager](https://github.com/Uniswap/v4-core/blob/main/src/PoolManager.sol) | [`0x8366a39CC670B4001A1121B8F6A443A643e40951`](https://explorer.arc.io/address/0x8366a39CC670B4001A1121B8F6A443A643e40951) | +| [PositionDescriptor](https://github.com/Uniswap/v4-periphery/blob/main/src/PositionDescriptor.sol) | [`0x516b8a945700D6bBfDeDaa6dcFc4586bA60B8707`](https://explorer.arc.io/address/0x516b8a945700D6bBfDeDaa6dcFc4586bA60B8707) | +| [PositionManager](https://github.com/Uniswap/v4-periphery/blob/main/src/PositionManager.sol) | [`0x6049c9a0e26405C0985f9E3685C87d0aE917f82B`](https://explorer.arc.io/address/0x6049c9a0e26405C0985f9E3685C87d0aE917f82B) | +| [Quoter](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/V4Quoter.sol) | [`0x8Dc178eFB8111BB0973Dd9d722ebeFF267c98F94`](https://explorer.arc.io/address/0x8Dc178eFB8111BB0973Dd9d722ebeFF267c98F94) | +| [StateView](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/StateView.sol) | [`0xF3334192D15450CdD385c8B70e03f9A6bD9E673b`](https://explorer.arc.io/address/0xF3334192D15450CdD385c8B70e03f9A6bD9E673b) | +| [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://explorer.arc.io/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | +| [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x4fcA4a51Ab4F23A7447b3284fBd7D73289A89Fb1`](https://explorer.arc.io/address/0x4fcA4a51Ab4F23A7447b3284fBd7D73289A89Fb1) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8702463e73f74d0b6765aBceb314Ef07aCb92650`](https://explorer.arc.io/address/0x8702463e73f74d0b6765aBceb314Ef07aCb92650) | +| [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://explorer.arc.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | + +### HyperEVM: 999 +| Contract | Address | +|----------|---------| +| [PoolManager](https://github.com/Uniswap/v4-core/blob/main/src/PoolManager.sol) | [`0x12D4Fd9C5DeDd00ab8a0bCe2CF0167bbf94b6B1F`](https://hyperevmscan.io/address/0x12D4Fd9C5DeDd00ab8a0bCe2CF0167bbf94b6B1F) | +| [PositionDescriptor](https://github.com/Uniswap/v4-periphery/blob/main/src/PositionDescriptor.sol) | [`0xfF0b85caDaC458D5aAcc22755e5107bfE31ED402`](https://hyperevmscan.io/address/0xfF0b85caDaC458D5aAcc22755e5107bfE31ED402) | +| [PositionManager](https://github.com/Uniswap/v4-periphery/blob/main/src/PositionManager.sol) | [`0x0d7Ab5B3db668128Aff6F70C4eBC71D7d4DA9bf9`](https://hyperevmscan.io/address/0x0d7Ab5B3db668128Aff6F70C4eBC71D7d4DA9bf9) | +| [Quoter](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/V4Quoter.sol) | [`0x108Bfe38532C98f8Cd8D7Ab49c9dDAa3675a1c5e`](https://hyperevmscan.io/address/0x108Bfe38532C98f8Cd8D7Ab49c9dDAa3675a1c5e) | +| [StateView](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/StateView.sol) | [`0x1656326235cb9E34Cb58CaDe53AE30789AB32A1A`](https://hyperevmscan.io/address/0x1656326235cb9E34Cb58CaDe53AE30789AB32A1A) | +| [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://hyperevmscan.io/address/0x0000001b173C3bbF3984D417d8614E3eed34865B) | +| [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x9aFe3C497e19501DB228F28CdBdD29bC98F65DBa`](https://hyperevmscan.io/address/0x9aFe3C497e19501DB228F28CdBdD29bC98F65DBa) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xeD270A1Bcdc63cf1356D695e7f40961d4819d6bF`](https://hyperevmscan.io/address/0xeD270A1Bcdc63cf1356D695e7f40961d4819d6bF) | +| [Permit2](https://github.com/Uniswap/permit2) | [`0x000000000022D473030F116dDEE9F6B43aC78BA3`](https://hyperevmscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) | + ## Testnet Deployments ### Unichain Sepolia: 1301 @@ -248,6 +296,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap |--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| | [PoolManager](https://github.com/Uniswap/v4-core/blob/main/src/PoolManager.sol) | [`0x00b036b58a818b1bc34d502d3fe730db729e62ac`](https://sepolia.uniscan.xyz/address/0x00b036b58a818b1bc34d502d3fe730db729e62ac#code) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xf70536b3bcc1bd1a972dc186a2cf84cc6da6be5d`](https://sepolia.uniscan.xyz/address/0xf70536b3bcc1bd1a972dc186a2cf84cc6da6be5d#code) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0xDf38F24fE153761634Be942F9d859f3DBA857E95`](https://sepolia.uniscan.xyz/address/0xDf38F24fE153761634Be942F9d859f3DBA857E95) | | [PositionManager](https://github.com/Uniswap/v4-periphery/blob/main/src/PositionManager.sol) | [`0xf969aee60879c54baaed9f3ed26147db216fd664`](https://sepolia.uniscan.xyz/address/0xf969aee60879c54baaed9f3ed26147db216fd664#code) | | [StateView](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/StateView.sol) | [`0xc199f1072a74d4e905aba1a84d9a45e2546b6222`](https://sepolia.uniscan.xyz/address/0xc199f1072a74d4e905aba1a84d9a45e2546b6222#code) | | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://sepolia.uniscan.xyz/address/0x0000001b173C3bbF3984D417d8614E3eed34865B#code) | @@ -262,6 +311,8 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap |--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| | [PoolManager](https://github.com/Uniswap/v4-core/blob/main/src/PoolManager.sol) | [`0xE03A1074c86CFeDd5C142C4F04F1a1536e203543`](https://sepolia.etherscan.io/address/0xE03A1074c86CFeDd5C142C4F04F1a1536e203543#code) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x3A9D48AB9751398BbFa63ad67599Bb04e4BdF98b`](https://sepolia.etherscan.io/address/0x3A9D48AB9751398BbFa63ad67599Bb04e4BdF98b#code) | +| [Universal Router 2.1.1](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x7dfd4f31be6814d2906bde155c3e1b146eac1468`](https://sepolia.etherscan.io/address/0x7dfd4f31be6814d2906bde155c3e1b146eac1468#code) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x7E4f6c5e954Da5c61B3423D81E2277431Ac043f3`](https://sepolia.etherscan.io/address/0x7E4f6c5e954Da5c61B3423D81E2277431Ac043f3) | | [PositionManager](https://github.com/Uniswap/v4-periphery/blob/main/src/PositionManager.sol) | [`0x429ba70129df741B2Ca2a85BC3A2a3328e5c09b4`](https://sepolia.etherscan.io/address/0x429ba70129df741B2Ca2a85BC3A2a3328e5c09b4#code) | | [StateView](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/StateView.sol) | [`0xe1dd9c3fa50edb962e442f60dfbc432e24537e4c`](https://sepolia.etherscan.io/address/0xe1dd9c3fa50edb962e442f60dfbc432e24537e4c#code) | | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://sepolia.etherscan.io/address/0x0000001b173C3bbF3984D417d8614E3eed34865B#code) | @@ -276,6 +327,7 @@ The latest version of `@uniswap/v4-core`, `@uniswap/v4-periphery`, and `@uniswap |--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| | [PoolManager](https://github.com/Uniswap/v4-core/blob/main/src/PoolManager.sol) | [`0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408`](https://sepolia.basescan.org/address/0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408#code) | | [Universal Router](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x492e6456d9528771018deb9e87ef7750ef184104`](https://sepolia.basescan.org/address/0x492e6456d9528771018deb9e87ef7750ef184104#code) | +| [Universal Router 2.1.2](https://github.com/Uniswap/universal-router/blob/dev/contracts/UniversalRouter.sol) | [`0x8702463e73f74d0b6765aBceb314Ef07aCb92650`](https://sepolia.basescan.org/address/0x8702463e73f74d0b6765aBceb314Ef07aCb92650) | | [PositionManager](https://github.com/Uniswap/v4-periphery/blob/main/src/PositionManager.sol) | [`0x4b2c77d209d3405f41a037ec6c77f7f5b8e2ca80`](https://sepolia.basescan.org/address/0x4b2c77d209d3405f41a037ec6c77f7f5b8e2ca80#code) | | [StateView](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/StateView.sol) | [`0x571291b572ed32ce6751a2cb2486ebee8defb9b4`](https://sepolia.basescan.org/address/0x571291b572ed32ce6751a2cb2486ebee8defb9b4#code) | | [ReservesLens](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/ReservesLens.sol) | [`0x0000001b173C3bbF3984D417d8614E3eed34865B`](https://sepolia.basescan.org/address/0x0000001b173C3bbF3984D417d8614E3eed34865B#code) | diff --git a/content/protocols/v4/guides/create-pool.mdx b/content/protocols/v4/guides/create-pool.mdx index 8efc090d4..e37546106 100644 --- a/content/protocols/v4/guides/create-pool.mdx +++ b/content/protocols/v4/guides/create-pool.mdx @@ -1,5 +1,6 @@ --- -title: Create Pool +title: Create a Pool on Uniswap v4 +sidebarTitle: Create Pool description: Create a Uniswap v4 pool and optionally initialize it with liquidity in one flow. --- @@ -183,3 +184,5 @@ PositionManager(posm).multicall{value: ethToSend}(params); > Excess Ether is **NOT** refunded unless developers encoded `SWEEP` in the `actions` parameter For a full end-to-end script, developers should see [v4-template's scripts](https://github.com/uniswapfoundation/v4-template/tree/main/script) + +For developer support, reach out to our team through the Help Center. diff --git a/content/protocols/v4/guides/erc-6909.mdx b/content/protocols/v4/guides/erc-6909.mdx index 92ac9d9bb..c0b3e84ca 100644 --- a/content/protocols/v4/guides/erc-6909.mdx +++ b/content/protocols/v4/guides/erc-6909.mdx @@ -1,5 +1,6 @@ --- -title: ERC-6909 +title: Using ERC-6909 in Uniswap v4 +sidebarTitle: ERC-6909 description: Use ERC-6909 primitives in Uniswap v4 to resolve deltas and manage balances efficiently. --- diff --git a/content/protocols/v4/guides/flash-accounting.mdx b/content/protocols/v4/guides/flash-accounting.mdx index 1352a808e..c6dcae372 100644 --- a/content/protocols/v4/guides/flash-accounting.mdx +++ b/content/protocols/v4/guides/flash-accounting.mdx @@ -1,5 +1,6 @@ --- -title: Flash Accounting +title: Building with Uniswap v4 Flash Accounting +sidebarTitle: Flash Accounting description: Build with Uniswap v4 flash accounting by understanding deltas, settlement, and PoolManager flows. --- diff --git a/content/protocols/v4/guides/getting-started.mdx b/content/protocols/v4/guides/getting-started.mdx index 56b9b4ad4..859f6182a 100644 --- a/content/protocols/v4/guides/getting-started.mdx +++ b/content/protocols/v4/guides/getting-started.mdx @@ -1,5 +1,6 @@ --- -title: Get Started +title: Get Started with Uniswap v4 +sidebarTitle: Get Started description: Choose your first Uniswap v4 integration path across pool creation, swapping, liquidity, and hooks. --- @@ -23,3 +24,5 @@ Use this page to choose a practical starting point in Uniswap v4 guides. - [ERC-6909](/docs/protocols/v4/guides/erc-6909) - [Subscriber](/docs/protocols/v4/guides/subscriber) - [Troubleshooting](/docs/protocols/v4/guides/troubleshooting) + +For developer support, reach out to our team through the Help Center. diff --git a/content/protocols/v4/guides/state-view.mdx b/content/protocols/v4/guides/state-view.mdx index 255284422..8ee9d083e 100644 --- a/content/protocols/v4/guides/state-view.mdx +++ b/content/protocols/v4/guides/state-view.mdx @@ -5,7 +5,7 @@ description: Read Uniswap v4 pool state offchain using StateView and compare wit ## StateView Overview -When building on **Uniswap v4**, you will often need to read pool state for both onchain and offchain use cases. Onchain contracts can directly invoke the [**StateLibrary**](https://github.com/Uniswap/v4-core/blob/main/src/libraries/StateLibrary.sol) to execute these reads during transactions, but offchain systems—such as frontends or analytics services—require a deployed contract with view functions. This is where [**StateView**](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/StateView.sol) comes in. +When building on **Uniswap v4**, you will often need to read pool state for both onchain and offchain use cases. Onchain contracts can directly invoke the [**StateLibrary**](https://github.com/Uniswap/v4-core/blob/main/src/libraries/StateLibrary.sol) to execute these reads during transactions, but offchain systems such as frontends or analytics services require a deployed contract with view functions. This is where [**StateView**](https://github.com/Uniswap/v4-periphery/blob/main/src/lens/StateView.sol) comes in. > *In short: Use StateLibrary within onchain contracts and use StateView with an RPC for frontends and analytics.* > @@ -57,7 +57,7 @@ This separation ensures that each context (onchain vs. offchain) uses the most e ## Usage With Frontend Clients -Frontend applications frequently display real-time information about pools, positions, and other market data—without incurring transaction costs. **StateView** addresses these requirements by exposing read-only functions tailored for offchain integrations. +Frontend applications frequently display real-time information about pools, positions, and other market data, without incurring transaction costs. **StateView** addresses these requirements by exposing read-only functions tailored for offchain integrations. ### Setting up with Viem diff --git a/content/protocols/v4/guides/swapping/getting-started.mdx b/content/protocols/v4/guides/swapping/getting-started.mdx index d3d640a5e..6a216b43c 100644 --- a/content/protocols/v4/guides/swapping/getting-started.mdx +++ b/content/protocols/v4/guides/swapping/getting-started.mdx @@ -1,5 +1,6 @@ --- -title: Get Started +title: Get Started with Uniswap v4 Swapping +sidebarTitle: Get Started description: Start swapping on Uniswap v4 using Universal Router setup, command routing, and verification steps. --- diff --git a/content/protocols/v4/guides/swapping/routing.mdx b/content/protocols/v4/guides/swapping/routing.mdx index eff4b5cc3..9f9676501 100644 --- a/content/protocols/v4/guides/swapping/routing.mdx +++ b/content/protocols/v4/guides/swapping/routing.mdx @@ -1,5 +1,6 @@ --- -title: Swap Routing +title: Swap Routing on Uniswap v4 +sidebarTitle: Swap Routing description: Configure Universal Router command encoding for Uniswap v4 swap routing flows. --- diff --git a/content/protocols/v4/guides/troubleshooting.mdx b/content/protocols/v4/guides/troubleshooting.mdx index 7233318c4..10ef93476 100644 --- a/content/protocols/v4/guides/troubleshooting.mdx +++ b/content/protocols/v4/guides/troubleshooting.mdx @@ -1,5 +1,4 @@ --- -id: troubleshooting title: Troubleshooting (v4) description: Review common Uniswap v4 custom error selectors to debug integration and runtime failures. --- @@ -99,3 +98,5 @@ These are custom error selectors for Uniswap v4 contracts. |-----------------------------------------------------|--------------| | `TickMath.InvalidTick.selector` | `0xce8ef7fc` | | `TickMath.InvalidSqrtPrice.selector` | `0x31efafe8` | + +For developer support, reach out to our team through the Help Center. diff --git a/content/protocols/v4/overview.mdx b/content/protocols/v4/overview.mdx index ae170456e..f18fd13ef 100644 --- a/content/protocols/v4/overview.mdx +++ b/content/protocols/v4/overview.mdx @@ -1,6 +1,6 @@ --- -id: overview -title: Overview +title: Uniswap v4 Protocol Overview +sidebarTitle: Overview description: Navigate Uniswap v4 concepts, framework guidance, and references for protocol integrations. --- diff --git a/content/protocols/v4/security.mdx b/content/protocols/v4/security.mdx index 55ac2674f..c329a16d4 100644 --- a/content/protocols/v4/security.mdx +++ b/content/protocols/v4/security.mdx @@ -1,5 +1,4 @@ --- -id: security-framework title: Security Framework description: Evaluate Uniswap v4 hook security risks with a structured framework, scoring model, and operational guidance. --- @@ -130,7 +129,7 @@ Even in these cases, strict controls are necessary. When safety is higher priority than convenience: -- Deploy new hook contracts (v1 —> v2) rather than upgrading old ones. +- Deploy new hook contracts (v1 -> v2) rather than upgrading old ones. - Allow pools to migrate voluntarily rather than forcing an upgrade path. ### Autonomous behavior or parameter updates diff --git a/content/sdks/overview.mdx b/content/sdks/overview.mdx index f4fd3ec34..d05c07de0 100644 --- a/content/sdks/overview.mdx +++ b/content/sdks/overview.mdx @@ -1,6 +1,33 @@ --- description: Explore Uniswap SDK families and choose the right version for your integration workflow. -title: SDKs Overview +title: Uniswap SDKs Overview +sidebarTitle: Overview +keywords: + - Uniswap SDK + - SDK versioning + - Trading API + - Quoter callStatic + - CurrencyAmount + - BigInt precision +faqs: + - question: Which Uniswap SDK version should I use, v2, v3, or v4? + answer: |- + Match the SDK to the protocol version of the pools you integrate with. Use the v4 SDK for new integrations that rely on hooks, flash accounting, and singleton pools. Use the v3 SDK for concentrated liquidity workflows on v3 pools. Use the v2 SDK for legacy constant product pools and older routing flows. The versions are not interchangeable because each targets a different set of onchain contracts. All three build on the Core SDK for shared token, amount, and price primitives. + - question: When should I use a Uniswap SDK versus the Trading API? + answer: |- + Use an SDK when you want client-side computation and want to construct calldata yourself. The SDK gives you utility classes to build pool keys, compute quotes, and encode swap parameters, but it does not execute trades or send transactions. You manage RPC connections, token definitions, and pool configuration. Use the Trading API when you prefer a hosted service that handles routing, quoting, and transaction building for you. The API returns encoded transaction data that your application signs and submits, so you do not manage pool state or routing logic yourself. + - question: Why does my Quoter call fail when I call it like a normal read function? + answer: |- + The Uniswap Quoter functions are not view functions. They rely on state-changing calls that are designed to revert in order to return the quote data, so executed as a transaction they cost gas. To read a quote, simulate the call instead with callStatic in ethers v5 or staticCall in ethers v6, which asks the node to simulate the state change and return the result rather than execute it. This applies to both the v3 and v4 Quoter contracts. + - question: How do I handle token amounts without losing precision? + answer: |- + Represent amounts in their smallest onchain unit, not as JavaScript floating point numbers, which lose precision on large integers. The Core SDK provides CurrencyAmount, which you create with CurrencyAmount.fromRawAmount using a Token and a raw integer amount. Convert a human readable amount into raw units by scaling by ten to the power of the token decimals. The SDKs represent these integers with JSBI, so convert strings or native BigInt values into JSBI before passing them to SDK constructors. The key rule is to keep amounts as integers in the token's base units through every calculation. + - question: What is the Core SDK and do I need it? + answer: |- + The Core SDK, published as @uniswap/sdk-core, provides the shared token, amount, and price primitives used across the v2, v3, and v4 SDKs. Types such as Token, CurrencyAmount, and Price live there. You almost always install it alongside a version SDK because the version SDKs expect these primitives as inputs and return them as outputs. + - question: Can the SDK execute swaps or send transactions for me? + answer: |- + No. The SDK computes and encodes the data required to interact with Uniswap safely, but it does not sign or broadcast transactions. Your application is responsible for connecting a signer, submitting the transaction through your RPC provider, and handling approvals. If you want a service that returns ready to sign transaction data instead, use the Trading API. --- Use this page to choose the right Uniswap SDK version for your integration and then jump into implementation guides. @@ -19,3 +46,106 @@ The Core SDK `@uniswap/sdk-core` provides shared token, amount, and price primit - [SDK Core GitHub Repo](https://github.com/Uniswap/sdk-core) - [Core SDK NPM Package](https://www.npmjs.com/package/@uniswap/sdk-core) + +## FAQ + +
+ Which Uniswap SDK version should I use, v2, v3, or v4? + + + + Match the SDK to the protocol version of the pools you integrate with: + + * [Uniswap v4 SDK](/docs/sdks/v4/overview) for new integrations that rely on hooks, flash accounting, and singleton pools. + * [Uniswap v3 SDK](/docs/sdks/v3/overview) for concentrated liquidity workflows on v3 pools. + * [Uniswap v2 SDK](/docs/sdks/v2/overview) for legacy constant product pools and older routing flows. + + The versions are not interchangeable because each targets a different set of onchain contracts. All three build on the Core SDK for shared token, amount, and price primitives. + + + +
+ +
+ When should I use a Uniswap SDK versus the Trading API? + + + + Use an SDK when you want client-side computation and want to construct calldata yourself. The SDK gives you utility classes to build pool keys, compute quotes, and encode swap parameters, but it does not execute trades or send transactions. You manage RPC connections, token definitions, and pool configuration. + + Use the [Trading API](/docs/trading/overview) when you prefer a hosted service that handles routing, quoting, and transaction building for you. The API returns encoded transaction data that your application signs and submits, so you do not manage pool state or routing logic yourself. + + + +
+ +
+ Why does my Quoter call fail when I call it like a normal read function? + + + + The Uniswap Quoter functions are not `view` functions. They rely on state-changing calls that are designed to revert in order to return the quote data, so executed as a transaction they cost gas. + + To read a quote, simulate the call instead with `callStatic` (ethers v5) or `staticCall` (ethers v6). This asks the node to simulate the state change and return the result rather than execute it: + + ```typescript + const quotedAmountOut = await quoterContract.callStatic.quoteExactInputSingle( + tokenIn, + tokenOut, + fee, + amountIn, + 0 + ) + ``` + + The snippet shows the v3 Quoter; the v4 Quoter takes a single struct parameter instead of positional arguments. The simulation requirement applies to both the [v3 Quoter](/docs/sdks/v3/guides/swapping/quoting) and the [v4 Quoter](/docs/sdks/v4/guides/swapping/quoting). + + + +
+ +
+ How do I handle token amounts without losing precision? + + + + Represent amounts in their smallest onchain unit, not as JavaScript floating point numbers, which lose precision on large integers. The Core SDK provides `CurrencyAmount`, which you create with `CurrencyAmount.fromRawAmount` from a `Token` and a raw integer amount: + + ```typescript + import { CurrencyAmount } from '@uniswap/sdk-core' + + // amountIn is already scaled to the token's base units (e.g. 1000 * 10 ** decimals) + const inputAmount = CurrencyAmount.fromRawAmount(USDC_TOKEN, amountIn) + ``` + + The SDKs represent these integers with `JSBI`, so convert strings or native `BigInt` values into `JSBI` before passing them to SDK constructors. The key rule is to keep amounts as integers in the token's base units through every calculation. + + + +
+ +
+ What is the Core SDK and do I need it? + + + + The Core SDK, published as [`@uniswap/sdk-core`](https://www.npmjs.com/package/@uniswap/sdk-core), provides the shared token, amount, and price primitives used across the v2, v3, and v4 SDKs. Types such as `Token`, `CurrencyAmount`, and `Price` live there. + + You almost always install it alongside a version SDK because the version SDKs expect these primitives as inputs and return them as outputs. + + + +
+ +
+ Can the SDK execute swaps or send transactions for me? + + + + No. The SDK computes and encodes the data required to interact with Uniswap safely, but it does not sign or broadcast transactions. Your application is responsible for connecting a signer, submitting the transaction through your RPC provider, and handling approvals. + + If you want a service that returns ready to sign transaction data instead, use the [Trading API](/docs/trading/overview). + + + +
diff --git a/content/sdks/v2/guides/getting-pair-address.mdx b/content/sdks/v2/guides/getting-pair-address.mdx index 092b2596e..5c46d76a1 100644 --- a/content/sdks/v2/guides/getting-pair-address.mdx +++ b/content/sdks/v2/guides/getting-pair-address.mdx @@ -1,6 +1,7 @@ --- description: Compute Uniswap v2 pair addresses with factory lookups or CREATE2 address derivation. -title: Pair Addresses +title: Getting Pair Addresses with the v2 SDK +sidebarTitle: Pair Addresses --- ## getPair diff --git a/content/sdks/v2/guides/pricing.mdx b/content/sdks/v2/guides/pricing.mdx index 43074e929..b688c6950 100644 --- a/content/sdks/v2/guides/pricing.mdx +++ b/content/sdks/v2/guides/pricing.mdx @@ -1,6 +1,7 @@ --- description: Calculate mid price and execution price with the Uniswap v2 SDK for swap integrations. -title: Pricing +title: Pricing with the v2 SDK +sidebarTitle: Pricing --- Let's talk pricing. This guide will focus on the two most important Uniswap prices: the **mid price** and the **execution price**. diff --git a/content/sdks/v2/overview.mdx b/content/sdks/v2/overview.mdx index 12c0407cd..5ceb306ee 100644 --- a/content/sdks/v2/overview.mdx +++ b/content/sdks/v2/overview.mdx @@ -1,6 +1,7 @@ --- description: Get started with Uniswap v2 SDK concepts, guides, and integration resources. -title: Overview +title: Uniswap v2 SDK Overview +sidebarTitle: Overview --- The Uniswap v2 SDK provides abstractions to assist you with interacting with the Uniswap v2 smart contracts in a TypeScript/JavaScript environment (for example websites and node scripts). diff --git a/content/sdks/v3/guides/getting-started.mdx b/content/sdks/v3/guides/getting-started.mdx index 4790b9da4..fa5a50aab 100644 --- a/content/sdks/v3/guides/getting-started.mdx +++ b/content/sdks/v3/guides/getting-started.mdx @@ -1,6 +1,7 @@ --- description: Set up a local mainnet-fork workflow for the Uniswap v3 SDK using Foundry and Anvil. -title: Get Started +title: Get Started with the Uniswap v3 SDK +sidebarTitle: Get Started --- Developing your dApps or smart contracts requires some tinkering to get a proper setup that is both a good simulation of how Mainnet will behave, diff --git a/content/sdks/v3/guides/managing-liquidity/collect-fees.mdx b/content/sdks/v3/guides/managing-liquidity/collect-fees.mdx index 07b9e6fab..d3d40d572 100644 --- a/content/sdks/v3/guides/managing-liquidity/collect-fees.mdx +++ b/content/sdks/v3/guides/managing-liquidity/collect-fees.mdx @@ -1,6 +1,7 @@ --- description: Collect accrued fees from Uniswap v3 positions using SDK-generated calldata and options. -title: Collecting Fees +title: Collecting Fees with the v3 SDK +sidebarTitle: Collecting Fees --- This guide will cover how to collect fees from a liquidity position on the Uniswap v3 protocol. It is based on the [collecting fees code example](https://github.com/Uniswap/examples/tree/main/v3-sdk/collecting-fees), found in the Uniswap code examples [repository](https://github.com/Uniswap/examples). To run this example, check out the examples's [README](https://github.com/Uniswap/examples/blob/main/v3-sdk/collecting-fees/README.md) and follow the setup instructions. diff --git a/content/sdks/v3/guides/managing-liquidity/position-fetching.mdx b/content/sdks/v3/guides/managing-liquidity/position-fetching.mdx index 46ae4b614..819c1f966 100644 --- a/content/sdks/v3/guides/managing-liquidity/position-fetching.mdx +++ b/content/sdks/v3/guides/managing-liquidity/position-fetching.mdx @@ -1,6 +1,7 @@ --- description: Fetch Uniswap v3 position data and decode position state with the SDK and periphery contracts. -title: Fetching Positions +title: Fetching Positions with the v3 SDK +sidebarTitle: Fetching Positions --- This guide will cover how to create (or mint) a liquidity position on the Uniswap v3 protocol. diff --git a/content/sdks/v3/guides/managing-liquidity/position-minting.mdx b/content/sdks/v3/guides/managing-liquidity/position-minting.mdx index 2255ea313..090a637d2 100644 --- a/content/sdks/v3/guides/managing-liquidity/position-minting.mdx +++ b/content/sdks/v3/guides/managing-liquidity/position-minting.mdx @@ -1,6 +1,7 @@ --- description: Mint a concentrated liquidity position with the Uniswap v3 SDK and position manager calldata. -title: Minting a Position +title: Minting a Position with the v3 SDK +sidebarTitle: Minting a Position --- This guide will cover how to create (or mint) a liquidity position on the Uniswap v3 protocol. diff --git a/content/sdks/v3/guides/managing-liquidity/range-orders.mdx b/content/sdks/v3/guides/managing-liquidity/range-orders.mdx index f2da9e878..157acd34a 100644 --- a/content/sdks/v3/guides/managing-liquidity/range-orders.mdx +++ b/content/sdks/v3/guides/managing-liquidity/range-orders.mdx @@ -1,6 +1,7 @@ --- description: Create range-order style strategies with Uniswap v3 positions and SDK position math. -title: Range Orders +title: Range Orders with the v3 SDK +sidebarTitle: Range Orders --- This guide will cover how single-side liquidity provisioning can be used to execute **Limit Orders** on Uniswap v3 Pools. diff --git a/content/sdks/v3/guides/pool-data.mdx b/content/sdks/v3/guides/pool-data.mdx index 5a7adc612..d69f5b549 100644 --- a/content/sdks/v3/guides/pool-data.mdx +++ b/content/sdks/v3/guides/pool-data.mdx @@ -1,6 +1,7 @@ --- description: Fetch and model Uniswap v3 pool state with the SDK for pricing and liquidity workflows. -title: Fetching Pool Data +title: Fetching Pool Data with the v3 SDK +sidebarTitle: Fetching Pool Data --- This guide will cover how to initialize a Pool with full tick data to allow offchain calculations. It is based on the [Fetching Pool data example](https://github.com/Uniswap/examples/tree/main/v3-sdk/pool-data), found in the Uniswap code examples [repository](https://github.com/Uniswap/examples). To run this example, check out the guide's [README](https://github.com/Uniswap/examples/blob/main/v3-sdk/pool-data/README.md) and follow the setup instructions. diff --git a/content/sdks/v3/guides/swapping/quoting.mdx b/content/sdks/v3/guides/swapping/quoting.mdx index d09a6aa3d..ec0553c3f 100644 --- a/content/sdks/v3/guides/swapping/quoting.mdx +++ b/content/sdks/v3/guides/swapping/quoting.mdx @@ -1,6 +1,7 @@ --- description: Get swap quotes with the Uniswap v3 SDK before you build and submit transactions. -title: Getting a Quote +title: Getting a Quote with the v3 SDK +sidebarTitle: Getting a Quote --- This guide will cover how to get the current quotes for any token pair on the Uniswap protocol. It is based on the [Quoting code example](https://github.com/Uniswap/examples/tree/main/v3-sdk/quoting), found in the Uniswap code examples [repository](https://github.com/Uniswap/examples). To run this example, check out the examples's [README](https://github.com/Uniswap/examples/blob/main/v3-sdk/quoting/README.md) and follow the setup instructions. diff --git a/content/sdks/v3/overview.mdx b/content/sdks/v3/overview.mdx index ad0c2e2cf..5b7f9397f 100644 --- a/content/sdks/v3/overview.mdx +++ b/content/sdks/v3/overview.mdx @@ -1,6 +1,7 @@ --- description: Get started with Uniswap v3 SDK concepts, guides, and integration resources. -title: Overview +title: Uniswap v3 SDK Overview +sidebarTitle: Overview --- The Uniswap v3 SDK provides abstractions to assist you with interacting with the Uniswap v3 smart contracts in a TypeScript/JavaScript environment (for example websites and node scripts). diff --git a/content/sdks/v4/guides/create-pool.mdx b/content/sdks/v4/guides/create-pool.mdx index 39ffd14db..1e6a1a3ff 100644 --- a/content/sdks/v4/guides/create-pool.mdx +++ b/content/sdks/v4/guides/create-pool.mdx @@ -1,6 +1,7 @@ --- description: Create and initialize a Uniswap v4 pool using SDK utilities and pool key configuration. -title: Create Pool +title: Create a Pool with the v4 SDK +sidebarTitle: Create Pool --- In this example we will use **ethers.js** and the **Uniswap v4 SDK** to create pools on Uniswap v4. Uniswap v4 is a popular destination for creating markets due to its: diff --git a/content/sdks/v4/guides/managing-liquidity/position-fetching.mdx b/content/sdks/v4/guides/managing-liquidity/position-fetching.mdx index 9821ad31a..b23394e9d 100644 --- a/content/sdks/v4/guides/managing-liquidity/position-fetching.mdx +++ b/content/sdks/v4/guides/managing-liquidity/position-fetching.mdx @@ -1,6 +1,7 @@ --- description: Fetch Uniswap v4 position details and map position metadata for SDK-driven workflows. -title: Fetching Positions +title: Fetching Positions with the v4 SDK +sidebarTitle: Fetching Positions --- This guide covers how to fetch and analyze liquidity positions in Uniswap v4 using the v4-sdk. diff --git a/content/sdks/v4/guides/managing-liquidity/position-minting.mdx b/content/sdks/v4/guides/managing-liquidity/position-minting.mdx index 03d5ce70a..18e53cb26 100644 --- a/content/sdks/v4/guides/managing-liquidity/position-minting.mdx +++ b/content/sdks/v4/guides/managing-liquidity/position-minting.mdx @@ -1,6 +1,7 @@ --- description: Mint a Uniswap v4 liquidity position using SDK position objects and mint call parameters. -title: Minting a Position +title: Minting a Position with the v4 SDK +sidebarTitle: Minting a Position --- This guide will introduce us to liquidity positions in Uniswap v4 and present the v4-sdk classes and contracts used to interact with the protocol. @@ -136,6 +137,7 @@ let tickUpper: number if (fullRange) { // For full-range positions, use Uniswap's minimum and maximum allowed ticks + // See the note below before hardcoding these bounds in a contract const MIN_TICK = -887272 const MAX_TICK = 887272 @@ -163,6 +165,12 @@ const amount0Desired = token0IsA ? amountADesired.toString() : amountBDesired.to const amount1Desired = token0IsA ? amountBDesired.toString() : amountADesired.toString() ``` +> Each tick has a `liquidityGross` counter capped at `maxLiquidityPerTick`. The cap bounds per-tick liquidity so that a pool's active liquidity cannot overflow when a tick is crossed. It is shared by every position that uses the tick as a bound, first come first served. +> +> At the minimum and maximum usable ticks the price range spanned by one tick spacing is very small, so filling the cap there costs very little. Anyone can do it. Once a tick is at its cap, any mint or increase using that exact tick reverts with `TickLiquidityOverflow`. If you hit this, move the affected bound in by one or two tick spacings. On a pool with tick spacing 10 the extreme bounds sit at prices around 1e38 and 1e-39, so shifting in by a spacing or two leaves the position covering the same trading range in practice and requires the same capital. +> +> Contracts that add liquidity at hardcoded extreme tick bounds can be griefed if the pool is not created atomically with the liquidity add. They therefore should not use the extreme ticks, and instead should choose ticks where filling `maxLiquidityPerTick` would be prohibitively expensive. Uniswap's [`InstantLaunchStrategy`](https://github.com/Uniswap/liquidity-launcher/blob/main/src/strategies/InstantLaunchStrategy.sol) does this with its `MIN_LAUNCH_TICK` and `MAX_INITIAL_TICK` values. + ### Step 5: Create a position Use the SDK to create a Position object that represents your liquidity position: diff --git a/content/sdks/v4/guides/pool-data.mdx b/content/sdks/v4/guides/pool-data.mdx index d2a633585..1ecacf6f8 100644 --- a/content/sdks/v4/guides/pool-data.mdx +++ b/content/sdks/v4/guides/pool-data.mdx @@ -1,6 +1,7 @@ --- description: Fetch and assemble Uniswap v4 pool state with StateView and SDK pool abstractions. -title: Fetching Pool Data +title: Fetching Pool Data with the v4 SDK +sidebarTitle: Fetching Pool Data --- In this example we will use **ethers JS** and **ethers-multicall** to construct a `Pool` object that we can use in the following guides. diff --git a/content/sdks/v4/guides/swapping/multi-hop-swapping.mdx b/content/sdks/v4/guides/swapping/multi-hop-swapping.mdx index 26385efaf..58b3b3a9a 100644 --- a/content/sdks/v4/guides/swapping/multi-hop-swapping.mdx +++ b/content/sdks/v4/guides/swapping/multi-hop-swapping.mdx @@ -52,6 +52,7 @@ export const CurrentConfig: SwapExactIn = { ), amountIn: ethers.utils.parseUnits('1', ETH_TOKEN.decimals).toString(), amountOutMinimum: "minAmountOut", // Change according to the slippage desired + minHopPriceX36: [], // Per-hop price floors added in Universal Router 2.1.1. An empty array disables them, so amountOutMinimum alone enforces slippage } ``` @@ -105,7 +106,7 @@ export function encodeMultihopExactInPath( We'll use the same contract addresses and ABIs from the single-hop guide and construct the **ethers** `Contract` for them: ```typescript -const UNIVERSAL_ROUTER_ADDRESS = "0x66a9893cC07D91D95644AEDD05D03f95e1dBA8Af" +const UNIVERSAL_ROUTER_ADDRESS = "0x23617e59A5925b2A4Bf75d73ff6711cD0b29De85" // Universal Router 2.1.2 on Ethereum mainnet const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3" // ABIs remain the same as in single-hop guide @@ -114,10 +115,10 @@ const ERC20_ABI = [/* ... */] const PERMIT2_ABI = [/* ... */] ``` -The main function for executing multi-hop swaps is very similar to the single-hop guide as well. The only difference is that the first action to the Universal Router is `SWAP_EXACT_IN` instead of `SWAP_EXACT_IN_SINGLE`. +The main function for executing multi-hop swaps is very similar to the single-hop guide as well. The only difference is that the first action to the Universal Router is `SWAP_EXACT_IN` instead of `SWAP_EXACT_IN_SINGLE`. As in the single-hop guide, the actions are encoded for `URVersion.V2_1_1`, the calldata format Universal Router 2.1.2 uses, and `minHopPriceX36` is left empty to disable per-hop price floors. ```typescript -import { Actions, V4Planner } from '@uniswap/v4-sdk' +import { Actions, URVersion, V4Planner } from '@uniswap/v4-sdk' import { CommandType, RoutePlanner } from '@uniswap/universal-router-sdk' const v4Planner = new V4Planner() @@ -125,9 +126,10 @@ const routePlanner = new RoutePlanner() const deadline = Math.floor(Date.now() / 1000) + 3600 -v4Planner.addAction(Actions.SWAP_EXACT_IN, [CurrentConfig]); -v4Planner.addAction(Actions.SETTLE_ALL, [ETH_USDC_POOL_KEY.currency0, CurrentConfig.amountIn]); -v4Planner.addAction(Actions.TAKE_ALL, [USDC_USDT_POOL_KEY.currency1, CurrentConfig.amountOutMinimum]); +// Universal Router 2.1.2 shares its calldata with 2.1.1, so encode the actions for URVersion.V2_1_1 +v4Planner.addAction(Actions.SWAP_EXACT_IN, [CurrentConfig], URVersion.V2_1_1); +v4Planner.addAction(Actions.SETTLE_ALL, [ETH_USDC_POOL_KEY.currency0, CurrentConfig.amountIn], URVersion.V2_1_1); +v4Planner.addAction(Actions.TAKE_ALL, [USDC_USDT_POOL_KEY.currency1, CurrentConfig.amountOutMinimum], URVersion.V2_1_1); const encodedActions = v4Planner.finalize() diff --git a/content/sdks/v4/guides/swapping/quoting.mdx b/content/sdks/v4/guides/swapping/quoting.mdx index e04162bbc..a6a27f870 100644 --- a/content/sdks/v4/guides/swapping/quoting.mdx +++ b/content/sdks/v4/guides/swapping/quoting.mdx @@ -1,6 +1,7 @@ --- description: Get Uniswap v4 swap quotes with Quoter simulations before submitting swap transactions. -title: Getting a Quote +title: Getting a Quote with the v4 SDK +sidebarTitle: Getting a Quote --- This guide will cover how to get the current quotes for any token pair on the Uniswap protocol. diff --git a/content/sdks/v4/guides/swapping/single-hop-swapping.mdx b/content/sdks/v4/guides/swapping/single-hop-swapping.mdx index ed00aa50c..f2fe96580 100644 --- a/content/sdks/v4/guides/swapping/single-hop-swapping.mdx +++ b/content/sdks/v4/guides/swapping/single-hop-swapping.mdx @@ -37,6 +37,7 @@ export const CurrentConfig: SwapExactInSingle = { zeroForOne: true, // The direction of swap is ETH to USDC. Change it to 'false' for the reverse direction amountIn: ethers.utils.parseUnits('1', ETH_TOKEN.decimals).toString(), amountOutMinimum: "minAmountOut", // Change according to the slippage desired + minHopPriceX36: "0", // Per-hop price floor added in Universal Router 2.1.1. "0" disables it, so amountOutMinimum alone enforces slippage hookData: '0x00' } ``` @@ -50,7 +51,7 @@ The Universal Router is a flexible, gas-efficient contract designed to execute c So, we construct an instance of an **ethers** `Contract` for the Universal Router contract in order to interact with it: ```typescript -const UNIVERSAL_ROUTER_ADDRESS = "0x66a9893cc07d91d95644aedd05d03f95e1dba8af" // Change the Universal Router address as per the chain +const UNIVERSAL_ROUTER_ADDRESS = "0x23617e59A5925b2A4Bf75d73ff6711cD0b29De85" // Universal Router 2.1.2 on Ethereum mainnet. Change the address as per the chain const UNIVERSAL_ROUTER_ABI = [ { @@ -73,7 +74,7 @@ const universalRouter = new ethers.Contract( ) ``` -We can get the `UNIVERSAL_ROUTER_ADDRESS` for our chain from [Uniswap Deployments](/docs/protocols/v4/deployments). +We can get the `UNIVERSAL_ROUTER_ADDRESS` for our chain from the Universal Router 2.1.2 row in [Uniswap Deployments](/docs/protocols/v4/deployments). Universal Router 2.1.2 uses the same calldata as 2.1.1, so the v4 SDK encodes for it with `URVersion.V2_1_1`. A signer object can be created like this: @@ -93,7 +94,7 @@ Now, let's implement the main function that handles the swap. When encoding a sw We will be doing an Exact Input swap in this example. ```typescript -import { Actions, V4Planner } from '@uniswap/v4-sdk' +import { Actions, URVersion, V4Planner } from '@uniswap/v4-sdk' import { CommandType, RoutePlanner } from '@uniswap/universal-router-sdk' const v4Planner = new V4Planner() @@ -102,9 +103,10 @@ const routePlanner = new RoutePlanner() // Set deadline (1 hour from now) const deadline = Math.floor(Date.now() / 1000) + 3600 -v4Planner.addAction(Actions.SWAP_EXACT_IN_SINGLE, [CurrentConfig]); -v4Planner.addAction(Actions.SETTLE_ALL, [CurrentConfig.poolKey.currency0, CurrentConfig.amountIn]); -v4Planner.addAction(Actions.TAKE_ALL, [CurrentConfig.poolKey.currency1, CurrentConfig.amountOutMinimum]); +// Universal Router 2.1.2 shares its calldata with 2.1.1, so encode the actions for URVersion.V2_1_1 +v4Planner.addAction(Actions.SWAP_EXACT_IN_SINGLE, [CurrentConfig], URVersion.V2_1_1); +v4Planner.addAction(Actions.SETTLE_ALL, [CurrentConfig.poolKey.currency0, CurrentConfig.amountIn], URVersion.V2_1_1); +v4Planner.addAction(Actions.TAKE_ALL, [CurrentConfig.poolKey.currency1, CurrentConfig.amountOutMinimum], URVersion.V2_1_1); const encodedActions = v4Planner.finalize() @@ -128,7 +130,7 @@ console.log('Swap completed! Transaction hash:', receipt.transactionHash) The actions in the planner define the sequence of operations that will be performed in our v4 swap: -- `SWAP_EXACT_IN_SINGLE`: This action specifies that we want to perform an exact input swap using a single pool. +- `SWAP_EXACT_IN_SINGLE`: This action specifies that we want to perform an exact input swap using a single pool. Its `minHopPriceX36` field is the per-hop price floor added in Universal Router 2.1.1. Setting it to `"0"` disables the per-hop check, so `amountOutMinimum` alone enforces slippage. - `SETTLE_ALL`: This action ensures all input tokens involved in the swap are properly paid. This is part of v4's settlement pattern for handling token transfers. - `TAKE_ALL`: This final action collects all output tokens after the swap is complete. diff --git a/content/sdks/v4/overview.mdx b/content/sdks/v4/overview.mdx index 0862df4f8..6b0b30bd4 100644 --- a/content/sdks/v4/overview.mdx +++ b/content/sdks/v4/overview.mdx @@ -1,7 +1,7 @@ --- description: Get started with Uniswap v4 SDK concepts, guides, and integration resources. -id: overview -title: Overview +title: Uniswap v4 SDK Overview +sidebarTitle: Overview --- The Uniswap v4 SDK provides abstractions to assist you with interacting with the Uniswap v4 smart contracts in a TypeScript/JavaScript environment (for example websites and node scripts). diff --git a/content/trading/custom-interface-links.mdx b/content/trading/custom-interface-links.mdx index 81e11e0fc..9786193b3 100644 --- a/content/trading/custom-interface-links.mdx +++ b/content/trading/custom-interface-links.mdx @@ -1,5 +1,4 @@ --- -id: custom-interface-linking title: Custom Linking description: Configure Uniswap interface URL parameters for prefilled swap and pool flows in v2 integration experiences. --- diff --git a/content/trading/embed-app.mdx b/content/trading/embed-app.mdx new file mode 100644 index 000000000..46e1b0d92 --- /dev/null +++ b/content/trading/embed-app.mdx @@ -0,0 +1,98 @@ +--- +title: "Embed the Uniswap App" +description: "Embed the Uniswap app in an iframe with full-app or swap-only layouts, swap prefill parameters, and origin allowlisting." +--- + +Embed the Uniswap app on your own site with an ` +``` + +Framing is gated by an origin allowlist. Your site cannot load the embed until your origin is added. See [Allowlist Your Origin](#allowlist-your-origin). + +## Layout Modes + +The `view` query parameter selects which surface renders. It is read once when the frame mounts and stays fixed for the session, so in-frame navigation cannot switch surfaces. + +| URL | Surface | +|---|---| +| `https://app.uniswap.org/embed` | Full app (default) | +| `https://app.uniswap.org/embed?view=swap` | Swap-only | + +### Full app + +The default surface renders the complete app, including the header, connection flows, balances, and pending transactions. Use it for larger embeds where users benefit from the full experience. + +### Swap only + +`?view=swap` drops the surrounding app interface (header, navigation, and menus) and mounts the swap form on its own: no chart, no tab switching, and no in-frame route changes. Use it for tight embeds where that surrounding interface, such as the hamburger menu, looks out of place. + +## Swap Configuration Parameters + +The swap form reads the same query parameters as [Custom Linking](/docs/trading/custom-interface-links). Append them to the embed URL to prefill the form. + +| Parameter | Type | Description | +|---|---|---| +| `chain` | `string` | Interface chain name, for example `ethereum`, `base`, `arbitrum`, or `unichain`. | +| `inputCurrency` | `address` or `ETH` | The currency to swap from. | +| `outputCurrency` | `address` or `ETH` | The currency to swap to. | +| `value` | `number` | The token amount. Only applied when a currency parameter is also set. | +| `field` | `string` | Which side `value` applies to. Must be `input` or `output`, and only applied when `value` is set. | + +### Example + +```html + +``` + +## Allowlist Your Origin + + + +The embed surface is served with a `frame-ancestors` Content Security Policy that blocks framing by default. Until your origin is on the embed allowlist, the browser refuses to load the iframe and logs a `frame-ancestors` CSP violation in the console. This is a deliberate onboarding step, not a setting you can configure yourself. + + + +Each allowlisted origin relaxes clickjacking protection for that origin, so additions are manually reviewed and applied by the Uniswap team. This is the same review that all approved embedders go through. + +### What to provide + +Send the exact production origin(s) you will frame from, each as a full scheme and host with no path or trailing slash, for example `https://app.example.com`. + +- Origins are matched exactly. `https://example.com` does not cover `https://app.example.com`, and `http://` does not cover `https://`. +- Subdomain wildcards are supported (`https://*.example.com`), but a wildcard does not match the apex domain. To cover both, list them separately: `https://example.com` and `https://*.example.com`. +- You can allowlist more than one origin. Include every origin you plan to embed from, such as separate staging or preview hosts. + +### How to request it + +Open a request through the Help Center with the origins above and a short description of where the embed will appear. The Uniswap team reviews each request and adds approved origins to the allowlist. + +Approved origins take effect with the next web release, so allow time for a deploy after your request is confirmed. Once live, your iframe loads without the CSP block. + +## Behavior Inside a Frame + +Two actions cannot complete inside a frame and instead **frame-bust**: the top-level window navigates to the full Uniswap app to finish the action outside the frame, preserving the current query string and hash. + +| Action | Top-level destination | +|---|---| +| Send | `/send` | +| Embedded wallet sign-in or sign-up (passkey) | `/swap` | + +Money-moving actions and in-DOM signing must happen on the top-level `app.uniswap.org` origin, never inside a third-party frame. Breaking out is a clickjacking protection: it guarantees the user sees the real Uniswap origin in the address bar before authorizing anything. Expect the parent page to navigate away when a user triggers one of these flows. diff --git a/content/trading/meta.json b/content/trading/meta.json index a5b1a0586..7f145c216 100644 --- a/content/trading/meta.json +++ b/content/trading/meta.json @@ -1,5 +1,5 @@ { - "title": "Trade", + "title": "Swapping", "root": true, - "pages": [ "overview", "swapping-api", "custom-interface-links"] + "pages": ["overview", "swapping-api", "custom-interface-links", "embed-app"] } diff --git a/content/trading/overview.mdx b/content/trading/overview.mdx index 568e27e25..e90a1777a 100644 --- a/content/trading/overview.mdx +++ b/content/trading/overview.mdx @@ -1,7 +1,30 @@ --- -id: Overview title: Trading Overview +sidebarTitle: Overview description: Understand swap integration paths on Uniswap v4 using Custom Linking, the Uniswap API, SDK, and smart contracts. +keywords: + - swap integration + - Trading API + - custom linking + - Universal Router + - swap hooks + - slippage +faqs: + - question: What are the ways to integrate Uniswap swaps into my app? + answer: |- + There are four integration paths, in rising order of complexity. Custom Linking directs users to the Uniswap web app with pre-filled swap parameters through URL query strings. The Uniswap Trading API is a hosted service that handles routing, quoting, and transaction construction. The Uniswap SDK computes routes and quotes locally on the client side. Direct smart contract integration against the Universal Router or PoolManager gives onchain contracts direct control and composability. + - question: Does the Uniswap Trading API execute swaps for me? + answer: |- + No. The Uniswap Trading API handles routing, quoting, and transaction construction, and returns encoded transaction data. Your application handles wallet signing and onchain submission through your own signer or RPC provider. The flow is check_approval to verify Permit2 or router authorization, quote to get routing and quote data, then swap to get the encoded transaction. + - question: How do I add Uniswap swaps to my site without building a swap UI? + answer: |- + Use Custom Linking. Append URL query parameters to the Uniswap web app swap URL to pre-fill the input and output tokens, the amount, and the UI theme. The Uniswap interface configures the swap automatically for the user, so you do not manage transactions, quoting, or a custom UI. + - question: How do I execute a Uniswap swap from a smart contract? + answer: |- + Interact with the Universal Router, the recommended entry point, or with the PoolManager directly. The Universal Router uses a command-encoding pattern where you pack a sequence of actions, such as swap, settle input tokens, and take output tokens, into byte arrays and execute them in a single transaction. Always enforce slippage limits through amountOutMinimum or an onchain price oracle; setting it to zero leaves your contract vulnerable to sandwich attacks and price manipulation. + - question: Can I customize how swaps execute on Uniswap v4? + answer: |- + Yes, by writing a hook contract. Hooks are external contracts that a Uniswap v4 pool calls at specific lifecycle points. For swaps, beforeSwap runs before the swap executes and can modify fees, enforce conditions, or reject the swap, while afterSwap runs after execution and receives the resulting balance delta. A hook declares which lifecycle points it implements through getHookPermissions. --- Uniswap offers distinct methods for integrating swapping functionality into your application. Choosing the right approach depends on your specific needs regarding customization, control, and development resources. @@ -155,3 +178,69 @@ Hooks are external contracts that a Uniswap v4 pool calls at specific points dur - **`afterSwap`**: called after the swap executes. Receives the resulting `BalanceDelta` and can perform follow-up logic. A hook contract declares which lifecycle points it implements via `getHookPermissions()`, and is associated with a pool during deployment. + +## FAQ + +
+ What are the ways to integrate Uniswap swaps into my app? + + + + There are four integration paths, in rising order of complexity: + + * **[Custom Linking](/docs/trading/custom-interface-links)**: directs users to the Uniswap web app with pre-filled swap parameters through URL query strings. + * **[Uniswap Trading API](/docs/trading/swapping-api/getting-started)**: a hosted service that handles routing, quoting, and transaction construction. + * **[Uniswap SDK](/docs/sdks/v4/guides/swapping/quoting)**: computes routes and quotes locally on the client side. + * **[Smart contracts](/docs/protocols/v4/guides/swapping/swapping)**: direct integration against the Universal Router or `PoolManager` for onchain control and composability. + + + +
+ +
+ Does the Uniswap Trading API execute swaps for me? + + + + No. The [Trading API](/docs/trading/swapping-api/getting-started) handles routing, quoting, and transaction construction, and returns encoded transaction data. Your application handles wallet signing and onchain submission through your own signer or RPC provider. + + The flow is `/check_approval` to verify Permit2 or router authorization, `/quote` to get routing and quote data, then `/swap` to get the encoded transaction. + + + +
+ +
+ How do I add Uniswap swaps to my site without building a swap UI? + + + + Use [Custom Linking](/docs/trading/custom-interface-links). Append URL query parameters to `https://app.uniswap.org/#/swap` to pre-fill the input and output tokens, the amount, and the UI theme. The Uniswap interface configures the swap automatically for the user, so you do not manage transactions, quoting, or a custom UI. + + + +
+ +
+ How do I execute a Uniswap swap from a smart contract? + + + + Interact with the [Universal Router](/docs/protocols/universal-router/overview), the recommended entry point, or with the `PoolManager` directly. The Universal Router uses a command-encoding pattern where you pack a sequence of actions, such as swap, settle input tokens, and take output tokens, into byte arrays and execute them in a single transaction. See [swapping with smart contracts](/docs/protocols/v4/guides/swapping/swapping). + + Always enforce slippage limits through `amountOutMinimum` or an onchain price oracle; setting it to zero leaves your contract vulnerable to sandwich attacks and price manipulation. + + + +
+ +
+ Can I customize how swaps execute on Uniswap v4? + + + + Yes, by writing a [hook](/docs/protocols/v4/guides/hooks/swap-hooks) contract. Hooks are external contracts that a Uniswap v4 pool calls at specific lifecycle points. For swaps, `beforeSwap` runs before the swap executes and can modify fees, enforce conditions, or reject the swap, while `afterSwap` runs after execution and receives the resulting `BalanceDelta`. A hook declares which lifecycle points it implements through `getHookPermissions`. + + + +
diff --git a/content/trading/swapping-api/amm-vs-uniswapx-routing.mdx b/content/trading/swapping-api/amm-vs-uniswapx-routing.mdx index 60a3250a5..337da6c71 100644 --- a/content/trading/swapping-api/amm-vs-uniswapx-routing.mdx +++ b/content/trading/swapping-api/amm-vs-uniswapx-routing.mdx @@ -1,5 +1,6 @@ --- title: "AMM vs UniswapX Routing" +sidebarTitle: "Routing" description: "Understand how the Uniswap API evaluates Uniswap AMM and UniswapX routes when returning swap quotes." --- @@ -89,3 +90,5 @@ The web app typically considers all available protocols unless the user changes This is expected in some cases. On some chains, UniswapX quotes are subject to minimum notional thresholds, and solver participation may vary by trade size and market conditions. For route behavior and configuration details, see [Swap Routing](/docs/trading/swapping-api/concepts/swap-routing) and the [POST `/quote` API reference](/docs/api-reference/aggregator_quote). + +For developer support, reach out to our team through the Help Center. diff --git a/content/trading/swapping-api/building-prerequisites.mdx b/content/trading/swapping-api/building-prerequisites.mdx deleted file mode 100644 index f8e3df7e4..000000000 --- a/content/trading/swapping-api/building-prerequisites.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: 'Building Prerequisites' -description: 'Prepare your Uniswap API integration with signer, RPC, JSON request, and API key management prerequisites.' ---- - -To build with the Uniswap API, you will need the following technical capabilities and environment parameters. - -**1. Ability to Sign and Send EVM Transactions and Messages** - -You must have the technical capability to: - -- Sign transactions using an EVM-compatible wallet, key management system, or backend signer -- Broadcast transactions to your preferred RPC provider -- Manage gas, nonces, and transaction lifecycle -- Present EIP-712 Permit2 messages to the user for signing - -**2. Familiarity with JSON-Based API Integration** - -You need to be able to: - -- Construct and parse JSON requests/responses -- Handle standard HTTP status codes -- Implement retries or timeouts where required - -**3. Access to Reliable RPC Infrastructure** - -You must operate or use a provider that supports: - -- The chains you wish to trade on (e.g., Ethereum, Unichain, other L2s) -- Knowledge of how to troubleshoot RPC submission failures - -**4. Secure API Key Management** - -Your system must be able to: - -- Store and protect your Uniswap API key -- Attach it to all requests via HTTPS -- Protect it from exposure in front-end code (ex. using a proxy) \ No newline at end of file diff --git a/content/trading/swapping-api/common-errors.mdx b/content/trading/swapping-api/common-errors.mdx index 5eea937cd..e4b2cb441 100644 --- a/content/trading/swapping-api/common-errors.mdx +++ b/content/trading/swapping-api/common-errors.mdx @@ -9,21 +9,39 @@ description: Troubleshoot common Uniswap API request, quoting, authentication, a The API is specific about request header validation. In particular, ensure that your `accept` and `content-type` headers only include the value `application/json`. For a complete example of properly formatted request headers, see the authentication section of the [Developer Dashboard](https://developers.uniswap.org/dashboard). -If you're sending the optional `X-Agent-Info` attribution header and it isn't being picked up, check the response for an `x-agent-info-status: malformed` header — see [Agent Attribution](/docs/trading/swapping-api/agent-attribution#confirming-it-was-received) for the full set of rules that make the header malformed. A malformed `X-Agent-Info` never causes an error response; the request proceeds without attribution. +If you're sending the optional `X-Agent-Info` attribution header and it isn't being picked up, check the response for an `x-agent-info-status: malformed` header. See [Agent Attribution](/docs/trading/swapping-api/start-building/agent-attribution#what-makes-a-header-malformed) for the full set of rules that make the header malformed. A malformed `X-Agent-Info` never causes an error response; the request proceeds without attribution. ### Rate limits -Most API keys have a default rate limit of 6 requests per second (RPS). If you exceed the rate limit supported by an API key you can expect to receive an HTTP 429 error. If you receive a 429 error, we recommend pausing all requests from your API key and then retrying your requests. If you require a higher rate limit than what your API key is currently provisioned for, please reach out to [Uniswap Developer Support](https://support.uniswap.org/hc/en-us/requests/new). For more information on rate limits, see the [Developer Dashboard](https://developers.uniswap.org/dashboard). +Most API keys have a default rate limit of 6 requests per second (RPS). If you exceed the rate limit supported by an API key you can expect to receive an HTTP 429 error. If you receive a 429 error, we recommend pausing all requests from your API key and then retrying your requests. If you require a higher rate limit than what your API key is currently provisioned for, please reach out to our team through the Help Center. For more information on rate limits, see the [Developer Dashboard](https://developers.uniswap.org/dashboard). ## Error Code Troubleshooting ### 404 No quotes available -The most commonly encountered HTTP error is an HTTP 404 with a message "No quotes available" from the [`/quote`](/docs/trading/swapping-api/getting-started) endpoint. This error can happen for a variety of reasons related to request syntax, rather than there being no actual route between the specified tokens. In order of most common to less common reasons for receiving this error: -* The `amount` is too low to be quoted by UniswapX. UniswapX requires a minimum of **300 USDC equivalent on all supported chains**. Requests below this threshold will fail. See [UniswapX Chain Support](/docs/trading/swapping-api/supported-chains#uniswapx-chain-support) for details. -* The specified chain is not supported by UniswapX. UniswapX has limited chain support. -* The specified token(s) do not match the specified chain. The token addresses specified must be those belonging to the token on the given chain (ex. the USDC address on Mainnet is different than that on Base). -* A combined bridge and swap quote is requested. The API can provide a quote for either a bridge (different input/output chains, same token) or a swap (same chain, different input/output tokens), but not both simultaneously. For a list of bridgeable tokens, see [Supported Chains](/docs/trading/swapping-api/supported-chains). +The most commonly encountered HTTP error is an HTTP 404 from the [`/quote`](/docs/trading/swapping-api/getting-started) endpoint. The `errorCode` field identifies the cause, and `detail` carries a human-readable explanation: + +```json +{ + "errorCode": "QuoteAmountTooLowError", + "detail": "Order size is below the minimum quotable size for the requested protocols on this chain.", + "requestId": "..." +} +``` + +`errorCode` is a stable enum. `detail` is free text and may be reworded without notice. New `errorCode` values may be added over time, so treat unrecognized values the same as you do `ResourceNotFound`. + +| `errorCode` | What it means | What to do | +|---|---|---| +| `QuoteAmountTooLowError` | The `amount` is below the minimum quotable size for the requested protocols — most commonly UniswapX minimums on L2s (see [UniswapX Chain Support](/docs/trading/swapping-api/supported-chains#uniswapx-chain-support)) | Increase the amount, or widen `protocols` | +| `NoRouteFoundError` | Routing completed and found no viable route for this pair | Verify token addresses match the specified chain; do not retry unchanged | +| `UnsupportedTokenError` | A requested token is not routable (unknown or not on this chain) | Verify the token address belongs to the given chain (ex. USDC on Mainnet differs from Base) | +| `UnsupportedChainError` | The chain is not supported for this operation | See [Supported Chains](/docs/trading/swapping-api/supported-chains) | +| `UniswapXNotSupportedOnChainError` | A UniswapX protocol was requested on a chain it does not serve | Remove the UniswapX protocol pin, or change chain | +| `UpstreamTimeoutError` | A routing dependency timed out or failed | **Retry with exponential backoff** — this is the only cause where an unchanged retry can succeed | +| `ResourceNotFound` | The failure could not be classified (`detail` is "No quotes available") | Retry cautiously; contact support with the `requestId` if persistent | + +A request that combines a bridge and a swap (different chains *and* different tokens) is not supported as a single quote and currently surfaces as `ResourceNotFound`. Request a bridge or a swap, not both — for bridgeable pairs see [Supported Chains](/docs/trading/swapping-api/supported-chains). ### 400 Request validation error @@ -31,4 +49,6 @@ Request validation errors are returned when a request does not contain the minim ### 401 Unauthorized error -All API requests must be authenticated through the inclusion of a valid API key in the header of the request. If you do not have an API key, you may create one through the [Uniswap Developer Platform](https://developers.uniswap.org/dashboard/welcome?utm_medium=eco&utm_source=platform&utm_campaign=20260428-swapping-api-errors&utm_content=auth-section&utm_term=self-serve). 401 errors may also be returned if the request has malformed or missing required headers, or if headers contain unsupported values (see above). For more details on authentication requirements, see the [Developer Dashboard](https://developers.uniswap.org/dashboard). \ No newline at end of file +All API requests must be authenticated through the inclusion of a valid API key in the header of the request. If you do not have an API key, you may create one through the [Uniswap Developer Platform](https://developers.uniswap.org/dashboard/welcome?utm_medium=eco&utm_source=platform&utm_campaign=20260428-swapping-api-errors&utm_content=auth-section&utm_term=self-serve). 401 errors may also be returned if the request has malformed or missing required headers, or if headers contain unsupported values (see above). For more details on authentication requirements, see the [Developer Dashboard](https://developers.uniswap.org/dashboard). + +For developer support, reach out to our team through the Help Center. \ No newline at end of file diff --git a/content/trading/swapping-api/chained-actions.mdx b/content/trading/swapping-api/concepts/chained-actions.mdx similarity index 89% rename from content/trading/swapping-api/chained-actions.mdx rename to content/trading/swapping-api/concepts/chained-actions.mdx index 9d96e2f80..dbe50bf65 100644 --- a/content/trading/swapping-api/chained-actions.mdx +++ b/content/trading/swapping-api/concepts/chained-actions.mdx @@ -1,5 +1,6 @@ --- title: Swapping with Chained Actions +sidebarTitle: Chained Actions description: Cross-chain and multi-step swaps execute as an ordered plan of steps through the Uniswap Trading API. --- @@ -13,13 +14,13 @@ A few common shapes: Without a coordinating API, an integrator would orchestrate each leg by hand: quote a swap, submit it, wait for confirmation, quote a bridge, submit it, wait again, and handle a failure at any stage. Chained Actions package that sequence into a state-tracked plan. The API handles routing and quoting. Your application handles execution and user confirmation. -To build against the plan endpoints, see the [Chained Actions Integration Guide](/docs/trading/swapping-api/chained-actions-integration). +To build against the plan endpoints, see the [Chained Actions Integration Guide](/docs/trading/swapping-api/start-building/chained-actions-integration). ## Execution flow A trade becomes a Chained Action when `/quote` returns `"routing": "CHAINED"`. From there, three `/plan` endpoints drive execution: `POST /plan` creates the plan, `PATCH /plan` advances it as each step completes, and `GET /plan` reports the current state. -![Chained Actions execution flow](../images/chained-actions-flow.png) +![Chained Actions execution flow](../../images/chained-actions-flow.png) At a high level: @@ -31,7 +32,7 @@ At a high level: ## Plans and steps -A plan is an ordered array of steps identified by a unique `planId`. Each step is one wallet action: an approval, a swap, a bridge, or a UniswapX order. To execute a step, you branch on its `method` and `payloadType`, covered in the [integration guide](/docs/trading/swapping-api/chained-actions-integration). +A plan is an ordered array of steps identified by a unique `planId`. Each step is one wallet action: an approval, a swap, a bridge, or a UniswapX order. To execute a step, you branch on its `method` and `payloadType`, covered in the [integration guide](/docs/trading/swapping-api/start-building/chained-actions-integration). Only one step is active at any moment. The rest stay blocked until the preceding step completes. Each future step's amounts derive from the confirmed output of the step before it, so only the active step and any completed steps carry a populated payload. @@ -57,7 +58,7 @@ The router automatically selects one of three patterns, based on the tokens and | **Bridge to Swap (B→S)** | Source token is native ETH, and the destination token is not directly bridgeable from it | ETH (Mainnet) to USDC (Base) | Bridge → Swap | | **Swap to Bridge to Swap (S→B→S)** | Default fallback, using ETH as the bridge medium | USDC (Mainnet) to PEPE (Base) | `[Approval]` → Swap → Bridge → Swap | -AMM swap steps can route through Uniswap v2, v3, or v4. The longest plan has three quote-generating steps, plus any approval steps on top. A plan can also end in error: see [error handling and recovery](/docs/trading/swapping-api/chained-actions-integration#error-handling-and-recovery) in the integration guide. +AMM swap steps can route through Uniswap v2, v3, or v4. The longest plan has three quote-generating steps, plus any approval steps on top. A plan can also end in error: see [error handling and recovery](/docs/trading/swapping-api/start-building/chained-actions-integration#error-handling-and-recovery) in the integration guide. ## Constraints @@ -67,5 +68,5 @@ AMM swap steps can route through Uniswap v2, v3, or v4. The longest plan has thr ## Next steps -- [Chained Actions Integration Guide](/docs/trading/swapping-api/chained-actions-integration): the full execution loop, with `cURL` examples for each step, proof submission, polling, and error recovery. +- [Chained Actions Integration Guide](/docs/trading/swapping-api/start-building/chained-actions-integration): the full execution loop, with `cURL` examples for each step, proof submission, polling, and error recovery. - [Swap Routing](/docs/trading/swapping-api/concepts/swap-routing): how to choose protocols and routing preferences on the underlying swaps. diff --git a/content/trading/swapping-api/concepts/meta.json b/content/trading/swapping-api/concepts/meta.json index 57d54a95c..811ce1cc7 100644 --- a/content/trading/swapping-api/concepts/meta.json +++ b/content/trading/swapping-api/concepts/meta.json @@ -3,6 +3,7 @@ "pages": [ "permit2", "no-permit2-workflow", - "swap-routing" + "swap-routing", + "chained-actions" ] } diff --git a/content/trading/swapping-api/concepts/no-permit2-workflow.mdx b/content/trading/swapping-api/concepts/no-permit2-workflow.mdx index 907bc4ab5..54bc04d8a 100644 --- a/content/trading/swapping-api/concepts/no-permit2-workflow.mdx +++ b/content/trading/swapping-api/concepts/no-permit2-workflow.mdx @@ -18,7 +18,7 @@ The proxy approval flow cannot execute UniswapX orders. UniswapX requires Permit ## When to Use Proxy Approval The no-Permit2 flow may be appropriate if: -- Your infrastructure requires a strict approve —> swap transaction sequence +- Your infrastructure requires a strict approve -> swap transaction sequence - Your system cannot generate Permit2 signatures - Your wallet or signing system does not support EIP-712 signing diff --git a/content/trading/swapping-api/concepts/permit2.mdx b/content/trading/swapping-api/concepts/permit2.mdx index 04dc17e88..cda3f493e 100644 --- a/content/trading/swapping-api/concepts/permit2.mdx +++ b/content/trading/swapping-api/concepts/permit2.mdx @@ -6,7 +6,7 @@ description: Learn how to use Permit2 approvals and troubleshoot common signing ## Swapping with Permit2 The Uniswap API supports a swap flow that uses Permit2 signatures. This option is the default and it provides security to swapper wallets which direct router approval workflows cannot. -In this flow, the swapping wallet grants ERC-20 approval to the Permit2 contract and then subsequently signs messages which authorize Permit2 to spend tokens from the swapping wallet with the Universal Router. This flow requires that integrators provide up to a three-step swap process: approve —> sign permit —> swap. +In this flow, the swapping wallet grants ERC-20 approval to the Permit2 contract and then subsequently signs messages which authorize Permit2 to spend tokens from the swapping wallet with the Universal Router. This flow requires that integrators provide up to a three-step swap process: approve -> sign permit -> swap. ## What Is a Permit2 Message and How Is It Used? diff --git a/content/trading/swapping-api/concepts/swap-routing.mdx b/content/trading/swapping-api/concepts/swap-routing.mdx index 386e3672f..3e9dfcf6d 100644 --- a/content/trading/swapping-api/concepts/swap-routing.mdx +++ b/content/trading/swapping-api/concepts/swap-routing.mdx @@ -1,5 +1,6 @@ --- -title: 'Swap Routing' +title: Swap Routing in the Uniswap API +sidebarTitle: Swap Routing description: 'Use Uniswap API routing fields to choose protocol paths and return the most efficient quote flow for your integration.' icon: 'route' --- @@ -9,7 +10,7 @@ In order to get the appropriate swap routing, it is important to closely conside - The `protocols` field is used to specify the protocols from which pricing will be considered and through which your swap may eventually be executed. The possible values for the field are `V2`, `V3`, `V4`, `UNISWAPX_V2`, and `UNISWAPX_V3` - The `routingPreference` field is used to specify the preferred matching strategy. The possible values for the field are `BEST_PRICE` and `FASTEST` -For complete information on the available values and combinations for the `protocols` and `routingPreference` fields, see [Swapping Architecture Overview](/docs/trading/swapping-api/getting-started). A summary is provided below: +For complete information on the available values and combinations for the `protocols` and `routingPreference` fields, see [Swapping via the Uniswap API](/docs/trading/swapping-api/getting-started). A summary is provided below: ## Routing Outcomes @@ -21,4 +22,4 @@ For complete information on the available values and combinations for the `proto ## Cross-chain and multi-step routing -Some trades cannot settle in a single transaction, either because they cross chains or because they need more than one step on the same chain. For these, `/quote` returns `"routing": "CHAINED"` and the API drives execution as an ordered plan of steps. See [Swapping with Chained Actions](/docs/trading/swapping-api/chained-actions). \ No newline at end of file +Some trades cannot settle in a single transaction, either because they cross chains or because they need more than one step on the same chain. For these, `/quote` returns `"routing": "CHAINED"` and the API drives execution as an ordered plan of steps. See [Swapping with Chained Actions](/docs/trading/swapping-api/concepts/chained-actions). \ No newline at end of file diff --git a/content/trading/swapping-api/faqs.mdx b/content/trading/swapping-api/faqs.mdx index fec878d93..415816d68 100644 --- a/content/trading/swapping-api/faqs.mdx +++ b/content/trading/swapping-api/faqs.mdx @@ -1,5 +1,5 @@ --- -title: Swapping FAQ +title: Uniswap API FAQs description: Find answers to common Uniswap API integration questions about authentication, quotes, routing, rate limits, Permit2 approvals, UniswapX, error handling, fees, and support. keywords: - uniswap-api @@ -21,7 +21,7 @@ faqs: - question: Is there an OpenAPI / OAS specification I can use to build a client? answer: "Yes. AI builders can consume the full Open API Specification (OAS) at https://trade-api.gateway.uniswap.org/v1/api.json." - question: What Permit2 address do I need to whitelist for approvals? - answer: "The Permit2 address for all chains we support EXCEPT zkSync is: 0x000000000022D473030F116dDEE9F6B43aC78BA3. The Permit2 address for zkSync is: 0x0000000000225e31D15943971F47aD3022F714Fa." + answer: Approving the Permit2 contract uses the same contract address across supported chains, with a separate address on zkSync. See the Permit2 FAQ for the canonical contract address and audit details. - question: What parameter determines if I receive a gasless quote? answer: |- When the /quote endpoint's routingPreference is set to BEST_PRICE, the endpoint will attempt to find a quote that nets users the best execution price for a trade. Assuming the protocols are not limited, the endpoint will attempt to get a gasless order and a Uniswap Protocol swap quote, calculate which is currently providing the best price to the user including transaction costs, and return that quote. Integrators of the API who only want gasless quotes may limit the protocols considered to just gasless options (for example UniswapX). There are some scenarios where the API will not be able to get a gasless quote, even if the integrator attempts to force it. The most common reason for this (on chains where UniswapX is supported) is that the gas price of the swap is too high relative to the value of the trade. In cases where the gas cost is 20% or more of the total trade value, the API will always return Uniswap Protocol swap quotes (if permitted by protocols) or fail. @@ -33,9 +33,9 @@ faqs: answer: If a quote fails, the response includes helpful information to understand the problem with the request. The most common quote failure reason is that no route can be found for the quoted pair. This can occur for various reasons, including all available routes would exceed the slippage tolerance, insufficient liquidity for the requested quote size, or no available route through the specified protocols. We recommend retrying the quote but modifying one or more parameters of the requested quote (protocols used, slippage allowed, or the size of the swap). - question: How do I quote the native token? answer: See the Supported Chains guide for native-token swap details. To quote the native token via UniswapX you must set the x-erc20eth-enabled header in your quote request to true. - - question: Why am I getting "No Quotes Available" as a response? + - question: Why am I getting 404 errors from /quote? answer: |- - A quote response with "No Quotes Available" means that the Uniswap router was unable to find a route for the proposed swap. This can happen for a number of reasons, many of which can be easily avoided by understanding the API constraints. While not exhaustive, some of the most common issues are: there is insufficient liquidity to fill the swap; if making a bridge request, the selected token cannot be bridged between the two selected networks; if making a UniswapX-only request, the amount is below 300 USDC equivalent and the UniswapX quote does not improve on the AMM route by at least 0.2%; the request is requesting a bridge and swap (currently not supported). + A 404 from /quote means the request passed schema validation, but the router could not return a quote for it. The errorCode field identifies the cause; the full reference, with what to do for each value, is in the Troubleshooting guide. Common causes: insufficient liquidity for the pair (NoRouteFoundError); a UniswapX-only request below the chain's minimum quotable size (QuoteAmountTooLowError); a token that is not routable (UnsupportedTokenError); or a chain not supported for the operation (UnsupportedChainError). Only UpstreamTimeoutError is safe to retry unchanged. - question: What are the valid values for the protocols field? answer: "The possible values are V2, V3, V4, UNISWAPX_V2, and UNISWAPX_V3. To perform a swap using only UniswapX protocol liquidity, specify protocols as UNISWAPX_V2 or UNISWAPX_V3. Multiple UniswapX protocols may not be specified in the same request. For more information, please visit Swap Routing." - question: Can I do a wrap/unwrap through UniswapX? @@ -83,7 +83,7 @@ faqs: answer: |- A Priority quote comes from the PriorityOrderReactor, an older UniswapX auction type that is not currently returned by the API. Today the API returns DutchV2 on Mainnet and DutchV3 on the other supported chains, and it notifies you of the auction type in the quote response. For more information on different auction types, see the auction-types docs. - question: Which chains and protocol versions does UniswapX support? - answer: "UniswapX v2 is supported on Mainnet (chain ID 1), Arbitrum (42161), and Base (8453). UniswapX v3 is supported on Arbitrum (42161), Avalanche (43114), Base (8453), BNB Smart Chain (56), Robinhood Chain (4663), Tempo (4217), and Unichain (130). If you submit a quote request with protocols set to UNISWAPX_V2 or UNISWAPX_V3 on a chain not listed above, the request will fail. Most integrators do not need to set protocols and can let the API select the best route." + answer: "UniswapX v2 is supported on Mainnet (chain ID 1), Arbitrum (42161), and Base (8453). UniswapX v3 is supported on Arbitrum (42161), Arc (5042), Avalanche (43114), Base (8453), BNB Smart Chain (56), Ink (57073), Monad (143), Robinhood Chain (4663), Tempo (4217), and Unichain (130). If you submit a quote request with protocols set to UNISWAPX_V2 or UNISWAPX_V3 on a chain not listed above, the request will fail. Most integrators do not need to set protocols and can let the API select the best route." - question: Are there restrictions on how I can integrate the API? answer: The API is free to integrate into any application including whitelabeled swap experiences, wallets, mobile apps, and more. You are responsible for ensuring that your integration complies with the API Terms of Use. We are flexible regarding how you decide to offer the API through your application. Developers may create a whitelabel swap experience, add swapping to a custodial wallet, integrate the APIs into a mobile application, and more. - question: Can I restrict token pairs available to my users? @@ -97,7 +97,7 @@ faqs: - question: Does Uniswap take positive slippage as fees? answer: No. Uniswap Labs never takes positive slippage. All price improvement achieved at execution is for the benefit of the end swapper. - question: How do I submit a ticket? - answer: Use the Uniswap API help form to reach the team without leaving this page. Note that we are unable to provide technical assistance with troubleshooting your code, deployment, or workflow. + answer: Use the Help Center to reach the team without leaving this page. Note that we are unable to provide technical assistance with troubleshooting your code, deployment, or workflow. - question: What information should I include when reporting an API issue to support? answer: "When reporting issues, include: Request ID from API response, Full request/response payloads (sanitize sensitive data), Chain ID and transaction hash (if applicable), Timestamp of the request." - question: Is there a sandbox environment? @@ -115,7 +115,7 @@ Use this page to find answers to the questions Uniswap API integrators ask most
- Integration of the API can be done in less than two weeks. We provide [sample code](/docs/trading/swapping-api/swapping-code-examples) to help get you off the ground quickly. To get started, reach out to request an API key. If you are not yet in touch with Uniswap Labs, register your interest in integrating the API through the [Uniswap Developer Platform](https://developers.uniswap.org/dashboard/welcome). + Integration of the API can be done in less than two weeks. We provide [sample code](/docs/trading/swapping-api/start-building/swapping-code-examples) to help get you off the ground quickly. To get started, reach out to request an API key. If you are not yet in touch with Uniswap Labs, register your interest in integrating the API through the [Uniswap Developer Platform](https://developers.uniswap.org/dashboard/welcome).
@@ -167,9 +167,7 @@ Use this page to find answers to the questions Uniswap API integrators ask most
- The Permit2 address for all chains we support **EXCEPT** zkSync is: `0x000000000022D473030F116dDEE9F6B43aC78BA3`. - - The Permit2 address for zkSync is: `0x0000000000225e31D15943971F47aD3022F714Fa`. + Approving the Permit2 contract uses the same contract address across supported chains, with a separate address on zkSync. See the [Permit2 FAQ](/docs/protocols/permit2/overview#faq) for the canonical contract address and audit details.
@@ -237,15 +235,14 @@ Use this page to find answers to the questions Uniswap API integrators ask most
- Why am I getting "No Quotes Available" as a response? + Why am I getting 404 errors from `/quote`?
- A quote response with "No Quotes Available" means that the Uniswap router was unable to find a route for the proposed swap. This can happen for a number of reasons, many of which can be easily avoided by understanding the API constraints. While not exhaustive, some of the most common issues are: - * There is insufficient liquidity to fill the swap + A 404 from `/quote` means the request passed schema validation, but the router could not return a quote for it. The `errorCode` field identifies the cause; the full reference, with what to do for each value, is in [Troubleshooting Common Errors](/docs/trading/swapping-api/common-errors#404-no-quotes-available). Common causes include: + * There is insufficient liquidity to fill the swap (`errorCode: NoRouteFoundError`) * If making a bridge request, the selected token cannot be bridged between the two selected networks (check [Supported Bridges](/docs/api-reference/get_swappable_tokens)) - * If making a UniswapX-only request, the amount is below 300 USDC equivalent and the UniswapX quote does not improve on the AMM route by at least 0.2% (see [Supported Chains](/docs/trading/swapping-api/supported-chains#uniswapx-chain-support)) - * The request is requesting a bridge and swap (currently not supported) + * If making a UniswapX-only request, the amount is below the chain's minimum quotable size (`errorCode: QuoteAmountTooLowError`; see [Supported Chains](/docs/trading/swapping-api/supported-chains#uniswapx-chain-support))
@@ -529,7 +526,7 @@ Use this page to find answers to the questions Uniswap API integrators ask most
- UniswapX v2 is supported on Mainnet (chain ID 1), Arbitrum (42161), and Base (8453). UniswapX v3 is supported on Arbitrum (42161), Avalanche (43114), Base (8453), BNB Smart Chain (56), Robinhood Chain (4663), Tempo (4217), and Unichain (130). + UniswapX v2 is supported on Mainnet (chain ID 1), Arbitrum (42161), and Base (8453). UniswapX v3 is supported on Arbitrum (42161), Arc (5042), Avalanche (43114), Base (8453), BNB Smart Chain (56), Ink (57073), Monad (143), Robinhood Chain (4663), Tempo (4217), and Unichain (130). If you submit a quote request with `protocols` set to `UNISWAPX_V2` or `UNISWAPX_V3` on a chain not listed above, the request will fail. Most integrators do not need to set `protocols` and can let the API select the best route. @@ -616,7 +613,7 @@ Use this page to find answers to the questions Uniswap API integrators ask most
- Use the Uniswap API help form to reach the team without leaving this page. Note that we are unable to provide technical assistance with troubleshooting your code, deployment, or workflow. + Use the Help Center to reach the team without leaving this page. Note that we are unable to provide technical assistance with troubleshooting your code, deployment, or workflow.
diff --git a/content/trading/swapping-api/getting-started.mdx b/content/trading/swapping-api/getting-started.mdx index 14773ea99..6854c282f 100644 --- a/content/trading/swapping-api/getting-started.mdx +++ b/content/trading/swapping-api/getting-started.mdx @@ -1,5 +1,6 @@ --- title: Swapping via the Uniswap API +sidebarTitle: Overview description: High-level overview of swapping through the Uniswap API --- @@ -21,10 +22,12 @@ The diagram below is an illustration of the token swap flow where steps in gray -If using UniswapX protocols, quote requests require a minimum of 300 USDC equivalent on all supported chains. Below that, UniswapX is included only when its quote improves on the AMM route by at least 0.2%. +If using UniswapX protocols, quote requests must meet a per-chain minimum quotable size. Below that, UniswapX is included only when its quote improves on the AMM route by at least 0.2%. -Requests that meet neither condition will return "No quotes available." See [Supported Chains](/docs/trading/swapping-api/supported-chains#uniswapx-chain-support) for details. +Requests that meet neither condition return a 404 with `errorCode: QuoteAmountTooLowError`. See [Supported Chains](/docs/trading/swapping-api/supported-chains#uniswapx-chain-support) for details. For full request and response schemas for each endpoint, see the [API Reference](/docs/api-reference). + +For developer support, reach out to our team through the Help Center. diff --git a/content/trading/swapping-api/images/permissioned-token-gating.png b/content/trading/swapping-api/images/permissioned-token-gating.png new file mode 100644 index 000000000..3f8a67ac8 Binary files /dev/null and b/content/trading/swapping-api/images/permissioned-token-gating.png differ diff --git a/content/trading/swapping-api/meta.json b/content/trading/swapping-api/meta.json index 1ef124c66..b5990fa51 100644 --- a/content/trading/swapping-api/meta.json +++ b/content/trading/swapping-api/meta.json @@ -1,18 +1,13 @@ { - "title": "Swapping", - "pages": [ - "getting-started", - "concepts", - "supported-chains", - "integration-guide", - "agent-attribution", - "chained-actions", - "chained-actions-integration", - "amm-vs-uniswapx-routing", - "swapping-code-examples", - "building-prerequisites", - "common-errors", - "faqs" - ] + "title": "Uniswap API", + "pages": [ + "getting-started", + "supported-chains", + "concepts", + "start-building", + "amm-vs-uniswapx-routing", + "swapping-permissioned-pools", + "common-errors", + "faqs" + ] } - \ No newline at end of file diff --git a/content/trading/swapping-api/agent-attribution.mdx b/content/trading/swapping-api/start-building/agent-attribution.mdx similarity index 78% rename from content/trading/swapping-api/agent-attribution.mdx rename to content/trading/swapping-api/start-building/agent-attribution.mdx index 168ad2f67..c0782c07f 100644 --- a/content/trading/swapping-api/agent-attribution.mdx +++ b/content/trading/swapping-api/start-building/agent-attribution.mdx @@ -1,5 +1,6 @@ --- title: Agent Attribution (X-Agent-Info) +sidebarTitle: Agent Attribution description: Send the optional X-Agent-Info header to attribute agent-driven Trading API traffic, and check x-agent-info-status to confirm it was recognized. --- @@ -13,12 +14,12 @@ The Uniswap API accepts an optional `X-Agent-Info` request header. Send it if an ## Sending the header -Send `X-Agent-Info` alongside your usual [authentication](/docs/trading/swapping-api/integration-guide#authentication) headers, with a JSON object value containing up to three fields: +Send `X-Agent-Info` alongside your usual [authentication](/docs/trading/swapping-api/start-building/integration-guide#authentication) headers, with a JSON object value containing up to three fields: | Field | Type | Required | Notes | | --- | --- | --- | --- | | `decision_origin` | string | Yes | Must be exactly `autonomous` or `human_mediated` (case-sensitive). Any other value marks the header malformed. | -| `integration_name` | string | No | Name of your integration or agent, e.g. `my-trading-bot`. Up to 256 UTF-16 code units — JavaScript's `String#length`. | +| `integration_name` | string | No | Name of your integration or agent, e.g. `my-trading-bot`. Up to 256 UTF-16 code units, which is JavaScript's `String#length`. | | `version` | string | No | Version identifier for your integration. Up to 256 UTF-16 code units. | Send only these three fields. Any other key is dropped rather than rejected, so an extra key never makes the header malformed. @@ -30,32 +31,33 @@ Send only these three fields. Any other key is dropped rather than rejected, so curl -X POST https://trade-api.gateway.uniswap.org/v1/quote \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ + -H "Accept: application/json" \ -H 'X-Agent-Info: {"decision_origin":"autonomous","integration_name":"my-trading-bot","version":"1.4.0"}' \ -d '{"tokenIn":"0x...","tokenOut":"0x...","tokenInChainId":1,"tokenOutChainId":1,"type":"EXACT_INPUT","amount":"1000000","swapper":"0x...","slippageTolerance":0.5}' ``` ## What makes a header malformed -A header is dropped (marked malformed) rather than rejected outright if any of the following hold. The request is handled exactly as if the header were absent — see [Confirming it was received](#confirming-it-was-received) below for how to tell the difference. +A header is dropped (marked malformed) rather than rejected outright if any of the following hold. The request is handled exactly as if the header were absent. See [Confirming it was received](#confirming-it-was-received) below for how to tell the difference. - The raw header value is larger than **1024 bytes**, measured on the raw value before parsing. JSON whitespace and `\u` escapes count toward the cap. - The raw header value contains any byte outside printable US-ASCII (`0x20`–`0x7E`). This is checked first, before the JSON is parsed, because bytes above `0x7E` decode differently in different HTTP stacks. So a literal `é`, an emoji, or a curly quote in the header marks it malformed no matter how short the value is. Send non-ASCII as a JSON `\u` escape instead. - The value isn't valid JSON, or is valid JSON that isn't a plain object (an array, string, number, boolean, or `null`). -- The request carried two or more `X-Agent-Info` header lines. They are joined with `", "`, which is almost never valid JSON. Set the header once rather than appending to it — some HTTP clients append by default. +- The request carried two or more `X-Agent-Info` header lines. They are joined with `", "`, which is almost never valid JSON. Set the header once rather than appending to it, since some HTTP clients append by default. - `decision_origin` is missing, or is anything other than exactly `autonomous` or `human_mediated`. - `integration_name` or `version` is present but isn't a string, or is longer than 256 UTF-16 code units. That count is JavaScript's `String#length`, so an emoji or other astral character costs two units, not one. - `integration_name` or `version` contains a disallowed character. Those are control characters (C0 `0x00`–`0x1F`, DEL `0x7F`, C1 `0x80`–`0x9F`), the Unicode line separators U+2028 and U+2029, and the replacement character U+FFFD. An escaped unpaired surrogate decodes to U+FFFD, so it is rejected too. Text pasted from a PDF, or left behind by a lossy re-encode, often carries one of these invisibly. -Not sending the header at all, or sending it with an empty value, isn't an error condition — both are simply "no attribution," the same outcome as a header that's out of scope for your client. +Not sending the header at all isn't an error condition. It's simply "no attribution," the same outcome as a header that's out of scope for your client. ## Confirming it was received Because the request succeeds regardless of whether `X-Agent-Info` parsed, check the `x-agent-info-status` response header to confirm your header was actually recognized: -- **`x-agent-info-status: malformed`** — the header was received but failed one of the checks above and was dropped. The value is always the fixed string `malformed`; it never echoes anything from your request. -- **No `x-agent-info-status` header at all** — your `X-Agent-Info` header parsed, or you didn't send one. +- **`x-agent-info-status: malformed`**: the header was received but failed one of the checks above and was dropped. The value is always the fixed string `malformed`; it never echoes anything from your request. +- **No `x-agent-info-status` header at all**: your `X-Agent-Info` header parsed, or you didn't send one. -The gateway sets this header after it routes your request, and before it writes its own response. Error responses carry it too — a 400, a 401, a 403, a 429, and a 404 for a path that does not exist. So you can debug the header without first getting a working quote. A CORS preflight carries no status header, because the gateway answers it before it looks at `X-Agent-Info`. +The gateway sets this header after it routes your request, and before it writes its own response. Error responses carry it too: a 400, a 401, a 403, a 429, and a 404 for a path that does not exist. So you can debug the header without first getting a working quote. A CORS preflight carries no status header, because the gateway answers it before it looks at `X-Agent-Info`. Call the Trading API server-to-server. The gateway sends CORS headers only to a small allow-list of origins, so a browser page on your own domain cannot read this header. Check it from a server or with curl. @@ -65,6 +67,7 @@ const response = await fetch('https://trade-api.gateway.uniswap.org/v1/quote', { headers: { 'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json', + Accept: 'application/json', 'X-Agent-Info': JSON.stringify({ decision_origin: 'autonomous', integration_name: 'my-trading-bot', @@ -84,7 +87,7 @@ const response = await fetch('https://trade-api.gateway.uniswap.org/v1/quote', { }); if (response.headers.get('x-agent-info-status') === 'malformed') { - // Received but dropped — check field names, decision_origin value, and length limits above. + // Received but dropped. Check field names, decision_origin value, and length limits above. console.warn('X-Agent-Info was sent but not recognized.'); } diff --git a/content/trading/swapping-api/chained-actions-integration.mdx b/content/trading/swapping-api/start-building/chained-actions-integration.mdx similarity index 93% rename from content/trading/swapping-api/chained-actions-integration.mdx rename to content/trading/swapping-api/start-building/chained-actions-integration.mdx index 693d496a2..25e24bc69 100644 --- a/content/trading/swapping-api/chained-actions-integration.mdx +++ b/content/trading/swapping-api/start-building/chained-actions-integration.mdx @@ -1,11 +1,12 @@ --- title: Chained Actions Integration Guide +sidebarTitle: Chained Actions Swap Guide description: Build cross-chain and multi-step swaps with the Uniswap Trading API plan endpoints, with cURL examples and the full execution loop. --- -This guide is the operational counterpart to [Swapping with Chained Actions](/docs/trading/swapping-api/chained-actions). When `/quote` returns `"routing": "CHAINED"`, you drive the trade through the `/plan` endpoints as an ordered sequence of steps under one `planId`. +This guide is the operational counterpart to [Swapping with Chained Actions](/docs/trading/swapping-api/concepts/chained-actions). When `/quote` returns `"routing": "CHAINED"`, you drive the trade through the `/plan` endpoints as an ordered sequence of steps under one `planId`. -For conceptual background (plans, steps, the state machine, and routing patterns), read the [concepts page](/docs/trading/swapping-api/chained-actions). For full request and response schemas, see the [API Reference](/docs/api-reference). AI builders can consume the full OpenAPI Specification at [https://trade-api.gateway.uniswap.org/v1/api.json](https://trade-api.gateway.uniswap.org/v1/api.json). +For conceptual background (plans, steps, the state machine, and routing patterns), read the [concepts page](/docs/trading/swapping-api/concepts/chained-actions). For full request and response schemas, see the [API Reference](/docs/api-reference). AI builders can consume the full OpenAPI Specification at [https://trade-api.gateway.uniswap.org/v1/api.json](https://trade-api.gateway.uniswap.org/v1/api.json). ## Endpoints @@ -195,7 +196,7 @@ Scan the steps array for `STEP_ERROR` rather than assuming which index failed. T `slippageTolerance` is the value set on the `/quote` request, or the API default if you omit it. It governs the AMM swap steps in a plan. It is fixed at quote time and applied to each swap step independently, not as a single end-to-end guarantee. For an S→B→S plan at 0.5%, each swap applies 0.5% on its own, so the combined deviation across both swaps can exceed 0.5%. Slippage cannot be changed after a plan is created. If no valid swap route exists within tolerance, the step fails with no automatic recovery. -The bridge step is not an AMM swap. It is quoted through the bridge provider (Across Protocol) when the plan is built, so `slippageTolerance` does not apply to it. The bridge runs as a `SEND_TX` step alongside approvals and swaps (see the [execution flow](/docs/trading/swapping-api/chained-actions#execution-flow)), but only the swap steps have a slippage tolerance band. +The bridge step is not an AMM swap. It is quoted through the bridge provider (Across Protocol) when the plan is built, so `slippageTolerance` does not apply to it. The bridge runs as a `SEND_TX` step alongside approvals and swaps (see the [execution flow](/docs/trading/swapping-api/concepts/chained-actions#execution-flow)), but only the swap steps have a slippage tolerance band. ## Gas @@ -210,7 +211,7 @@ Gas applies only to `SEND_TX` steps (approvals, swaps, and bridges). `SIGN_MSG` ## API Reference -For full request and response schemas, see the [API Reference](/docs/api-reference). For conceptual background, see [Swapping with Chained Actions](/docs/trading/swapping-api/chained-actions). +For full request and response schemas, see the [API Reference](/docs/api-reference). For conceptual background, see [Swapping with Chained Actions](/docs/trading/swapping-api/concepts/chained-actions). ## Support diff --git a/content/trading/swapping-api/integration-guide.mdx b/content/trading/swapping-api/start-building/integration-guide.mdx similarity index 90% rename from content/trading/swapping-api/integration-guide.mdx rename to content/trading/swapping-api/start-building/integration-guide.mdx index 3c4ff7673..c8094fa76 100644 --- a/content/trading/swapping-api/integration-guide.mdx +++ b/content/trading/swapping-api/start-building/integration-guide.mdx @@ -1,11 +1,12 @@ --- title: Swapping API Integration Guide +sidebarTitle: Standard Swap Guide description: Build swapping integrations with the Uniswap API using this practical step-by-step guide. --- -This guide covers single-transaction swaps. When `/quote` returns `"routing": "CHAINED"` (a trade that crosses chains or needs more than one step), drive execution through the `/plan` endpoints instead. See the [Chained Actions Integration Guide](/docs/trading/swapping-api/chained-actions-integration). +This guide covers single-transaction swaps. When `/quote` returns `"routing": "CHAINED"` (a trade that crosses chains or needs more than one step), drive execution through the `/plan` endpoints instead. See the [Chained Actions Integration Guide](/docs/trading/swapping-api/start-building/chained-actions-integration). @@ -48,9 +49,9 @@ const quote = await response.json(); AI builders can consume the full Open API Specification (OAS) at [https://trade-api.gateway.uniswap.org/v1/api.json](https://trade-api.gateway.uniswap.org/v1/api.json). -If your integration is built or operated by an AI agent, also consider sending the optional [`X-Agent-Info` attribution header](/docs/trading/swapping-api/agent-attribution) alongside your request. +If your integration is built or operated by an AI agent, also consider sending the optional [`X-Agent-Info` attribution header](/docs/trading/swapping-api/start-building/agent-attribution) alongside your request. -Full code examples for completing a basic swap workflow are available in [Swapping Code Examples](/docs/trading/swapping-api/swapping-code-examples). +Full code examples for completing a basic swap workflow are available in [API Swapping Code Examples](/docs/trading/swapping-api/start-building/swapping-code-examples). ## Architecture @@ -79,8 +80,7 @@ Your integration must include: - **RPC Provider**: Connection to blockchain nodes (ex. Infura, Alchemy, or self-hosted) - **Web3 Library**: ethers.js, viem, or web3.js for transaction signing - **Wallet Integration**: Uniswap Wallet, MetaMask, or similar for user signing - -See the [Build Prerequisites](/docs/trading/swapping-api/building-prerequisites) for more details. +- **API Key Handling**: Store your Uniswap API key server-side and attach it to requests over HTTPS. Do not ship it in front-end code; proxy calls through your own backend so the key is never exposed to users. ### Data flow @@ -333,13 +333,13 @@ interface ErrorResponse { #### No quotes available -**Cause**: No route found for the requested swap +**Cause**: identified by the `errorCode` field on the 404 body (see the [full reference](/docs/trading/swapping-api/common-errors#404-no-quotes-available)) **Solutions**: -- Verify token addresses are correct and on the specified chain -- Check chains are available for selected protocol (note [limited chain support for UniswapX](/docs/trading/swapping-api/supported-chains)) -- Try different protocols or routing preferences -- Reduce trade size +- Handle the 404 by `errorCode`: only `UpstreamTimeoutError` can succeed on an unchanged retry; all other values indicate the request must be modified +- Verify token addresses are correct and on the specified chain (`UnsupportedTokenError`, `NoRouteFoundError`) +- Check chains are available for the selected protocol (`UniswapXNotSupportedOnChainError`; note [limited chain support for UniswapX](/docs/trading/swapping-api/supported-chains)) +- Increase trade size for UniswapX minimums (`QuoteAmountTooLowError`) #### Validation error @@ -476,7 +476,7 @@ Balance protection vs execution success: ### Error recovery -If a quote fails, read the error message to address the specific error cause. If the quote fails due to no quotes available, implement retry logic with exponential backoff: +If a quote fails with a 404, use the `errorCode` field to address the specific cause (see the [errorCode reference](/docs/trading/swapping-api/common-errors#404-no-quotes-available)). Only retry when `errorCode` is `UpstreamTimeoutError` (or, cautiously, `ResourceNotFound`) — every other cause is deterministic and will fail again unchanged. Retry with exponential backoff: ```typescript async function fetchQuoteWithRetry( @@ -642,11 +642,11 @@ The API does not return every field that some libraries expect to generate an EI - **`UNISWAPX_V2`**: Mainnet, Arbitrum, Base only -- **`UNISWAPX_V3`**: Arbitrum, Avalanche, Base, BNB Smart Chain, Robinhood Chain, Tempo, Unichain -- **UniswapX minimum**: 300 USDC equivalent on all supported chains +- **`UNISWAPX_V3`**: Arbitrum, Arc, Avalanche, Base, BNB Smart Chain, Ink, Monad, Robinhood Chain, Tempo, Unichain +- **UniswapX minimum**: a per-chain minimum quotable size (see [Supported Chains](/docs/trading/swapping-api/supported-chains#uniswapx-chain-support)) - **Native token swaps**: UniswapX for native token input only when the `x-erc20eth-enabled` header is set to `true` on `/quote` and `/order` -Requests below the minimum threshold will return "No quotes available." See [Supported Chains](/docs/trading/swapping-api/supported-chains#uniswapx-chain-support) for details. +Requests below the minimum threshold return a 404 with `errorCode: QuoteAmountTooLowError`. See [Supported Chains](/docs/trading/swapping-api/supported-chains#uniswapx-chain-support) for details. diff --git a/content/trading/swapping-api/start-building/meta.json b/content/trading/swapping-api/start-building/meta.json new file mode 100644 index 000000000..2ee5ab081 --- /dev/null +++ b/content/trading/swapping-api/start-building/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Start building", + "pages": ["integration-guide", "agent-attribution", "chained-actions-integration", "swapping-code-examples"] +} diff --git a/content/trading/swapping-api/swapping-code-examples.mdx b/content/trading/swapping-api/start-building/swapping-code-examples.mdx similarity index 100% rename from content/trading/swapping-api/swapping-code-examples.mdx rename to content/trading/swapping-api/start-building/swapping-code-examples.mdx diff --git a/content/trading/swapping-api/supported-chains.mdx b/content/trading/swapping-api/supported-chains.mdx index 506664290..a65e601c3 100644 --- a/content/trading/swapping-api/supported-chains.mdx +++ b/content/trading/swapping-api/supported-chains.mdx @@ -9,37 +9,40 @@ The following chains are supported for swapping. **Note the router address, whic For the avoidance of any doubt, the most up to date list of routers is available in GitHub [here](https://github.com/Uniswap/sdks/blob/main/sdks/universal-router-sdk/src/utils/constants.ts). - -| Chain ID | Chain Name | Universal Router 2.0 Address | Universal Router 2.1.1 Address | UniswapX Support | -| :------------------- | :------------------------- | :----------------------------------------- | :----------------------------------------- | :------- | -| 1 | Mainnet (Ethereum) | 0x66a9893cc07d91d95644aedd05d03f95e1dba8af | 0x4c82d1fbfe28c977cbb58d8c7ff8fcf9f70a2cca | Yes | -| 10 | OP Mainnet | 0x851116d9223fabed8e56c0e6b8ad0c31d98b3507 | 0x8b844f885672f333bc0042cb669255f93a4c1e6b | | -| 56 | BNB Smart Chain | 0x1906c1d672b88cd1b9ac7593301ca990f94eae07 | 0x8b844f885672f333bc0042cb669255f93a4c1e6b | Yes | -| 130 | Unichain | 0xef740bf23acae26f6492b10de645d6b98dc8eaf3 | 0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7 | | -| 137 | Polygon | 0x1095692a6237d83c6a72f3f5efedb9a670c49223 | 0x8b844f885672f333bc0042cb669255f93a4c1e6b | | -| 143 | Monad | 0x0d97dc33264bfc1c226207428a79b26757fb9dc3 | 0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7 | | -| 196 | X Layer | 0x5507749f2c558bb3e162c6e90c314c092e7372ff | 0x8b844f885672f333bc0042cb669255f93a4c1e6b | | -| 324 | zkSync | 0x28731BCC616B5f51dD52CF2e4dF0E78dD1136C06 | | | -| 480 | World Chain | 0x8ac7bee993bb44dab564ea4bc9ea67bf9eb5e743 | 0x8b844f885672f333bc0042cb669255f93a4c1e6b | | -| 1868 | Soneium | 0x0e2850543f69f678257266e0907ff9a58b3f13de | 0x8b844f885672f333bc0042cb669255f93a4c1e6b | | -| 4217 | Tempo | 0x1febb76be10aaf3a1402f04e8e835f2c382f7914 | 0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7 | Yes | -| 4326 | MegaETH | 0x48fd03529d2a91be835f07f6b72f53b4aad6093d | 0x47837eb80db5908eabba9105626d9b348bea7b02 | | -| 4663 | Robinhood Chain | | 0x8876789976decbfcbbbe364623c63652db8c0904 | Yes | -| 8453 | Base | 0x6ff5693b99212da76ad316178a184ab56d299b43 | 0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7 | Yes | -| 42161 | Arbitrum | 0xa51afafe0263b40edaef0df8781ea9aa03e381a3 | 0x8b844f885672f333bc0042cb669255f93a4c1e6b | Yes | -| 42220 | Celo | 0xcb695bc5D3Aa22cAD1E6DF07801b061a05A0233A | 0x8b844f885672f333bc0042cb669255f93a4c1e6b | | -| 43114 | Avalanche | 0x94b75331ae8d42c1b61065089b7d48fe14aa73b7 | 0x8b844f885672f333bc0042cb669255f93a4c1e6b | Yes | -| 57073 | Ink | 0x112908dac86e20e7241b0927479ea3bf935d1fa0 | 0x28bd21bb4ea4fda370d8d7544992038375d8d456 | | -| 59144 | Linea | 0x661e93cca42afacb172121ef892830ca3b70f08d | 0x8b844f885672f333bc0042cb669255f93a4c1e6b | | -| 7777777 | Zora | 0x3315ef7ca28db74abadc6c44570efdf06b04b020 | 0xfdf682f51fe81aa4898f0ae2163d8a55c127fbc7 | | -| **Testnets** | | | | | -| 1301 | Unichain Sepolia (Testnet) | 0xf70536b3bcc1bd1a972dc186a2cf84cc6da6be5d | 0x8b844f885672f333bc0042cb669255f93a4c1e6b | | -| 84532 | Base Sepolia (Testnet) | 0x492e6456d9528771018deb9e87ef7750ef184104 | 0x8b844f885672f333bc0042cb669255f93a4c1e6b | | -| 11155111 | Ethereum Sepolia (Testnet) | 0x3a9d48ab9751398bbfa63ad67599bb04e4bdf98b | 0xed4885c9a52c23312facbf9d5aff409779e1babc | | +Support for Universal Router 2.0 and 2.1.1 ends on October 21, 2026. See [Sunset of Universal Router 2.0 and 2.1.1](/docs/changelog/active-notifications/sunset-of-universal-router-2-0-and-2-1-1). + + +| Chain ID | Chain Name | Universal Router 2.1.2 Address | UniswapX Support | +| :------------------- | :------------------------- | :----------------------------------------- | :--------------- | +| 1 | Mainnet (Ethereum) | 0x23617e59A5925b2A4Bf75d73ff6711cD0b29De85 | Yes | +| 10 | OP Mainnet | 0xC09255D86DB563cBc11C2fCf4a0C512e160111B4 | | +| 56 | BNB Smart Chain | 0xDc264714F68d84CF29BC605589405E78bDBE7C9f | Yes | +| 130 | Unichain | 0xD1b797D92d87B688193A2B976eFc8D577D204343 | Yes | +| 137 | Polygon | 0xDc264714F68d84CF29BC605589405E78bDBE7C9f | | +| 143 | Monad | 0xa6CE4F10d83dBdDAc17E68e1837ca9cE6a1b596e | Yes | +| 196 | X Layer | 0x1cd182C94fcF42277B80DBB9060F88024809E61E | | +| 324 | zkSync | (See note below) | | +| 480 | World Chain | 0xF025e0Fe9E331A0eF05c2ad3C4E9C64b625cda6f | | +| 1868 | Soneium | 0x661E93cca42AfacB172121EF892830cA3b70F08d | | +| 4217 | Tempo | 0x182a927119D56008d921126764bF884221b10f59 | Yes | +| 4326 | MegaETH | 0xAedd1CF4C14e833140A61E9C0d2b73a64795c823 | | +| 4663 | Robinhood Chain | 0x204FAca1764B154221e35c0d20aBb3c525710498 | Yes | +| 5042 | Arc | 0x8702463e73f74d0b6765aBceb314Ef07aCb92650 | Yes | +| 8453 | Base | 0xd6145b2D3F379919E8CdEda7B97e37c4b2Ca9c40 | Yes | +| 42161 | Arbitrum | 0x2d01411773c8C24805306E89A41F7855C3c4Fe65 | Yes | +| 42220 | Celo | 0xe2023F3FA515cF070e07fD9d51c1d236e07843f4 | | +| 43114 | Avalanche | 0x661E93cca42AfacB172121EF892830cA3b70F08d | Yes | +| 57073 | Ink | 0x661E93cca42AfacB172121EF892830cA3b70F08d | Yes | +| 59144 | Linea | 0xDc264714F68d84CF29BC605589405E78bDBE7C9f | | +| 7777777 | Zora | 0xF025e0Fe9E331A0eF05c2ad3C4E9C64b625cda6f | | +| **Testnets** | | | | +| 1301 | Unichain Sepolia (Testnet) | 0xDf38F24fE153761634Be942F9d859f3DBA857E95 | | +| 84532 | Base Sepolia (Testnet) | 0x8702463e73f74d0b6765aBceb314Ef07aCb92650 | | +| 11155111 | Ethereum Sepolia (Testnet) | 0x7E4f6c5e954Da5c61B3423D81E2277431Ac043f3 | | -Only Ethereum Sepolia and Unichain Sepolia are available as testnets on the [Uniswap web interface](https://app.uniswap.org). All listed testnets are accessible via the API. +Only Ethereum Sepolia and Unichain Sepolia are available as testnets on the [Uniswap web interface](https://app.uniswap.org). All listed testnets above are accessible via the API. @@ -49,27 +52,46 @@ The Trading API builds swap calldata for a specific Universal Router version. Se ### Default version -When you do not send the `x-universal-router-version` header, the API defaults to Universal Router `2.0` on most chains. Some chains default to `2.1.1`, such as Robinhood Chain and Ink, so you do not need to set the header there to get `2.1.1`. +When you do not send the `x-universal-router-version` header, the API defaults to Universal Router `2.1.2` on every chain that has a 2.1.2 deployment. zkSync has no 2.1.2 and runs `2.0` only. zkSync's 2.0 Universal Router address is `0x28731BCC616B5f51dD52CF2e4dF0E78dD1136C06`. -You can always set the header explicitly. Requesting a version a chain does not support returns an error, for example `2.0` on Robinhood Chain, which has no `2.0` deployment. +You can always set the header explicitly. Requesting a version a chain does not support returns an error, for example `2.0` on Robinhood Chain and Arc, neither of which has a `2.0` deployment. -The supported chains table above shows which versions each chain runs. zkSync supports `2.0` only. **The default can change over time, so set the header explicitly when you need a stable target.** +The table above lists the 2.1.2 address for each chain. **The default can change over time, so set the header explicitly when you need a stable target.** ### SDK compatibility for decoding calldata -If you decode the calldata the API returns with the [Universal Router SDK](https://github.com/Uniswap/sdks/tree/main/sdks/universal-router-sdk), your `@uniswap/universal-router-sdk` version must support the Universal Router version used for the request. Decoding with an older version can fail or produce incorrect results. +If you decode the calldata the API returns with the [Universal Router SDK](https://github.com/Uniswap/sdks/tree/main/sdks/universal-router-sdk), your `@uniswap/universal-router-sdk` version must support the Universal Router version used for the request, and you must pass the matching `UniversalRouterVersion` to `CommandParser.parseCalldata`. Decoding with an older version, or without the version argument, can fail or produce incomplete results. If you submit the returned calldata onchain and never decode it yourself, only the header matters. -Use at least the SDK version that introduced support for the router version you decode: +Use at least the SDK version that introduced support for the router version you decode, and pass its `UniversalRouterVersion` member to the parser: -| Universal Router version | Minimum `@uniswap/universal-router-sdk` | -| :--- | :--- | -| 2.0 | 3.1.0 | -| 2.1.1 | 5.9.0 | -| 2.2.0 | 5.9.0 | +| Universal Router version | `UniversalRouterVersion` | Minimum `@uniswap/universal-router-sdk` | +| :--- | :--- | :--- | +| 2.0 | `V2_0` | 3.1.0 | +| 2.1.1 | `V2_1_1` | 5.9.0 | +| 2.1.2 | `V2_1_2` | 5.12.0 | +| 2.2.0 | `V2_2_0` | 5.12.0 | + +Versions 5.12.0 and later are the first to resolve 2.1.2, and the first to carry the current 2.2.0 addresses. Earlier releases resolve 2.2.0 to a deployment that was replaced, so do not use them for that version. + +From 2.1.1 onward, the V2 and V3 swap commands carry an extra `minHopPriceX36` per-hop slippage array, and the v4 swap actions have the same field. SDK 5.9.0 is the first release whose parser decodes that array and the first whose `parseCalldata` accepts a `UniversalRouterVersion` argument, which defaults to `V2_0`. Older SDKs may parse newer calldata without an error but drop `minHopPriceX36`, so your validation can be incomplete even when it appears to succeed. + +```typescript +import { CommandParser, UniversalRouterVersion } from '@uniswap/universal-router-sdk' + +// `calldata` is the value returned by the /swap response. +// The version you pass must match the x-universal-router-version header you sent. + +// Defaults to V2_0. On 2.1.1 and later calldata the per-hop slippage array is +// silently dropped, and on SDK < 5.9.0 there is no version argument to fix it. +const parsedWrong = CommandParser.parseCalldata(calldata) + +// SDK >= 5.12.0: pass the matching version so 2.1.2 calldata decodes fully. +const parsed = CommandParser.parseCalldata(calldata, UniversalRouterVersion.V2_1_2) +``` Track the [SDK releases](https://github.com/Uniswap/sdks/releases) so your decoder stays compatible when the router version changes. The current mapping lives in the SDK [constants file](https://github.com/Uniswap/sdks/blob/main/sdks/universal-router-sdk/src/utils/constants.ts). @@ -80,7 +102,7 @@ UniswapX is available on the following chains: | Protocol | Supported Chains | | :--- | :--- | | UniswapX V2 | Mainnet (1), Arbitrum (42161), Base (8453) | -| UniswapX V3 | Arbitrum (42161), Avalanche (43114), Base (8453), BNB Smart Chain (56), Robinhood Chain (4663), Tempo (4217), Unichain (130) | +| UniswapX V3 | Arbitrum (42161), Arc (5042), Avalanche (43114), Base (8453), BNB Smart Chain (56), Ink (57073), Monad (143), Robinhood Chain (4663), Tempo (4217), Unichain (130) | If you submit a quote request with `protocols` set to `UNISWAPX_V2` or `UNISWAPX_V3` on a chain not listed above, the request will fail. @@ -88,9 +110,9 @@ Most integrators do not need to set `protocols`. With the default `BEST_PRICE` r -All UniswapX quote requests require a minimum swap value of 300 USDC equivalent across all supported chains. Below that, UniswapX is included only when its quote improves on the AMM route by at least 0.2%. +All UniswapX quote requests must meet a per-chain minimum swap value. Below that, UniswapX is included only when its quote improves on the AMM route by at least 0.2%. -Requests that meet neither condition will return **"No quotes available"**. This is the most common cause of failed UniswapX quote requests. +Requests that meet neither condition return a 404 with `errorCode: QuoteAmountTooLowError` (see [Troubleshooting](/docs/trading/swapping-api/common-errors#404-no-quotes-available)). This is the most common cause of failed UniswapX quote requests. diff --git a/content/trading/swapping-api/swapping-permissioned-pools.mdx b/content/trading/swapping-api/swapping-permissioned-pools.mdx new file mode 100644 index 000000000..63f2c940e --- /dev/null +++ b/content/trading/swapping-api/swapping-permissioned-pools.mdx @@ -0,0 +1,86 @@ +--- +title: Swapping through Permissioned Pools +sidebarTitle: Permissioned Pools +description: Swap tokens that trade through permissioned pools on Uniswap v4 and gate them in your app using the Uniswap API check permissions endpoint. +keywords: + - permissioned-pools + - tokenized-pools + - allowlist + - check-permissions + - uniswap-api +--- + +Some tokens on Uniswap v4 trade through [permissioned pools](/docs/protocols/uniswap-labs-hooks/permissioned-pools/overview), which restrict swaps and liquidity provisioning to allowlisted addresses. Before a wallet can swap one of these tokens, your app must confirm the wallet is allowlisted. The Uniswap API exposes a check permissions endpoint for this purpose. This check is a client-side safeguard for user experience: the swap endpoints reject transactions from wallets that are not allowlisted regardless, so a token never becomes tradable just because an app skips the check. + +## Check Permissions Before Swapping + +Send the connected wallet and the tokens it wants to trade to the check permissions endpoint. The request accepts up to two tokens. + +Like every Uniswap API endpoint, `/v1/permissions` requires an API key in the `x-api-key` header. Without one it returns `401`. Create a key in the [Uniswap Developer Platform](https://developers.uniswap.org/dashboard/welcome). + +```bash +curl -X POST https://trade-api.gateway.uniswap.org/v1/permissions \ + -H "x-api-key: YOUR_API_KEY" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + -d '{ + "walletAddress": "0xC9bebBA9f481b12cE6f3EA54c4B182c9636ec421", + "tokens": ["0x1111111111111111111111111111111111111111"], + "chainId": 1 + }' +``` + +![App gating flow: check permissions, then allow quote and swap when allowlisted, or block submit and redirect to the KYC URL when not](./images/permissioned-token-gating.png) + +## Handle the Response + +`isPermissioned` describes the token, meaning whether it trades through a permissioned pool. `isAllowlisted` describes the connected wallet, meaning whether that wallet may trade the token. Each token returns a result with one of three shapes: + +```json +{ + "requestId": "e63f1e1e-b9e9-411a-bcc8-ff18ce4e77cf", + "results": [ + { + "token": "0x1111111111111111111111111111111111111111", + "isPermissioned": true, + "isAllowlisted": false, + "adapterTokenAddress": "0x2222222222222222222222222222222222222222", + "kycUrl": "https://your-kyc-provider.example/verify", + "issuer": "Your Issuer Name" + } + ] +} +``` + +- **Not permissioned:** `isPermissioned` is `false`. No token in the request requires permission to trade, so proceed to quoting and swapping normally. +- **Permissioned and allowlisted:** `isPermissioned` and `isAllowlisted` are both `true`. Trade normally. +- **Permissioned and not allowlisted:** `isAllowlisted` is `false` and the result includes a `kycUrl`. Direct the user to complete verification. The result also includes `issuer`, the KYC provider display name, so you can tell the user who runs the verification. + +## Gate Your Interface + +For a wallet that is not allowlisted, let the user quote the token so they can see prices, but block transaction submission to avoid reverts and a confusing experience. Link the user to the `kycUrl` so they can complete verification. + + +Check permissions before submitting. The swap endpoints reject transactions from wallets that are not allowlisted, so a pre-check avoids failed requests and wasted gas. + + +## Set the Universal Router Version + +Quotes and swaps that involve a permissioned token must use [Universal Router](/docs/trading/swapping-api/supported-chains#universal-router-version) 2.2.0 or higher. Send the version header when any token in the request is permissioned. + +```bash +x-universal-router-version: 2.2.0 +``` + +## Routing Behavior + +Routing will not send a user through a permissioned pool they are not allowed to trade in. Permissioned tokens are matched only as the input or output of a trade, never as an intermediate hop, so a disallowed user is never routed through a restricted token. For example, a permissioned token to USDC to ETH route is supported for an allowlisted user, while an unrelated trade routed through a permissioned token is not. + +## Providing Liquidity + +This page covers the swap path through the API. Liquidity provision is gated by the same allowlist: the permissioned hook checks `LIQUIDITY_ALLOWED` on `beforeAddLiquidity`, and positions are minted through the Permissioned Position Manager, which enforces the allowlist and issues non-transferable position NFTs. For the contract details, see [Permissioned Pools Architecture](/docs/protocols/uniswap-labs-hooks/permissioned-pools/architecture) and [Deploy a Permissioned Pool](/docs/protocols/uniswap-labs-hooks/permissioned-pools/deploy-a-permissioned-pool). + +## Where to Go Next + +- Learn how the pools work in [Permissioned Pools Architecture](/docs/protocols/uniswap-labs-hooks/permissioned-pools/architecture). +- Onboard a token in [Deploy a Permissioned Pool](/docs/protocols/uniswap-labs-hooks/permissioned-pools/deploy-a-permissioned-pool). diff --git a/content/unichain/index.mdx b/content/unichain/index.mdx index f579cbb3c..69aad6d97 100644 --- a/content/unichain/index.mdx +++ b/content/unichain/index.mdx @@ -1,6 +1,33 @@ --- title: Unichain Overview +sidebarTitle: Overview description: Learn what Unichain is and how it supports faster, lower-cost onchain liquidity and cross-chain interoperability. +keywords: + - Unichain + - layer 2 + - Superchain + - Flashblocks + - chain ID + - bridging +faqs: + - question: How is Unichain different from other Ethereum L2s? + answer: |- + Unichain is a DeFi-focused Ethereum L2 built on the OP Stack and part of the Superchain, so it shares standards, tooling, and native interoperability with other OP Stack chains. It is a Stage 1 rollup with a permissionless fault-proof system for trust-minimized security. Compared with a general-purpose L2, Unichain targets fast, low-cost onchain liquidity: it runs 1-second block times with 200 ms preconfirmations through Flashblocks, and is designed to reduce value lost to MEV by increasing arbitrage frequency. + - question: What are Flashblocks and how do I use them? + answer: |- + Flashblocks provide transaction preconfirmations on Unichain in about 200 milliseconds, so apps can show faster feedback than the 1-second block time. They are an out-of-protocol extension that streams partial block updates and does not change Unichain's core consensus. Most apps can benefit with minimal changes: use the pending block tag with standard Ethereum JSON-RPC methods such as eth_getBlockByNumber, eth_call, eth_getBalance, and eth_getTransactionCount. The public RPC endpoints are Flashblocks-aware but rate limited, so use a node provider that supports Flashblocks for production. + - question: What are the chain ID and RPC URL for Unichain? + answer: |- + Unichain Mainnet uses chain ID 130 with the public RPC URL https://mainnet.unichain.org, ETH as the currency symbol, and the Uniscan block explorer at https://uniscan.xyz. Unichain Sepolia Testnet uses chain ID 1301 with the public RPC URL https://sepolia.unichain.org. Both public RPC URLs are rate limited and not intended for production, so use a node provider for production workloads. + - question: How do I bridge assets to Unichain? + answer: |- + You can bridge ETH and other supported assets from Ethereum L1 to Unichain through Superbridge, which supports both Unichain Mainnet and Unichain Sepolia. Several third-party bridges also support Unichain, including Across, Brid.gg, Allbridge, Synapse, thirdweb, Relay, and Orbiter Finance. See the Bridges reference for the full list and supported networks. + - question: Can I use my existing Ethereum tooling on Unichain? + answer: |- + Yes. As an OP Stack chain, Unichain is EVM-equivalent with minimal changes to standard Ethereum behavior, so existing Ethereum tooling such as Hardhat and Foundry works after you point it at a Unichain RPC URL. The main differences are network parameters: Unichain uses a 1-second block time and OP Stack EIP-1559 settings rather than Ethereum mainnet values. See the EVM Equivalence and Network Information references for details. + - question: What is the difference between Unichain Mainnet and Unichain Sepolia? + answer: |- + Unichain Mainnet is the production network where real value is at stake. Unichain Sepolia is the public testnet, used to test contracts and integrations with test funds before deploying to mainnet. Both share the same OP Stack architecture and Flashblocks support, so behavior on Sepolia closely matches mainnet. See the Network Information reference on the Unichain docs for chain IDs, RPC URLs, and explorers. --- ## What is Unichain? Unichain is a DeFi-focused Ethereum L2 designed for fast blocks, lower costs, and efficient onchain liquidity across chains. @@ -17,6 +44,90 @@ Unichain is designed to align with Ethereum's scaling roadmap by moving executio ### Cross-chain liquidity Unichain supports interoperability across multiple chains. As part of the Superchain, Unichain supports native [interoperability](https://docs.optimism.io/get-started/interop) and cross-chain liquidity access. +## FAQ + +
+ How is Unichain different from other Ethereum L2s? + + + + Unichain is a DeFi-focused Ethereum L2 built on the OP Stack and part of the [Superchain](https://docs.optimism.io/superchain/superchain-explainer), so it shares standards, tooling, and native [interoperability](https://docs.optimism.io/get-started/interop) with other OP Stack chains. It is a Stage 1 rollup with a permissionless fault-proof system for trust-minimized security. + + Compared with a general-purpose L2, Unichain targets fast, low-cost onchain liquidity: + + * 1-second block times, with 200 ms preconfirmations through [Flashblocks](/docs/unichain/technical-information/flashblocks) + * Lower latency designed to increase arbitrage frequency and reduce value lost to MEV + + + +
+ +
+ What are Flashblocks and how do I use them? + + + + [Flashblocks](/docs/unichain/technical-information/flashblocks) provide transaction preconfirmations in about 200 milliseconds, so apps can show faster feedback than the 1-second block time. They are an out-of-protocol extension that streams partial block updates and does not change Unichain's core consensus. + + Most apps can benefit with minimal changes. Use the `pending` block tag with standard Ethereum JSON-RPC methods such as `eth_getBlockByNumber`, `eth_call`, `eth_getBalance`, and `eth_getTransactionCount`. The public RPC endpoints are Flashblocks-aware but rate limited, so use a [node provider](/docs/unichain/tools/node-providers) that supports Flashblocks for production. + + + +
+ +
+ What are the chain ID and RPC URL for Unichain? + + + + | Network | Chain ID | Public RPC URL | Block Explorer | + | :-- | :-- | :-- | :-- | + | Unichain Mainnet | `130` | `https://mainnet.unichain.org` | [uniscan.xyz](https://uniscan.xyz) | + | Unichain Sepolia | `1301` | `https://sepolia.unichain.org` | [sepolia.uniscan.xyz](https://sepolia.uniscan.xyz) | + + Both public RPC URLs are rate limited and not intended for production. Use a [node provider](/docs/unichain/tools/node-providers) for production workloads. See [Network Information](/docs/unichain/technical-information/network-information) for full parameters. + + + +
+ +
+ How do I bridge assets to Unichain? + + + + You can bridge ETH and other supported assets from Ethereum L1 to Unichain through [Superbridge](https://superbridge.app), which supports both [Unichain Mainnet](https://superbridge.app/unichain) and [Unichain Sepolia](https://superbridge.app/unichain-sepolia). + + Several third-party bridges also support Unichain, including Across, Brid.gg, Allbridge, Synapse, thirdweb, Relay, and Orbiter Finance. See the [Bridges](/docs/unichain/tools/bridges) reference for the full list and supported networks. + + + +
+ +
+ Can I use my existing Ethereum tooling on Unichain? + + + + Yes. As an OP Stack chain, Unichain is [EVM-equivalent](/docs/unichain/technical-information/evm-equivalence) with minimal changes to standard Ethereum behavior, so existing tooling such as Hardhat and Foundry works after you point it at a Unichain RPC URL. + + The main differences are network parameters: Unichain uses a 1-second block time and OP Stack EIP-1559 settings rather than Ethereum mainnet values. See [EVM Equivalence](/docs/unichain/technical-information/evm-equivalence) and [Network Information](/docs/unichain/technical-information/network-information) for details. + + + +
+ +
+ What is the difference between Unichain Mainnet and Unichain Sepolia? + + + + Unichain Mainnet is the production network where real value is at stake. Unichain Sepolia is the public testnet, used to test contracts and integrations with test funds before deploying to mainnet. Both share the same OP Stack architecture and Flashblocks support, so behavior on Sepolia closely matches mainnet. See [Network Information](/docs/unichain/technical-information/network-information) for chain IDs, RPC URLs, and explorers. + + + +
+ ## Where to Go Next - [Read the Unichain Whitepaper](/whitepaper_unichain.pdf) diff --git a/content/unichain/tools/oracles.mdx b/content/unichain/tools/oracles.mdx index 682cbe386..79c0e69c5 100644 --- a/content/unichain/tools/oracles.mdx +++ b/content/unichain/tools/oracles.mdx @@ -1,5 +1,6 @@ --- -title: Oracles +title: Oracles on Unichain +sidebarTitle: Oracles description: Connect oracle services to fetch real-time data feeds for applications built on Unichain. --- diff --git a/content/uniswap-ai/overview.mdx b/content/uniswap-ai/overview.mdx index 1bb646c00..1c2a29dd4 100644 --- a/content/uniswap-ai/overview.mdx +++ b/content/uniswap-ai/overview.mdx @@ -1,11 +1,35 @@ --- title: Uniswap AI Overview +sidebarTitle: Overview description: Get started with Uniswap AI plugins, skills, and LLM context. +keywords: + - Uniswap AI + - AI plugins + - coding agents + - llms.txt + - Claude Code marketplace + - open source +faqs: + - question: Is Uniswap AI free and open source? + answer: |- + Yes. Uniswap AI is an open-source collection of plugins and skills published under the MIT license in the Uniswap/uniswap-ai repository on GitHub. There is no cost to install or use the skills, and you can read, fork, and contribute to the source. + - question: Do I need Claude Code to use Uniswap AI skills? + answer: |- + No. The skills are designed for any coding agent and install with the Skills CLI. Claude Code is one supported option: it adds a plugin marketplace that bundles the skills with expert agents and protocol-specific tools, but it is not required. + - question: Do Uniswap AI skills run in production? + answer: |- + No. Skills are build-time workflows that guide your coding agent while you write integration code. They are instructions and references loaded into the agent, not a runtime service that ships inside your deployed application. The code your agent produces with a skill is what runs in production. + - question: How are skills different from the llms.txt context files? + answer: |- + Both give an AI model Uniswap knowledge, but at different levels of structure. The llms.txt and llms-full.txt files are raw documentation context you add to a model's context window. Skills are structured, task-scoped workflows with step-by-step instructions and references that a coding agent activates directly or by matching your prompt. Use the context files when you want plain documentation grounding, and use skills when you want guided, protocol-specific workflows. + - question: Which skills are available and how do I install them? + answer: |- + Uniswap AI publishes skills such as swap-integration, v4-security-foundations, and liquidity-planner; see the Uniswap/uniswap-ai repository on GitHub for the full, current list. Install them with the Skills CLI, or add the Claude Code marketplace to install plugins individually. --- Use Uniswap AI to speed up swap integration, hook development, and EVM workflows with tools designed for builders on Uniswap. -If your agent talks to the Trading API directly, send the optional [`X-Agent-Info` attribution header](/docs/trading/swapping-api/agent-attribution) so agent-driven traffic is measured separately from human-driven traffic. +If your agent talks to the Trading API directly, send the optional [`X-Agent-Info` attribution header](/docs/trading/swapping-api/start-building/agent-attribution) so agent-driven traffic is measured separately from human-driven traffic. ## Uniswap AI @@ -99,6 +123,80 @@ https://developers.uniswap.org/llms-full.txt Install the Uniswap AI plugins (see [above](#claude-code-marketplace)) for the richest integration. The plugins provide structured skills, expert agents, and protocol-specific tools that go beyond static documentation context. +## FAQ + +
+ Is Uniswap AI free and open source? + + + + Yes. Uniswap AI is an open-source collection of plugins and skills published under the MIT license in the [Uniswap/uniswap-ai](https://github.com/Uniswap/uniswap-ai) repository on GitHub. There is no cost to install or use the skills, and you can read, fork, and contribute to the source. + + + +
+ +
+ Do I need Claude Code to use Uniswap AI skills? + + + + No. The skills are designed for any coding agent and install with the Skills CLI: + + ```bash + npx skills add Uniswap/uniswap-ai + ``` + + [Claude Code](https://claude.ai/code) is one supported option: it adds a [plugin marketplace](#claude-code-marketplace) that bundles the skills with expert agents and protocol-specific tools, but it is not required. + + + +
+ +
+ Do Uniswap AI skills run in production? + + + + No. Skills are build-time workflows that guide your coding agent while you write integration code. They are instructions and references loaded into the agent, not a runtime service that ships inside your deployed application. The code your agent produces with a skill is what runs in production. See [Uniswap Skills](/docs/uniswap-ai/skills) for how skills activate. + + + +
+ +
+ How are skills different from the llms.txt context files? + + + + Both give an AI model Uniswap knowledge, but at different levels of structure: + + * `llms.txt` and `llms-full.txt` are raw documentation context you add to a model's context window. See [LLM Context Files](#llm-context-files). + * Skills are structured, task-scoped workflows with step-by-step instructions and references that a coding agent activates directly or by matching your prompt. + + Use the context files when you want plain documentation grounding, and use skills when you want guided, protocol-specific workflows. + + + +
+ +
+ Which skills are available and how do I install them? + + + + Uniswap AI publishes skills such as `swap-integration`, `v4-security-foundations`, and `liquidity-planner`. See the [Uniswap/uniswap-ai](https://github.com/Uniswap/uniswap-ai) repository for the full, current list. Install them with the Skills CLI: + + ```bash + npx skills add Uniswap/uniswap-ai + ``` + + Alternatively, add the [Claude Code marketplace](#claude-code-marketplace) to install plugins individually. + + + +
+ ## Where to Go Next - [Browse official skills](/docs/uniswap-ai/skills) diff --git a/content/uniswap-ai/skills.mdx b/content/uniswap-ai/skills.mdx index 12e8f4ece..e407dfc4e 100644 --- a/content/uniswap-ai/skills.mdx +++ b/content/uniswap-ai/skills.mdx @@ -1,6 +1,14 @@ --- title: Uniswap Skills description: Browse available Uniswap AI skills for swap integration, hook development, liquidity management, and more. +keywords: + - Uniswap AI + - skills + - plugins + - coding agents + - llms.txt + - open source + --- Use Uniswap AI skills to run specialized workflows for swap integration, hook development, EVM interactions, and liquidity planning. @@ -81,3 +89,4 @@ Each skill is defined in a `SKILL.md` file and typically includes: 2. Add a `SKILL.md` file with frontmatter and clear instructions 3. Register the skill in the plugin manifest (`plugin.json`) 4. Validate the skill with lint and test checks before opening a PR +