chore(deployments): point the default UniversalRouter key at 2.1.2 on all chains - #169
Merged
Merged
Conversation
… 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
approved these changes
Sep 22, 2026
ericneil-sanc
left a comment
Contributor
There was a problem hiding this comment.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The unversioned
UniversalRouterkey 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:Two separate problems were in play:
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.So
UniversalRouterresolved 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.2entries are untouched, so pinning a specific version still works; the bare key is now a pointer to the current recommended router.Not covered
0x3ae6d8a282d67893e17aa70eBfFb33EE5aa65893. Needs a deploy, not a registry edit.UniversalRouterrecorded at all (V3-only deployment).main, independent of this change:deployments/11155111.mdhas no## Contractsbody, 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:
UniversalRouterentry is byte-identical to that chain'sUniversalRouter#v2.1.2entry (address,deploymentTxn,initcodeHash,timestamp,commitHash) — 23/23HEADmove by exactly 0 or 1 as expected:## Deployment History,<details>,</table>,<tr>,###,---HEADpre-commit run --files <changed>passes all three hooksWhy hand-edited rather than regenerated
script/util/regenerate_deployment_markdown.pyis not idempotent on this tree — running it with zero JSON changes still rewrites1.md(31+/24-): it reorders rows, re-adds a dropped history entry, and rewrites commit links fromhttps://github.com/Uniswap/universal-router/commit/802fe4ctogit@github.com:Uniswap/contracts/commit/802fe4c, becauseforge-chroniclesderives that URL from the local git remote. Hand-editing keeps the diff to exactly the alias. Worth fixing separately.CI note
mainis currently red, but on push/schedule workflows (Update Submodules, Push Briefcase, Deploy to Tenderly) — not the PR gates.verify-briefcasehas failed on every run since 2025 and is unrelated.pre-commitis the meaningful check and passes.One caveat from
forge fmt: runningpre-commit run --all-fileslocally reformats 5 pre-existing.solfiles undersrc/briefcase/. That's a Foundry version artifact — local 1.8.1 vs the v1.5.0 thatpre-commit.yamlpins — and those files are not in this commit.Maintenance note
applyDuplicateTagsinlib/forge-chronicles/extractor.jspreserves 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