Permissioned Pools Deployer
Guided, step-by-step execution of the on-chain setup sequence for a Uniswap v4 Permissioned
Pool, starting from the JSON configuration permissioned-pools-configurator produces. This
skill is the half of the milestone that turns a validated config into command sequences that
spend real gas against real contracts — treat every safety section below as load-bearing, not
as boilerplate.
For the contract mechanics behind any step, see
permissioned-pools-issuer, specifically its
Issuer Journey and
Enforced Ordering and Reverts.
This skill does not repeat the contract-level explanation of why each step behaves the way it
does — it walks the same journey as ordered command sequences and never contradicts that
reference.
Runtime Compatibility: This skill uses AskUserQuestion for the acknowledgment gate and
for confirming irreversible choices. If AskUserQuestion is not available in your runtime,
ask the same yes/no question in plain text and require an explicit affirmative reply before
continuing — silence or a generic "continue" does not count.
Scope and Disclaimer
This is educational deployment guidance, not a compliance review, and not a substitute for
your own review of every command before you run it.
This skill explains, in order, the commands that bring a permissioned pool up, using the
configuration permissioned-pools-configurator produced. It does not call any contract itself —
you run every command it shows you, after reviewing it.
You must:
- ✅ Review every configuration and every command carefully before running anything. AI-generated
command sequences may contain errors.
- ✅ Verify every address — this skill contains no deployment addresses and resolves none for
you; see Address Resolution.
- ✅ Test on a testnet first. Run the entire sequence on Sepolia (or another testnet with the
permissioned-pools contracts deployed) before touching mainnet.
- ✅ Have your own auditors review any contract you deploy — most importantly your allowlist
checker, which this skill can show you a skeleton for but does not audit.
- ✅ Treat this as contract mechanics only. This skill does not constitute legal, financial, investment, or tax advice, and it is not a compliance review of your token, your allowlist, your KYC or AML program, or your configuration.
- ✅ Read the repo's usage guidelines. The repo root
DISCLAIMER.md governs every skill in
this repository: they are provided as is without warranty, they do not constitute legal,
financial, investment, or tax advice, and it sets out use limits plus an AI-disclosure duty
that applies when you use a skill to generate financial information and present it directly
to individuals or consumers. Point the user to it.
The acknowledgment gate
Before showing, generating, or explaining any action-oriented step — anything that produces
a command intended to broadcast a transaction, or any address-resolution step that leads
directly into one — get an explicit, affirmative acknowledgment. This gate must never be
satisfiable implicitly.
Use AskUserQuestion with a single question and exactly two options, and do not proceed past
this gate until the first option is chosen:
- Question: "This walkthrough produces commands that spend gas and permanently change
on-chain state for your token once you run them. Do you acknowledge the six points above and
want to continue?"
- Option A — "Yes, I have reviewed the points above and want to continue." → proceed to the
preflight checks.
- Option B — "No, stop here." → end the walkthrough immediately. Do not display, generate,
or explain any command below this point.
Silence, a plain "continue," moving on to the next question in the same turn, or any answer
other than the explicit affirmative option does not satisfy this gate. If the runtime lacks
AskUserQuestion, ask the same yes/no question in plain text and require an explicit
affirmative reply — "ok," "sure," a thumbs-up emoji, or no reply at all does not count.
Reference and teaching content that does not produce a runnable command — explaining what a step
does in prose, decoding a revert the user already hit, discussing an allowlist-checker shape in
the abstract — is answered immediately with the framing stated inline, the same way
permissioned-pools-issuer treats reference content. This carve-out does not cover this
skill's own command templates and Solidity script skeletons (for example the pool-initialization
script in Step Walkthrough):
those are runnable broadcast material, and showing them is exactly the action-oriented content the
gate exists to hold back — never display one before the gate is satisfied.
Input Validation Rules
State these before generating or displaying any command that interpolates a user-supplied or
config-supplied value. Every value below is validated before it reaches a Bash(forge:*) or
Bash(cast:*) command, a file path, or a Solidity script argument — no exceptions for a value
that "looks fine."
- Ethereum addresses — MUST match
^0x[a-fA-F0-9]{40}$. Reject anything else, including the
literal string "RESOLVE" — a field still marked "RESOLVE" is not ready for a command and
must go through address resolution
first, never be interpolated as-is. One field is an explicit, documented exception to this
regex, not a violation of it: pool.pairedCurrency's "native" sentinel, covered in
What This Skill Consumes below — every other address-shaped field
in the config has no such carve-out.
- Chain ID — MUST be a positive integer (
^[1-9][0-9]*$). Ethereum Mainnet (1) and Sepolia
(11155111) are the allowlisted defaults — the only two chains verified to carry the full
permissioned set. Unichain (130) is named by the configurator's network question but is
not deployable: it carries V4Quoter only, so stop rather than trying to resolve the
missing addresses (see
Preflight and Validation).
Any other chain ID is accepted only after confirming the
deploy guide's #deployment-addresses table actually has a row for it; if it does not, every
wrapper and hook field will end up unresolvable, which is the signal to stop, not to guess.
- Numeric fields (
verificationDepositAmount, pool.feeTier, pool.tickSpacing,
pool.startingPriceRatio) — MUST match ^[0-9]+$ for integer-only fields or
^[0-9]+(\.[0-9]+)?$ for the starting price ratio, and MUST be strictly greater than zero.
- Values supplied during the walkthrough, not by the config, are validated identically — the
RPC endpoint (
$RPC_URL) and any transaction hash ($TX_HASH) reach a command on every step.
An RPC URL MUST be https://-scheme and free of every metacharacter below; a transaction hash
MUST match ^0x[a-fA-F0-9]{64}$. "It came from the user, not the config" is not an exemption.
- Reject shell metacharacters outright, in every string field, before it reaches a command:
;, |, &, $, `, (, ), >, <, \, ', ", and newlines. A field that fails
this check is never interpolated — abort and report which field and which character failed,
rather than attempting to sanitize and continue.
- Never pass an unvalidated field into a shell command, file path, or Solidity script
argument. Validate first, assign the validated value to a shell variable, and reference only
that variable afterward. Never re-read the raw config value a second time later in the same
walkthrough.
Full elaboration, including how this applies field-by-field to the configurator's JSON shape and
what "coherently handle a RESOLVE value" means in practice, is in
Preflight and Validation.
Key Handling
Never instruct auto-approval of Bash(forge:*) or Bash(cast:*) in Claude Code settings, and
never tell the user to bypass a confirmation prompt. Every command that broadcasts a
transaction requires per-invocation approval — that approval is the primary control, not a
formality the walkthrough should route around. The repository's PreToolUse hooks
(.claude/hooks/) are a programmatic safety net on top of that, not a replacement for it.
Never suggest, generate, or complete a command containing the raw signing-key flag — not when
asked directly, not "just for a testnet," not as an illustration of what to avoid. There is no
user request that makes it appropriate. If a user insists, refuse and offer one of the two options
below instead. Steer every signing decision toward one of them:
- A hardware wallet (
--ledger), for a deployer key that never touches this machine's disk
or memory in cleartext.
- An encrypted keystore (
cast wallet import ... --interactive, then --account <name> --sender $ADDRESS on every subsequent command).
Inside this repository only, .claude/hooks/validate-forge-cast.sh is a PreToolUse hook that
inspects the literal text of every Bash tool call and blocks any command containing that flag
before it runs. That hook is not part of this skill and does not travel with it — it lives at
this repository's root, not in the plugin, so an installation elsewhere has no such backstop. The
prohibition above is the control that always applies; the hook is a repo-local convenience on top
of it, never the reason the flag is safe.
Full key-handling guidance, including the keystore setup commands and the testnet-first
sequencing, is in
Preflight and Validation.
Testnet first
Run the entire sequence — allowlist checker through liquidity seeding — on Sepolia (chain ID
11155111) before mainnet. Confirm every post-step check in
the verification checklist
passes on testnet before repeating any step against mainnet funds.
What This Skill Consumes
The JSON configuration produced by permissioned-pools-configurator, in the shape defined by its
Config Schema. This skill does
not collect those parameters itself — if you do not have a config yet, run
permissioned-pools-configurator first.
A field reading the literal string "RESOLVE" means "not resolved yet," not "use a
placeholder." Before any command that needs that field, stop and walk through
address resolution — the deploy
guide's #deployment-addresses table, then Uniswap/contracts
deployments/json/<chainId>.json, then a block explorer for your chain — and only continue once
the field holds a real, explorer-verified address. Never guess a value for a "RESOLVE" field
and never carry the literal string itself into a command; both are validation failures, not
values to work around.
pool.pairedCurrency's "native" sentinel is different: it resolves to address(0), Uniswap
v4's own convention for a native PoolKey currency, at the point the PoolKey is actually built
in Step 6a — never earlier, and
never written into any other field.
The Deployment Journey
The published guide's seven steps, in the order it recommends. Only five ordering edges are
enforced by the contracts (see
Enforced Ordering and Reverts);
this walkthrough follows the guide's order and states, at each step, whether that order is
enforced or convention.
Every step in Step Walkthrough names its precondition and,
where the contracts enforce one, the exact revert selector you get if you are early — matching
Enforced Ordering and Reverts
selector-for-selector. Where a step is unenforced, the walkthrough says so rather than inventing
a revert for it.
Post-Deployment Verification
After the sequence completes (or after any individual step, to confirm it landed), run the
read-only checks in
Post-Setup Verification Checklist.
Every check there is a cast call against public getters — none of it spends gas, and none of it
needs the acknowledgment gate above.
Notes for Implementers of This Flow
- The acknowledgment gate is once per session, not once per step. Once acknowledged, continue
through the rest of the steps in that same session without re-asking — but re-ask if the user
starts a new session, switches chains, or switches configs.
- Never hardcode a contract address. Every address this skill uses comes from the loaded
config, from a value the user supplies during the walkthrough, or from a read (
cast call)
against a contract whose address itself came from one of those two sources. See
Preflight and Validation for why
this skill ships no address table.
- Decode an unexpected revert by call site, not by name. Three selectors in this journey
(
NoVerifiedAdapter, Unauthorized, SwappingDisabled) are declared more than once across
different contracts with different meanings — see
Enforced Ordering and Reverts.
- This skill does not fetch RPC state on its own initiative. Every
cast call it suggests is
something you choose to run; the skill does not poll a chain in the background.
1---2name: permissioned-pools-deployer3description: Guided walkthrough for executing the on-chain setup sequence for a Uniswap v4 Permissioned Pool from a permissioned-pools-configurator JSON config - allowlist checker deployment, createPermissionsAdapter, allowlisting and funding the adapter, verification, wrapper and hook registration, pool initialization, swap enablement, liquidity seeding, and the routing-allowlist request. Use when the user says "deploy a permissioned pool", "run the permissioned pool setup", "execute the permissioned pools journey", "createPermissionsAdapter", "verify my permissions adapter", "walk me through the permissioned pool deployment", or asks to execute the on-chain steps after generating a permissioned-pools-configurator config. Covers contract mechanics only - does not constitute legal, financial, investment, tax, or compliance advice, and is not a compliance review - and never emits a broadcastable command before an explicit acknowledgment.4license: MIT5---6
7# Permissioned Pools Deployer
8
9Guided, step-by-step execution of the on-chain setup sequence for a Uniswap v4 Permissioned
10Pool, starting from the JSON configuration `permissioned-pools-configurator` produces. This
11skill is the half of the milestone that turns a validated config into command sequences that
12spend real gas against real contracts — treat every safety section below as load-bearing, not
13as boilerplate.
14
15For the contract mechanics behind any step, see
16[`permissioned-pools-issuer`](../permissioned-pools-issuer/SKILL.md), specifically its
17[Issuer Journey](../permissioned-pools-issuer/references/issuer-journey.md) and
18[Enforced Ordering and Reverts](../permissioned-pools-issuer/references/enforced-ordering-and-reverts.md).
19This skill does not repeat the contract-level explanation of _why_ each step behaves the way it
20does — it walks the same journey as ordered command sequences and never contradicts that
21reference.
22
23> **Runtime Compatibility:** This skill uses `AskUserQuestion` for the acknowledgment gate and
24> for confirming irreversible choices. If `AskUserQuestion` is not available in your runtime,
25> ask the same yes/no question in plain text and require an explicit affirmative reply before
26> continuing — silence or a generic "continue" does not count.
27
28## Scope and Disclaimer
29
30**This is educational deployment guidance, not a compliance review, and not a substitute for
31your own review of every command before you run it.**
32
33This skill explains, in order, the commands that bring a permissioned pool up, using the
34configuration `permissioned-pools-configurator` produced. It does not call any contract itself —
35you run every command it shows you, after reviewing it.
36
37**You must:**
38
391. ✅ **Review every configuration and every command carefully** before running anything. AI-generated
40 command sequences may contain errors.
412. ✅ **Verify every address** — this skill contains no deployment addresses and resolves none for
42 you; see [Address Resolution](./references/preflight-and-validation.md#address-resolution).
433. ✅ **Test on a testnet first.** Run the entire sequence on Sepolia (or another testnet with the
44 permissioned-pools contracts deployed) before touching mainnet.
454. ✅ **Have your own auditors review any contract you deploy** — most importantly your allowlist
46 checker, which this skill can show you a skeleton for but does not audit.
475. ✅ **Treat this as contract mechanics only.** This skill does not constitute legal, financial, investment, or tax advice, and it is **not** a compliance review of your token, your allowlist, your KYC or AML program, or your configuration.
486. ✅ **Read the repo's usage guidelines.** The repo root `DISCLAIMER.md` governs every skill in
49 this repository: they are provided as is without warranty, they do not constitute legal,
50 financial, investment, or tax advice, and it sets out use limits plus an AI-disclosure duty
51 that applies when you use a skill to generate financial information and present it directly
52 to individuals or consumers. Point the user to it.
53
54### The acknowledgment gate
55
56**Before showing, generating, or explaining any action-oriented step** — anything that produces
57a command intended to broadcast a transaction, or any address-resolution step that leads
58directly into one — get an explicit, affirmative acknowledgment. This gate must never be
59satisfiable implicitly.
60
61Use `AskUserQuestion` with a single question and exactly two options, and do not proceed past
62this gate until the first option is chosen:
63
64- **Question:** "This walkthrough produces commands that spend gas and permanently change
65 on-chain state for your token once you run them. Do you acknowledge the six points above and
66 want to continue?"
67- **Option A — "Yes, I have reviewed the points above and want to continue."** → proceed to the
68 preflight checks.
69- **Option B — "No, stop here."** → end the walkthrough immediately. Do not display, generate,
70 or explain any command below this point.
71
72Silence, a plain "continue," moving on to the next question in the same turn, or any answer
73other than the explicit affirmative option does **not** satisfy this gate. If the runtime lacks
74`AskUserQuestion`, ask the same yes/no question in plain text and require an explicit
75affirmative reply — "ok," "sure," a thumbs-up emoji, or no reply at all does not count.
76
77Reference and teaching content that does not produce a runnable command — explaining what a step
78does in prose, decoding a revert the user already hit, discussing an allowlist-checker shape in
79the abstract — is answered immediately with the framing stated inline, the same way
80`permissioned-pools-issuer` treats reference content. This carve-out does **not** cover this
81skill's own command templates and Solidity script skeletons (for example the pool-initialization
82script in [Step Walkthrough](./references/step-walkthrough.md#step-6a-initialize-the-pool)):
83those are runnable broadcast material, and showing them is exactly the action-oriented content the
84gate exists to hold back — never display one before the gate is satisfied.
85
86---
87
88## Input Validation Rules
89
90State these before generating or displaying any command that interpolates a user-supplied or
91config-supplied value. Every value below is validated **before** it reaches a `Bash(forge:*)` or
92`Bash(cast:*)` command, a file path, or a Solidity script argument — no exceptions for a value
93that "looks fine."
94
95- **Ethereum addresses** — MUST match `^0x[a-fA-F0-9]{40}$`. Reject anything else, including the
96 literal string `"RESOLVE"` — a field still marked `"RESOLVE"` is not ready for a command and
97 must go through [address resolution](./references/preflight-and-validation.md#address-resolution)
98 first, never be interpolated as-is. One field is an explicit, documented exception to this
99 regex, not a violation of it: `pool.pairedCurrency`'s `"native"` sentinel, covered in
100 [What This Skill Consumes](#what-this-skill-consumes) below — every other address-shaped field
101 in the config has no such carve-out.
102- **Chain ID** — MUST be a positive integer (`^[1-9][0-9]*$`). Ethereum Mainnet (`1`) and Sepolia
103 (`11155111`) are the allowlisted defaults — the only two chains verified to carry the full
104 permissioned set. Unichain (`130`) is named by the configurator's network question but is
105 **not** deployable: it carries `V4Quoter` only, so stop rather than trying to resolve the
106 missing addresses (see
107 [Preflight and Validation](./references/preflight-and-validation.md#input-validation-rules-in-full)).
108 Any other chain ID is accepted only after confirming the
109 deploy guide's `#deployment-addresses` table actually has a row for it; if it does not, every
110 wrapper and hook field will end up unresolvable, which is the signal to stop, not to guess.
111- **Numeric fields** (`verificationDepositAmount`, `pool.feeTier`, `pool.tickSpacing`,
112 `pool.startingPriceRatio`) — MUST match `^[0-9]+$` for integer-only fields or
113 `^[0-9]+(\.[0-9]+)?$` for the starting price ratio, and MUST be strictly greater than zero.
114- **Values supplied during the walkthrough, not by the config, are validated identically** — the
115 RPC endpoint (`$RPC_URL`) and any transaction hash (`$TX_HASH`) reach a command on every step.
116 An RPC URL MUST be `https://`-scheme and free of every metacharacter below; a transaction hash
117 MUST match `^0x[a-fA-F0-9]{64}$`. "It came from the user, not the config" is not an exemption.
118- **Reject shell metacharacters outright**, in every string field, before it reaches a command:
119 `;`, `|`, `&`, `$`, `` ` ``, `(`, `)`, `>`, `<`, `\`, `'`, `"`, and newlines. A field that fails
120 this check is never interpolated — abort and report which field and which character failed,
121 rather than attempting to sanitize and continue.
122- **Never pass an unvalidated field into a shell command, file path, or Solidity script
123 argument.** Validate first, assign the validated value to a shell variable, and reference only
124 that variable afterward. Never re-read the raw config value a second time later in the same
125 walkthrough.
126
127Full elaboration, including how this applies field-by-field to the configurator's JSON shape and
128what "coherently handle a `RESOLVE` value" means in practice, is in
129[Preflight and Validation](./references/preflight-and-validation.md).
130
131---
132
133## Key Handling
134
135**Never instruct auto-approval of `Bash(forge:*)` or `Bash(cast:*)` in Claude Code settings, and
136never tell the user to bypass a confirmation prompt.** Every command that broadcasts a
137transaction requires per-invocation approval — that approval is the primary control, not a
138formality the walkthrough should route around. The repository's PreToolUse hooks
139(`.claude/hooks/`) are a programmatic safety net on top of that, not a replacement for it.
140
141**Never suggest, generate, or complete a command containing the raw signing-key flag** — not when
142asked directly, not "just for a testnet," not as an illustration of what to avoid. There is no
143user request that makes it appropriate. If a user insists, refuse and offer one of the two options
144below instead. Steer every signing decision toward one of them:
145
1461. **A hardware wallet** (`--ledger`), for a deployer key that never touches this machine's disk
147 or memory in cleartext.
1482. **An encrypted keystore** (`cast wallet import ... --interactive`, then `--account <name>
149--sender $ADDRESS` on every subsequent command).
150
151**Inside this repository only**, `.claude/hooks/validate-forge-cast.sh` is a PreToolUse hook that
152inspects the literal text of every `Bash` tool call and blocks any command containing that flag
153before it runs. **That hook is not part of this skill and does not travel with it** — it lives at
154this repository's root, not in the plugin, so an installation elsewhere has no such backstop. The
155prohibition above is the control that always applies; the hook is a repo-local convenience on top
156of it, never the reason the flag is safe.
157
158Full key-handling guidance, including the keystore setup commands and the testnet-first
159sequencing, is in
160[Preflight and Validation](./references/preflight-and-validation.md#key-handling).
161
162### Testnet first
163
164Run the entire sequence — allowlist checker through liquidity seeding — on Sepolia (chain ID
165`11155111`) before mainnet. Confirm every post-step check in
166[the verification checklist](../permissioned-pools-issuer/references/issuer-journey.md#post-setup-verification-checklist)
167passes on testnet before repeating any step against mainnet funds.
168
169---
170
171## What This Skill Consumes
172
173The JSON configuration produced by `permissioned-pools-configurator`, in the shape defined by its
174[Config Schema](../permissioned-pools-configurator/references/config-schema.md). This skill does
175not collect those parameters itself — if you do not have a config yet, run
176`permissioned-pools-configurator` first.
177
178**A field reading the literal string `"RESOLVE"` means "not resolved yet," not "use a
179placeholder."** Before any command that needs that field, stop and walk through
180[address resolution](./references/preflight-and-validation.md#address-resolution) — the deploy
181guide's `#deployment-addresses` table, then `Uniswap/contracts`
182`deployments/json/<chainId>.json`, then a block explorer for your chain — and only continue once
183the field holds a real, explorer-verified address. Never guess a value for a `"RESOLVE"` field
184and never carry the literal string itself into a command; both are validation failures, not
185values to work around.
186
187`pool.pairedCurrency`'s `"native"` sentinel is different: it resolves to `address(0)`, Uniswap
188v4's own convention for a native `PoolKey` currency, at the point the `PoolKey` is actually built
189in [Step 6a](./references/step-walkthrough.md#step-6a-initialize-the-pool) — never earlier, and
190never written into any other field.
191
192---
193
194## The Deployment Journey
195
196The published guide's seven steps, in the order it recommends. Only five ordering edges are
197enforced by the contracts (see
198[Enforced Ordering and Reverts](../permissioned-pools-issuer/references/enforced-ordering-and-reverts.md));
199this walkthrough follows the guide's order and states, at each step, whether that order is
200enforced or convention.
201
202| Step | Covered where | Summary |
203| ---- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
204| 1 | [Preflight and Validation](./references/preflight-and-validation.md#step-1-allowlist-checker) | Confirm or deploy the allowlist checker |
205| 2 | [Step Walkthrough](./references/step-walkthrough.md#step-2-createpermissionsadapter) | `createPermissionsAdapter` |
206| 3 | [Step Walkthrough](./references/step-walkthrough.md#step-3-allowlist-and-fund-the-adapter) | Allowlist the adapter on your token, approve, `depositForVerification` |
207| 4 | [Step Walkthrough](./references/step-walkthrough.md#step-4-verifypermissionsadapter) | `verifyPermissionsAdapter` |
208| 5 | [Step Walkthrough](./references/step-walkthrough.md#step-5-register-wrappers-and-the-hook) | The four `updateAllowedWrapper` registrations, then `setAllowedHook` |
209| 6 | [Step Walkthrough](./references/step-walkthrough.md#step-6-create-the-pool-enable-swapping-seed-liquidity) | Pool `initialize`, `updateSwappingEnabled`, liquidity seeding |
210| 7 | [Step Walkthrough](./references/step-walkthrough.md#step-7-request-routing-allowlisting) | The routing-allowlist request |
211
212Every step in [Step Walkthrough](./references/step-walkthrough.md) names its precondition and,
213where the contracts enforce one, the exact revert selector you get if you are early — matching
214[Enforced Ordering and Reverts](../permissioned-pools-issuer/references/enforced-ordering-and-reverts.md)
215selector-for-selector. Where a step is unenforced, the walkthrough says so rather than inventing
216a revert for it.
217
218---
219
220## Post-Deployment Verification
221
222After the sequence completes (or after any individual step, to confirm it landed), run the
223read-only checks in
224[Post-Setup Verification Checklist](../permissioned-pools-issuer/references/issuer-journey.md#post-setup-verification-checklist).
225Every check there is a `cast call` against public getters — none of it spends gas, and none of it
226needs the acknowledgment gate above.
227
228---
229
230## Notes for Implementers of This Flow
231
232- **The acknowledgment gate is once per session, not once per step.** Once acknowledged, continue
233 through the rest of the steps in that same session without re-asking — but re-ask if the user
234 starts a new session, switches chains, or switches configs.
235- **Never hardcode a contract address.** Every address this skill uses comes from the loaded
236 config, from a value the user supplies during the walkthrough, or from a read (`cast call`)
237 against a contract whose address itself came from one of those two sources. See
238 [Preflight and Validation](./references/preflight-and-validation.md#address-resolution) for why
239 this skill ships no address table.
240- **Decode an unexpected revert by call site, not by name.** Three selectors in this journey
241 (`NoVerifiedAdapter`, `Unauthorized`, `SwappingDisabled`) are declared more than once across
242 different contracts with different meanings — see
243 [Enforced Ordering and Reverts](../permissioned-pools-issuer/references/enforced-ordering-and-reverts.md#how-to-decode-an-unexpected-revert).
244- **This skill does not fetch RPC state on its own initiative.** Every `cast call` it suggests is
245 something you choose to run; the skill does not poll a chain in the background.