Skip to content

ops(script): HyperEVM token deploy (RAI-1511) - #278

Merged
thedavidmeister merged 6 commits into
mainfrom
ops/hyperevm-token-deploy
Aug 10, 2026
Merged

ops(script): HyperEVM token deploy (RAI-1511)#278
thedavidmeister merged 6 commits into
mainfrom
ops/hyperevm-token-deploy

Conversation

@hardyjosh

@hardyjosh hardyjosh commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

The HyperEVM token bootstrap (RAI-1511), landing as the provenance record of
a deploy that has already run: EXECUTED 2026-07-24 by manual-broadcast run
30114307165, which deployed all 29 canonical tokens, wired them onto the
HyperEVM V4 authoriser, and handed them to the HyperEVM Safe. The resulting
tuples are pinned in productionTokensHyperEvm() by #277.

The script is self-scoping — it joins the canonical config against
productionTokensHyperEvm() and selects only the all-zero rows — so against
the now fully-hydrated table _selectMissing() reverts NoMissingTokens.
It is therefore inert as merged: it cannot re-mint what it already deployed.
What it still carries is the record of how those 29 tokens came to exist,
plus live machinery for a token added to the canonical set later — such a
token lands as an all-zero HyperEVM row, and a re-dispatch picks it up
automatically with no edit to this script.

Per token, identical to the executed Ethereum flow: 0.1.1 unified deployer
(initialAdmin = deploy key) -> receipt readback -> setAuthorizer(HyperEVM
V4 authoriser) -> transferOwnership(HyperEVM Safe). Pre-flight hard-gates
encode the RAI-1511 ordering: 0.1.1 core deployed, in-use beacons
HyperEVM-Safe-owned (beacon-owner migration), authoriser pin hydrated,
Safe pin hydrated — an early dispatch is a typed revert, never a partial
deploy. Registered in manual-broadcast (dispatch on network = hyperevm).

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01VPs1hCTxusmaSeFKvoc4Kr

Summary by CodeRabbit

  • New Features

    • Added a deployment process for missing tokens on HyperEVM.
    • Validates deployment readiness and configuration before proceeding.
    • Automatically deploys, configures, and transfers ownership of missing tokens.
  • Bug Fixes

    • Added safeguards for unavailable infrastructure, invalid configuration, and already-complete token tables.
  • Tests

    • Added coverage for complete token tables and missing core deployments.
    • Enabled HyperEVM RPC access in scheduled and standard test workflows.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

HyperEVM gap-fill deployment

Layer / File(s) Summary
Selection and preflight validation
script/20260722-deploy-missing-tokens-hyperevm.s.sol, test/script/DeployMissingTokensHyperEvmHarness.sol, test/script/20260722-deploy-missing-tokens-hyperevm.t.sol
The script validates pinned HyperEVM infrastructure and selects all-zero token rows that match canonical configuration. Tests cover hydrated tables and missing core deployment.
Deployment and ownership wiring
script/20260722-deploy-missing-tokens-hyperevm.s.sol
The script deploys each missing token, configures receipt-vault authorization, transfers ownership to the Safe, and logs deployment tuples.
Workflow and RPC integration
.github/workflows/manual-broadcast.yaml, .github/workflows/rainix-sol-scheduled.yaml, .github/workflows/rainix-sol.yaml
The manual workflow registers the deployment script. Solidity workflows receive the HyperEVM fork RPC secret.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: thedavidmeister

Poem

I’m a rabbit with tokens to sow,
Through HyperEVM’s tables they go.
The Safe takes the keys,
Vaults wire with ease,
And workflows now help them all grow.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change as the HyperEVM token deployment script and includes the relevant issue identifier.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ops/hyperevm-token-deploy

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hardyjosh
hardyjosh force-pushed the pin/hyperevm-invariant-surface branch from e62574b to febb397 Compare July 23, 2026 14:14
@hardyjosh
hardyjosh force-pushed the ops/hyperevm-token-deploy branch 2 times, most recently from 8ada2a7 to 456dcf4 Compare July 23, 2026 22:33
@hardyjosh
hardyjosh force-pushed the pin/hyperevm-invariant-surface branch 2 times, most recently from 06a06a1 to 8dcc2c4 Compare July 23, 2026 23:05
@hardyjosh
hardyjosh force-pushed the ops/hyperevm-token-deploy branch 2 times, most recently from 5651ace to 12e57b0 Compare July 23, 2026 23:06
@hardyjosh
hardyjosh force-pushed the pin/hyperevm-invariant-surface branch 2 times, most recently from 103833b to 6a9b197 Compare July 24, 2026 11:20
@hardyjosh
hardyjosh force-pushed the ops/hyperevm-token-deploy branch 2 times, most recently from c3b9c96 to eb39cdb Compare July 24, 2026 12:21
@hardyjosh
hardyjosh force-pushed the pin/hyperevm-invariant-surface branch from 6a9b197 to 866cabe Compare July 24, 2026 12:21
@thedavidmeister
thedavidmeister force-pushed the pin/hyperevm-invariant-surface branch from 866cabe to 2d5c3bf Compare July 24, 2026 13:47
@thedavidmeister
thedavidmeister force-pushed the ops/hyperevm-token-deploy branch from eb39cdb to 2166e37 Compare July 24, 2026 13:48
@hardyjosh
hardyjosh force-pushed the pin/hyperevm-invariant-surface branch from 2d5c3bf to e421b17 Compare July 24, 2026 14:25
@hardyjosh
hardyjosh force-pushed the ops/hyperevm-token-deploy branch from 2166e37 to 939bc0a Compare July 24, 2026 14:25
@hardyjosh
hardyjosh force-pushed the ops/hyperevm-token-deploy branch from 939bc0a to 5e26954 Compare July 24, 2026 14:29
@hardyjosh
hardyjosh force-pushed the pin/hyperevm-invariant-surface branch from e421b17 to eb0a0a4 Compare July 24, 2026 14:29
@hardyjosh
hardyjosh force-pushed the ops/hyperevm-token-deploy branch from 5e26954 to 8b1ecb5 Compare July 24, 2026 15:00
@hardyjosh
hardyjosh force-pushed the pin/hyperevm-invariant-surface branch from eb0a0a4 to 7e515e4 Compare July 24, 2026 15:00
@hardyjosh
hardyjosh force-pushed the ops/hyperevm-token-deploy branch from 8b024bb to c95c9cf Compare August 10, 2026 09:18
@hardyjosh
hardyjosh force-pushed the pin/hyperevm-invariant-surface branch 2 times, most recently from 1117683 to 3548b6c Compare August 10, 2026 10:03
@hardyjosh
hardyjosh force-pushed the ops/hyperevm-token-deploy branch from c95c9cf to 6ce221a Compare August 10, 2026 10:03
@hardyjosh
hardyjosh force-pushed the pin/hyperevm-invariant-surface branch from 3548b6c to 1117683 Compare August 10, 2026 10:18
@hardyjosh
hardyjosh force-pushed the ops/hyperevm-token-deploy branch from 19c2376 to 8dc140c Compare August 10, 2026 10:18
@hardyjosh
hardyjosh force-pushed the pin/hyperevm-invariant-surface branch from 1117683 to 6e82100 Compare August 10, 2026 11:05
Josh Hardy and others added 5 commits August 10, 2026 11:06
The initial HyperEVM token bootstrap as a gap-fill: the same self-scoping
shape as the executed Ethereum gap-fill, joined against the (all-zero)
productionTokensHyperEvm() table — so the first dispatch deploys the whole
29-token canonical set, a partial failure recovers by re-dispatch, a token
added pre-execution is picked up automatically, and a fully-hydrated table
refuses to mint duplicates (NoMissingTokens).

Per token, identical to the executed Ethereum flow: 0.1.1 unified deployer
(initialAdmin = deploy key) -> receipt readback -> setAuthorizer(HyperEVM
V4 authoriser) -> transferOwnership(HyperEVM Safe). Pre-flight hard-gates
encode the RAI-1511 ordering: 0.1.1 core deployed, in-use beacons
HyperEVM-Safe-owned (beacon-owner migration), authoriser pin hydrated,
Safe pin hydrated — an early dispatch is a typed revert, never a partial
deploy. Registered in manual-broadcast (dispatch on `network = hyperevm`).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VPs1hCTxusmaSeFKvoc4Kr
rainix declares and consumes RPC_URL_HYPEREVM_FORK, but neither
rainix-sol.yaml nor rainix-sol-scheduled.yaml in this repo passed it, so
the reusable workflow fell back to its default and every HyperEVM fork test
hit the public rpc.hyperliquid.xyz endpoint — failing with rate limits
(-32005) on the token-table suites and invalid block heights on the parity
check. The repo secret being set had no effect because it was never
forwarded.

Unblocks the HyperEVM legs on both this stack and the governance-timelock
stack above it.
@hardyjosh
hardyjosh force-pushed the ops/hyperevm-token-deploy branch from 8dc140c to e259ff3 Compare August 10, 2026 11:06
@thedavidmeister
thedavidmeister changed the base branch from pin/hyperevm-invariant-surface to main August 10, 2026 13:06
The HyperEVM gap-fill was authored from its Ethereum sibling, and six doc
comments carried the source chain's name into text describing THIS script's
own subject: the NoMissingTokens and TokenTableMisaligned notices, the
tableUnderlying param, _assertAuthoriserReady (over a body returning
STOX_PROD_AUTHORISER_V4_CLONE_HYPEREVM), _selectMissing (over
productionTokensHyperEvm()), and run.

The deliberate cross-references are untouched: the contract NatSpec still
names 20260722-deploy-missing-tokens-ethereum as the shape this one copies,
the per-token flow is still described as identical to the executed Ethereum
flow, and ISetAuthorizer still points at the 20260706 script. Those name
other scripts on purpose.

Comments only — no executable Solidity, test, or workflow changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thedavidmeister

Copy link
Copy Markdown
Contributor

Two documentation defects fixed. No executable Solidity, test, or workflow changed — the diff is six /// lines.

1. Chain-name references corrected in script/20260722-deploy-missing-tokens-hyperevm.s.sol

The script was authored from its Ethereum sibling and carried the source chain's name into text describing its own subject. Six, not five — the @param tableUnderlying line was an extra one:

Line Was Context that makes it wrong
38 fully-hydrated Ethereum table entry NoMissingTokens is raised off the HyperEVM table
43 the Ethereum token table have drifted TokenTableMisaligned compares against the HyperEVM table
49 The Ethereum table's underlying at that row same error's @param tableUnderlying
96 Assert the Ethereum V4 authoriser body returns STOX_PROD_AUTHORISER_V4_CLONE_HYPEREVM
110 Ethereum table entry is all-zero body reads productionTokensHyperEvm()
146 still missing from the Ethereum table run() deploys against the HyperEVM table

Deliberately left alone, because they name a real other script rather than this one's subject:

  • the contract NatSpec naming 20260722-deploy-missing-tokens-ethereum as the shape this one copies (lines 62-63);
  • "identical to the executed Ethereum flow" (line 70), whose own clause then correctly says HyperEVM authoriser and HyperEVM Safe;
  • the ISetAuthorizer pointer at "the 20260706 script" (line 234).

"Ethereum" and "HyperEVM" are both 8 characters, so no comment re-wrapping was needed and every line stayed within its existing wrap.

2. PR body rewritten to describe the post-execution state

The body described a pre-execution world: it called the table "(all-zero)" and said "the first dispatch deploys the whole 29-token canonical set". Both were true when written and are false now — the deploy executed 2026-07-24 (manual-broadcast run 30114307165, a successful workflow_dispatch at 2026-07-24T17:46:18Z), and productionTokensHyperEvm() was pinned fully hydrated by #277 (8be65e553bf5d5027e4146838228cbd69614a834).

I verified the hydration directly rather than taking it on trust: all 29 rows are populated and the table contains zero zero-addresses, so _selectMissing() reverts NoMissingTokens and the script is inert as merged. That matches what testSelectionRevertsWhenTableFullyHydrated already asserts.

The rewritten body records the execution, the inertness, and the remaining value (provenance plus the machinery a late-added token would re-dispatch into), and keeps the pre-flight ordering paragraph, which is still accurate.

Gates

Run under the repo's own nix develop toolchain (forge 1.6.0-nightly):

  • forge build — pass
  • forge fmt --check — pass
  • forge test — pass
  • pre-commit run --all-files — the Solidity-relevant hooks pass. deadnix and nixfmt fail on flake.nix, which is byte-identical to main and untouched by this PR; CI's static job is green on the same file, so that is local toolchain drift, not a regression here.

Note for anyone reproducing locally: a fresh clone needs forge soldeer install before forge build, otherwise the build dies with several hundred unresolved-import errors.

@thedavidmeister

Copy link
Copy Markdown
Contributor

Reviewed 5248ac4: approve
Rulings-conformance: checked against every ruling stated for this work. (1) "agent both" on the two findings I raised — both fixed and nothing else: six /// lines corrected from Ethereum to HyperEVM (the agent found one more than my list of five — @param tableUnderlying at line 49, a second wrong reference inside TokenTableMisaligned), and the body rewritten to describe what this PR lands today rather than a pre-execution state. No executable Solidity, test or workflow logic touched. (2) "never invent scope" — the three deliberate cross-references to sibling scripts were left alone: 20260722-deploy-missing-tokens-ethereum in the contract NatSpec, "the 20260706 script" on ISetAuthorizer, and "identical to the executed Ethereum flow" at line 70, whose own clause correctly names the HyperEVM authoriser and Safe. The two findings I deliberately excluded — no pranked fork test over the state-changing half, and the transient hot-key initialAdmin = deploy key pattern — are untouched and unmentioned, and remain open decisions about the NEXT dispatch rather than the executed one. (3) "coverage, not manual verification" — the local forge test red was verified as a single class rather than waved through: 270 [FAIL: lines (forge prints each twice), all vm.createSelectFork: environment variable <CHAIN>_RPC_URL not found, enumerated against the completed log rather than a mid-run grep. Zero real failures; this PR's own two tests pass explicitly, and CI's test job is green here. (4) "verify all CI failures before admin-merge" — no red: all six checks SUCCESS, 0 unresolved threads. (5) "no squash-merge for Graphite stacks" — merging with --merge; this is the last of the RAI-1511 stack (274/275/276/277 already merged). (6) Workflow-change check: the RPC_URL_HYPEREVM_FORK lines in rainix-sol.yaml and rainix-sol-scheduled.yaml are already on main from #275 — both files are byte-identical to main at this head with exactly one occurrence of the key each, so there is no duplicate mapping key and the merge is a no-op for them. The only CI-config line this PR actually lands is the script name in manual-broadcast.yaml's dropdown; 'hyperevm' as a network and the HYPEREVM_RPC_URL mapping already exist there. (7) Provenance: EXECUTED 2026-07-24 is checkable — manual-broadcast run 30114307165 is a successful workflow_dispatch at 2026-07-24T17:46:18Z, and this PR is the record that #277's pinned table lacked. The script is inert as merged: _selectMissing() reverts NoMissingTokens against the hydrated table, which its own test asserts.

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