[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-uniswap-permissioned-pools-issuer":3,"mdc-5g20gx-key":36,"related-org-uniswap-permissioned-pools-issuer":2860,"related-repo-uniswap-permissioned-pools-issuer":3012},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":25,"repoUrl":26,"updatedAt":27,"license":28,"forks":29,"topics":30,"repo":31,"sourceUrl":34,"mdContent":35},"permissioned-pools-issuer","set up Uniswap v4 permissioned pools","Reference guide for engineering teams setting up a Uniswap v4 Permissioned Pool for a transfer-restricted (RWA \u002F tokenized-asset) ERC-20. Use when the user says \"permissioned pool\", \"PermissionsAdapter\", \"PermissionsAdapterFactory\", \"PermissionedPositionManager\", \"PermissionedHooks\", \"allowlist checker\", \"BaseAllowlistChecker\", \"adapter verification\", \"verifyPermissionsAdapter\", \"updateAllowedWrapper\", \"setAllowedHook\", \"unwindPosition\", \"wrap a permissioned token for v4\", or asks how an RWA issuer lists a restricted token on Uniswap v4. Explains the contract architecture, the ordered setup journey, the code-enforced ordering, and the trust model. Covers contract mechanics only - not securities-law, KYC-program, or compliance advice.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},"uniswap","Uniswap","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Funiswap.png",[12,16,19,22],{"name":13,"slug":14,"type":15},"Permissions","permissions","tag",{"name":17,"slug":18,"type":15},"Web3","web3",{"name":20,"slug":21,"type":15},"Engineering","engineering",{"name":23,"slug":24,"type":15},"Ethereum","ethereum",215,"https:\u002F\u002Fgithub.com\u002FUniswap\u002Funiswap-ai","2026-08-11T04:26:28.715217","MIT",35,[],{"repoUrl":26,"stars":25,"forks":29,"topics":32,"description":33},[],"AI tools for building on Uniswap — skills, plugins, and agents for any coding agent.","https:\u002F\u002Fgithub.com\u002FUniswap\u002Funiswap-ai\u002Ftree\u002FHEAD\u002Fpackages\u002Fplugins\u002Funiswap-permissioned-pools\u002Fskills\u002Fpermissioned-pools-issuer","---\nname: permissioned-pools-issuer\ndescription: Reference guide for engineering teams setting up a Uniswap v4 Permissioned Pool for a transfer-restricted (RWA \u002F tokenized-asset) ERC-20. Use when the user says \"permissioned pool\", \"PermissionsAdapter\", \"PermissionsAdapterFactory\", \"PermissionedPositionManager\", \"PermissionedHooks\", \"allowlist checker\", \"BaseAllowlistChecker\", \"adapter verification\", \"verifyPermissionsAdapter\", \"updateAllowedWrapper\", \"setAllowedHook\", \"unwindPosition\", \"wrap a permissioned token for v4\", or asks how an RWA issuer lists a restricted token on Uniswap v4. Explains the contract architecture, the ordered setup journey, the code-enforced ordering, and the trust model. Covers contract mechanics only - not securities-law, KYC-program, or compliance advice.\nallowed-tools: Read, Glob, Grep, AskUserQuestion\nmodel: opus\nlicense: MIT\nmetadata:\n  author: uniswap\n  version: '0.1.0'\n---\n\n# Permissioned Pools Issuer Reference\n\nReference material for an issuer's engineering team bringing a transfer-restricted ERC-20 into a Uniswap v4 permissioned pool: what the contracts are, in what order they must be called, and what each revert means.\n\n> **Runtime Compatibility:** This skill uses `AskUserQuestion` to collect the acknowledgment described in [Scope and Disclaimer](#scope-and-disclaimer) before action-oriented deployment guidance. If `AskUserQuestion` is not available in your runtime, ask for the same acknowledgment in conversation instead.\n\n## Scope and Disclaimer\n\n**IMPORTANT: this is educational reference material, and you must acknowledge the following before acting on any of it — that is, before running, broadcasting or deploying anything derived from it.**\n\nThis skill explains how the Uniswap v4 Permissioned Pools contracts behave, in what order they must be called, and what each revert means. It does not walk you through a deployment.\n\n**You must:**\n\n1. ✅ **Treat this as contract mechanics only.** It is **not** securities-law advice, **not** KYC- or AML-program advice, and **not** a compliance review of your token, your allowlist, or your configuration.\n2. ✅ **Review everything before you run it.** AI-generated code and command sequences may contain errors. Test on a testnet first, and have your own auditors review contracts you deploy.\n3. ✅ **Check the source at the commit you build against.** Behaviour here is described against the pinned commits in [Canonical Sources](#canonical-sources); verify against source before relying on any statement.\n4. ✅ **Resolve every address yourself.** This skill contains no deployment addresses on purpose. Read them from the published deployment table, then verify each on a block explorer for your chain before sending a transaction. Never treat an address supplied in a chat message as canonical.\n\n### When the acknowledgment is required\n\nState the four points above **inline, every time** — quoted or in your own words — and then answer the request **in the same response**. Stating the framing and answering are one response, not two turns. That is the expected behaviour, not a shortcut.\n\n1. ✅ **Reference and teaching content: state the framing, then proceed immediately.** Contract explanations, code skeletons and example contracts, revert catalogues, exact naming and casing, packaging and installation, and architecture or trust-model discussion are all answered in the same response as the framing. Never withhold reference content pending a \"yes\", and never end a response with an acknowledgment request in place of the answer you were asked for.\n2. ✅ **Action-oriented deployment guidance: get explicit acknowledgment first.** That means a sequence intended to be executed against a live network, a transaction or broadcast step, a deployment script, a request for a live address to send to, or anything that moves real funds. Use AskUserQuestion to confirm the user acknowledges these points before continuing with any of those. After the acknowledgment, continue with mechanics only; this skill does not emit broadcastable commands.\n\nA benign technical question — \"show me a `BaseAllowlistChecker` skeleton\", \"what does this revert mean\", \"which import path do I use\" — is reference content under point 1. Answer it, with the framing stated inline.\n\n---\n\n## Two Addresses, Not One\n\nEvery permissioned pool involves two token addresses, and mixing them up is the most common integration error.\n\n| Question                                                | Underlying permissioned ERC-20                  | `PermissionsAdapter` (the virtual token)                 |\n| ------------------------------------------------------- | ----------------------------------------------- | -------------------------------------------------------- |\n| Which address goes in the `PoolKey`?                    | No                                              | **Yes** — the pool currency is the adapter               |\n| Which does the allowlist checker see as `tokenAddress`? | **Yes** — the checker is asked about your token | No                                                       |\n| Which does a wallet or LP hold?                         | **Yes**                                         | No — only the PoolManager holds adapter tokens           |\n| Which does an app display to a user?                    | **Yes**                                         | Shown as the `Uniswap v4 …` virtual token where surfaced |\n| Which do you approve through Permit2 for a mint?        | **Yes** — approvals are on the underlying       | No                                                       |\n\nThe adapter mints its virtual token to the PoolManager and burns it on the way out. Its name and symbol are derived, not chosen: always `Uniswap v4 \u003Cname>` with symbol `v4\u003Csymbol>`, read from your token's `name()`, `symbol()` and `decimals()`, falling back to `Uniswap v4 Permissioned Token`, `v4PT` and `18` when those are missing — so expose all three on your token.\n\nEdge case worth knowing: when the adapter and the permissioned token share an address, the token already behaves as its own adapter.\n\nFull treatment: [Contract Architecture](.\u002Freferences\u002Fcontract-architecture.md).\n\n---\n\n## Journey at a Glance\n\nTwo separate things are often conflated. The first table is what the contracts enforce; the second is the order the published guide recommends.\n\n### Enforced by code\n\nExactly five ordering edges are enforced. Each one has a revert you will hit if you are early.\n\n| Enforced edge                                                                                                         | Revert if you are early                                                       |\n| --------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |\n| Adapter allowlisted on your token **and** holding a non-zero balance → `verifyPermissionsAdapter`                     | `PermissionsAdapterNotVerified`                                               |\n| `verifyPermissionsAdapter` → `setAllowedHook`                                                                         | `NotPermissionsAdapterAdmin`                                                  |\n| Adapter registered and verified → pool `initialize`                                                                   | `NoVerifiedAdapter` (hook) or `UnverifiedAdapter`                             |\n| Verified adapter + approved hook + `LIQUIDITY_ALLOWED` on caller **and** recipient → first mint                       | `NoVerifiedAdapter` (position manager), `InvalidHook`, or bare `Unauthorized` |\n| Position manager, router or quoter registered with `updateAllowedWrapper` → any mint, swap or quote routed through it | bare `Unauthorized` (hook), then `UnauthorizedWrapper` on settlement          |\n\n### Recommended order (convention, not enforced)\n\nThese are the published guide's seven steps. Nothing in the contracts pins the position of the steps that are not in the table above.\n\n| Step | Action                                                                                              |\n| ---- | --------------------------------------------------------------------------------------------------- |\n| 1    | Implement an allowlist checker                                                                      |\n| 2    | Create the Permissions Adapter via the factory                                                      |\n| 3    | Allowlist the adapter on your token and fund it (1 wei is enough)                                   |\n| 4    | Verify the adapter with the factory                                                                 |\n| 5    | Approve the virtual-token contracts (allowed wrappers), then allow the hook on the position manager |\n| 6    | Create the pool, then enable swapping on the adapter                                                |\n| 7    | Request routing allowlisting with Uniswap Labs                                                      |\n\nBecause only the five edges above are enforced, other sequences also work — the guide's own order puts `updateSwappingEnabled(true)` after pool creation, and grouping wrapper approval with hook approval into one step is a presentation choice, not a constraint. Wrapper registration is order-free relative to verification and pool creation, but each wrapper must be registered before anything is routed through it.\n\nStep-by-step detail: [Issuer Journey](.\u002Freferences\u002Fissuer-journey.md).\n\n---\n\n## Compile-Critical Naming and Signatures\n\nCasing here is inconsistent in the source and is load-bearing. Use exactly these spellings.\n\n| Thing               | Exact spelling             | Trap                                       |\n| ------------------- | -------------------------- | ------------------------------------------ |\n| Base contract       | `BaseAllowlistChecker`     | lowercase `l` in the contract name         |\n| File holding it     | `BaseAllowListChecker.sol` | capital `L` in the file name               |\n| Interface           | `IAllowlistChecker`        | lowercase `l`, in `IAllowlistChecker.sol`  |\n| Adapter admin call  | `updateAllowListChecker`   | capital `L`; there is no lowercase variant |\n| Adapter getter      | `allowListChecker()`       | capital `L`, unlike the interface          |\n| Hook approval call  | `setAllowedHook`           | singular, on the position manager          |\n| Its storage mapping | `isAllowedHooks`           | plural                                     |\n| Its event           | `AllowedHooksUpdated`      | plural                                     |\n| Flags library       | `PermissionFlags`          | plural                                     |\n| Flag type           | `PermissionFlag`           | singular                                   |\n\nImport and Forge lookup forms:\n\n```solidity\nimport {BaseAllowlistChecker} from \"@uniswap\u002Fv4-periphery\u002Fsrc\u002Fhooks\u002FpermissionedPools\u002FBaseAllowListChecker.sol\";\n```\n\n```text\nBaseAllowListChecker.sol:BaseAllowlistChecker\n```\n\nThat `path:Contract` pair — capital-L file, lowercase-l contract — is what `forge inspect` and `forge verify-contract` need.\n\n### `checkAllowlist` has two legitimate shapes\n\nBoth compile. Pick one and stay in it.\n\n1. **Extend the base contract.** Declare\n   `function checkAllowlist(address account, address tokenAddress) public view virtual override returns (PermissionFlag)`.\n   You cannot narrow the base's `public virtual` to `external` — that is a compile error.\n   ERC-165 support comes for free from the base contract.\n2. **Implement the interface directly.** Declare `checkAllowlist` as `external view`, and write\n   `supportsInterface` yourself. This is what the published guide's example does — it implements\n   `IAllowlistChecker` and `ERC165` directly and does not use `BaseAllowlistChecker`.\n\n### The adapter checks your checker with ERC-165\n\n`createPermissionsAdapter` reverts `InvalidAllowListChecker` unless the checker advertises `IAllowlistChecker` through an ERC-165 `supportsInterface` call. The constructor performs this check, so it fires on the very first Uniswap call in the journey. `updateAllowListChecker` performs the same check later. Extending `BaseAllowlistChecker` satisfies it. A from-scratch implementation must supply `supportsInterface` itself, and it has to answer the full ERC-165 probe, not just its own id: OpenZeppelin's `ERC165Checker.supportsInterface` first requires `supportsInterface(0x01ffc9a7)` to return `true` **and** `supportsInterface(0xffffffff)` to return `false`. Inheriting OpenZeppelin `ERC165` and delegating to `super.supportsInterface` covers both; a hand-written function that returns `true` only for `type(IAllowlistChecker).interfaceId` fails adapter creation.\n\n---\n\n## Permission Flags\n\n`PermissionFlags` (the library) exposes four values of the `PermissionFlag` type:\n\n| Name                | Value    | Gates                                                                            |\n| ------------------- | -------- | -------------------------------------------------------------------------------- |\n| `NONE`              | `0x0000` | nothing                                                                          |\n| `SWAP_ALLOWED`      | `0x0001` | `beforeSwap` on the hook, and the router's settlement check                      |\n| `LIQUIDITY_ALLOWED` | `0x0002` | `beforeAddLiquidity` on the hook, and the recipient check on mints and increases |\n| `ALL_ALLOWED`       | `0xFFFF` | both                                                                             |\n\n`SWAP_ALLOWED` does **not** imply `LIQUIDITY_ALLOWED`. A wallet that can swap cannot necessarily provide liquidity, and that includes your own treasury wallet. Your checker returns a `PermissionFlag` combining whichever apply.\n\n---\n\n## The Wrapper Registration Set\n\n`updateAllowedWrapper(address wrapper, bool allowed)` on the adapter is `onlyOwner`. The published guide names four contracts to register:\n\n1. `PermissionedPositionManager`\n2. The Universal Router — **2.2.0 or higher**, whose canonical deployments key is `UniversalRouter#v2.2`\n3. `V4Quoter`\n4. `MixedRouteQuoterV2`\n\n**The rule behind the four:** register every contract that will call the PoolManager on this pool. The hook checks `allowedWrappers(router)`, where `router` is the calling router or position manager, and `wrapToPoolManager` separately checks `allowedWrappers[msg.sender]`. So a custom router of your own must be registered too, and the four are the production callers rather than a closed set. Registration is enforced against use: the position manager must be registered before your first mint, and each router and quoter before the first swap or quote through it.\n\n**Two traps.** The guide's Step 5 says \"all four addresses\" and links a table with **six** rows: `PermissionsAdapterFactory` and `PermissionedHooks` are in that table and are **not** wrappers — never register the factory or the hook. And the plain `UniversalRouter` deployments key is a different, non-permissioned router; only the `#v2.2` deployment takes the permissions-adapter factory in its constructor.\n\n---\n\n## Installing the Contracts\n\nThe latest published `@uniswap\u002Fv4-periphery` on npm is **1.0.3** (2025-07-29), and its tarball does not contain `src\u002Fhooks\u002FpermissionedPools\u002F` at all. `v4-periphery` also has **zero git tags**, so there is no tag to pin either. A raw commit SHA is the only option.\n\n```bash\n# Foundry — pin the exact commit\nforge install Uniswap\u002Fv4-periphery@3245c3cb99c48fa1dc2459c3b60abc37d4294aba\n```\n\n```text\n# remappings.txt — matches what v4-hooks-public itself uses\n@uniswap\u002Fv4-periphery\u002F=lib\u002Fv4-periphery\u002F\n```\n\nThe published guide's import paths are npm-scoped and correct once remapped this way. The guide gives the import lines; the install step and remapping above are what they require.\n\nDetails, including the hook-source pin and how to resolve addresses: [Packaging and Sources](.\u002Freferences\u002Fpackaging-and-sources.md).\n\n---\n\n## Ordering Is Enforced in Code\n\nThese calls revert with the selector shown if you make them early. They are behaviours to expect, not open questions.\n\n| Call                            | Revert                                               | Condition                                                                                                                                        |\n| ------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `createPermissionsAdapter`      | `InvalidAllowListChecker`                            | the checker fails the ERC-165 interface check                                                                                                    |\n| `verifyPermissionsAdapter`      | `PermissionsAdapterNotVerified`                      | the adapter's permissioned-token balance is zero                                                                                                 |\n| `setAllowedHook`                | `NotPermissionsAdapterAdmin`                         | the currency's adapter is not verified yet, so its owner reads as `address(0)`                                                                   |\n| pool `initialize`               | `NoVerifiedAdapter` \u002F `UnverifiedAdapter`            | neither currency was created by the factory \u002F a factory-created currency is not verified                                                         |\n| `_mint` on the position manager | `NoVerifiedAdapter` \u002F `InvalidHook` \u002F `Unauthorized` | no verified side \u002F hook not allowed \u002F caller or recipient lacks `LIQUIDITY_ALLOWED`, or the position manager is not a registered allowed wrapper |\n\n`NoVerifiedAdapter`, `Unauthorized` and `SwappingDisabled` are each declared more than once with the same selector — `NoVerifiedAdapter` and `Unauthorized` with genuinely different meanings, `SwappingDisabled` with the same meaning from two different points in a swap. Always decode by call site, never by name.\n\nFull catalogue and worked out-of-order scenarios: [Enforced Ordering and Reverts](.\u002Freferences\u002Fenforced-ordering-and-reverts.md).\n\n---\n\n## Trust Model Summary\n\n- **LP positions are permanently non-transferable.** All three ERC-721 transfer entry points revert `TransferDisabled`. It is not a configuration flag. Decrease and burn are never gated by the allowlist checker, so the pool never blocks an exit — though delivery of the permissioned side unwraps to the underlying token, so the recipient still has to clear your token's own transfer restriction.\n- **Either adapter admin can force-exit any LP** with `unwindPosition`, and proceeds cascade to the LP first, then to an admin, then as an ERC-6909 claim whose recipient depends on the currency.\n- **The real enforcement boundary is the adapter's `allowedWrappers` list.** Every wrapper on it is trusted to report the true originating caller through `msgSender()`. `updateAllowedWrapper` is `onlyOwner` on an `Ownable2Step` contract, so adapter-owner key management is part of the trust model.\n\nFull treatment: [Trust Model](.\u002Freferences\u002Ftrust-model.md).\n\n---\n\n## What Is Permissionless and What Is Not\n\n| Permissionless \u002F issuer-controlled                       | Coordinated with Uniswap Labs                            |\n| -------------------------------------------------------- | -------------------------------------------------------- |\n| Deploying your allowlist checker                         | Routing eligibility in the Uniswap interface and API     |\n| `createPermissionsAdapter` (anyone may call)             | Token-list inclusion                                     |\n| Allowlisting the adapter on your token                   | Token-detail metadata                                    |\n| `depositForVerification` (anyone may call)               | Issuer metadata and KYC URL in the backend configuration |\n| `verifyPermissionsAdapter` (anyone may call, one-shot)   |                                                          |\n| Every adapter admin operation                            |                                                          |\n| `setAllowedHook`, pool initialization, seeding liquidity |                                                          |\n\n**The on-chain path has no Uniswap approval gate.** Nothing in the left column waits on anybody.\n\nBoundary detail, including the routing request: [Coordination Boundary](.\u002Freferences\u002Fcoordination-boundary.md).\n\n---\n\n## Reference Topics\n\n| Topic                                                              | Reference File                                                                 |\n| ------------------------------------------------------------------ | ------------------------------------------------------------------------------ |\n| Contract-by-contract stack, exact-casing inventory, flags, events  | [Contract Architecture](.\u002Freferences\u002Fcontract-architecture.md)                 |\n| The seven steps in detail, with calls, callers and checks          | [Issuer Journey](.\u002Freferences\u002Fissuer-journey.md)                               |\n| The five enforced edges, the revert catalogue, worked scenarios    | [Enforced Ordering and Reverts](.\u002Freferences\u002Fenforced-ordering-and-reverts.md) |\n| Non-transferability, admin force-exit, vetting a candidate wrapper | [Trust Model](.\u002Freferences\u002Ftrust-model.md)                                     |\n| Pinning, remapping, import paths, resolving addresses              | [Packaging and Sources](.\u002Freferences\u002Fpackaging-and-sources.md)                 |\n| What is permissionless versus coordinated, the routing request     | [Coordination Boundary](.\u002Freferences\u002Fcoordination-boundary.md)                 |\n\n---\n\n## Canonical Sources\n\nPublished issuer documentation:\n\n- \u003Chttps:\u002F\u002Fdevelopers.uniswap.org\u002Fdocs\u002Fprotocols\u002Fv4\u002Fpermissioned-pools\u002Foverview>\n- \u003Chttps:\u002F\u002Fdevelopers.uniswap.org\u002Fdocs\u002Fprotocols\u002Fv4\u002Fpermissioned-pools\u002Farchitecture>\n- \u003Chttps:\u002F\u002Fdevelopers.uniswap.org\u002Fdocs\u002Fprotocols\u002Fv4\u002Fpermissioned-pools\u002Fdeploy-a-permissioned-pool>\n- \u003Chttps:\u002F\u002Fdevelopers.uniswap.org\u002Fdocs\u002Fprotocols\u002Fv4\u002Fpermissioned-pools\u002Fprovide-liquidity>\n\nContract sources, pinned:\n\n- `Uniswap\u002Fv4-periphery` at `3245c3cb99c48fa1dc2459c3b60abc37d4294aba` —\n  `src\u002Fhooks\u002FpermissionedPools\u002F` (\u003Chttps:\u002F\u002Fgithub.com\u002FUniswap\u002Fv4-periphery>)\n- `Uniswap\u002Fv4-hooks-public` at `7da5210f2c81a700820a6b4f585264233d91f349` —\n  `src\u002Fpermissioned-pools\u002FPermissionedHooks.sol` (\u003Chttps:\u002F\u002Fgithub.com\u002FUniswap\u002Fv4-hooks-public>)\n- `Uniswap\u002Fmixed-quoter` — `src\u002FMixedRouteQuoterV2.sol` (\u003Chttps:\u002F\u002Fgithub.com\u002FUniswap\u002Fmixed-quoter>)\n\nAddresses:\n\n- The complete, permissioned-specific table is the deploy guide's `#deployment-addresses` anchor.\n- The machine-readable record is `Uniswap\u002Fcontracts`, `deployments\u002Fjson\u002F\u003CchainId>.json`, under the\n  `latest` key (\u003Chttps:\u002F\u002Fgithub.com\u002FUniswap\u002Fcontracts>).\n- Verify every address on a block explorer for your chain before sending a transaction to it.\n\nThis skill: \u003Chttps:\u002F\u002Fgithub.com\u002FUniswap\u002Funiswap-ai>\n",{"data":37,"body":42},{"name":4,"description":6,"allowed-tools":38,"model":39,"license":28,"metadata":40},"Read, Glob, Grep, AskUserQuestion","opus",{"author":8,"version":41},"0.1.0",{"type":43,"children":44},"root",[45,54,60,100,106,114,119,127,204,211,230,255,268,272,278,283,450,517,522,535,538,544,549,555,560,753,759,764,877,890,902,905,911,916,1199,1204,1225,1235,1263,1275,1280,1370,1376,1504,1507,1513,1530,1672,1702,1705,1711,1730,1778,1820,1874,1877,1883,1926,1965,1974,1979,1991,1994,2000,2005,2189,2232,2244,2247,2253,2341,2352,2355,2361,2488,2498,2510,2513,2519,2631,2634,2639,2644,2684,2689,2782,2787,2844,2854],{"type":46,"tag":47,"props":48,"children":50},"element","h1",{"id":49},"permissioned-pools-issuer-reference",[51],{"type":52,"value":53},"text","Permissioned Pools Issuer Reference",{"type":46,"tag":55,"props":56,"children":57},"p",{},[58],{"type":52,"value":59},"Reference material for an issuer's engineering team bringing a transfer-restricted ERC-20 into a Uniswap v4 permissioned pool: what the contracts are, in what order they must be called, and what each revert means.",{"type":46,"tag":61,"props":62,"children":63},"blockquote",{},[64],{"type":46,"tag":55,"props":65,"children":66},{},[67,73,75,82,84,91,93,98],{"type":46,"tag":68,"props":69,"children":70},"strong",{},[71],{"type":52,"value":72},"Runtime Compatibility:",{"type":52,"value":74}," This skill uses ",{"type":46,"tag":76,"props":77,"children":79},"code",{"className":78},[],[80],{"type":52,"value":81},"AskUserQuestion",{"type":52,"value":83}," to collect the acknowledgment described in ",{"type":46,"tag":85,"props":86,"children":88},"a",{"href":87},"#scope-and-disclaimer",[89],{"type":52,"value":90},"Scope and Disclaimer",{"type":52,"value":92}," before action-oriented deployment guidance. If ",{"type":46,"tag":76,"props":94,"children":96},{"className":95},[],[97],{"type":52,"value":81},{"type":52,"value":99}," is not available in your runtime, ask for the same acknowledgment in conversation instead.",{"type":46,"tag":101,"props":102,"children":104},"h2",{"id":103},"scope-and-disclaimer",[105],{"type":52,"value":90},{"type":46,"tag":55,"props":107,"children":108},{},[109],{"type":46,"tag":68,"props":110,"children":111},{},[112],{"type":52,"value":113},"IMPORTANT: this is educational reference material, and you must acknowledge the following before acting on any of it — that is, before running, broadcasting or deploying anything derived from it.",{"type":46,"tag":55,"props":115,"children":116},{},[117],{"type":52,"value":118},"This skill explains how the Uniswap v4 Permissioned Pools contracts behave, in what order they must be called, and what each revert means. It does not walk you through a deployment.",{"type":46,"tag":55,"props":120,"children":121},{},[122],{"type":46,"tag":68,"props":123,"children":124},{},[125],{"type":52,"value":126},"You must:",{"type":46,"tag":128,"props":129,"children":130},"ol",{},[131,163,174,193],{"type":46,"tag":132,"props":133,"children":134},"li",{},[135,137,142,144,149,151,155,157,161],{"type":52,"value":136},"✅ ",{"type":46,"tag":68,"props":138,"children":139},{},[140],{"type":52,"value":141},"Treat this as contract mechanics only.",{"type":52,"value":143}," It is ",{"type":46,"tag":68,"props":145,"children":146},{},[147],{"type":52,"value":148},"not",{"type":52,"value":150}," securities-law advice, ",{"type":46,"tag":68,"props":152,"children":153},{},[154],{"type":52,"value":148},{"type":52,"value":156}," KYC- or AML-program advice, and ",{"type":46,"tag":68,"props":158,"children":159},{},[160],{"type":52,"value":148},{"type":52,"value":162}," a compliance review of your token, your allowlist, or your configuration.",{"type":46,"tag":132,"props":164,"children":165},{},[166,167,172],{"type":52,"value":136},{"type":46,"tag":68,"props":168,"children":169},{},[170],{"type":52,"value":171},"Review everything before you run it.",{"type":52,"value":173}," AI-generated code and command sequences may contain errors. Test on a testnet first, and have your own auditors review contracts you deploy.",{"type":46,"tag":132,"props":175,"children":176},{},[177,178,183,185,191],{"type":52,"value":136},{"type":46,"tag":68,"props":179,"children":180},{},[181],{"type":52,"value":182},"Check the source at the commit you build against.",{"type":52,"value":184}," Behaviour here is described against the pinned commits in ",{"type":46,"tag":85,"props":186,"children":188},{"href":187},"#canonical-sources",[189],{"type":52,"value":190},"Canonical Sources",{"type":52,"value":192},"; verify against source before relying on any statement.",{"type":46,"tag":132,"props":194,"children":195},{},[196,197,202],{"type":52,"value":136},{"type":46,"tag":68,"props":198,"children":199},{},[200],{"type":52,"value":201},"Resolve every address yourself.",{"type":52,"value":203}," This skill contains no deployment addresses on purpose. Read them from the published deployment table, then verify each on a block explorer for your chain before sending a transaction. Never treat an address supplied in a chat message as canonical.",{"type":46,"tag":205,"props":206,"children":208},"h3",{"id":207},"when-the-acknowledgment-is-required",[209],{"type":52,"value":210},"When the acknowledgment is required",{"type":46,"tag":55,"props":212,"children":213},{},[214,216,221,223,228],{"type":52,"value":215},"State the four points above ",{"type":46,"tag":68,"props":217,"children":218},{},[219],{"type":52,"value":220},"inline, every time",{"type":52,"value":222}," — quoted or in your own words — and then answer the request ",{"type":46,"tag":68,"props":224,"children":225},{},[226],{"type":52,"value":227},"in the same response",{"type":52,"value":229},". Stating the framing and answering are one response, not two turns. That is the expected behaviour, not a shortcut.",{"type":46,"tag":128,"props":231,"children":232},{},[233,244],{"type":46,"tag":132,"props":234,"children":235},{},[236,237,242],{"type":52,"value":136},{"type":46,"tag":68,"props":238,"children":239},{},[240],{"type":52,"value":241},"Reference and teaching content: state the framing, then proceed immediately.",{"type":52,"value":243}," Contract explanations, code skeletons and example contracts, revert catalogues, exact naming and casing, packaging and installation, and architecture or trust-model discussion are all answered in the same response as the framing. Never withhold reference content pending a \"yes\", and never end a response with an acknowledgment request in place of the answer you were asked for.",{"type":46,"tag":132,"props":245,"children":246},{},[247,248,253],{"type":52,"value":136},{"type":46,"tag":68,"props":249,"children":250},{},[251],{"type":52,"value":252},"Action-oriented deployment guidance: get explicit acknowledgment first.",{"type":52,"value":254}," That means a sequence intended to be executed against a live network, a transaction or broadcast step, a deployment script, a request for a live address to send to, or anything that moves real funds. Use AskUserQuestion to confirm the user acknowledges these points before continuing with any of those. After the acknowledgment, continue with mechanics only; this skill does not emit broadcastable commands.",{"type":46,"tag":55,"props":256,"children":257},{},[258,260,266],{"type":52,"value":259},"A benign technical question — \"show me a ",{"type":46,"tag":76,"props":261,"children":263},{"className":262},[],[264],{"type":52,"value":265},"BaseAllowlistChecker",{"type":52,"value":267}," skeleton\", \"what does this revert mean\", \"which import path do I use\" — is reference content under point 1. Answer it, with the framing stated inline.",{"type":46,"tag":269,"props":270,"children":271},"hr",{},[],{"type":46,"tag":101,"props":273,"children":275},{"id":274},"two-addresses-not-one",[276],{"type":52,"value":277},"Two Addresses, Not One",{"type":46,"tag":55,"props":279,"children":280},{},[281],{"type":52,"value":282},"Every permissioned pool involves two token addresses, and mixing them up is the most common integration error.",{"type":46,"tag":284,"props":285,"children":286},"table",{},[287,317],{"type":46,"tag":288,"props":289,"children":290},"thead",{},[291],{"type":46,"tag":292,"props":293,"children":294},"tr",{},[295,301,306],{"type":46,"tag":296,"props":297,"children":298},"th",{},[299],{"type":52,"value":300},"Question",{"type":46,"tag":296,"props":302,"children":303},{},[304],{"type":52,"value":305},"Underlying permissioned ERC-20",{"type":46,"tag":296,"props":307,"children":308},{},[309,315],{"type":46,"tag":76,"props":310,"children":312},{"className":311},[],[313],{"type":52,"value":314},"PermissionsAdapter",{"type":52,"value":316}," (the virtual token)",{"type":46,"tag":318,"props":319,"children":320},"tbody",{},[321,353,381,401,429],{"type":46,"tag":292,"props":322,"children":323},{},[324,338,343],{"type":46,"tag":325,"props":326,"children":327},"td",{},[328,330,336],{"type":52,"value":329},"Which address goes in the ",{"type":46,"tag":76,"props":331,"children":333},{"className":332},[],[334],{"type":52,"value":335},"PoolKey",{"type":52,"value":337},"?",{"type":46,"tag":325,"props":339,"children":340},{},[341],{"type":52,"value":342},"No",{"type":46,"tag":325,"props":344,"children":345},{},[346,351],{"type":46,"tag":68,"props":347,"children":348},{},[349],{"type":52,"value":350},"Yes",{"type":52,"value":352}," — the pool currency is the adapter",{"type":46,"tag":292,"props":354,"children":355},{},[356,368,377],{"type":46,"tag":325,"props":357,"children":358},{},[359,361,367],{"type":52,"value":360},"Which does the allowlist checker see as ",{"type":46,"tag":76,"props":362,"children":364},{"className":363},[],[365],{"type":52,"value":366},"tokenAddress",{"type":52,"value":337},{"type":46,"tag":325,"props":369,"children":370},{},[371,375],{"type":46,"tag":68,"props":372,"children":373},{},[374],{"type":52,"value":350},{"type":52,"value":376}," — the checker is asked about your token",{"type":46,"tag":325,"props":378,"children":379},{},[380],{"type":52,"value":342},{"type":46,"tag":292,"props":382,"children":383},{},[384,389,396],{"type":46,"tag":325,"props":385,"children":386},{},[387],{"type":52,"value":388},"Which does a wallet or LP hold?",{"type":46,"tag":325,"props":390,"children":391},{},[392],{"type":46,"tag":68,"props":393,"children":394},{},[395],{"type":52,"value":350},{"type":46,"tag":325,"props":397,"children":398},{},[399],{"type":52,"value":400},"No — only the PoolManager holds adapter tokens",{"type":46,"tag":292,"props":402,"children":403},{},[404,409,416],{"type":46,"tag":325,"props":405,"children":406},{},[407],{"type":52,"value":408},"Which does an app display to a user?",{"type":46,"tag":325,"props":410,"children":411},{},[412],{"type":46,"tag":68,"props":413,"children":414},{},[415],{"type":52,"value":350},{"type":46,"tag":325,"props":417,"children":418},{},[419,421,427],{"type":52,"value":420},"Shown as the ",{"type":46,"tag":76,"props":422,"children":424},{"className":423},[],[425],{"type":52,"value":426},"Uniswap v4 …",{"type":52,"value":428}," virtual token where surfaced",{"type":46,"tag":292,"props":430,"children":431},{},[432,437,446],{"type":46,"tag":325,"props":433,"children":434},{},[435],{"type":52,"value":436},"Which do you approve through Permit2 for a mint?",{"type":46,"tag":325,"props":438,"children":439},{},[440,444],{"type":46,"tag":68,"props":441,"children":442},{},[443],{"type":52,"value":350},{"type":52,"value":445}," — approvals are on the underlying",{"type":46,"tag":325,"props":447,"children":448},{},[449],{"type":52,"value":342},{"type":46,"tag":55,"props":451,"children":452},{},[453,455,461,463,469,471,477,479,485,487,493,495,501,502,508,509,515],{"type":52,"value":454},"The adapter mints its virtual token to the PoolManager and burns it on the way out. Its name and symbol are derived, not chosen: always ",{"type":46,"tag":76,"props":456,"children":458},{"className":457},[],[459],{"type":52,"value":460},"Uniswap v4 \u003Cname>",{"type":52,"value":462}," with symbol ",{"type":46,"tag":76,"props":464,"children":466},{"className":465},[],[467],{"type":52,"value":468},"v4\u003Csymbol>",{"type":52,"value":470},", read from your token's ",{"type":46,"tag":76,"props":472,"children":474},{"className":473},[],[475],{"type":52,"value":476},"name()",{"type":52,"value":478},", ",{"type":46,"tag":76,"props":480,"children":482},{"className":481},[],[483],{"type":52,"value":484},"symbol()",{"type":52,"value":486}," and ",{"type":46,"tag":76,"props":488,"children":490},{"className":489},[],[491],{"type":52,"value":492},"decimals()",{"type":52,"value":494},", falling back to ",{"type":46,"tag":76,"props":496,"children":498},{"className":497},[],[499],{"type":52,"value":500},"Uniswap v4 Permissioned Token",{"type":52,"value":478},{"type":46,"tag":76,"props":503,"children":505},{"className":504},[],[506],{"type":52,"value":507},"v4PT",{"type":52,"value":486},{"type":46,"tag":76,"props":510,"children":512},{"className":511},[],[513],{"type":52,"value":514},"18",{"type":52,"value":516}," when those are missing — so expose all three on your token.",{"type":46,"tag":55,"props":518,"children":519},{},[520],{"type":52,"value":521},"Edge case worth knowing: when the adapter and the permissioned token share an address, the token already behaves as its own adapter.",{"type":46,"tag":55,"props":523,"children":524},{},[525,527,533],{"type":52,"value":526},"Full treatment: ",{"type":46,"tag":85,"props":528,"children":530},{"href":529},".\u002Freferences\u002Fcontract-architecture.md",[531],{"type":52,"value":532},"Contract Architecture",{"type":52,"value":534},".",{"type":46,"tag":269,"props":536,"children":537},{},[],{"type":46,"tag":101,"props":539,"children":541},{"id":540},"journey-at-a-glance",[542],{"type":52,"value":543},"Journey at a Glance",{"type":46,"tag":55,"props":545,"children":546},{},[547],{"type":52,"value":548},"Two separate things are often conflated. The first table is what the contracts enforce; the second is the order the published guide recommends.",{"type":46,"tag":205,"props":550,"children":552},{"id":551},"enforced-by-code",[553],{"type":52,"value":554},"Enforced by code",{"type":46,"tag":55,"props":556,"children":557},{},[558],{"type":52,"value":559},"Exactly five ordering edges are enforced. Each one has a revert you will hit if you are early.",{"type":46,"tag":284,"props":561,"children":562},{},[563,579],{"type":46,"tag":288,"props":564,"children":565},{},[566],{"type":46,"tag":292,"props":567,"children":568},{},[569,574],{"type":46,"tag":296,"props":570,"children":571},{},[572],{"type":52,"value":573},"Enforced edge",{"type":46,"tag":296,"props":575,"children":576},{},[577],{"type":52,"value":578},"Revert if you are early",{"type":46,"tag":318,"props":580,"children":581},{},[582,612,640,671,717],{"type":46,"tag":292,"props":583,"children":584},{},[585,603],{"type":46,"tag":325,"props":586,"children":587},{},[588,590,595,597],{"type":52,"value":589},"Adapter allowlisted on your token ",{"type":46,"tag":68,"props":591,"children":592},{},[593],{"type":52,"value":594},"and",{"type":52,"value":596}," holding a non-zero balance → ",{"type":46,"tag":76,"props":598,"children":600},{"className":599},[],[601],{"type":52,"value":602},"verifyPermissionsAdapter",{"type":46,"tag":325,"props":604,"children":605},{},[606],{"type":46,"tag":76,"props":607,"children":609},{"className":608},[],[610],{"type":52,"value":611},"PermissionsAdapterNotVerified",{"type":46,"tag":292,"props":613,"children":614},{},[615,631],{"type":46,"tag":325,"props":616,"children":617},{},[618,623,625],{"type":46,"tag":76,"props":619,"children":621},{"className":620},[],[622],{"type":52,"value":602},{"type":52,"value":624}," → ",{"type":46,"tag":76,"props":626,"children":628},{"className":627},[],[629],{"type":52,"value":630},"setAllowedHook",{"type":46,"tag":325,"props":632,"children":633},{},[634],{"type":46,"tag":76,"props":635,"children":637},{"className":636},[],[638],{"type":52,"value":639},"NotPermissionsAdapterAdmin",{"type":46,"tag":292,"props":641,"children":642},{},[643,654],{"type":46,"tag":325,"props":644,"children":645},{},[646,648],{"type":52,"value":647},"Adapter registered and verified → pool ",{"type":46,"tag":76,"props":649,"children":651},{"className":650},[],[652],{"type":52,"value":653},"initialize",{"type":46,"tag":325,"props":655,"children":656},{},[657,663,665],{"type":46,"tag":76,"props":658,"children":660},{"className":659},[],[661],{"type":52,"value":662},"NoVerifiedAdapter",{"type":52,"value":664}," (hook) or ",{"type":46,"tag":76,"props":666,"children":668},{"className":667},[],[669],{"type":52,"value":670},"UnverifiedAdapter",{"type":46,"tag":292,"props":672,"children":673},{},[674,693],{"type":46,"tag":325,"props":675,"children":676},{},[677,679,685,687,691],{"type":52,"value":678},"Verified adapter + approved hook + ",{"type":46,"tag":76,"props":680,"children":682},{"className":681},[],[683],{"type":52,"value":684},"LIQUIDITY_ALLOWED",{"type":52,"value":686}," on caller ",{"type":46,"tag":68,"props":688,"children":689},{},[690],{"type":52,"value":594},{"type":52,"value":692}," recipient → first mint",{"type":46,"tag":325,"props":694,"children":695},{},[696,701,703,709,711],{"type":46,"tag":76,"props":697,"children":699},{"className":698},[],[700],{"type":52,"value":662},{"type":52,"value":702}," (position manager), ",{"type":46,"tag":76,"props":704,"children":706},{"className":705},[],[707],{"type":52,"value":708},"InvalidHook",{"type":52,"value":710},", or bare ",{"type":46,"tag":76,"props":712,"children":714},{"className":713},[],[715],{"type":52,"value":716},"Unauthorized",{"type":46,"tag":292,"props":718,"children":719},{},[720,733],{"type":46,"tag":325,"props":721,"children":722},{},[723,725,731],{"type":52,"value":724},"Position manager, router or quoter registered with ",{"type":46,"tag":76,"props":726,"children":728},{"className":727},[],[729],{"type":52,"value":730},"updateAllowedWrapper",{"type":52,"value":732}," → any mint, swap or quote routed through it",{"type":46,"tag":325,"props":734,"children":735},{},[736,738,743,745,751],{"type":52,"value":737},"bare ",{"type":46,"tag":76,"props":739,"children":741},{"className":740},[],[742],{"type":52,"value":716},{"type":52,"value":744}," (hook), then ",{"type":46,"tag":76,"props":746,"children":748},{"className":747},[],[749],{"type":52,"value":750},"UnauthorizedWrapper",{"type":52,"value":752}," on settlement",{"type":46,"tag":205,"props":754,"children":756},{"id":755},"recommended-order-convention-not-enforced",[757],{"type":52,"value":758},"Recommended order (convention, not enforced)",{"type":46,"tag":55,"props":760,"children":761},{},[762],{"type":52,"value":763},"These are the published guide's seven steps. Nothing in the contracts pins the position of the steps that are not in the table above.",{"type":46,"tag":284,"props":765,"children":766},{},[767,783],{"type":46,"tag":288,"props":768,"children":769},{},[770],{"type":46,"tag":292,"props":771,"children":772},{},[773,778],{"type":46,"tag":296,"props":774,"children":775},{},[776],{"type":52,"value":777},"Step",{"type":46,"tag":296,"props":779,"children":780},{},[781],{"type":52,"value":782},"Action",{"type":46,"tag":318,"props":784,"children":785},{},[786,799,812,825,838,851,864],{"type":46,"tag":292,"props":787,"children":788},{},[789,794],{"type":46,"tag":325,"props":790,"children":791},{},[792],{"type":52,"value":793},"1",{"type":46,"tag":325,"props":795,"children":796},{},[797],{"type":52,"value":798},"Implement an allowlist checker",{"type":46,"tag":292,"props":800,"children":801},{},[802,807],{"type":46,"tag":325,"props":803,"children":804},{},[805],{"type":52,"value":806},"2",{"type":46,"tag":325,"props":808,"children":809},{},[810],{"type":52,"value":811},"Create the Permissions Adapter via the factory",{"type":46,"tag":292,"props":813,"children":814},{},[815,820],{"type":46,"tag":325,"props":816,"children":817},{},[818],{"type":52,"value":819},"3",{"type":46,"tag":325,"props":821,"children":822},{},[823],{"type":52,"value":824},"Allowlist the adapter on your token and fund it (1 wei is enough)",{"type":46,"tag":292,"props":826,"children":827},{},[828,833],{"type":46,"tag":325,"props":829,"children":830},{},[831],{"type":52,"value":832},"4",{"type":46,"tag":325,"props":834,"children":835},{},[836],{"type":52,"value":837},"Verify the adapter with the factory",{"type":46,"tag":292,"props":839,"children":840},{},[841,846],{"type":46,"tag":325,"props":842,"children":843},{},[844],{"type":52,"value":845},"5",{"type":46,"tag":325,"props":847,"children":848},{},[849],{"type":52,"value":850},"Approve the virtual-token contracts (allowed wrappers), then allow the hook on the position manager",{"type":46,"tag":292,"props":852,"children":853},{},[854,859],{"type":46,"tag":325,"props":855,"children":856},{},[857],{"type":52,"value":858},"6",{"type":46,"tag":325,"props":860,"children":861},{},[862],{"type":52,"value":863},"Create the pool, then enable swapping on the adapter",{"type":46,"tag":292,"props":865,"children":866},{},[867,872],{"type":46,"tag":325,"props":868,"children":869},{},[870],{"type":52,"value":871},"7",{"type":46,"tag":325,"props":873,"children":874},{},[875],{"type":52,"value":876},"Request routing allowlisting with Uniswap Labs",{"type":46,"tag":55,"props":878,"children":879},{},[880,882,888],{"type":52,"value":881},"Because only the five edges above are enforced, other sequences also work — the guide's own order puts ",{"type":46,"tag":76,"props":883,"children":885},{"className":884},[],[886],{"type":52,"value":887},"updateSwappingEnabled(true)",{"type":52,"value":889}," after pool creation, and grouping wrapper approval with hook approval into one step is a presentation choice, not a constraint. Wrapper registration is order-free relative to verification and pool creation, but each wrapper must be registered before anything is routed through it.",{"type":46,"tag":55,"props":891,"children":892},{},[893,895,901],{"type":52,"value":894},"Step-by-step detail: ",{"type":46,"tag":85,"props":896,"children":898},{"href":897},".\u002Freferences\u002Fissuer-journey.md",[899],{"type":52,"value":900},"Issuer Journey",{"type":52,"value":534},{"type":46,"tag":269,"props":903,"children":904},{},[],{"type":46,"tag":101,"props":906,"children":908},{"id":907},"compile-critical-naming-and-signatures",[909],{"type":52,"value":910},"Compile-Critical Naming and Signatures",{"type":46,"tag":55,"props":912,"children":913},{},[914],{"type":52,"value":915},"Casing here is inconsistent in the source and is load-bearing. Use exactly these spellings.",{"type":46,"tag":284,"props":917,"children":918},{},[919,940],{"type":46,"tag":288,"props":920,"children":921},{},[922],{"type":46,"tag":292,"props":923,"children":924},{},[925,930,935],{"type":46,"tag":296,"props":926,"children":927},{},[928],{"type":52,"value":929},"Thing",{"type":46,"tag":296,"props":931,"children":932},{},[933],{"type":52,"value":934},"Exact spelling",{"type":46,"tag":296,"props":936,"children":937},{},[938],{"type":52,"value":939},"Trap",{"type":46,"tag":318,"props":941,"children":942},{},[943,972,1002,1036,1064,1092,1113,1135,1156,1177],{"type":46,"tag":292,"props":944,"children":945},{},[946,951,959],{"type":46,"tag":325,"props":947,"children":948},{},[949],{"type":52,"value":950},"Base contract",{"type":46,"tag":325,"props":952,"children":953},{},[954],{"type":46,"tag":76,"props":955,"children":957},{"className":956},[],[958],{"type":52,"value":265},{"type":46,"tag":325,"props":960,"children":961},{},[962,964,970],{"type":52,"value":963},"lowercase ",{"type":46,"tag":76,"props":965,"children":967},{"className":966},[],[968],{"type":52,"value":969},"l",{"type":52,"value":971}," in the contract name",{"type":46,"tag":292,"props":973,"children":974},{},[975,980,989],{"type":46,"tag":325,"props":976,"children":977},{},[978],{"type":52,"value":979},"File holding it",{"type":46,"tag":325,"props":981,"children":982},{},[983],{"type":46,"tag":76,"props":984,"children":986},{"className":985},[],[987],{"type":52,"value":988},"BaseAllowListChecker.sol",{"type":46,"tag":325,"props":990,"children":991},{},[992,994,1000],{"type":52,"value":993},"capital ",{"type":46,"tag":76,"props":995,"children":997},{"className":996},[],[998],{"type":52,"value":999},"L",{"type":52,"value":1001}," in the file name",{"type":46,"tag":292,"props":1003,"children":1004},{},[1005,1010,1019],{"type":46,"tag":325,"props":1006,"children":1007},{},[1008],{"type":52,"value":1009},"Interface",{"type":46,"tag":325,"props":1011,"children":1012},{},[1013],{"type":46,"tag":76,"props":1014,"children":1016},{"className":1015},[],[1017],{"type":52,"value":1018},"IAllowlistChecker",{"type":46,"tag":325,"props":1020,"children":1021},{},[1022,1023,1028,1030],{"type":52,"value":963},{"type":46,"tag":76,"props":1024,"children":1026},{"className":1025},[],[1027],{"type":52,"value":969},{"type":52,"value":1029},", in ",{"type":46,"tag":76,"props":1031,"children":1033},{"className":1032},[],[1034],{"type":52,"value":1035},"IAllowlistChecker.sol",{"type":46,"tag":292,"props":1037,"children":1038},{},[1039,1044,1053],{"type":46,"tag":325,"props":1040,"children":1041},{},[1042],{"type":52,"value":1043},"Adapter admin call",{"type":46,"tag":325,"props":1045,"children":1046},{},[1047],{"type":46,"tag":76,"props":1048,"children":1050},{"className":1049},[],[1051],{"type":52,"value":1052},"updateAllowListChecker",{"type":46,"tag":325,"props":1054,"children":1055},{},[1056,1057,1062],{"type":52,"value":993},{"type":46,"tag":76,"props":1058,"children":1060},{"className":1059},[],[1061],{"type":52,"value":999},{"type":52,"value":1063},"; there is no lowercase variant",{"type":46,"tag":292,"props":1065,"children":1066},{},[1067,1072,1081],{"type":46,"tag":325,"props":1068,"children":1069},{},[1070],{"type":52,"value":1071},"Adapter getter",{"type":46,"tag":325,"props":1073,"children":1074},{},[1075],{"type":46,"tag":76,"props":1076,"children":1078},{"className":1077},[],[1079],{"type":52,"value":1080},"allowListChecker()",{"type":46,"tag":325,"props":1082,"children":1083},{},[1084,1085,1090],{"type":52,"value":993},{"type":46,"tag":76,"props":1086,"children":1088},{"className":1087},[],[1089],{"type":52,"value":999},{"type":52,"value":1091},", unlike the interface",{"type":46,"tag":292,"props":1093,"children":1094},{},[1095,1100,1108],{"type":46,"tag":325,"props":1096,"children":1097},{},[1098],{"type":52,"value":1099},"Hook approval call",{"type":46,"tag":325,"props":1101,"children":1102},{},[1103],{"type":46,"tag":76,"props":1104,"children":1106},{"className":1105},[],[1107],{"type":52,"value":630},{"type":46,"tag":325,"props":1109,"children":1110},{},[1111],{"type":52,"value":1112},"singular, on the position manager",{"type":46,"tag":292,"props":1114,"children":1115},{},[1116,1121,1130],{"type":46,"tag":325,"props":1117,"children":1118},{},[1119],{"type":52,"value":1120},"Its storage mapping",{"type":46,"tag":325,"props":1122,"children":1123},{},[1124],{"type":46,"tag":76,"props":1125,"children":1127},{"className":1126},[],[1128],{"type":52,"value":1129},"isAllowedHooks",{"type":46,"tag":325,"props":1131,"children":1132},{},[1133],{"type":52,"value":1134},"plural",{"type":46,"tag":292,"props":1136,"children":1137},{},[1138,1143,1152],{"type":46,"tag":325,"props":1139,"children":1140},{},[1141],{"type":52,"value":1142},"Its event",{"type":46,"tag":325,"props":1144,"children":1145},{},[1146],{"type":46,"tag":76,"props":1147,"children":1149},{"className":1148},[],[1150],{"type":52,"value":1151},"AllowedHooksUpdated",{"type":46,"tag":325,"props":1153,"children":1154},{},[1155],{"type":52,"value":1134},{"type":46,"tag":292,"props":1157,"children":1158},{},[1159,1164,1173],{"type":46,"tag":325,"props":1160,"children":1161},{},[1162],{"type":52,"value":1163},"Flags library",{"type":46,"tag":325,"props":1165,"children":1166},{},[1167],{"type":46,"tag":76,"props":1168,"children":1170},{"className":1169},[],[1171],{"type":52,"value":1172},"PermissionFlags",{"type":46,"tag":325,"props":1174,"children":1175},{},[1176],{"type":52,"value":1134},{"type":46,"tag":292,"props":1178,"children":1179},{},[1180,1185,1194],{"type":46,"tag":325,"props":1181,"children":1182},{},[1183],{"type":52,"value":1184},"Flag type",{"type":46,"tag":325,"props":1186,"children":1187},{},[1188],{"type":46,"tag":76,"props":1189,"children":1191},{"className":1190},[],[1192],{"type":52,"value":1193},"PermissionFlag",{"type":46,"tag":325,"props":1195,"children":1196},{},[1197],{"type":52,"value":1198},"singular",{"type":46,"tag":55,"props":1200,"children":1201},{},[1202],{"type":52,"value":1203},"Import and Forge lookup forms:",{"type":46,"tag":1205,"props":1206,"children":1211},"pre",{"className":1207,"code":1208,"language":1209,"meta":1210,"style":1210},"language-solidity shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import {BaseAllowlistChecker} from \"@uniswap\u002Fv4-periphery\u002Fsrc\u002Fhooks\u002FpermissionedPools\u002FBaseAllowListChecker.sol\";\n","solidity","",[1212],{"type":46,"tag":76,"props":1213,"children":1214},{"__ignoreMap":1210},[1215],{"type":46,"tag":1216,"props":1217,"children":1220},"span",{"class":1218,"line":1219},"line",1,[1221],{"type":46,"tag":1216,"props":1222,"children":1223},{},[1224],{"type":52,"value":1208},{"type":46,"tag":1205,"props":1226,"children":1230},{"className":1227,"code":1229,"language":52,"meta":1210},[1228],"language-text","BaseAllowListChecker.sol:BaseAllowlistChecker\n",[1231],{"type":46,"tag":76,"props":1232,"children":1233},{"__ignoreMap":1210},[1234],{"type":52,"value":1229},{"type":46,"tag":55,"props":1236,"children":1237},{},[1238,1240,1246,1248,1254,1255,1261],{"type":52,"value":1239},"That ",{"type":46,"tag":76,"props":1241,"children":1243},{"className":1242},[],[1244],{"type":52,"value":1245},"path:Contract",{"type":52,"value":1247}," pair — capital-L file, lowercase-l contract — is what ",{"type":46,"tag":76,"props":1249,"children":1251},{"className":1250},[],[1252],{"type":52,"value":1253},"forge inspect",{"type":52,"value":486},{"type":46,"tag":76,"props":1256,"children":1258},{"className":1257},[],[1259],{"type":52,"value":1260},"forge verify-contract",{"type":52,"value":1262}," need.",{"type":46,"tag":205,"props":1264,"children":1266},{"id":1265},"checkallowlist-has-two-legitimate-shapes",[1267,1273],{"type":46,"tag":76,"props":1268,"children":1270},{"className":1269},[],[1271],{"type":52,"value":1272},"checkAllowlist",{"type":52,"value":1274}," has two legitimate shapes",{"type":46,"tag":55,"props":1276,"children":1277},{},[1278],{"type":52,"value":1279},"Both compile. Pick one and stay in it.",{"type":46,"tag":128,"props":1281,"children":1282},{},[1283,1317],{"type":46,"tag":132,"props":1284,"children":1285},{},[1286,1291,1293,1299,1301,1307,1309,1315],{"type":46,"tag":68,"props":1287,"children":1288},{},[1289],{"type":52,"value":1290},"Extend the base contract.",{"type":52,"value":1292}," Declare\n",{"type":46,"tag":76,"props":1294,"children":1296},{"className":1295},[],[1297],{"type":52,"value":1298},"function checkAllowlist(address account, address tokenAddress) public view virtual override returns (PermissionFlag)",{"type":52,"value":1300},".\nYou cannot narrow the base's ",{"type":46,"tag":76,"props":1302,"children":1304},{"className":1303},[],[1305],{"type":52,"value":1306},"public virtual",{"type":52,"value":1308}," to ",{"type":46,"tag":76,"props":1310,"children":1312},{"className":1311},[],[1313],{"type":52,"value":1314},"external",{"type":52,"value":1316}," — that is a compile error.\nERC-165 support comes for free from the base contract.",{"type":46,"tag":132,"props":1318,"children":1319},{},[1320,1325,1327,1332,1334,1340,1342,1348,1350,1355,1356,1362,1364,1369],{"type":46,"tag":68,"props":1321,"children":1322},{},[1323],{"type":52,"value":1324},"Implement the interface directly.",{"type":52,"value":1326}," Declare ",{"type":46,"tag":76,"props":1328,"children":1330},{"className":1329},[],[1331],{"type":52,"value":1272},{"type":52,"value":1333}," as ",{"type":46,"tag":76,"props":1335,"children":1337},{"className":1336},[],[1338],{"type":52,"value":1339},"external view",{"type":52,"value":1341},", and write\n",{"type":46,"tag":76,"props":1343,"children":1345},{"className":1344},[],[1346],{"type":52,"value":1347},"supportsInterface",{"type":52,"value":1349}," yourself. This is what the published guide's example does — it implements\n",{"type":46,"tag":76,"props":1351,"children":1353},{"className":1352},[],[1354],{"type":52,"value":1018},{"type":52,"value":486},{"type":46,"tag":76,"props":1357,"children":1359},{"className":1358},[],[1360],{"type":52,"value":1361},"ERC165",{"type":52,"value":1363}," directly and does not use ",{"type":46,"tag":76,"props":1365,"children":1367},{"className":1366},[],[1368],{"type":52,"value":265},{"type":52,"value":534},{"type":46,"tag":205,"props":1371,"children":1373},{"id":1372},"the-adapter-checks-your-checker-with-erc-165",[1374],{"type":52,"value":1375},"The adapter checks your checker with ERC-165",{"type":46,"tag":55,"props":1377,"children":1378},{},[1379,1385,1387,1393,1395,1400,1402,1407,1409,1414,1416,1421,1423,1428,1430,1436,1438,1444,1446,1452,1454,1458,1459,1465,1466,1472,1474,1479,1481,1487,1489,1494,1496,1502],{"type":46,"tag":76,"props":1380,"children":1382},{"className":1381},[],[1383],{"type":52,"value":1384},"createPermissionsAdapter",{"type":52,"value":1386}," reverts ",{"type":46,"tag":76,"props":1388,"children":1390},{"className":1389},[],[1391],{"type":52,"value":1392},"InvalidAllowListChecker",{"type":52,"value":1394}," unless the checker advertises ",{"type":46,"tag":76,"props":1396,"children":1398},{"className":1397},[],[1399],{"type":52,"value":1018},{"type":52,"value":1401}," through an ERC-165 ",{"type":46,"tag":76,"props":1403,"children":1405},{"className":1404},[],[1406],{"type":52,"value":1347},{"type":52,"value":1408}," call. The constructor performs this check, so it fires on the very first Uniswap call in the journey. ",{"type":46,"tag":76,"props":1410,"children":1412},{"className":1411},[],[1413],{"type":52,"value":1052},{"type":52,"value":1415}," performs the same check later. Extending ",{"type":46,"tag":76,"props":1417,"children":1419},{"className":1418},[],[1420],{"type":52,"value":265},{"type":52,"value":1422}," satisfies it. A from-scratch implementation must supply ",{"type":46,"tag":76,"props":1424,"children":1426},{"className":1425},[],[1427],{"type":52,"value":1347},{"type":52,"value":1429}," itself, and it has to answer the full ERC-165 probe, not just its own id: OpenZeppelin's ",{"type":46,"tag":76,"props":1431,"children":1433},{"className":1432},[],[1434],{"type":52,"value":1435},"ERC165Checker.supportsInterface",{"type":52,"value":1437}," first requires ",{"type":46,"tag":76,"props":1439,"children":1441},{"className":1440},[],[1442],{"type":52,"value":1443},"supportsInterface(0x01ffc9a7)",{"type":52,"value":1445}," to return ",{"type":46,"tag":76,"props":1447,"children":1449},{"className":1448},[],[1450],{"type":52,"value":1451},"true",{"type":52,"value":1453}," ",{"type":46,"tag":68,"props":1455,"children":1456},{},[1457],{"type":52,"value":594},{"type":52,"value":1453},{"type":46,"tag":76,"props":1460,"children":1462},{"className":1461},[],[1463],{"type":52,"value":1464},"supportsInterface(0xffffffff)",{"type":52,"value":1445},{"type":46,"tag":76,"props":1467,"children":1469},{"className":1468},[],[1470],{"type":52,"value":1471},"false",{"type":52,"value":1473},". Inheriting OpenZeppelin ",{"type":46,"tag":76,"props":1475,"children":1477},{"className":1476},[],[1478],{"type":52,"value":1361},{"type":52,"value":1480}," and delegating to ",{"type":46,"tag":76,"props":1482,"children":1484},{"className":1483},[],[1485],{"type":52,"value":1486},"super.supportsInterface",{"type":52,"value":1488}," covers both; a hand-written function that returns ",{"type":46,"tag":76,"props":1490,"children":1492},{"className":1491},[],[1493],{"type":52,"value":1451},{"type":52,"value":1495}," only for ",{"type":46,"tag":76,"props":1497,"children":1499},{"className":1498},[],[1500],{"type":52,"value":1501},"type(IAllowlistChecker).interfaceId",{"type":52,"value":1503}," fails adapter creation.",{"type":46,"tag":269,"props":1505,"children":1506},{},[],{"type":46,"tag":101,"props":1508,"children":1510},{"id":1509},"permission-flags",[1511],{"type":52,"value":1512},"Permission Flags",{"type":46,"tag":55,"props":1514,"children":1515},{},[1516,1521,1523,1528],{"type":46,"tag":76,"props":1517,"children":1519},{"className":1518},[],[1520],{"type":52,"value":1172},{"type":52,"value":1522}," (the library) exposes four values of the ",{"type":46,"tag":76,"props":1524,"children":1526},{"className":1525},[],[1527],{"type":52,"value":1193},{"type":52,"value":1529}," type:",{"type":46,"tag":284,"props":1531,"children":1532},{},[1533,1554],{"type":46,"tag":288,"props":1534,"children":1535},{},[1536],{"type":46,"tag":292,"props":1537,"children":1538},{},[1539,1544,1549],{"type":46,"tag":296,"props":1540,"children":1541},{},[1542],{"type":52,"value":1543},"Name",{"type":46,"tag":296,"props":1545,"children":1546},{},[1547],{"type":52,"value":1548},"Value",{"type":46,"tag":296,"props":1550,"children":1551},{},[1552],{"type":52,"value":1553},"Gates",{"type":46,"tag":318,"props":1555,"children":1556},{},[1557,1583,1615,1646],{"type":46,"tag":292,"props":1558,"children":1559},{},[1560,1569,1578],{"type":46,"tag":325,"props":1561,"children":1562},{},[1563],{"type":46,"tag":76,"props":1564,"children":1566},{"className":1565},[],[1567],{"type":52,"value":1568},"NONE",{"type":46,"tag":325,"props":1570,"children":1571},{},[1572],{"type":46,"tag":76,"props":1573,"children":1575},{"className":1574},[],[1576],{"type":52,"value":1577},"0x0000",{"type":46,"tag":325,"props":1579,"children":1580},{},[1581],{"type":52,"value":1582},"nothing",{"type":46,"tag":292,"props":1584,"children":1585},{},[1586,1595,1604],{"type":46,"tag":325,"props":1587,"children":1588},{},[1589],{"type":46,"tag":76,"props":1590,"children":1592},{"className":1591},[],[1593],{"type":52,"value":1594},"SWAP_ALLOWED",{"type":46,"tag":325,"props":1596,"children":1597},{},[1598],{"type":46,"tag":76,"props":1599,"children":1601},{"className":1600},[],[1602],{"type":52,"value":1603},"0x0001",{"type":46,"tag":325,"props":1605,"children":1606},{},[1607,1613],{"type":46,"tag":76,"props":1608,"children":1610},{"className":1609},[],[1611],{"type":52,"value":1612},"beforeSwap",{"type":52,"value":1614}," on the hook, and the router's settlement check",{"type":46,"tag":292,"props":1616,"children":1617},{},[1618,1626,1635],{"type":46,"tag":325,"props":1619,"children":1620},{},[1621],{"type":46,"tag":76,"props":1622,"children":1624},{"className":1623},[],[1625],{"type":52,"value":684},{"type":46,"tag":325,"props":1627,"children":1628},{},[1629],{"type":46,"tag":76,"props":1630,"children":1632},{"className":1631},[],[1633],{"type":52,"value":1634},"0x0002",{"type":46,"tag":325,"props":1636,"children":1637},{},[1638,1644],{"type":46,"tag":76,"props":1639,"children":1641},{"className":1640},[],[1642],{"type":52,"value":1643},"beforeAddLiquidity",{"type":52,"value":1645}," on the hook, and the recipient check on mints and increases",{"type":46,"tag":292,"props":1647,"children":1648},{},[1649,1658,1667],{"type":46,"tag":325,"props":1650,"children":1651},{},[1652],{"type":46,"tag":76,"props":1653,"children":1655},{"className":1654},[],[1656],{"type":52,"value":1657},"ALL_ALLOWED",{"type":46,"tag":325,"props":1659,"children":1660},{},[1661],{"type":46,"tag":76,"props":1662,"children":1664},{"className":1663},[],[1665],{"type":52,"value":1666},"0xFFFF",{"type":46,"tag":325,"props":1668,"children":1669},{},[1670],{"type":52,"value":1671},"both",{"type":46,"tag":55,"props":1673,"children":1674},{},[1675,1680,1682,1686,1688,1693,1695,1700],{"type":46,"tag":76,"props":1676,"children":1678},{"className":1677},[],[1679],{"type":52,"value":1594},{"type":52,"value":1681}," does ",{"type":46,"tag":68,"props":1683,"children":1684},{},[1685],{"type":52,"value":148},{"type":52,"value":1687}," imply ",{"type":46,"tag":76,"props":1689,"children":1691},{"className":1690},[],[1692],{"type":52,"value":684},{"type":52,"value":1694},". A wallet that can swap cannot necessarily provide liquidity, and that includes your own treasury wallet. Your checker returns a ",{"type":46,"tag":76,"props":1696,"children":1698},{"className":1697},[],[1699],{"type":52,"value":1193},{"type":52,"value":1701}," combining whichever apply.",{"type":46,"tag":269,"props":1703,"children":1704},{},[],{"type":46,"tag":101,"props":1706,"children":1708},{"id":1707},"the-wrapper-registration-set",[1709],{"type":52,"value":1710},"The Wrapper Registration Set",{"type":46,"tag":55,"props":1712,"children":1713},{},[1714,1720,1722,1728],{"type":46,"tag":76,"props":1715,"children":1717},{"className":1716},[],[1718],{"type":52,"value":1719},"updateAllowedWrapper(address wrapper, bool allowed)",{"type":52,"value":1721}," on the adapter is ",{"type":46,"tag":76,"props":1723,"children":1725},{"className":1724},[],[1726],{"type":52,"value":1727},"onlyOwner",{"type":52,"value":1729},". The published guide names four contracts to register:",{"type":46,"tag":128,"props":1731,"children":1732},{},[1733,1742,1760,1769],{"type":46,"tag":132,"props":1734,"children":1735},{},[1736],{"type":46,"tag":76,"props":1737,"children":1739},{"className":1738},[],[1740],{"type":52,"value":1741},"PermissionedPositionManager",{"type":46,"tag":132,"props":1743,"children":1744},{},[1745,1747,1752,1754],{"type":52,"value":1746},"The Universal Router — ",{"type":46,"tag":68,"props":1748,"children":1749},{},[1750],{"type":52,"value":1751},"2.2.0 or higher",{"type":52,"value":1753},", whose canonical deployments key is ",{"type":46,"tag":76,"props":1755,"children":1757},{"className":1756},[],[1758],{"type":52,"value":1759},"UniversalRouter#v2.2",{"type":46,"tag":132,"props":1761,"children":1762},{},[1763],{"type":46,"tag":76,"props":1764,"children":1766},{"className":1765},[],[1767],{"type":52,"value":1768},"V4Quoter",{"type":46,"tag":132,"props":1770,"children":1771},{},[1772],{"type":46,"tag":76,"props":1773,"children":1775},{"className":1774},[],[1776],{"type":52,"value":1777},"MixedRouteQuoterV2",{"type":46,"tag":55,"props":1779,"children":1780},{},[1781,1786,1788,1794,1796,1802,1804,1810,1812,1818],{"type":46,"tag":68,"props":1782,"children":1783},{},[1784],{"type":52,"value":1785},"The rule behind the four:",{"type":52,"value":1787}," register every contract that will call the PoolManager on this pool. The hook checks ",{"type":46,"tag":76,"props":1789,"children":1791},{"className":1790},[],[1792],{"type":52,"value":1793},"allowedWrappers(router)",{"type":52,"value":1795},", where ",{"type":46,"tag":76,"props":1797,"children":1799},{"className":1798},[],[1800],{"type":52,"value":1801},"router",{"type":52,"value":1803}," is the calling router or position manager, and ",{"type":46,"tag":76,"props":1805,"children":1807},{"className":1806},[],[1808],{"type":52,"value":1809},"wrapToPoolManager",{"type":52,"value":1811}," separately checks ",{"type":46,"tag":76,"props":1813,"children":1815},{"className":1814},[],[1816],{"type":52,"value":1817},"allowedWrappers[msg.sender]",{"type":52,"value":1819},". So a custom router of your own must be registered too, and the four are the production callers rather than a closed set. Registration is enforced against use: the position manager must be registered before your first mint, and each router and quoter before the first swap or quote through it.",{"type":46,"tag":55,"props":1821,"children":1822},{},[1823,1828,1830,1835,1837,1843,1844,1850,1852,1856,1858,1864,1866,1872],{"type":46,"tag":68,"props":1824,"children":1825},{},[1826],{"type":52,"value":1827},"Two traps.",{"type":52,"value":1829}," The guide's Step 5 says \"all four addresses\" and links a table with ",{"type":46,"tag":68,"props":1831,"children":1832},{},[1833],{"type":52,"value":1834},"six",{"type":52,"value":1836}," rows: ",{"type":46,"tag":76,"props":1838,"children":1840},{"className":1839},[],[1841],{"type":52,"value":1842},"PermissionsAdapterFactory",{"type":52,"value":486},{"type":46,"tag":76,"props":1845,"children":1847},{"className":1846},[],[1848],{"type":52,"value":1849},"PermissionedHooks",{"type":52,"value":1851}," are in that table and are ",{"type":46,"tag":68,"props":1853,"children":1854},{},[1855],{"type":52,"value":148},{"type":52,"value":1857}," wrappers — never register the factory or the hook. And the plain ",{"type":46,"tag":76,"props":1859,"children":1861},{"className":1860},[],[1862],{"type":52,"value":1863},"UniversalRouter",{"type":52,"value":1865}," deployments key is a different, non-permissioned router; only the ",{"type":46,"tag":76,"props":1867,"children":1869},{"className":1868},[],[1870],{"type":52,"value":1871},"#v2.2",{"type":52,"value":1873}," deployment takes the permissions-adapter factory in its constructor.",{"type":46,"tag":269,"props":1875,"children":1876},{},[],{"type":46,"tag":101,"props":1878,"children":1880},{"id":1879},"installing-the-contracts",[1881],{"type":52,"value":1882},"Installing the Contracts",{"type":46,"tag":55,"props":1884,"children":1885},{},[1886,1888,1894,1896,1901,1903,1909,1911,1917,1919,1924],{"type":52,"value":1887},"The latest published ",{"type":46,"tag":76,"props":1889,"children":1891},{"className":1890},[],[1892],{"type":52,"value":1893},"@uniswap\u002Fv4-periphery",{"type":52,"value":1895}," on npm is ",{"type":46,"tag":68,"props":1897,"children":1898},{},[1899],{"type":52,"value":1900},"1.0.3",{"type":52,"value":1902}," (2025-07-29), and its tarball does not contain ",{"type":46,"tag":76,"props":1904,"children":1906},{"className":1905},[],[1907],{"type":52,"value":1908},"src\u002Fhooks\u002FpermissionedPools\u002F",{"type":52,"value":1910}," at all. ",{"type":46,"tag":76,"props":1912,"children":1914},{"className":1913},[],[1915],{"type":52,"value":1916},"v4-periphery",{"type":52,"value":1918}," also has ",{"type":46,"tag":68,"props":1920,"children":1921},{},[1922],{"type":52,"value":1923},"zero git tags",{"type":52,"value":1925},", so there is no tag to pin either. A raw commit SHA is the only option.",{"type":46,"tag":1205,"props":1927,"children":1931},{"className":1928,"code":1929,"language":1930,"meta":1210,"style":1210},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Foundry — pin the exact commit\nforge install Uniswap\u002Fv4-periphery@3245c3cb99c48fa1dc2459c3b60abc37d4294aba\n","bash",[1932],{"type":46,"tag":76,"props":1933,"children":1934},{"__ignoreMap":1210},[1935,1944],{"type":46,"tag":1216,"props":1936,"children":1937},{"class":1218,"line":1219},[1938],{"type":46,"tag":1216,"props":1939,"children":1941},{"style":1940},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[1942],{"type":52,"value":1943},"# Foundry — pin the exact commit\n",{"type":46,"tag":1216,"props":1945,"children":1947},{"class":1218,"line":1946},2,[1948,1954,1960],{"type":46,"tag":1216,"props":1949,"children":1951},{"style":1950},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[1952],{"type":52,"value":1953},"forge",{"type":46,"tag":1216,"props":1955,"children":1957},{"style":1956},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[1958],{"type":52,"value":1959}," install",{"type":46,"tag":1216,"props":1961,"children":1962},{"style":1956},[1963],{"type":52,"value":1964}," Uniswap\u002Fv4-periphery@3245c3cb99c48fa1dc2459c3b60abc37d4294aba\n",{"type":46,"tag":1205,"props":1966,"children":1969},{"className":1967,"code":1968,"language":52,"meta":1210},[1228],"# remappings.txt — matches what v4-hooks-public itself uses\n@uniswap\u002Fv4-periphery\u002F=lib\u002Fv4-periphery\u002F\n",[1970],{"type":46,"tag":76,"props":1971,"children":1972},{"__ignoreMap":1210},[1973],{"type":52,"value":1968},{"type":46,"tag":55,"props":1975,"children":1976},{},[1977],{"type":52,"value":1978},"The published guide's import paths are npm-scoped and correct once remapped this way. The guide gives the import lines; the install step and remapping above are what they require.",{"type":46,"tag":55,"props":1980,"children":1981},{},[1982,1984,1990],{"type":52,"value":1983},"Details, including the hook-source pin and how to resolve addresses: ",{"type":46,"tag":85,"props":1985,"children":1987},{"href":1986},".\u002Freferences\u002Fpackaging-and-sources.md",[1988],{"type":52,"value":1989},"Packaging and Sources",{"type":52,"value":534},{"type":46,"tag":269,"props":1992,"children":1993},{},[],{"type":46,"tag":101,"props":1995,"children":1997},{"id":1996},"ordering-is-enforced-in-code",[1998],{"type":52,"value":1999},"Ordering Is Enforced in Code",{"type":46,"tag":55,"props":2001,"children":2002},{},[2003],{"type":52,"value":2004},"These calls revert with the selector shown if you make them early. They are behaviours to expect, not open questions.",{"type":46,"tag":284,"props":2006,"children":2007},{},[2008,2029],{"type":46,"tag":288,"props":2009,"children":2010},{},[2011],{"type":46,"tag":292,"props":2012,"children":2013},{},[2014,2019,2024],{"type":46,"tag":296,"props":2015,"children":2016},{},[2017],{"type":52,"value":2018},"Call",{"type":46,"tag":296,"props":2020,"children":2021},{},[2022],{"type":52,"value":2023},"Revert",{"type":46,"tag":296,"props":2025,"children":2026},{},[2027],{"type":52,"value":2028},"Condition",{"type":46,"tag":318,"props":2030,"children":2031},{},[2032,2056,2080,2110,2143],{"type":46,"tag":292,"props":2033,"children":2034},{},[2035,2043,2051],{"type":46,"tag":325,"props":2036,"children":2037},{},[2038],{"type":46,"tag":76,"props":2039,"children":2041},{"className":2040},[],[2042],{"type":52,"value":1384},{"type":46,"tag":325,"props":2044,"children":2045},{},[2046],{"type":46,"tag":76,"props":2047,"children":2049},{"className":2048},[],[2050],{"type":52,"value":1392},{"type":46,"tag":325,"props":2052,"children":2053},{},[2054],{"type":52,"value":2055},"the checker fails the ERC-165 interface check",{"type":46,"tag":292,"props":2057,"children":2058},{},[2059,2067,2075],{"type":46,"tag":325,"props":2060,"children":2061},{},[2062],{"type":46,"tag":76,"props":2063,"children":2065},{"className":2064},[],[2066],{"type":52,"value":602},{"type":46,"tag":325,"props":2068,"children":2069},{},[2070],{"type":46,"tag":76,"props":2071,"children":2073},{"className":2072},[],[2074],{"type":52,"value":611},{"type":46,"tag":325,"props":2076,"children":2077},{},[2078],{"type":52,"value":2079},"the adapter's permissioned-token balance is zero",{"type":46,"tag":292,"props":2081,"children":2082},{},[2083,2091,2099],{"type":46,"tag":325,"props":2084,"children":2085},{},[2086],{"type":46,"tag":76,"props":2087,"children":2089},{"className":2088},[],[2090],{"type":52,"value":630},{"type":46,"tag":325,"props":2092,"children":2093},{},[2094],{"type":46,"tag":76,"props":2095,"children":2097},{"className":2096},[],[2098],{"type":52,"value":639},{"type":46,"tag":325,"props":2100,"children":2101},{},[2102,2104],{"type":52,"value":2103},"the currency's adapter is not verified yet, so its owner reads as ",{"type":46,"tag":76,"props":2105,"children":2107},{"className":2106},[],[2108],{"type":52,"value":2109},"address(0)",{"type":46,"tag":292,"props":2111,"children":2112},{},[2113,2123,2138],{"type":46,"tag":325,"props":2114,"children":2115},{},[2116,2118],{"type":52,"value":2117},"pool ",{"type":46,"tag":76,"props":2119,"children":2121},{"className":2120},[],[2122],{"type":52,"value":653},{"type":46,"tag":325,"props":2124,"children":2125},{},[2126,2131,2133],{"type":46,"tag":76,"props":2127,"children":2129},{"className":2128},[],[2130],{"type":52,"value":662},{"type":52,"value":2132}," \u002F ",{"type":46,"tag":76,"props":2134,"children":2136},{"className":2135},[],[2137],{"type":52,"value":670},{"type":46,"tag":325,"props":2139,"children":2140},{},[2141],{"type":52,"value":2142},"neither currency was created by the factory \u002F a factory-created currency is not verified",{"type":46,"tag":292,"props":2144,"children":2145},{},[2146,2157,2177],{"type":46,"tag":325,"props":2147,"children":2148},{},[2149,2155],{"type":46,"tag":76,"props":2150,"children":2152},{"className":2151},[],[2153],{"type":52,"value":2154},"_mint",{"type":52,"value":2156}," on the position manager",{"type":46,"tag":325,"props":2158,"children":2159},{},[2160,2165,2166,2171,2172],{"type":46,"tag":76,"props":2161,"children":2163},{"className":2162},[],[2164],{"type":52,"value":662},{"type":52,"value":2132},{"type":46,"tag":76,"props":2167,"children":2169},{"className":2168},[],[2170],{"type":52,"value":708},{"type":52,"value":2132},{"type":46,"tag":76,"props":2173,"children":2175},{"className":2174},[],[2176],{"type":52,"value":716},{"type":46,"tag":325,"props":2178,"children":2179},{},[2180,2182,2187],{"type":52,"value":2181},"no verified side \u002F hook not allowed \u002F caller or recipient lacks ",{"type":46,"tag":76,"props":2183,"children":2185},{"className":2184},[],[2186],{"type":52,"value":684},{"type":52,"value":2188},", or the position manager is not a registered allowed wrapper",{"type":46,"tag":55,"props":2190,"children":2191},{},[2192,2197,2198,2203,2204,2210,2212,2217,2218,2223,2225,2230],{"type":46,"tag":76,"props":2193,"children":2195},{"className":2194},[],[2196],{"type":52,"value":662},{"type":52,"value":478},{"type":46,"tag":76,"props":2199,"children":2201},{"className":2200},[],[2202],{"type":52,"value":716},{"type":52,"value":486},{"type":46,"tag":76,"props":2205,"children":2207},{"className":2206},[],[2208],{"type":52,"value":2209},"SwappingDisabled",{"type":52,"value":2211}," are each declared more than once with the same selector — ",{"type":46,"tag":76,"props":2213,"children":2215},{"className":2214},[],[2216],{"type":52,"value":662},{"type":52,"value":486},{"type":46,"tag":76,"props":2219,"children":2221},{"className":2220},[],[2222],{"type":52,"value":716},{"type":52,"value":2224}," with genuinely different meanings, ",{"type":46,"tag":76,"props":2226,"children":2228},{"className":2227},[],[2229],{"type":52,"value":2209},{"type":52,"value":2231}," with the same meaning from two different points in a swap. Always decode by call site, never by name.",{"type":46,"tag":55,"props":2233,"children":2234},{},[2235,2237,2243],{"type":52,"value":2236},"Full catalogue and worked out-of-order scenarios: ",{"type":46,"tag":85,"props":2238,"children":2240},{"href":2239},".\u002Freferences\u002Fenforced-ordering-and-reverts.md",[2241],{"type":52,"value":2242},"Enforced Ordering and Reverts",{"type":52,"value":534},{"type":46,"tag":269,"props":2245,"children":2246},{},[],{"type":46,"tag":101,"props":2248,"children":2250},{"id":2249},"trust-model-summary",[2251],{"type":52,"value":2252},"Trust Model Summary",{"type":46,"tag":2254,"props":2255,"children":2256},"ul",{},[2257,2275,2293],{"type":46,"tag":132,"props":2258,"children":2259},{},[2260,2265,2267,2273],{"type":46,"tag":68,"props":2261,"children":2262},{},[2263],{"type":52,"value":2264},"LP positions are permanently non-transferable.",{"type":52,"value":2266}," All three ERC-721 transfer entry points revert ",{"type":46,"tag":76,"props":2268,"children":2270},{"className":2269},[],[2271],{"type":52,"value":2272},"TransferDisabled",{"type":52,"value":2274},". It is not a configuration flag. Decrease and burn are never gated by the allowlist checker, so the pool never blocks an exit — though delivery of the permissioned side unwraps to the underlying token, so the recipient still has to clear your token's own transfer restriction.",{"type":46,"tag":132,"props":2276,"children":2277},{},[2278,2283,2285,2291],{"type":46,"tag":68,"props":2279,"children":2280},{},[2281],{"type":52,"value":2282},"Either adapter admin can force-exit any LP",{"type":52,"value":2284}," with ",{"type":46,"tag":76,"props":2286,"children":2288},{"className":2287},[],[2289],{"type":52,"value":2290},"unwindPosition",{"type":52,"value":2292},", and proceeds cascade to the LP first, then to an admin, then as an ERC-6909 claim whose recipient depends on the currency.",{"type":46,"tag":132,"props":2294,"children":2295},{},[2296,2309,2311,2317,2319,2324,2326,2331,2333,2339],{"type":46,"tag":68,"props":2297,"children":2298},{},[2299,2301,2307],{"type":52,"value":2300},"The real enforcement boundary is the adapter's ",{"type":46,"tag":76,"props":2302,"children":2304},{"className":2303},[],[2305],{"type":52,"value":2306},"allowedWrappers",{"type":52,"value":2308}," list.",{"type":52,"value":2310}," Every wrapper on it is trusted to report the true originating caller through ",{"type":46,"tag":76,"props":2312,"children":2314},{"className":2313},[],[2315],{"type":52,"value":2316},"msgSender()",{"type":52,"value":2318},". ",{"type":46,"tag":76,"props":2320,"children":2322},{"className":2321},[],[2323],{"type":52,"value":730},{"type":52,"value":2325}," is ",{"type":46,"tag":76,"props":2327,"children":2329},{"className":2328},[],[2330],{"type":52,"value":1727},{"type":52,"value":2332}," on an ",{"type":46,"tag":76,"props":2334,"children":2336},{"className":2335},[],[2337],{"type":52,"value":2338},"Ownable2Step",{"type":52,"value":2340}," contract, so adapter-owner key management is part of the trust model.",{"type":46,"tag":55,"props":2342,"children":2343},{},[2344,2345,2351],{"type":52,"value":526},{"type":46,"tag":85,"props":2346,"children":2348},{"href":2347},".\u002Freferences\u002Ftrust-model.md",[2349],{"type":52,"value":2350},"Trust Model",{"type":52,"value":534},{"type":46,"tag":269,"props":2353,"children":2354},{},[],{"type":46,"tag":101,"props":2356,"children":2358},{"id":2357},"what-is-permissionless-and-what-is-not",[2359],{"type":52,"value":2360},"What Is Permissionless and What Is Not",{"type":46,"tag":284,"props":2362,"children":2363},{},[2364,2380],{"type":46,"tag":288,"props":2365,"children":2366},{},[2367],{"type":46,"tag":292,"props":2368,"children":2369},{},[2370,2375],{"type":46,"tag":296,"props":2371,"children":2372},{},[2373],{"type":52,"value":2374},"Permissionless \u002F issuer-controlled",{"type":46,"tag":296,"props":2376,"children":2377},{},[2378],{"type":52,"value":2379},"Coordinated with Uniswap Labs",{"type":46,"tag":318,"props":2381,"children":2382},{},[2383,2396,2414,2427,2445,2461,2472],{"type":46,"tag":292,"props":2384,"children":2385},{},[2386,2391],{"type":46,"tag":325,"props":2387,"children":2388},{},[2389],{"type":52,"value":2390},"Deploying your allowlist checker",{"type":46,"tag":325,"props":2392,"children":2393},{},[2394],{"type":52,"value":2395},"Routing eligibility in the Uniswap interface and API",{"type":46,"tag":292,"props":2397,"children":2398},{},[2399,2409],{"type":46,"tag":325,"props":2400,"children":2401},{},[2402,2407],{"type":46,"tag":76,"props":2403,"children":2405},{"className":2404},[],[2406],{"type":52,"value":1384},{"type":52,"value":2408}," (anyone may call)",{"type":46,"tag":325,"props":2410,"children":2411},{},[2412],{"type":52,"value":2413},"Token-list inclusion",{"type":46,"tag":292,"props":2415,"children":2416},{},[2417,2422],{"type":46,"tag":325,"props":2418,"children":2419},{},[2420],{"type":52,"value":2421},"Allowlisting the adapter on your token",{"type":46,"tag":325,"props":2423,"children":2424},{},[2425],{"type":52,"value":2426},"Token-detail metadata",{"type":46,"tag":292,"props":2428,"children":2429},{},[2430,2440],{"type":46,"tag":325,"props":2431,"children":2432},{},[2433,2439],{"type":46,"tag":76,"props":2434,"children":2436},{"className":2435},[],[2437],{"type":52,"value":2438},"depositForVerification",{"type":52,"value":2408},{"type":46,"tag":325,"props":2441,"children":2442},{},[2443],{"type":52,"value":2444},"Issuer metadata and KYC URL in the backend configuration",{"type":46,"tag":292,"props":2446,"children":2447},{},[2448,2458],{"type":46,"tag":325,"props":2449,"children":2450},{},[2451,2456],{"type":46,"tag":76,"props":2452,"children":2454},{"className":2453},[],[2455],{"type":52,"value":602},{"type":52,"value":2457}," (anyone may call, one-shot)",{"type":46,"tag":325,"props":2459,"children":2460},{},[],{"type":46,"tag":292,"props":2462,"children":2463},{},[2464,2469],{"type":46,"tag":325,"props":2465,"children":2466},{},[2467],{"type":52,"value":2468},"Every adapter admin operation",{"type":46,"tag":325,"props":2470,"children":2471},{},[],{"type":46,"tag":292,"props":2473,"children":2474},{},[2475,2485],{"type":46,"tag":325,"props":2476,"children":2477},{},[2478,2483],{"type":46,"tag":76,"props":2479,"children":2481},{"className":2480},[],[2482],{"type":52,"value":630},{"type":52,"value":2484},", pool initialization, seeding liquidity",{"type":46,"tag":325,"props":2486,"children":2487},{},[],{"type":46,"tag":55,"props":2489,"children":2490},{},[2491,2496],{"type":46,"tag":68,"props":2492,"children":2493},{},[2494],{"type":52,"value":2495},"The on-chain path has no Uniswap approval gate.",{"type":52,"value":2497}," Nothing in the left column waits on anybody.",{"type":46,"tag":55,"props":2499,"children":2500},{},[2501,2503,2509],{"type":52,"value":2502},"Boundary detail, including the routing request: ",{"type":46,"tag":85,"props":2504,"children":2506},{"href":2505},".\u002Freferences\u002Fcoordination-boundary.md",[2507],{"type":52,"value":2508},"Coordination Boundary",{"type":52,"value":534},{"type":46,"tag":269,"props":2511,"children":2512},{},[],{"type":46,"tag":101,"props":2514,"children":2516},{"id":2515},"reference-topics",[2517],{"type":52,"value":2518},"Reference Topics",{"type":46,"tag":284,"props":2520,"children":2521},{},[2522,2538],{"type":46,"tag":288,"props":2523,"children":2524},{},[2525],{"type":46,"tag":292,"props":2526,"children":2527},{},[2528,2533],{"type":46,"tag":296,"props":2529,"children":2530},{},[2531],{"type":52,"value":2532},"Topic",{"type":46,"tag":296,"props":2534,"children":2535},{},[2536],{"type":52,"value":2537},"Reference File",{"type":46,"tag":318,"props":2539,"children":2540},{},[2541,2556,2571,2586,2601,2616],{"type":46,"tag":292,"props":2542,"children":2543},{},[2544,2549],{"type":46,"tag":325,"props":2545,"children":2546},{},[2547],{"type":52,"value":2548},"Contract-by-contract stack, exact-casing inventory, flags, events",{"type":46,"tag":325,"props":2550,"children":2551},{},[2552],{"type":46,"tag":85,"props":2553,"children":2554},{"href":529},[2555],{"type":52,"value":532},{"type":46,"tag":292,"props":2557,"children":2558},{},[2559,2564],{"type":46,"tag":325,"props":2560,"children":2561},{},[2562],{"type":52,"value":2563},"The seven steps in detail, with calls, callers and checks",{"type":46,"tag":325,"props":2565,"children":2566},{},[2567],{"type":46,"tag":85,"props":2568,"children":2569},{"href":897},[2570],{"type":52,"value":900},{"type":46,"tag":292,"props":2572,"children":2573},{},[2574,2579],{"type":46,"tag":325,"props":2575,"children":2576},{},[2577],{"type":52,"value":2578},"The five enforced edges, the revert catalogue, worked scenarios",{"type":46,"tag":325,"props":2580,"children":2581},{},[2582],{"type":46,"tag":85,"props":2583,"children":2584},{"href":2239},[2585],{"type":52,"value":2242},{"type":46,"tag":292,"props":2587,"children":2588},{},[2589,2594],{"type":46,"tag":325,"props":2590,"children":2591},{},[2592],{"type":52,"value":2593},"Non-transferability, admin force-exit, vetting a candidate wrapper",{"type":46,"tag":325,"props":2595,"children":2596},{},[2597],{"type":46,"tag":85,"props":2598,"children":2599},{"href":2347},[2600],{"type":52,"value":2350},{"type":46,"tag":292,"props":2602,"children":2603},{},[2604,2609],{"type":46,"tag":325,"props":2605,"children":2606},{},[2607],{"type":52,"value":2608},"Pinning, remapping, import paths, resolving addresses",{"type":46,"tag":325,"props":2610,"children":2611},{},[2612],{"type":46,"tag":85,"props":2613,"children":2614},{"href":1986},[2615],{"type":52,"value":1989},{"type":46,"tag":292,"props":2617,"children":2618},{},[2619,2624],{"type":46,"tag":325,"props":2620,"children":2621},{},[2622],{"type":52,"value":2623},"What is permissionless versus coordinated, the routing request",{"type":46,"tag":325,"props":2625,"children":2626},{},[2627],{"type":46,"tag":85,"props":2628,"children":2629},{"href":2505},[2630],{"type":52,"value":2508},{"type":46,"tag":269,"props":2632,"children":2633},{},[],{"type":46,"tag":101,"props":2635,"children":2637},{"id":2636},"canonical-sources",[2638],{"type":52,"value":190},{"type":46,"tag":55,"props":2640,"children":2641},{},[2642],{"type":52,"value":2643},"Published issuer documentation:",{"type":46,"tag":2254,"props":2645,"children":2646},{},[2647,2657,2666,2675],{"type":46,"tag":132,"props":2648,"children":2649},{},[2650],{"type":46,"tag":85,"props":2651,"children":2655},{"href":2652,"rel":2653},"https:\u002F\u002Fdevelopers.uniswap.org\u002Fdocs\u002Fprotocols\u002Fv4\u002Fpermissioned-pools\u002Foverview",[2654],"nofollow",[2656],{"type":52,"value":2652},{"type":46,"tag":132,"props":2658,"children":2659},{},[2660],{"type":46,"tag":85,"props":2661,"children":2664},{"href":2662,"rel":2663},"https:\u002F\u002Fdevelopers.uniswap.org\u002Fdocs\u002Fprotocols\u002Fv4\u002Fpermissioned-pools\u002Farchitecture",[2654],[2665],{"type":52,"value":2662},{"type":46,"tag":132,"props":2667,"children":2668},{},[2669],{"type":46,"tag":85,"props":2670,"children":2673},{"href":2671,"rel":2672},"https:\u002F\u002Fdevelopers.uniswap.org\u002Fdocs\u002Fprotocols\u002Fv4\u002Fpermissioned-pools\u002Fdeploy-a-permissioned-pool",[2654],[2674],{"type":52,"value":2671},{"type":46,"tag":132,"props":2676,"children":2677},{},[2678],{"type":46,"tag":85,"props":2679,"children":2682},{"href":2680,"rel":2681},"https:\u002F\u002Fdevelopers.uniswap.org\u002Fdocs\u002Fprotocols\u002Fv4\u002Fpermissioned-pools\u002Fprovide-liquidity",[2654],[2683],{"type":52,"value":2680},{"type":46,"tag":55,"props":2685,"children":2686},{},[2687],{"type":52,"value":2688},"Contract sources, pinned:",{"type":46,"tag":2254,"props":2690,"children":2691},{},[2692,2726,2757],{"type":46,"tag":132,"props":2693,"children":2694},{},[2695,2701,2703,2709,2711,2716,2718,2724],{"type":46,"tag":76,"props":2696,"children":2698},{"className":2697},[],[2699],{"type":52,"value":2700},"Uniswap\u002Fv4-periphery",{"type":52,"value":2702}," at ",{"type":46,"tag":76,"props":2704,"children":2706},{"className":2705},[],[2707],{"type":52,"value":2708},"3245c3cb99c48fa1dc2459c3b60abc37d4294aba",{"type":52,"value":2710}," —\n",{"type":46,"tag":76,"props":2712,"children":2714},{"className":2713},[],[2715],{"type":52,"value":1908},{"type":52,"value":2717}," (",{"type":46,"tag":85,"props":2719,"children":2722},{"href":2720,"rel":2721},"https:\u002F\u002Fgithub.com\u002FUniswap\u002Fv4-periphery",[2654],[2723],{"type":52,"value":2720},{"type":52,"value":2725},")",{"type":46,"tag":132,"props":2727,"children":2728},{},[2729,2735,2736,2742,2743,2749,2750,2756],{"type":46,"tag":76,"props":2730,"children":2732},{"className":2731},[],[2733],{"type":52,"value":2734},"Uniswap\u002Fv4-hooks-public",{"type":52,"value":2702},{"type":46,"tag":76,"props":2737,"children":2739},{"className":2738},[],[2740],{"type":52,"value":2741},"7da5210f2c81a700820a6b4f585264233d91f349",{"type":52,"value":2710},{"type":46,"tag":76,"props":2744,"children":2746},{"className":2745},[],[2747],{"type":52,"value":2748},"src\u002Fpermissioned-pools\u002FPermissionedHooks.sol",{"type":52,"value":2717},{"type":46,"tag":85,"props":2751,"children":2754},{"href":2752,"rel":2753},"https:\u002F\u002Fgithub.com\u002FUniswap\u002Fv4-hooks-public",[2654],[2755],{"type":52,"value":2752},{"type":52,"value":2725},{"type":46,"tag":132,"props":2758,"children":2759},{},[2760,2766,2768,2774,2775,2781],{"type":46,"tag":76,"props":2761,"children":2763},{"className":2762},[],[2764],{"type":52,"value":2765},"Uniswap\u002Fmixed-quoter",{"type":52,"value":2767}," — ",{"type":46,"tag":76,"props":2769,"children":2771},{"className":2770},[],[2772],{"type":52,"value":2773},"src\u002FMixedRouteQuoterV2.sol",{"type":52,"value":2717},{"type":46,"tag":85,"props":2776,"children":2779},{"href":2777,"rel":2778},"https:\u002F\u002Fgithub.com\u002FUniswap\u002Fmixed-quoter",[2654],[2780],{"type":52,"value":2777},{"type":52,"value":2725},{"type":46,"tag":55,"props":2783,"children":2784},{},[2785],{"type":52,"value":2786},"Addresses:",{"type":46,"tag":2254,"props":2788,"children":2789},{},[2790,2803,2839],{"type":46,"tag":132,"props":2791,"children":2792},{},[2793,2795,2801],{"type":52,"value":2794},"The complete, permissioned-specific table is the deploy guide's ",{"type":46,"tag":76,"props":2796,"children":2798},{"className":2797},[],[2799],{"type":52,"value":2800},"#deployment-addresses",{"type":52,"value":2802}," anchor.",{"type":46,"tag":132,"props":2804,"children":2805},{},[2806,2808,2814,2815,2821,2823,2829,2831,2837],{"type":52,"value":2807},"The machine-readable record is ",{"type":46,"tag":76,"props":2809,"children":2811},{"className":2810},[],[2812],{"type":52,"value":2813},"Uniswap\u002Fcontracts",{"type":52,"value":478},{"type":46,"tag":76,"props":2816,"children":2818},{"className":2817},[],[2819],{"type":52,"value":2820},"deployments\u002Fjson\u002F\u003CchainId>.json",{"type":52,"value":2822},", under the\n",{"type":46,"tag":76,"props":2824,"children":2826},{"className":2825},[],[2827],{"type":52,"value":2828},"latest",{"type":52,"value":2830}," key (",{"type":46,"tag":85,"props":2832,"children":2835},{"href":2833,"rel":2834},"https:\u002F\u002Fgithub.com\u002FUniswap\u002Fcontracts",[2654],[2836],{"type":52,"value":2833},{"type":52,"value":2838},").",{"type":46,"tag":132,"props":2840,"children":2841},{},[2842],{"type":52,"value":2843},"Verify every address on a block explorer for your chain before sending a transaction to it.",{"type":46,"tag":55,"props":2845,"children":2846},{},[2847,2849],{"type":52,"value":2848},"This skill: ",{"type":46,"tag":85,"props":2850,"children":2852},{"href":26,"rel":2851},[2654],[2853],{"type":52,"value":26},{"type":46,"tag":2855,"props":2856,"children":2857},"style",{},[2858],{"type":52,"value":2859},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2861,"total":3011},[2862,2877,2892,2905,2918,2931,2944,2957,2971,2982,2989,3000],{"slug":2863,"name":2863,"fn":2864,"description":2865,"org":2866,"tags":2867,"stars":25,"repoUrl":26,"updatedAt":2876},"configurator","configure auction smart contract parameters","Configure CCA (Continuous Clearing Auction) smart contract parameters through an interactive bulk form flow. Use when user says \"configure auction\", \"cca auction\", \"setup token auction\", \"auction configuration\", \"continuous auction\", or mentions CCA contracts.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2868,2871,2872,2875],{"name":2869,"slug":2870,"type":15},"Configuration","configuration",{"name":23,"slug":24,"type":15},{"name":2873,"slug":2874,"type":15},"Smart Contracts","smart-contracts",{"name":17,"slug":18,"type":15},"2026-07-17T06:08:08.974641",{"slug":2878,"name":2878,"fn":2879,"description":2880,"org":2881,"tags":2882,"stars":25,"repoUrl":26,"updatedAt":2891},"copy-trade","copy trades from crypto wallets","This skill should be used when the user asks to \"copy trades from\" a wallet, \"mirror a wallet\", \"follow this address\", set up \"copy trading\", \"track and replicate a trader\", or mirror another account's swaps bounded by guardrails. Watches a target wallet and mirrors its trades, filtered by chain, asset match, position size, and the follower's own portfolio state.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2883,2886,2887,2890],{"name":2884,"slug":2885,"type":15},"Automation","automation",{"name":23,"slug":24,"type":15},{"name":2888,"slug":2889,"type":15},"Trading","trading",{"name":17,"slug":18,"type":15},"2026-07-17T06:04:21.974052",{"slug":2893,"name":2893,"fn":2894,"description":2895,"org":2896,"tags":2897,"stars":25,"repoUrl":26,"updatedAt":2904},"dca-bot","automate dollar cost average token purchases","This skill should be used when the user wants to \"dca into\" a token, \"buy X every day\", set up a \"recurring buy\", \"dollar cost average\" into an asset, \"schedule a buy\", or \"auto-buy on a dip\". Buys a fixed amount into a token on a schedule, optionally only when a condition holds (for example only when ETH is below a price threshold). The host agent's scheduler wakes the skill on a cadence; each wake is one self-contained run.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2898,2899,2902,2903],{"name":2884,"slug":2885,"type":15},{"name":2900,"slug":2901,"type":15},"DeFi","defi",{"name":2888,"slug":2889,"type":15},{"name":17,"slug":18,"type":15},"2026-07-17T06:05:37.160647",{"slug":2906,"name":2906,"fn":2907,"description":2908,"org":2909,"tags":2910,"stars":25,"repoUrl":26,"updatedAt":2917},"deployer","deploy Uniswap CCA smart contracts","Deploy CCA (Continuous Clearing Auction) smart contracts using the Factory pattern. Use when user says \"deploy auction\", \"deploy cca\", \"factory deployment\", or wants to deploy a configured auction.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2911,2914,2915,2916],{"name":2912,"slug":2913,"type":15},"Deployment","deployment",{"name":23,"slug":24,"type":15},{"name":2873,"slug":2874,"type":15},{"name":17,"slug":18,"type":15},"2026-07-17T06:08:09.661977",{"slug":2919,"name":2919,"fn":2920,"description":2921,"org":2922,"tags":2923,"stars":25,"repoUrl":26,"updatedAt":2930},"index-bot","create and rebalance asset portfolios","This skill should be used when the user asks to \"create an index\", \"build a basket of top assets\", \"buy a weighted basket\", \"make a portfolio of assets\", \"equal-weight basket\", \"rebalance my portfolio\", \"track the top N tokens\", or wants an automated, weighted multi-asset basket that buys in one pass and rebalances on a cadence. Builds the basket spec, delegates each buy and rebalance swap to the swap-integration Trading API flow, and records target weights in state.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2924,2925,2928,2929],{"name":23,"slug":24,"type":15},{"name":2926,"slug":2927,"type":15},"Portfolio Management","portfolio-management",{"name":2888,"slug":2889,"type":15},{"name":17,"slug":18,"type":15},"2026-07-17T06:04:22.328253",{"slug":2932,"name":2932,"fn":2933,"description":2934,"org":2935,"tags":2936,"stars":25,"repoUrl":26,"updatedAt":2943},"liquidity-planner","plan and create liquidity positions","This skill should be used when the user asks to \"provide liquidity\", \"create LP position\", \"add liquidity to pool\", \"become a liquidity provider\", \"create v3 position\", \"create v4 position\", \"concentrated liquidity\", \"set price range\", or mentions providing liquidity, LP positions, or liquidity pools on Uniswap. Generates deep links to create positions in the Uniswap interface.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2937,2938,2939,2942],{"name":2900,"slug":2901,"type":15},{"name":23,"slug":24,"type":15},{"name":2940,"slug":2941,"type":15},"Liquidity","liquidity",{"name":17,"slug":18,"type":15},"2026-08-08T03:55:37.214112",{"slug":2945,"name":2945,"fn":2946,"description":2947,"org":2948,"tags":2949,"stars":25,"repoUrl":26,"updatedAt":2956},"lp-integration","integrate Uniswap liquidity provisioning","Integrate Uniswap liquidity provisioning (LP) into applications via the LP REST API. Use when the user says \"LP API\", \"liquidity provisioning API\", \"provide liquidity programmatically\", \"create LP position via API\", \"add liquidity via API\", \"increase liquidity\", \"decrease liquidity\", \"remove liquidity\", \"claim LP fees\", \"collect LP fees\", \"manage LP positions in code\", or mentions building a backend, bot, or frontend that creates or manages Uniswap v2\u002Fv3\u002Fv4 liquidity positions through an API. Also use when debugging LP API calls (e.g. \u002Flp\u002Fcreate, \u002Flp\u002Fcheck_approval, \u002Flp\u002Fincrease, \u002Flp\u002Fdecrease, \u002Flp\u002Fclaim_fees), unexpected response fields, the approval or EIP-712 permit flow, or transaction-building errors for liquidity positions. For generating deep links to the Uniswap web app instead of calling the API, use the liquidity-planner skill; for using the Uniswap v4 SDK directly rather than the REST API, use the v4-sdk-integration skill.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2950,2953,2954,2955],{"name":2951,"slug":2952,"type":15},"API Development","api-development",{"name":2900,"slug":2901,"type":15},{"name":2940,"slug":2941,"type":15},{"name":17,"slug":18,"type":15},"2026-08-08T03:55:34.112025",{"slug":2958,"name":2958,"fn":2959,"description":2960,"org":2961,"tags":2962,"stars":25,"repoUrl":26,"updatedAt":2970},"pay-with-any-token","pay HTTP 402 challenges with Uniswap","Pay HTTP 402 payment challenges using tokens via the Tempo CLI and Uniswap Trading API. Use when the user encounters a 402 Payment Required response, needs to fulfill a machine payment, mentions \"MPP\", \"Tempo payment\", \"pay for API access\", \"HTTP 402\", \"x402\", \"machine payment protocol\", \"pay-with-any-token\", \"use tempo\", \"tempo request\", or \"tempo wallet\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2963,2964,2967,2968],{"name":2900,"slug":2901,"type":15},{"name":2965,"slug":2966,"type":15},"Payments","payments",{"name":2888,"slug":2889,"type":15},{"name":2969,"slug":2969,"type":15},"x402","2026-08-08T03:55:36.210847",{"slug":2972,"name":2972,"fn":2973,"description":2974,"org":2975,"tags":2976,"stars":25,"repoUrl":26,"updatedAt":2981},"pay-with-app","pay 402 payment challenges","Pay HTTP 402 payment challenges issued by OKX's Agent Payments Protocol (APP) on X Layer using tokens from any chain via the Uniswap Trading API. Use this skill whenever the user encounters a 402 challenge whose network resolves to X Layer (chain 196), mentions \"APP\", \"Agent Payments Protocol\", \"OKX agent payment\", \"OKX Onchain OS\", \"OKX agentic wallet\", \"x402 on X Layer\", \"USDT0\", \"x42\", \"Instant Payment\", \"Batch Payment\", \"pay for X Layer API\", or wants to pay an OKX-backed merchant. Even when the user does not explicitly say APP, prefer this skill for any 402 challenge whose network resolves to X Layer (chain 196). For 402 challenges on other chains (Ethereum, Base, Arbitrum, Tempo) use pay-with-any-token instead.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2977,2978,2979,2980],{"name":2951,"slug":2952,"type":15},{"name":2965,"slug":2966,"type":15},{"name":17,"slug":18,"type":15},{"name":2969,"slug":2969,"type":15},"2026-08-08T03:55:32.164995",{"slug":4,"name":4,"fn":5,"description":6,"org":2983,"tags":2984,"stars":25,"repoUrl":26,"updatedAt":27},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2985,2986,2987,2988],{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"slug":2990,"name":2990,"fn":2991,"description":2992,"org":2993,"tags":2994,"stars":25,"repoUrl":26,"updatedAt":2999},"swap-integration","integrate Uniswap swap functionality","Integrate Uniswap swaps into applications. Use when user says \"integrate swaps\", \"uniswap\", \"trading api\", \"add swap functionality\", \"build a swap frontend\", \"create a swap script\", \"smart contract swap integration\", \"use Universal Router\", \"Trading API\", or mentions swapping tokens via Uniswap.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[2995,2996,2997,2998],{"name":2951,"slug":2952,"type":15},{"name":2900,"slug":2901,"type":15},{"name":2888,"slug":2889,"type":15},{"name":17,"slug":18,"type":15},"2026-08-08T03:55:33.189242",{"slug":3001,"name":3001,"fn":3002,"description":3003,"org":3004,"tags":3005,"stars":25,"repoUrl":26,"updatedAt":3010},"swap-planner","plan and execute token swaps","This skill should be used when the user asks to \"swap tokens\", \"trade ETH for USDC\", \"exchange tokens on Uniswap\", \"buy tokens\", \"sell tokens\", \"convert ETH to stablecoins\", \"find memecoins\", \"discover tokens\", \"research tokens\", \"tokens to buy\", \"find tokens to swap\", \"what should I buy\", or mentions swapping, trading, researching, discovering, buying, or exchanging tokens on any Uniswap-supported chain. Supports both known token swaps and token discovery workflows (discovery uses keyword search and web search — there is no live \"trending\" feed). Generates deep links to execute swaps in the Uniswap interface.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3006,3007,3008,3009],{"name":2900,"slug":2901,"type":15},{"name":2940,"slug":2941,"type":15},{"name":2888,"slug":2889,"type":15},{"name":17,"slug":18,"type":15},"2026-08-08T03:55:35.104047",22,{"items":3013,"total":3063},[3014,3021,3028,3035,3042,3049,3056],{"slug":2863,"name":2863,"fn":2864,"description":2865,"org":3015,"tags":3016,"stars":25,"repoUrl":26,"updatedAt":2876},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3017,3018,3019,3020],{"name":2869,"slug":2870,"type":15},{"name":23,"slug":24,"type":15},{"name":2873,"slug":2874,"type":15},{"name":17,"slug":18,"type":15},{"slug":2878,"name":2878,"fn":2879,"description":2880,"org":3022,"tags":3023,"stars":25,"repoUrl":26,"updatedAt":2891},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3024,3025,3026,3027],{"name":2884,"slug":2885,"type":15},{"name":23,"slug":24,"type":15},{"name":2888,"slug":2889,"type":15},{"name":17,"slug":18,"type":15},{"slug":2893,"name":2893,"fn":2894,"description":2895,"org":3029,"tags":3030,"stars":25,"repoUrl":26,"updatedAt":2904},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3031,3032,3033,3034],{"name":2884,"slug":2885,"type":15},{"name":2900,"slug":2901,"type":15},{"name":2888,"slug":2889,"type":15},{"name":17,"slug":18,"type":15},{"slug":2906,"name":2906,"fn":2907,"description":2908,"org":3036,"tags":3037,"stars":25,"repoUrl":26,"updatedAt":2917},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3038,3039,3040,3041],{"name":2912,"slug":2913,"type":15},{"name":23,"slug":24,"type":15},{"name":2873,"slug":2874,"type":15},{"name":17,"slug":18,"type":15},{"slug":2919,"name":2919,"fn":2920,"description":2921,"org":3043,"tags":3044,"stars":25,"repoUrl":26,"updatedAt":2930},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3045,3046,3047,3048],{"name":23,"slug":24,"type":15},{"name":2926,"slug":2927,"type":15},{"name":2888,"slug":2889,"type":15},{"name":17,"slug":18,"type":15},{"slug":2932,"name":2932,"fn":2933,"description":2934,"org":3050,"tags":3051,"stars":25,"repoUrl":26,"updatedAt":2943},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3052,3053,3054,3055],{"name":2900,"slug":2901,"type":15},{"name":23,"slug":24,"type":15},{"name":2940,"slug":2941,"type":15},{"name":17,"slug":18,"type":15},{"slug":2945,"name":2945,"fn":2946,"description":2947,"org":3057,"tags":3058,"stars":25,"repoUrl":26,"updatedAt":2956},{"slug":8,"name":9,"logoUrl":10,"githubOrg":9},[3059,3060,3061,3062],{"name":2951,"slug":2952,"type":15},{"name":2900,"slug":2901,"type":15},{"name":2940,"slug":2941,"type":15},{"name":17,"slug":18,"type":15},16]