mcpField
P
permissioned-pools-issuer

permissioned-pools-issuer

github.com/uniswap開発236245 回インストール2 日前に更新
リポジトリ

permissioned-pools-issuer について

譲渡制限付き ERC-20 を Uniswap v4 Permissioned Pool に組み込む発行者のエンジニア向けコントラクトリファレンスです。コントラクトの挙動や推奨呼び出し順、エラーの原因、実装時に重要な名称を説明します。

主な機能

  1. 01コントラクト構成と呼び出し順の解説
  2. 02強制順序と関連するリバートの説明
  3. 03基礎トークンとアダプターのアドレス区別
  4. 04権限フラグとラッパー登録の整理
  5. 05正確なコントラクト名とシグネチャの参照

活用シーン

  1. 01Permissioned Pool のコントラクト統合の計画
  2. 02順序が早すぎる呼び出しによるリバートの調査
  3. 03allowlist checker の実装とインターフェース確認
  4. 04ラッパー登録と権限設定の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/uniswap/uniswap-ai --skill permissioned-pools-issuer

インストール後、Claude Code で/permissioned-pools-issuerを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
contract-architecture.md
coordination-boundary.md
enforced-ordering-and-reverts.md
issuer-journey.md
packaging-and-sources.md
trust-model.md

詳細

Permissioned Pools Issuer Reference

Uniswap v4 の許可制プールに移行制限付き ERC-20 を導入する発行者のエンジニアリングチーム向けリファレンスです。対象となるコントラクト、呼び出す順序、それぞれのリバートの意味について説明します。

ランタイムの互換性: このスキルでは、操作を伴うデプロイ手順を案内する前に、Scope and Disclaimer に記載されている確認を得るため、AskUserQuestion を使用します。お使いのランタイムで AskUserQuestion を利用できない場合は、会話の中で同じ確認を求めてください。

Scope and Disclaimer

重要:これは教育目的のリファレンス資料です。この内容に基づいて行動する前に、つまり、ここから派生したものを実行、ブロードキャスト、またはデプロイする前に、以下を確認する必要があります。

このスキルでは、Uniswap v4 Permissioned Pools のコントラクトの動作、呼び出す順序、それぞれのリバートの意味について説明します。デプロイ手順を案内するものではありません。

必ず以下を守ってください:

  1. ✅ コントラクトの仕組みに関する情報としてのみ扱ってください。 このスキルは、法律、金融、投資、税務に関する助言ではありません。また、トークン、許可リスト、KYC または AML プログラム、設定のコンプライアンスレビューでもありません。
  2. ✅ 実行前にすべて確認してください。 AI が生成したコードやコマンドの手順には誤りが含まれている場合があります。まずテストネットでテストし、デプロイするコントラクトは独自の監査担当者に確認してもらってください。
  3. ✅ ビルド対象のコミットのソースを確認してください。 ここで説明する動作は、Canonical Sources に記載されている固定コミットに基づいています。記載内容を信頼する前に、必ずソースを確認してください。
  4. ✅ アドレスはすべて自分で確認してください。 このスキルには意図的にデプロイアドレスを記載していません。公開されているデプロイテーブルからアドレスを確認し、トランザクションを送信する前に、ご利用のチェーンのブロックエクスプローラーで各アドレスを検証してください。チャットメッセージで提示されたアドレスを正規のものとして扱わないでください。
  5. ✅ リポジトリの利用ガイドラインを読んでください。 リポジトリのルートにある DISCLAIMER.md は、このリポジトリ内のすべてのスキルに適用されます。各スキルは無保証で提供され、法律、金融、投資、税務に関する助言ではありません。また、利用制限に加え、スキルを使って金融情報を生成し、それを個人や消費者に直接提示する場合に適用される AI による生成である旨の開示義務も定めています。ユーザーにその内容を案内してください。
確認が必要な場合

上記の5項目を毎回、回答の中で明示してください。引用でも、自分の言葉での説明でもかまいません。そのうえで、同じ回答の中で依頼に答えてください。注意事項の提示と回答は、1つの回答として行います。2回に分けることはありません。これが期待される動作であり、近道ではありません。

  1. ✅ リファレンスや解説の内容:注意事項を示したうえで、すぐに回答してください。 コントラクトの説明、コードの骨組みやサンプルコントラクト、リバートの一覧、正確な名前や大文字・小文字の指定、パッケージングとインストール、アーキテクチャや信頼モデルに関する説明は、いずれも注意事項と同じ回答の中で説明します。「はい」という返答を待ってリファレンス情報の提供を保留したり、求められた回答の代わりに確認を求めて回答を終えたりしてはいけません。
  2. ✅ 操作を伴うデプロイ手順:まず明示的な確認を得てください。 ライブネットワークに対して実行する手順、トランザクションやブロードキャストの手順、デプロイスクリプト、送信先となる実在のアドレスの提示依頼、または実際の資金を動かすものが該当します。これらを案内する前に、ユーザーが上記の項目を確認し、同意したことを AskUserQuestion で確認してください。確認を得た後は、仕組みに関する情報のみを続けてください。このスキルでは、ブロードキャスト可能なコマンドは出力しません。

「BaseAllowlistChecker の骨組みを見せてください」「このリバートはどういう意味ですか」「どのインポートパスを使いますか」といった無害な技術的質問は、1のリファレンス情報に該当します。注意事項を回答内で明示したうえで、質問に答えてください。

アドレスは1つではなく2つ

許可制プールには必ず2つのトークンアドレスが関係し、それらを取り違えることが最もよくある統合エラーです。

質問基盤となる許可制 ERC-20PermissionsAdapter(仮想トークン)
PoolKey に指定するアドレスはどちらですか?いいえはい — プールの通貨はアダプターです
許可リストチェッカーが tokenAddress として受け取るのはどちらですか?はい — チェッカーはお使いのトークンについて照会されますいいえ
ウォレットまたはLPが保有するのはどちらですか?はいいいえ — アダプタートークンを保有するのはPoolManagerだけです
アプリがユーザーに表示するのはどちらですか?はい表示される場合は Uniswap v4 … 仮想トークンとして表示されます
ミントのためにPermit2経由で承認するのはどちらですか?はい — 承認対象は基盤となるトークンですいいえ

アダプターは仮想トークンをPoolManagerにミントし、出庫時にバーンします。名前とシンボルは選択するものではなく、派生して決まります。常に Uniswap v4 <name> と v4<symbol> となり、お使いのトークンの name()、symbol()、decimals() から読み取られます。これらが取得できない場合は Uniswap v4 Permissioned Token、v4PT、18 が使用されます。そのため、お使いのトークンでは3つすべてを公開してください。

知っておくべき例外:アダプターと許可制トークンのアドレスが同じ場合、そのトークンはすでにアダプターとして動作します。

詳しくはコントラクトアーキテクチャをご覧ください。


手順の概要

混同されがちなことが2つあります。1つ目の表はコントラクトが強制する内容、2つ目の表は公開ガイドが推奨する順序です。

コードによって強制される内容

強制される順序関係はちょうど5つです。いずれも早すぎると発生するリバートがあります。

強制される順序関係早すぎる場合のリバート
アダプターがお使いのトークンの許可リストに登録され、かつゼロ以外の残高を保有 → verifyPermissionsAdapterPermissionsAdapterNotVerified
verifyPermissionsAdapter → setAllowedHookNotPermissionsAdapterAdmin
アダプターが登録され、検証済み → プールの initializeNoVerifiedAdapter(フック)または UnverifiedAdapter
検証済みアダプター+承認済みフック+呼び出し元 および 受取人の LIQUIDITY_ALLOWED → 初回ミントNoVerifiedAdapter(ポジションマネージャー)、InvalidHook、または単独の Unauthorized
ポジションマネージャー、ルーター、クオーターを updateAllowedWrapper で登録 → それらを経由するあらゆるミント、スワップ、または見積もり単独の Unauthorized(フック)、続いて精算時に UnauthorizedWrapper
推奨される順序(慣例であり、強制ではありません)

以下は、公開されているガイドの7つの手順です。上の表にない手順の位置は、コントラクトでは固定されていません。

手順操作
1許可リストチェッカーを実装します
2ファクトリーを使って Permissions Adapter を作成します
3トークンでアダプターを許可リストに追加し、資金を入れます(1 wei で十分です)
4ファクトリーでアダプターを検証します
5仮想トークンのコントラクト(許可されたラッパー)を承認してから、ポジションマネージャーでフックを許可します
6プールを作成してから、アダプターでスワップを有効にします
7Uniswap Labs にルーティングの許可リストへの追加を依頼します

上記の5つの順序関係のみが強制されるため、ほかの順序でも機能します。ガイド自体の順序では、プール作成後に updateSwappingEnabled(true) を呼び出します。また、ラッパーの承認とフックの承認を1つの手順にまとめているのは説明上の都合であり、制約ではありません。ラッパーの登録は、検証やプール作成との順序に制約はありませんが、ラッパーを経由して何かをルーティングする前に登録しておく必要があります。

手順の詳細:発行者の手順。


コンパイルに必須の名前とシグネチャ

この表記はソース内で一貫しておらず、動作に影響します。以下のスペルを正確に使用してください。

対象正確な表記注意点
基底コントラクトBaseAllowlistCheckerコントラクト名の l は小文字です
含まれるファイルBaseAllowListChecker.solファイル名の L は大文字です
インターフェースIAllowlistCheckerl は小文字で、ファイル名は IAllowlistChecker.sol です
アダプターの管理者用呼び出しupdateAllowListCheckerL は大文字です。小文字の別表記はありません
アダプターのゲッターallowListChecker()L は大文字です。インターフェースとは異なります
フックの承認呼び出しsetAllowedHook単数形で、ポジションマネージャー上にあります
対応するストレージマッピングisAllowedHooks複数形
対応するイベントAllowedHooksUpdated複数形
フラグライブラリPermissionFlags複数形
フラグ型PermissionFlag単数形

インポートと Forge の検索形式:

import {BaseAllowlistChecker} from "@uniswap/v4-periphery/src/hooks/permissionedPools/BaseAllowListChecker.sol";
BaseAllowListChecker.sol:BaseAllowlistChecker

この path:Contract の組み合わせ(ファイル名では L が大文字、コントラクト名では l が小文字)が、forge inspect と forge verify-contract に必要です。

checkAllowlist には正当な形が2つあります

どちらもコンパイルできます。どちらか一方を選び、一貫して使用してください。

  1. 基底コントラクトを拡張します。 次のように宣言します。 function checkAllowlist(address account, address tokenAddress) public view virtual override returns (PermissionFlag). 基底コントラクトの public virtual を external に狭めることはできません。コンパイルエラーになります。 ERC-165 のサポートは基底コントラクトから自動的に得られます。
  2. インターフェースを直接実装します。 checkAllowlist を external view として宣言し、 supportsInterface を自分で記述します。公開されているガイドの例ではこの方法が使われています。IAllowlistChecker と ERC165 を直接実装し、BaseAllowlistChecker は使用しません。
アダプターはERC-165でチェッカーを検証します

createPermissionsAdapter は、ERC-165 の supportsInterface 呼び出しを通じてチェッカーが IAllowlistChecker を通知しない場合、InvalidAllowListChecker を revert します。このチェックはコンストラクターで実行されるため、一連の処理で最初の Uniswap 呼び出し時に発生します。updateAllowListChecker も、後で同じチェックを実行します。BaseAllowlistChecker を拡張すれば、この要件を満たせます。一から実装する場合は、supportsInterface を自分で実装する必要があり、独自のIDだけでなく、ERC-165のプローブ全体に応答しなければなりません。OpenZeppelin の ERC165Checker.supportsInterface はまず、supportsInterface(0x01ffc9a7) が true を返し、かつ supportsInterface(0xffffffff) が false を返すことを要求します。OpenZeppelin の ERC165 を継承し、super.supportsInterface に委譲すれば、両方に対応できます。type(IAllowlistChecker).interfaceId に対してのみ true を返す手書きの関数では、アダプターの作成に失敗します。


権限フラグ

PermissionFlags(ライブラリ)は、PermissionFlag 型の値を4つ公開します。

名前値対象
NONE0x0000なし
SWAP_ALLOWED0x0001フックの beforeSwap と、ルーターの決済チェック
LIQUIDITY_ALLOWED0x0002フックの beforeAddLiquidity と、mintおよび増額時の受取人チェック
ALL_ALLOWED0xFFFF両方

SWAP_ALLOWED は LIQUIDITY_ALLOWED を意味しません。スワップできるウォレットが、必ずしも流動性を提供できるとは限りません。これは自分のトレジャリーウォレットも同様です。チェッカーは、該当する権限を組み合わせた PermissionFlag を返します。


ラッパーの登録セット

アダプターの updateAllowedWrapper(address wrapper, bool allowed) は onlyOwner です。公開されているガイドでは、次の4つのコントラクトを登録するよう案内しています。

  1. PermissionedPositionManager
  2. Universal Router — 2.2.0以降。正規デプロイのキーは UniversalRouter#v2.2 です
  3. V4Quoter
  4. MixedRouteQuoterV2

4つの登録が必要な理由: このプールで PoolManager を呼び出すすべてのコントラクトを登録します。フックは allowedWrappers(router) を確認します。ここでの router は、呼び出し元のルーターまたはポジションマネージャーです。また、wrapToPoolManager は別途 allowedWrappers[msg.sender] を確認します。したがって、独自のカスタムルーターも登録する必要があります。この4つは実運用で呼び出し元となるものであり、登録対象の完全な一覧ではありません。登録は利用時に適用されるため、最初のmint前にポジションマネージャーを登録し、各ルーターおよびクオーターを、それぞれを通じた最初のスワップまたはクォートの前に登録する必要があります。

注意すべき点が2つあります。 ガイドのステップ5には「4つすべてのアドレス」とありますが、リンク先の表には 6行 あります。その表にある PermissionsAdapterFactory と PermissionedHooks はラッパーではありません。ファクトリーもフックも、決して登録しないでください。また、通常の UniversalRouter のデプロイキーは、権限対応ではない別のルーターを指します。コンストラクターで permissions-adapter factory を受け取るのは、#v2.2 のデプロイのみです。


コントラクトのインストール

npmで公開されている最新の @uniswap/v4-periphery は 1.0.3(2025-07-29)で、そのtarballには src/hooks/permissionedPools/ がまったく含まれていません。また、v4-periphery には git tag が 1つもない ため、タグを指定することもできません。唯一の選択肢は、コミットSHAを直接指定することです。

# Foundry — pin the exact commit
forge install Uniswap/v4-periphery@3245c3cb99c48fa1dc2459c3b60abc37d4294aba
# remappings.txt — matches what v4-hooks-public itself uses
@uniswap/v4-periphery/=lib/v4-periphery/

公開されているガイドのインポートパスは、次の方法で読み替えれば、npmスコープに対応しており正しいものです。ガイドにはインポート行が記載されています。インストール手順と上記の読み替えが、そのために必要な内容です。

フックのソースの固定方法やアドレスの解決方法などの詳細については、パッケージとソースを参照してください。


順序はコードで強制されます

これらの呼び出しを早い段階で行うと、示されているセレクターでリバートします。これは想定される動作であり、未解決の疑問ではありません。

呼び出しリバート条件
createPermissionsAdapterInvalidAllowListCheckerチェッカーが ERC-165 インターフェースチェックに失敗する場合
verifyPermissionsAdapterPermissionsAdapterNotVerifiedアダプターの permissioned-token 残高がゼロの場合
setAllowedHookNotPermissionsAdapterAdmin通貨のアダプターがまだ検証されておらず、そのため所有者が address(0) として読み取られる場合
プールの initializeNoVerifiedAdapter / UnverifiedAdapterどちらの通貨もファクトリーによって作成されていない場合、またはファクトリーが作成した通貨が検証されていない場合
ポジションマネージャーの _mintNoVerifiedAdapter / InvalidHook / Unauthorized検証済みの側がない場合/フックが許可されていない場合/呼び出し元または受取人が LIQUIDITY_ALLOWED を持たない場合、あるいはポジションマネージャーが登録済みの許可ラッパーではない場合

NoVerifiedAdapter、Unauthorized、SwappingDisabled は、それぞれ同じセレクターで複数回宣言されています。NoVerifiedAdapter と Unauthorized は実際に意味が異なり、SwappingDisabled はスワップ中の異なる2箇所で同じ意味を持ちます。名前ではなく、必ず呼び出し箇所に基づいてデコードしてください。

全項目の一覧と、順序が守られない場合のシナリオ例については、順序の強制とリバートを参照してください。


信頼モデルの概要

  • LP ポジションは恒久的に譲渡できません。 3つすべての ERC-721 転送エントリーポイントは TransferDisabled でリバートします。これは設定フラグではありません。減額とバーンが許可リストチェッカーによって制限されることはないため、プールが退出を妨げることはありません。ただし、permissioned 側を受け渡す際には基礎トークンにアンラップされるため、受取人は引き続き、トークン独自の転送制限を通過する必要があります。
  • どちらのアダプター管理者も unwindPosition で任意の LP を強制退出させられます。収益はまず LP に、次に管理者に渡され、その後は通貨に応じた受取人を持つ ERC-6909 クレームとして処理されます。
  • これらのコントラクトに関するレポートは3件公開されています。Cantina、OpenZeppelin、OpenZeppelin による修正レビューで、v4-periphery の audits/permissionedPools/ にあります。それぞれがどのコントラクトを対象にしたかは各レポートに記載されているため、ディレクトリから対象範囲を推測せず、スコープのセクションを読んでください。v4-hooks-public リポジトリにはフックがありますが、監査一覧表に permissioned-pools の行はありません。その記載がないことも、何の証明にもなりません。3件のいずれも、あなたが作成する許可リストチェッカーを対象としていません。
  • 実際の強制境界は、アダプターの allowedWrappers リストです。 リストに登録されたすべてのラッパーは、msgSender() を通じて実際の呼び出し元を正しく報告すると信頼されています。updateAllowedWrapper は Ownable2Step コントラクト上で onlyOwner となっているため、アダプター所有者のキー管理も信頼モデルの一部です。

詳細については、信頼モデルを参照してください。


パーミッションレスなものと、そうでないもの

パーミッションレス/発行者が制御するものUniswap Labs と連携するもの
許可リストチェッカーのデプロイUniswap インターフェースと API におけるルーティングの適格性
createPermissionsAdapter(誰でも呼び出し可能)トークンリストへの掲載
トークンでのアダプターの許可リスト登録トークン詳細のメタデータ
depositForVerification(誰でも呼び出し可能)バックエンド設定での発行者メタデータと KYC URL
verifyPermissionsAdapter(誰でも呼び出し可能、1 回限り)
すべてのアダプター管理操作
setAllowedHook、プールの初期化、流動性のシード

オンチェーンの手続きに Uniswap の承認ゲートはありません。 左列の項目は、どれも誰かの承認待ちにはなりません。

ルーティングリクエストを含む境界の詳細:連携の境界。


リファレンストピック

トピックリファレンスファイル
コントラクトごとのスタック、正確な大文字・小文字表記の一覧、フラグ、イベントコントラクトアーキテクチャ
呼び出し、呼び出し元、チェックを含む 7 つのステップの詳細発行者の手順
適用される 5 つのエッジ、リバート一覧、具体的なシナリオ順序制約とリバート
譲渡不可性、管理者による強制退出、候補ラッパーの審査信頼モデル
ピン留め、リマッピング、インポートパス、アドレスの解決パッケージングとソース
パーミッションレスなものと連携が必要なもの、ルーティングリクエスト連携の境界

正式な情報源

公開されている発行元のドキュメント:

コントラクトのソース(特定のコミットに固定):

これらのコントラクトに関する公開レポート:

  • Uniswap/v4-periphery の audits/permissionedPools/ — Cantina、OpenZeppelin、および OpenZeppelin による修正レビュー。2026-08-20 に追加 (https://github.com/Uniswap/v4-periphery/tree/main/audits/permissionedPools)。これらは上記の特定コミットより後の日付のため、各レポートの対象範囲に関するセクションを確認してください。

アドレス:

  • 権限付きプールに関するアドレスの完全な一覧は、デプロイガイドの #deployment-addresses アンカーにあります。
  • 機械可読な記録は、Uniswap/contracts の deployments/json/<chainId>.json にある latest キーの下にあります (https://github.com/Uniswap/contracts)。
  • トランザクションを送信する前に、お使いのチェーンのブロックエクスプローラーで各アドレスを確認してください。

このスキル:https://github.com/Uniswap/uniswap-ai

コメント