The post-change validation contract for warp routes — after any step that changes (or proposes) on-chain state, prove the route's config matches the target via hyperlane warp check. Run a live check when the change already executed (deployer-signed); run a fork-simulate-from-owner check via /warp-route-check when the change is pending multisig/file execution. Referenced by every deploy/update skill that mutates a route.
Scanned 9/12/2026
Install to Claude Code
npx -y skills add hyperlane-xyz/hyperlane-monorepo --skill warp-verify-onchain-config --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Warp Verify Onchain Config?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/hyperlane-xyz-warp-verify-onchain-config)More formats (shields.io, HTML) on the badges page.
---
name: warp-verify-onchain-config
description: The post-change validation contract for warp routes — after any step that changes (or proposes) on-chain state, prove the route's config matches the target via hyperlane warp check. Run a live check when the change already executed (deployer-signed); run a fork-simulate-from-owner check via /warp-route-check when the change is pending multisig/file execution. Referenced by every deploy/update skill that mutates a route.
---
# Verify On-Chain Warp Config After a Change
Every on-chain-changing step in the deploy/update chain must be followed by a validation that the route's config is **exactly** the target — never assume `warp apply` / `warp deploy` "just worked". A silent misconfiguration (wrong owner, wrong ISM threshold, an enrollment that reverted, a fee on the wrong contract) is far cheaper to catch here than after the route is live. This skill is the single contract for that check so every caller does it the same way.
## The rule
After a step mutates route state — a deploy, an ownership transfer, a `warp apply`, a fee/ISM/hook change, a chain extension — validate config against the target **before** treating the step as done. How you validate depends on whether the change has actually executed on-chain yet.
## Mode A — the change executed now (deployer-signed / `jsonRpc`)
The txs were signed by the deployer key and are already mined (fresh deploys, ownership transfers to real owners, any deployer-executed `warp apply`). Validate against **live** on-chain state:
```bash
# Comprehensive: every contract in the route vs the target deploy.yaml
pnpm --silent -C typescript/cli hyperlane warp check \
--registry <registry> \
--warp-route-id <WARP_ROUTE_ID>
```
If any owner is an ICA, additionally run the ICA-aware check (additive):
```bash
pnpm --silent -C typescript/cli hyperlane warp check --ica \
--origin <ICA_ORIGIN_CHAIN> \
--originOwner <CONTROLLING_OWNER_ON_ORIGIN> \
--chains <route-chains>
```
`--originOwner` is REQUIRED when the ICA's origin chain is NOT one of the route chains (otherwise the CLI errors `Origin chain <name> does not have an owner configured`); safest to always pass it. **No violations = on-chain matches the target.** Violations ⇒ the change did not land as intended — stop and investigate; do NOT proceed to the registry PR / monitor / next step.
## Mode B — the change is pending multisig / file execution
The `warp apply` emitted a Safe TX Builder batch / Squads instructions / a `file`-submitter batch that a human still has to sign + execute. A live `warp check` would (correctly) report violations because nothing has executed yet — so validate two ways instead:
1. **Up-front, on a fork (simulate execution from the owner):** run `/warp-route-check` — it forks each chain, queries each target's **current on-chain `owner()`** and `anvil_impersonateAccount`s it (multisig / timelock included), replays the batch calldata from those addresses, self-relays any ICA messages, then runs `warp check` on the fork against the target. This proves the batch we generated yields the expected config, with no signatures required. This is the hard gate before proposing.
**Owner-changing batches — a PASS is NOT sufficient on its own.** `/warp-route-check` tolerates ownership mismatches on the chains it touches (it impersonates the _existing_ owner to replay, and does not fail on the owner field alone), so a batch that is supposed to change an owner can PASS its functional checks without the fork proving the new owner landed. When the batch changes any `owner`, additionally assert on the fork that the post-replay `owner()` equals the target owner (`cast call <artifact> "owner()(address)"` against the fork), and treat a mismatch as a failure. If you cannot make that explicit owner assertion, do NOT report the owner change as fork-verified — rely on the post-execution registry-PR CI in step 2 for it.
2. **Post-execution, on the real chain:** the registry PR's `check-warp-deploy.yaml` CI runs `warp check` against live state on every push and only goes green **after** the signers execute the proposals. That is the real-chain confirmation; open the PR immediately (the deploy.yaml already reflects the target) and let CI green once execution lands — sometimes hours/days later.
Mode B's fork check is your suggestion made routine: you get the "config == expected" answer immediately by simulating the multisig, and the CI catches any divergence between the proposed batch and what the signers actually executed.
**Current implementation limitation — fail closed, don't over-claim.** `/warp-route-check` today ingests a **single flat EVM transactions file** (it parses a top-level array of `{chainId, to, …}` and decodes EVM calldata). It does **not** yet accept a receipts _directory_, Safe-TX-Builder object receipts (`{version, chainId, transactions: […]}`), SVM receipt arrays (base58 tx blobs), or distinguish already-executed `jsonRpc` batches from pending governance batches. So the Mode-B fork gate is authoritative **only** for a single-file EVM batch. For a receipts directory, a Safe-object batch, or any SVM batch, the fork gate **cannot run** — do NOT report those as fork-verified; fail closed (surface the batch for manual verification and rely on the post-execution registry-PR CI in step 2). Reconciling `/warp-route-check` to the receipts-directory format is tracked as part-2 work.
## Picking the mode per batch
A single run can produce BOTH kinds of batch — e.g. a `warp apply` that deploys a new contract deployer-signed (Mode A) AND emits a Safe batch for an ownership change (Mode B). Verify each batch by how it executes: live-check the deployer-executed parts now, fork-check + CI the multisig parts.
## Consumers
`/warp-deploy-update-owners` (Mode A — live check after the deployer-signed transfer), `/warp-update` (Mode A for deployer-executed batches, Mode B for multisig batches), `/warp-update-extend` (Mode B — fork-simulate-from-customer-multisig before shipping tx files). `/warp-route-check` is the Mode-B fork implementation; `/fetch-safe-tx-batch` feeds it a pending Safe batch.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!