Skip to content

Ship the network-config check, behind one binding consumers keep - #155

Merged
thedavidmeister merged 1 commit into
mainfrom
151-ship-supported-networks-check
Aug 27, 2026
Merged

Ship the network-config check, behind one binding consumers keep#155
thedavidmeister merged 1 commit into
mainfrom
151-ship-supported-networks-check

Conversation

@thedavidmeister

Copy link
Copy Markdown
Contributor

Closes #151.

testSupportedNetworksAreFullyConfigured lived in test/src/lib/LibRainDeploy.t.sol, which .soldeerignore strips from the published package, so no consumer had it. Per the scope correction on the issue, moving it into a shipped abstract only makes it available — four repos would each owe a binding, and nothing red-lines the one that skips it. So this ships the check and the single entrypoint that makes it, and every check after it, arrive.

What shipped

  • src/abstract/RainDeployVerify.solabstract contract RainDeployVerify is RainDeployVerifyChain, RainDeployVerifySnapshot {}. The one contract a deploy repo binds. A check added to either half, or to the union, reaches every binder on a version bump with no downstream edit. The convention it carries: a new check goes into something this already inherits, never into an abstract beside it.
  • testSupportedNetworksAreFullyConfigured moved into src/abstract/RainDeployVerifySnapshot.sol — the network-free side, body unchanged. vm.readFile("foundry.toml") resolves against the project root of whatever runs it, so a consumer's binding reads the consumer's foundry.toml against this package's supportedNetworks().
  • LibStringSet moved test/lib/src/lib/ — a shipped abstract cannot depend on a stripped one. Four test imports follow it.
  • RegistryDeployChainTest + RegistryDeploySnapshotTestRegistryDeployVerifyTest — this repo's exemplar is now the same single line a consumer writes, so a check that does not reach the exemplar never shipped. Fork load is unchanged: one contract, seven forks, once.
  • slither.config.json gains the new abstract by exact filename, never by the src/abstract/ prefix. README documents the union, adds the config group to the verification table, and states the fs_permissions a consumer needs.

RainDeployVerifyChain and RainDeployVerifySnapshot stay separate contracts underneath. That split is runtime, not binding — the chain half forks every supported network, the snapshot half touches none — so a credential-free job can still bind and --match-contract the offline half.

Verified from a consumer's position

A check that only runs upstream is the defect being fixed, so the evidence is downstream, not here. All of it is against a clone of rain.tofu.erc20-decimals.deploy.

  1. It is in the package. forge soldeer push --dry-run produces a zip carrying src/abstract/RainDeployVerify.sol, src/abstract/RainDeployVerifySnapshot.sol and src/lib/LibStringSet.sol, and zero test/ entries.
  2. Base does not have it. With the published 0.1.7 dependency and that repo's existing Chain + Snapshot bindings, deleting flare from its [etherscan] leaves the suite green — 3 passed, 0 failed. That is the issue, reproduced downstream.
  3. A real consumer inherits it. The dry-run zip extracted over dependencies/rain-deploy-0.1.7/, the two bindings replaced with one is TOFUTokenDecimalsDeploySuites, RainDeployVerify {}: testSupportedNetworksAreFullyConfigured runs there and passes against that repo's own foundry.toml.
  4. The next check arrives without a downstream edit. A throwaway test function added to RainDeployVerify.sol inside the consumer's dependencies/ — no consumer source touched — showed up and ran in that consumer's bound contract on the next forge test. That is the property the issue asks for, demonstrated rather than asserted.

What each consumer must do

Nothing in this PR touches any consumer repo.

repo today to pick this up
rain.metadata.deploy binds Chain + Snapshot, rain-deploy 0.1.7 bump; replace MetaBoardDeployChainTest + MetaBoardDeploySnapshotTest with one MetaBoardDeployVerifyTest is MetaBoardDeploySuites, RainDeployVerify {}
rain.math.float.deploy binds Chain + Snapshot, rain-deploy 0.1.7 bump; same collapse over DecimalFloatDeploySuites
rain.tofu.erc20-decimals.deploy binds Chain + Snapshot, rain-deploy 0.1.7 bump; same collapse over TOFUTokenDecimalsDeploySuites
st0x.deploy binds neither, rain-deploy 0.1.4 bump from 0.1.4, then its first verification binding — one RainDeployVerify line. It deploys to Base, Ethereum and HyperEVM in production, so it is where a missing [etherscan] key costs the most: one unresolvable entry takes verification down for every entry, not only its own

All three of the first group already carry { access = "read", path = "./foundry.toml" } in fs_permissions; a repo that does not needs it, and fails loudly without it. Nothing here can be checked for st0x.deploy from this account — that row is from the issue.

Expect the bump to go red wherever a consumer has already drifted. That is the check working, and the version-bump PR is where it surfaces. Every check after this one is free.

QA

  • Discriminating tests: testSupportedNetworksAreFullyConfigured, now on RainDeployVerifySnapshot and therefore reached through RainDeployVerify. It fails on base in the only sense available to it: on base it does not exist downstream at all, so every mutation below passes silently there — verified by running the flare [etherscan] deletion against the pristine published 0.1.7 dependency and the consumer's own Chain + Snapshot bindings, which stayed green (3 passed, 0 failed). Upstream it also runs in RegistryDeployVerifyTest (4 passed offline), which is now the same one-line binding a consumer writes.
  • Mutations applied: all five against the consumer's files, with the branch's package as its dependency, each killed by that one test with a distinct message.
    • foundry.toml delete [etherscan] flaresupported network has no [etherscan] key: flare
    • foundry.toml delete [rpc_endpoints] flaresupported network has no [rpc_endpoints] alias: flare
    • foundry.toml add [rpc_endpoints] optimism[rpc_endpoints] alias is not a supported network: optimism
    • foundry.toml add [etherscan] optimism[etherscan] key is not a supported network: optimism
    • foundry.toml drop { access = "read", path = "./foundry.toml" } from fs_permissionsvm.readFile: the path foundry.toml is not allowed to be accessed for read operations, i.e. a repo that cannot read its own config fails rather than passing on a file it never opened
    • all four assertion branches covered; consumer restored to baseline green after each (4 passed, 0 failed)
    • a sixth, non-foundry.toml mutation — a test function added to RainDeployVerify.sol inside the consumer's dependencies/ — is the propagation check in point 4, not a kill.
  • Oracle: LibRainDeploy.supportedNetworks(), which is the list the deploy broadcasts to and the chain group forks, read independently of the foundry.toml under test. The failure modes are foundry's own: [rpc_endpoints] is what makes an alias forkable, [etherscan] is what makes --verify resolve, and an [etherscan] entry with neither chain nor url under an alias foundry cannot resolve takes the whole section down. The fs_permissions behaviour is forge's cheatcode boundary, not this code's.
  • Category check: the issue as filed asks (a) the assertion leaves test/ for a shipped abstract and (b) the exemplars bind it. The scope-correction comment supersedes the remedy with (c) a single RainDeployVerify union consumers bind once, (d) that union being the only thing they bind, and (e) Chain/Snapshot kept separately runnable. Covered a, b, c, d, e. (e) is kept at the abstract level: both remain distinct contracts, so --match-contract can still select the offline half; a repo binding only the union trades that selection for the guarantee, which is what the ruling prescribes. Not covered, and out of scope by the ruling: the downstream bumps and st0x.deploy's first binding, which no upstream change can remove.

`testSupportedNetworksAreFullyConfigured` lived in `test/`, which
`.soldeerignore` strips, so no consumer had it. Moving it into
`RainDeployVerifySnapshot` makes it available; `RainDeployVerify` is what
makes it arrive. The union is the whole verification binding, so the next
check added upstream reaches every binder on a version bump rather than
waiting on four independent downstream edits that nothing red-lines.

`LibStringSet` moves to `src/lib/` because a shipped abstract cannot
depend on a stripped one.

Closes #151

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

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 55 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3a7f987e-3244-4571-8fa6-6a2f242c1ae4

📥 Commits

Reviewing files that changed from the base of the PR and between 4dfa421 and 8e715e7.

📒 Files selected for processing (17)
  • .github/workflows/manual-sol-artifacts.yaml
  • README.md
  • script/Deploy.sol
  • slither.config.json
  • src/abstract/RainDeployVerify.sol
  • src/abstract/RainDeployVerifyChain.sol
  • src/abstract/RainDeployVerifySnapshot.sol
  • src/abstract/RegistryDeploySuites.sol
  • src/lib/LibStringSet.sol
  • test/script/Build.t.sol
  • test/src/abstract/RainDeployVerifySnapshotBase.t.sol
  • test/src/abstract/RegistryDeployChain.t.sol
  • test/src/abstract/RegistryDeploySnapshot.t.sol
  • test/src/abstract/RegistryDeployVerify.t.sol
  • test/src/lib/GeneratedSnapshotShape.t.sol
  • test/src/lib/LibRainDeploy.t.sol
  • test/src/lib/LibRainDeploySnapshot.t.sol

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.

@thedavidmeister
thedavidmeister merged commit 96a9061 into main Aug 27, 2026
5 checks passed
thedavidmeister pushed a commit that referenced this pull request Aug 27, 2026
#155 renamed RegistryDeployChainTest to RegistryDeployVerifyTest inside
the paragraph this branch deletes, so main re-added it in updated form
still carrying the false claim. The deletion stands.

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

supportedNetworks() vs foundry.toml consistency test is not shipped, so no consumer has it

1 participant