Skip to content

chore(deployments): point the default UniversalRouter key at 2.1.2 on all chains - #169

Merged
dianakocsis merged 1 commit into
mainfrom
fix/universal-router-default-key
Sep 22, 2026
Merged

dianakocsis merged 1 commit into
mainfrom
fix/universal-router-default-key

Conversation

@dianakocsis

Copy link
Copy Markdown
Contributor

Description

The unversioned UniversalRouter key is what the dev portal surfaces as the default router — it's the entry an integrator gets when they ask for "UniversalRouter" without pinning a version. It had drifted badly:

chains with a bare key what it pointed at
before this PR 16 a 2.1-generation deploy (v2.0 on ink + monad)
after this PR 23 that chain's 2.1.2 router

Two separate problems were in play:

  1. Stale on 15 chains. The bare key was the leftover untagged default from an older deploy. Constructor arity confirms the generation (9 params = v2.0, 10 params w/ spokePool = 2.1 family, 11 params w/ permissionsAdapterFactory = v2.2): 17 of 19 were 2.1-family, ink and monad were genuinely v2.0. None were 2.1.2.
  2. Missing on 8 chains. feat: deploy UniversalRouter 2.2.0 to mainnet, sepolia and ink #165 dropped it on mainnet, sepolia and ink; Add missing contracts and tag UniversalRouter versions for Base (8453) #134 / Deploy xlayer #123 / Ur2.0 deployment support #126 dropped it earlier on base, linea, x-layer, 4217 and 4326 when those routers were version-tagged.

So UniversalRouter resolved either to a router the 2.1.2 migration docs are telling integrators to move off, or to nothing at all, depending on the chain.

This aliases the bare key to each chain's 2.1.2 router on all 23 chains that have one — 8 added, 15 refreshed. The versioned UniversalRouter#v2.1.2 entries are untouched, so pinning a specific version still works; the bare key is now a pointer to the current recommended router.

⚠️ This supersedes the pre-#165 values rather than restoring them. The default has never pointed at 2.1.2 on any chain before now, so reviewers will see 23 changed addresses, not a revert.

Not covered

  • Monad testnet (10143) — no 2.1.2 deployed, so its default is still the v2.0 router at 0x3ae6d8a282d67893e17aa70eBfFb33EE5aa65893. Needs a deploy, not a registry edit.
  • Rootstock (30) — no UniversalRouter recorded at all (V3-only deployment).
  • Sepolia markdown is malformed on main, independent of this change: deployments/11155111.md has no ## Contracts body, just an orphan ### Universal Router (v2.1.2) section under a stray date heading. The summary-table row (what the portal reads) is correct; the body wants a separate regen cleanup.

How Has This Been Tested?

Registry-only change — no contract code touched, so the deployment checklist below doesn't apply.

Verified programmatically across all 26 chain files:

  • the bare UniversalRouter entry is byte-identical to that chain's UniversalRouter#v2.1.2 entry (address, deploymentTxn, initcodeHash, timestamp, commitHash) — 23/23
  • each markdown has exactly one bare summary-table row, detail section and TOC entry, all carrying the 2.1.2 address
  • structural counts vs HEAD move by exactly 0 or 1 as expected: ## Deployment History, <details>, </table>, <tr>, ###, ---
  • Deployment History is untouched on every chain
  • the 3 skipped chains (30, 1337, 10143) are byte-identical to HEAD
  • 15 refreshed chains have a zero line delta (pure in-place field updates); 8 added chains are +22 each
  • pre-commit run --files <changed> passes all three hooks

Why hand-edited rather than regenerated

script/util/regenerate_deployment_markdown.py is not idempotent on this tree — running it with zero JSON changes still rewrites 1.md (31+/24-): it reorders rows, re-adds a dropped history entry, and rewrites commit links from https://github.com/Uniswap/universal-router/commit/802fe4c to git@github.com:Uniswap/contracts/commit/802fe4c, because forge-chronicles derives that URL from the local git remote. Hand-editing keeps the diff to exactly the alias. Worth fixing separately.

CI note

main is currently red, but on push/schedule workflows (Update Submodules, Push Briefcase, Deploy to Tenderly) — not the PR gates. verify-briefcase has failed on every run since 2025 and is unrelated. pre-commit is the meaningful check and passes.

One caveat from forge fmt: running pre-commit run --all-files locally reformats 5 pre-existing .sol files under src/briefcase/. That's a Foundry version artifact — local 1.8.1 vs the v1.5.0 that pre-commit.yaml pins — and those files are not in this commit.

Maintenance note

applyDuplicateTags in lib/forge-chronicles/extractor.js preserves one untagged entry per base name, so the alias survives ordinary regens. Two things would collapse it: a run passing --tag-address 0x23617e59…:v2.1.2 (a user tag wins over an existing untagged key), or a new untagged router deploy overwriting the bare key — the latter is arguably the desired behavior, since the default would then follow the newest router. Worth deciding whether the bare key is maintained by hand each release or left to follow deploys.

🤖 Generated with Claude Code

… all chains

The unversioned `UniversalRouter` key is what the dev portal surfaces as the
default router, but it had drifted: on the 19 chains that still carried it, it
pointed at a 2.1-generation deploy (v2.0 on ink and monad), and on eight chains
it was missing entirely -- dropped by #165 on mainnet, sepolia and ink, and
earlier by #134/#123/#126 on base, linea, x-layer, 4217 and 4326 when those
routers were version-tagged.

So `UniversalRouter` resolved either to a router the 2.1.2 migration docs are
telling integrators to move off, or to nothing at all, depending on the chain.

Alias the bare key to each chain's 2.1.2 router on all 23 chains that have one
(8 added, 15 refreshed). The versioned `UniversalRouter#v2.1.2` entries are
untouched, so pinning a specific version still works; the bare key is now a
pointer to the current recommended router.

Note this supersedes the pre-#165 values rather than restoring them -- the
default has never pointed at 2.1.2 on any chain before now.

Edits are to the `latest` map in deployments/json/<chain>.json plus the matching
summary-table row, detail section and TOC entry in deployments/<chain>.md.
Deployment History is untouched. The markdown was hand-edited rather than
regenerated because regenerate_deployment_markdown.py is not idempotent on this
tree: it reorders rows, re-adds a dropped history entry, and rewrites commit
links to the git@ form derived from the local git remote.

Not covered: monad testnet (10143) has no 2.1.2 deployed, so its default is
still the v2.0 router at 0x3ae6d8a282d67893e17aa70eBfFb33EE5aa65893. Rootstock
(30) has no UniversalRouter at all. Both need a deploy, not a registry edit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@ericneil-sanc ericneil-sanc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spot-checked: bare UniversalRouter matches #v2.1.2 on all 23 chains, matches universal-router-sdk V2_1_2 constants, and verified on-chain (code present, deploy tx creates the address, initcodeHash matches) on 14 chains. LGTM.

@dianakocsis
dianakocsis merged commit 12e3736 into main Sep 22, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants