Skip to content

feat(multichain): HyperEVM token-owner Safe pin plumbing (RAI-1511) - #275

Merged
thedavidmeister merged 2 commits into
mainfrom
feat/hyperevm-safe-pin
Aug 10, 2026
Merged

feat(multichain): HyperEVM token-owner Safe pin plumbing (RAI-1511)#275
thedavidmeister merged 2 commits into
mainfrom
feat/hyperevm-safe-pin

Conversation

@hardyjosh

@hardyjosh hardyjosh commented Jul 22, 2026

Copy link
Copy Markdown
Contributor
  • STOX_TOKEN_OWNER_SAFE_HYPEREVM = address(0) until the freshly-created
    HyperEVM Safe's address lands (canonical Safe v1.4.1 infra verified live
    on HyperEVM at the canonical addresses, 2026-07-22).
  • safeForChainId branch for chain 999 — every consumer of
    assertActiveChainTokenOwnerSafe becomes HyperEVM-aware the moment the
    pin hydrates, with zero further code changes.
  • HyperEvmTokenOwnerSafeParityTest, mirroring the Ethereum parity pin:
    PENDING (loud) while the pin is unhydrated, then asserts the shared
    policy against the live HyperEVM Safe. Second loud PENDING gate on the
    RPC env: the shared rainix test workflow has no HyperEVM secret slot
    yet, so CI cannot fork HyperEVM until rainix grows one (noted for
    follow-up in RAI-1511).

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

Summary by CodeRabbit

  • New Features

    • Added support for resolving the designated token-owner Safe on HyperEVM.
    • Added HyperEVM chain configuration for scheduled and standard validation workflows.
  • Tests

    • Added validation confirming the HyperEVM token-owner Safe matches the required owners, approval threshold, and identity policy.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The change adds HyperEVM Safe address routing for chain ID 999, validates the pinned Safe against shared invariants on a fork, and passes the HyperEVM RPC secret to Rainix workflows.

Changes

HyperEVM Safe support

Layer / File(s) Summary
HyperEVM Safe routing
src/lib/LibSafeInvariants.sol
The library defines the HyperEVM token-owner Safe address and returns it for chain ID 999.
Parity validation and fork CI
test/src/concrete/deploy/HyperEvmTokenOwnerSafeParity.t.sol, .github/workflows/rainix-sol.yaml, .github/workflows/rainix-sol-scheduled.yaml
The fork test checks the Safe owner set, threshold, and identity policy. Both Rainix workflows pass RPC_URL_HYPEREVM_FORK.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: thedavidmeister

Poem

A rabbit checks the Safe at night,
Chain nine-nine-nine resolves just right.
The fork confirms each owner’s place,
Rainix carries RPC grace.
Hop, hop—HyperEVM joins the race!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the HyperEVM token-owner Safe plumbing, which is the main change in the pull request.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/hyperevm-safe-pin

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 feat/hyperevm-authoriser-pin branch from c61c4b9 to 8e010e5 Compare July 23, 2026 14:14
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-safe-pin branch from 75a463a to 773cda8 Compare July 23, 2026 14:14
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-authoriser-pin branch from 8e010e5 to 9b894c3 Compare July 23, 2026 22:33
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-safe-pin branch from 773cda8 to 9777630 Compare July 23, 2026 22:33
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-authoriser-pin branch from 9b894c3 to bb342c0 Compare July 23, 2026 23:05
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-safe-pin branch 2 times, most recently from 7865d57 to f3df426 Compare July 23, 2026 23:06
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-authoriser-pin branch from bb342c0 to 3e90fed Compare July 23, 2026 23:06
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-safe-pin branch from f3df426 to d8b790b Compare July 24, 2026 11:20
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-authoriser-pin branch from 3e90fed to b14ffe4 Compare July 24, 2026 11:20
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-safe-pin branch from d8b790b to 6751d21 Compare July 24, 2026 12:21
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-authoriser-pin branch from b14ffe4 to 54e4482 Compare July 24, 2026 12:21
@thedavidmeister
thedavidmeister force-pushed the feat/hyperevm-authoriser-pin branch 2 times, most recently from eaea4fe to bc35fb2 Compare July 24, 2026 13:46
@thedavidmeister
thedavidmeister force-pushed the feat/hyperevm-safe-pin branch from 6751d21 to 95b64ee Compare July 24, 2026 13:46
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-safe-pin branch from 95b64ee to f448568 Compare July 24, 2026 14:25
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-authoriser-pin branch from bc35fb2 to 860e444 Compare July 24, 2026 14:25
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-authoriser-pin branch from 860e444 to a4014f5 Compare July 24, 2026 14:29
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-safe-pin branch 2 times, most recently from 56c25f9 to fcb3b38 Compare July 24, 2026 15:00
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-safe-pin branch from b110fc7 to db861f0 Compare August 10, 2026 09:18
@hardyjosh
hardyjosh changed the base branch from graphite-base/275 to feat/hyperevm-authoriser-pin August 10, 2026 09:18
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-authoriser-pin branch from fa517d7 to b4ea3ba Compare August 10, 2026 10:03
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-safe-pin branch from db861f0 to b110fc7 Compare August 10, 2026 10:03
@hardyjosh
hardyjosh changed the base branch from feat/hyperevm-authoriser-pin to graphite-base/275 August 10, 2026 10:04
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-safe-pin branch from b110fc7 to db861f0 Compare August 10, 2026 10:18
@hardyjosh
hardyjosh changed the base branch from graphite-base/275 to feat/hyperevm-authoriser-pin August 10, 2026 10:18
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-authoriser-pin branch 2 times, most recently from f6dee27 to b814c8e Compare August 10, 2026 11:04
- STOX_TOKEN_OWNER_SAFE_HYPEREVM = address(0) until the freshly-created
  HyperEVM Safe's address lands (canonical Safe v1.4.1 infra verified live
  on HyperEVM at the canonical addresses, 2026-07-22).
- safeForChainId branch for chain 999 — every consumer of
  assertActiveChainTokenOwnerSafe becomes HyperEVM-aware the moment the
  pin hydrates, with zero further code changes.
- HyperEvmTokenOwnerSafeParityTest, mirroring the Ethereum parity pin:
  PENDING (loud) while the pin is unhydrated, then asserts the shared
  policy against the live HyperEVM Safe. Second loud PENDING gate on the
  RPC env: the shared rainix test workflow has no HyperEVM secret slot
  yet, so CI cannot fork HyperEVM until rainix grows one (noted for
  follow-up in RAI-1511).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VPs1hCTxusmaSeFKvoc4Kr
@hardyjosh
hardyjosh force-pushed the feat/hyperevm-safe-pin branch from db861f0 to 52076bd Compare August 10, 2026 11:04
@thedavidmeister
thedavidmeister changed the base branch from feat/hyperevm-authoriser-pin to main August 10, 2026 11:29
rainix's reusable rainix-sol.yaml already declares RPC_URL_HYPEREVM_FORK
(and binds it to RAINIX_RPC_SECRET_HYPEREVM in the rpc-preflight step);
this repo's two callers just never passed it through, so HYPEREVM_RPC_URL
was absent in CI. Added the one missing pass-through line to both
rainix-sol.yaml and rainix-sol-scheduled.yaml.

With the secret carried, both PENDING return guards in
HyperEvmTokenOwnerSafeParityTest go: the address guard was already dead
(STOX_TOKEN_OWNER_SAFE_HYPEREVM ships non-zero) and the RPC guard turned
a missing fork endpoint into a silent pass. The test is now
fork-and-assert unconditionally, so a missing RPC is a hard failure.

Docstring follows the code: the pending-gate prose is gone, and the
claim that the HyperEVM Safe "is a distinct address from the other
chains' Safes" is corrected — it is byte-identical to
STOX_TOKEN_OWNER_SAFE_ETHEREUM by design, as the constant's own doc says,
because the canonical Safe proxy factory with the same initializer gives
the same CREATE2 address across chains.

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

Copy link
Copy Markdown
Contributor

Forwarded the HyperEVM RPC secret; the parity test now actually runs

Head is now 9f18d50fa8afac41cfa53011085fbe3b6837787b. Two changes.

1. RPC_URL_HYPEREVM_FORK pass-through

rainix's reusable workflow already declares the slot — rainix-sol.yaml line 21 in rainlanguage/rainix, forwarded to rainix-sol-test.yaml line 21, where the rpc-preflight step binds RAINIX_RPC_SECRET_HYPEREVM / RAINIX_RPC_VARS_HYPEREVM (lines 80-81). This repo's callers just never passed it through, so HYPEREVM_RPC_URL was absent in CI. One line added to each of the two callers, in the existing alphabetical position between FLARE and POLYGON:

.github/workflows/rainix-sol.yaml
.github/workflows/rainix-sol-scheduled.yaml

      RPC_URL_HYPEREVM_FORK: ${{ secrets.RPC_URL_HYPEREVM_FORK }}

The scheduled workflow had the identical omission, so it is fixed too — a daily parity re-run that silently skips HyperEVM is exactly the drift this workflow exists to catch.

2. Both PENDING return guards deleted from HyperEvmTokenOwnerSafeParity.t.sol

  • The hyperevmSafe == address(0) guard was already dead code: STOX_TOKEN_OWNER_SAFE_HYPEREVM ships non-zero at 0x3840aeDaEc8e82f79d8F6a8F6ADCa271E13E0329.
  • The HYPEREVM_RPC_URL guard turned a missing fork endpoint into a silent pass. With the secret carried, that skip is what the docstring itself asked to remove.

The test is now fork-and-assert unconditionally, and the docstring follows the code — the pending-gate prose is gone.

Also corrected a false claim in the same docstring: it said the HyperEVM Safe "is a distinct address from the other chains' Safes". It is not. STOX_TOKEN_OWNER_SAFE_HYPEREVM is byte-identical to STOX_TOKEN_OWNER_SAFE_ETHEREUM (both 0x3840aeDa…), deliberately — the canonical Safe proxy factory with the same initializer yields the same CREATE2 address across chains, exactly as LibSafeInvariants.sol line 216-223 documents twelve lines from the constant. The test asserts no distinctness anywhere, so nothing but the prose was wrong. (Note the sibling EthereumTokenOwnerSafeParityTest does assert distinctness from Base, and correctly so — that Safe genuinely is a distinct per-chain address. Only the HyperEVM copy of the sentence was wrong.)

LibSafeInvariants.sol is untouched by this push — no constant changed, no change to the assertTokenOwnerSafePolicy call.

Live-run evidence

Preflight, confirming the Safe proxy genuinely exists on HyperEVM (chain id 0x3e7 = 999):

$ curl -s -X POST -H 'Content-Type: application/json' \
    --data '{"jsonrpc":"2.0","id":1,"method":"eth_getCode","params":["0x3840aeDaEc8e82f79d8F6a8F6ADCa271E13E0329","latest"]}' \
    https://rpc.hyperliquid.xyz/evm
{"jsonrpc":"2.0","id":1,"result":"0x608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e…"}

That is the Safe v1.4.1 SafeProxy runtime bytecode, not an empty account.

The test, against live HyperEVM state, in the repo's own CI toolchain:

$ HYPEREVM_RPC_URL=https://rpc.hyperliquid.xyz/evm \
  nix develop github:rainlanguage/rainix/53e96a7d0a97d7c7c75c3b2412521324776fdac6#sol-shell \
    -c forge test --match-path 'test/src/concrete/deploy/HyperEvmTokenOwnerSafeParity.t.sol' -vvv

Compiling 183 files with Solc 0.8.25
Solc 0.8.25 finished in 5.73s
Compiler run successful!

Ran 1 test for test/src/concrete/deploy/HyperEvmTokenOwnerSafeParity.t.sol:HyperEvmTokenOwnerSafeParityTest
[PASS] testHyperEvmSafeMatchesSharedPolicy() (gas: 58694)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.51s (5.51s CPU time)

assertTokenOwnerSafePolicy passes on live HyperEVM state: owner set (order-insensitive), threshold, v1.4.1 identity. The gas figure is the tell that it really forked and made the calls rather than returning early.

And the negative case, proving the skip is genuinely gone — same command with HYPEREVM_RPC_URL unset:

[FAIL: vm.createSelectFork: environment variable `HYPEREVM_RPC_URL` not found] testHyperEvmSafeMatchesSharedPolicy() (gas: 3188)
Suite result: FAILED. 0 passed; 1 failed; 0 skipped

A missing RPC is now a hard failure instead of a green skip, which is the whole point of the change. Full-project compile (183 files) succeeded and forge fmt --check is clean.

Raised, not fixed

Nothing blocking. One observation: this branch's CI has never had a HyperEVM RPC, so the run on 9f18d50 is the first time this test executes in CI — if the repo secret RPC_URL_HYPEREVM_FORK is not actually populated, the job will now go red rather than skip. That is the intended behaviour, but it is worth watching the first run rather than assuming.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/src/concrete/deploy/HyperEvmTokenOwnerSafeParity.t.sol`:
- Around line 25-26: Update the HyperEVM parity test to assert block.chainid
equals LibSafeInvariants.HYPEREVM_CHAIN_ID, resolve the Safe via
assertActiveChainTokenOwnerSafe(block.chainid), and compare the resolved address
against both pinned Safe addresses instead of reading
STOX_TOKEN_OWNER_SAFE_HYPEREVM directly.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 63b5725a-ee6a-45d8-936b-bf6b4f7c3187

📥 Commits

Reviewing files that changed from the base of the PR and between 13d77f3 and 9f18d50.

📒 Files selected for processing (4)
  • .github/workflows/rainix-sol-scheduled.yaml
  • .github/workflows/rainix-sol.yaml
  • src/lib/LibSafeInvariants.sol
  • test/src/concrete/deploy/HyperEvmTokenOwnerSafeParity.t.sol

Comment on lines +25 to +26
vm.createSelectFork(LibStoxDeployNetworks.HYPEREVM);
LibSafeInvariants.assertTokenOwnerSafePolicy(IGnosisSafe(hyperevmSafe));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Exercise the HyperEVM routing path in this parity test.

The production consumer in src/lib/LibInvariants.sol:45-54 resolves the Safe through assertActiveChainTokenOwnerSafe, but this test reads STOX_TOKEN_OWNER_SAFE_HYPEREVM directly. A broken safeForChainId(999) branch can pass this test. Because the HyperEVM and Ethereum pins share an address, an incorrectly selected Ethereum fork can also pass.

Assert block.chainid == LibSafeInvariants.HYPEREVM_CHAIN_ID, resolve the Safe through assertActiveChainTokenOwnerSafe(block.chainid), and compare the result with both pinned addresses.

Proposed fix
         vm.createSelectFork(LibStoxDeployNetworks.HYPEREVM);
-        LibSafeInvariants.assertTokenOwnerSafePolicy(IGnosisSafe(hyperevmSafe));
+        assertEq(block.chainid, LibSafeInvariants.HYPEREVM_CHAIN_ID);
+        IGnosisSafe resolvedSafe = IGnosisSafe(
+            LibSafeInvariants.assertActiveChainTokenOwnerSafe(block.chainid)
+        );
+        assertEq(address(resolvedSafe), hyperevmSafe);
+        assertEq(address(resolvedSafe), LibSafeInvariants.STOX_TOKEN_OWNER_SAFE_ETHEREUM);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
vm.createSelectFork(LibStoxDeployNetworks.HYPEREVM);
LibSafeInvariants.assertTokenOwnerSafePolicy(IGnosisSafe(hyperevmSafe));
vm.createSelectFork(LibStoxDeployNetworks.HYPEREVM);
assertEq(block.chainid, LibSafeInvariants.HYPEREVM_CHAIN_ID);
IGnosisSafe resolvedSafe = IGnosisSafe(
LibSafeInvariants.assertActiveChainTokenOwnerSafe(block.chainid)
);
assertEq(address(resolvedSafe), hyperevmSafe);
assertEq(address(resolvedSafe), LibSafeInvariants.STOX_TOKEN_OWNER_SAFE_ETHEREUM);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/src/concrete/deploy/HyperEvmTokenOwnerSafeParity.t.sol` around lines 25
- 26, Update the HyperEVM parity test to assert block.chainid equals
LibSafeInvariants.HYPEREVM_CHAIN_ID, resolve the Safe via
assertActiveChainTokenOwnerSafe(block.chainid), and compare the resolved address
against both pinned Safe addresses instead of reading
STOX_TOKEN_OWNER_SAFE_HYPEREVM directly.

@thedavidmeister

Copy link
Copy Markdown
Contributor

Reviewed 9f18d50: pass

The HyperEVM Safe pin, with the coverage now actually executing rather than skipping.

Verified against the chain, not the repo. eth_getCode on HyperEVM at 0x3840aeDaEc8e82f79d8F6a8F6ADCa271E13E0329 returns the Safe proxy runtime (0x608060527…a619486e, the masterCopy() selector), so the pinned Safe genuinely exists there. It is byte-identical to STOX_TOKEN_OWNER_SAFE_ETHEREUM deliberately: the canonical Safe proxy factory with the same initializer gives the same CREATE2 address across chains, exactly as the constant's own doc states.

Verified in CI, not only locally. rainix-sol / test on this head:

Ran 1 test for test/src/concrete/deploy/HyperEvmTokenOwnerSafeParity.t.sol:HyperEvmTokenOwnerSafeParityTest
[PASS] testHyperEvmSafeMatchesSharedPolicy() (gas: 58694)

Same gas as the local run against https://rpc.hyperliquid.xyz/evm, so the job forked live HyperEVM state and assertTokenOwnerSafePolicy held. This is the first CI run in which this test executes at all.

What changed since my first read, and why it matters. As originally written both branches returned early — an address(0) guard that was already dead (the constant ships non-zero) and an HYPEREVM_RPC_URL guard that always fired, because .github/workflows/rainix-sol.yaml forwards six RPC secrets to the shared rainix workflow and RPC_URL_HYPEREVM_FORK was not among them. rainix has declared that slot all along (rainix-sol.yaml line 21, bound as RAINIX_RPC_SECRET_HYPEREVM in its rpc-preflight step); only the caller was missing the pass-through. One line in each of rainix-sol.yaml and rainix-sol-scheduled.yaml — the scheduled workflow had the identical omission, and fixing one without the other would have left the nightly still skipping.

The skip is provably gone rather than merely edited: with HYPEREVM_RPC_URL unset the test now fails at vm.createSelectFork instead of logging PENDING and passing green.

One docstring correction. The contract's doc claimed the Safe "is a distinct address from the other chains' Safes". It is not, the test asserts no such thing, and the constant twelve lines away says the opposite. That false premise is precisely what led me to misread the sibling pin in #274 as a copy-paste defect before the chain corrected me — an identical address across chains reads as a bug unless something states it is deterministic. Now it does.

Rulings-conformance:

  • Enumerate authority from the chain, never from repo greps. OBEYED: every claim above rests on eth_getCode or a CI log, not on reading a constant.
  • Coverage, not manual verification. OBEYED, and this is the substance: a guard that returns early is not coverage, and the negative case was run to prove its removal bites.
  • Comments describe CURRENT behaviour only. OBEYED: the pending-gate prose went with the gates it described.
  • *.deploy repos are audited code, internally consistent. LibSafeInvariants.sol's constants and assertTokenOwnerSafePolicy are untouched.
  • Never invent scope. The sibling EthereumTokenOwnerSafeParityTest carries the same now-dead address(0) guard and was deliberately left alone — raised, not fixed.

CI: every check passes. Merging with --merge per the standing no-squash rule for Graphite stacks; 276 is based on this head branch and will need retargeting to main.

@thedavidmeister
thedavidmeister merged commit 1c4eceb into main Aug 10, 2026
7 checks passed
thedavidmeister pushed a commit that referenced this pull request Aug 10, 2026
Both premises the gates were waiting on are now false:
`STOX_TOKEN_OWNER_SAFE_HYPEREVM` is pinned non-zero, and #275 forwards
`RPC_URL_HYPEREVM_FORK` to the shared rainix workflow from both
`rainix-sol.yaml` and `rainix-sol-scheduled.yaml`, so `HYPEREVM_RPC_URL`
resolves in CI. The docstring's own condition — "Remove the env gate once
CI carries the secret" — is met, so the invariant now runs unconditionally
and the `@dev` paragraph documents that instead of the removed gates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
thedavidmeister added a commit that referenced this pull request Aug 10, 2026
The premise these guards stated — the shared rainix test workflow has no
HyperEVM secret slot, so CI cannot create the fork — is dead. #275 forwards
`RPC_URL_HYPEREVM_FORK` to the shared workflow and #276 deleted the identical
guards from `HyperEvmBeaconOwnership.t.sol` against a real fork.

They were fail-open: had the RPC lapsed, `testProdDeployHyperEvmV4` and the
HyperEVM half of `testCrossChainParity` would have gone green having asserted
nothing. Both now fork unconditionally, so a missing RPC fails at fork time.

`assertTrue(hyperRpcAvailable, ...)` in the parity deadline block goes with the
bool — a missing RPC is no longer something to detect later. The deadline and
its three leg assertions stay, as does every inner `base.X && hyper.X` gate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
thedavidmeister added a commit that referenced this pull request Aug 10, 2026
Brings in #274, #275 and #276. #275's `RPC_URL_HYPEREVM_FORK` forwarding in
`rainix-sol.yaml` is what lets this branch's own push run resolve the HyperEVM
alias from the secret rather than the rainix preflight's public default, so the
unconditional forks this branch introduces are exercised against the secret
path the new comments describe.
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.

3 participants