Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@
ARBITRUM_RPC_URL=https://arb1.arbitrum.io/rpc
BASE_RPC_URL=https://mainnet.base.org
BASE_SEPOLIA_RPC_URL=https://sepolia.base.org
ETHEREUM_RPC_URL=https://eth-pokt.nodies.app
FLARE_RPC_URL=https://flare-api.flare.network/ext/C/rpc
HYPEREVM_RPC_URL=https://rpc.hyperliquid.xyz/evm
POLYGON_RPC_URL=https://polygon-bor-rpc.publicnode.com
8 changes: 5 additions & 3 deletions .github/workflows/manual-sol-verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ on:
networks:
type: string
required: true
default: arbitrum base base-sepolia flare polygon
default: arbitrum base base-sepolia mainnet flare hyperliquid polygon
description: |
Which explorers to submit to. FOUNDRY's chain names, not the
`[rpc_endpoints]` aliases: `base-sepolia` is a chain name and
`base_sepolia` is rejected outright. The default is
`[rpc_endpoints]` aliases, and the two differ on three of the seven:
the aliases `base_sepolia`, `ethereum` and `hyperevm` are rejected
outright, and the chain names are `base-sepolia`, `mainnet` and
`hyperliquid`. The default is
`LibRainDeploy.supportedNetworks()` spelled that way, i.e. every
network the deploy broadcasts to, so it has to move when that does.
jobs:
Expand Down
11 changes: 11 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ recursive_deps = false
arbitrum = "${ARBITRUM_RPC_URL}"
base = "${BASE_RPC_URL}"
base_sepolia = "${BASE_SEPOLIA_RPC_URL}"
ethereum = "${ETHEREUM_RPC_URL}"
flare = "${FLARE_RPC_URL}"
hyperevm = "${HYPEREVM_RPC_URL}"
polygon = "${POLYGON_RPC_URL}"

# `rainix-manual-sol-artifacts` passes `--verify` by default and exports exactly
Expand All @@ -88,9 +90,18 @@ polygon = "${POLYGON_RPC_URL}"
# Both sections are checked against `LibRainDeploy.supportedNetworks()`, in both
# directions, by `testSupportedNetworksAreFullyConfigured`. Adding a network is
# an edit to all three or a red test, not a broadcast that discovers it.
#
# `chain` is stated on the entries whose alias foundry does not itself resolve
# to a chain. An entry with neither `chain` nor `url` under such an alias is not
# a missing key, it is a config error — "At least one of `url` or `chain` must
# be present for Etherscan config with unknown alias" — raised while resolving
# the section, so it takes down verification for every network in it and not
# only its own.
[etherscan]
arbitrum = { key = "${CI_DEPLOY_ARBITRUM_ETHERSCAN_API_KEY}" }
base = { key = "${CI_DEPLOY_BASE_ETHERSCAN_API_KEY}" }
base_sepolia = { key = "${CI_DEPLOY_BASE_SEPOLIA_ETHERSCAN_API_KEY}" }
ethereum = { key = "${CI_DEPLOY_ETHEREUM_ETHERSCAN_API_KEY}", chain = 1 }
flare = { key = "${CI_DEPLOY_FLARE_ETHERSCAN_API_KEY}" }
hyperevm = { key = "${CI_DEPLOY_HYPEREVM_ETHERSCAN_API_KEY}", chain = 999 }
polygon = { key = "${CI_DEPLOY_POLYGON_ETHERSCAN_API_KEY}" }
4 changes: 2 additions & 2 deletions script/Deploy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import {RegistryDeploySuites} from "../src/abstract/RegistryDeploySuites.sol";
///
/// Deploying is idempotent by construction. `deployToNetworks` checks the
/// recorded address against the creation code before it forks anything, then
/// skips any network that already has code there, so a partial run — three
/// chains of five, one RPC down — is fixed by running it again rather than by
/// skips any network that already has code there, so a partial run — five
/// chains of seven, one RPC down — is fixed by running it again rather than by
/// unpicking anything.
///
/// `RegistryDeployChainTest` is what says whether this has been run and worked
Expand Down
6 changes: 3 additions & 3 deletions src/abstract/RainDeployVerifyChain.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ error CodeHashMismatchOnNetwork(
///
/// This is the only group that can catch a suite that never deployed to a
/// network, or that is not there any more. Neither is a fact the repo can hold:
/// both can go false with nobody touching it — a release that reached four
/// chains of five, a chain added to `supportedNetworks()` after a release that
/// both can go false with nobody touching it — a release that reached six
/// chains of seven, a chain added to `supportedNetworks()` after a release that
/// therefore never got it, a deploy that silently failed.
///
/// ## Released only, for the same reason source anchors the candidate only
Expand Down Expand Up @@ -108,7 +108,7 @@ abstract contract RainDeployVerifyChain is RainDeployVerifyBase {
/// expectation.
/// @param derived The derivation of every suite to check.
function checkDeployedOnSupportedNetworks(DerivedDeploy[] memory derived) internal {
// Nothing to check is not a reason to touch five RPC endpoints. Forking
// Nothing to check is not a reason to touch seven RPC endpoints. Forking
// to check nothing turns an outage into the failure of an assertion
// that has no subject, which is the one failure this contract is
// supposed to be legible against.
Expand Down
14 changes: 11 additions & 3 deletions src/lib/LibRainDeploy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,15 @@ library LibRainDeploy {
/// Config name for Base Sepolia testnet.
string constant BASE_SEPOLIA = "base_sepolia";

/// Config name for Ethereum mainnet.
string constant ETHEREUM = "ethereum";

/// Config name for Flare network.
string constant FLARE = "flare";

/// Config name for HyperEVM network.
string constant HYPEREVM = "hyperevm";

/// Config name for Polygon network.
string constant POLYGON = "polygon";

Expand Down Expand Up @@ -251,12 +257,14 @@ library LibRainDeploy {
/// Returns the list of networks currently supported by Rain deployments.
/// @return The list of supported network names.
function supportedNetworks() internal pure returns (string[] memory) {
string[] memory networks = new string[](5);
string[] memory networks = new string[](7);
networks[0] = ARBITRUM_ONE;
networks[1] = BASE;
networks[2] = BASE_SEPOLIA;
networks[3] = FLARE;
networks[4] = POLYGON;
networks[3] = ETHEREUM;
networks[4] = FLARE;
networks[5] = HYPEREVM;
networks[6] = POLYGON;
return networks;
}

Expand Down
2 changes: 1 addition & 1 deletion test/concrete/MissingDependencyDeploy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ address constant ABSENT_DEPENDENCY = address(0xdeadbee5);
/// dependency check by design and would say nothing about the list.
///
/// One network, so the refusal names a chain that is the whole target set
/// rather than the first of five. Keyed `second-address-candidate` for the
/// rather than the first of seven. Keyed `second-address-candidate` for the
/// reason `StalePinDeploy` gives.
contract MissingDependencyDeploy is RainDeployBroadcast {
/// @inheritdoc RainDeployBroadcast
Expand Down
8 changes: 4 additions & 4 deletions test/src/abstract/RainDeployBroadcast.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ contract RainDeployBroadcastTest is Test {
//
// A fixture that names ONE network, so that where the broadcast went is
// observable at all. `sDeploy` takes the default target set, and a suite
// deployed to all five chains and a suite deployed to the one chain the
// deployed to all seven chains and a suite deployed to the one chain the
// repo asked for are indistinguishable from a fixture that asks for all
// five.
// seven.
ExampleDeploySingleNetwork single = new ExampleDeploySingleNetwork();

// Derived here from the same source the declaration derives them from,
Expand Down Expand Up @@ -198,7 +198,7 @@ contract RainDeployBroadcastTest is Test {
// arbitrum for this fixture's single-element override, polygon for the
// default. That is the whole of the difference an assertion can see, and
// an override `run()` ignored is a repo that asked for one chain getting
// a suite on five — with a revert partway through leaving a dispatch
// a suite on seven — with a revert partway through leaving a dispatch
// half done.
//
// `testDeployNetworksDefaultsToSupportedNetworks` asserts the default
Expand Down Expand Up @@ -258,7 +258,7 @@ contract RainDeployBroadcastTest is Test {
/// before the `CREATE2` goes out compares the recorded address against the
/// recorded creation code, both of which come out of the same generated
/// file. That catches a stale PIN and cannot catch a snapshot of the wrong
/// CONTRACT, so without this the bytes reaching five chains are whatever the
/// CONTRACT, so without this the bytes reaching seven chains are whatever the
/// generated file happens to hold. `CREATE2` at a zero salt makes that
/// permanent: the wrong bytes take the wrong bytes' own address, on every
/// chain the dispatch reached, and the dispatch is `workflow_dispatch` on a
Expand Down
12 changes: 6 additions & 6 deletions test/src/abstract/RainDeployVerifyChain.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ import {
/// "nothing is deployed at this address" from something the fixture arranged
/// into a claim about the world. That claim is false here: the exemplar's
/// addresses come from `src/generated/candidate/`, which is exactly what
/// `Manual sol artifacts` broadcasts, and `AddressRegistry` is live on all five
/// supported networks. A negative case resting on it asserts nothing and
/// reports `next call did not revert as expected` — a fixture that only worked
/// while the repo had not yet done the thing it exists to do.
/// `Manual sol artifacts` broadcasts, and `AddressRegistry` is live on five of
/// the seven supported networks. A negative case resting on it asserts nothing
/// and reports `next call did not revert as expected` — a fixture that only
/// worked while the repo had not yet done the thing it exists to do.
///
/// Pointing the fixture at a mock nobody deploys would move that dependency
/// rather than remove it: the Zoltu factory is permissionless, so no address is
Expand Down Expand Up @@ -94,7 +94,7 @@ contract RainDeployVerifyChainTest is ExampleDeploySuites, RainDeployVerifyChain

/// A version that is not on a network MUST fail, naming the network, the
/// version and the address. This is the whole reason the group exists: a
/// release that reached four chains of five, or a chain added after a
/// release that reached six chains of seven, or a chain added after a
/// release that therefore never got it, is invisible to every other check.
function testChainNotDeployedReverts() external {
// Emptied, and left persistent, so every fork carries an empty account
Expand Down Expand Up @@ -164,7 +164,7 @@ contract RainDeployVerifyChainTest is ExampleDeploySuites, RainDeployVerifyChain
///
/// This contract is where it belongs because it already forks every
/// supported network. Asserting it from the empty-set side would hand the
/// contract that exists to need no RPC endpoint the five-endpoint dependency
/// contract that exists to need no RPC endpoint the seven-endpoint dependency
/// the early return removes from it.
function testChainWithASingleSubjectDoesFork() external {
(bool activeBefore,) = address(vm).call(abi.encodeWithSignature("activeFork()"));
Expand Down
6 changes: 3 additions & 3 deletions test/src/abstract/RegistryDeployChain.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@ import {RegistryDeploySuites} from "../../../src/abstract/RegistryDeploySuites.s
/// itself.
contract RegistryDeployChainTest is RegistryDeploySuites, RainDeployVerifyChain {
/// Nothing to check MUST NOT touch an RPC endpoint. This repo has released
/// nothing, so this is the branch every CI run takes: forking five networks
/// nothing, so this is the branch every CI run takes: forking seven networks
/// to check nothing turns an outage into the failure of an assertion with
/// no subject, which is the one failure this contract exists to stay
/// legible against.
///
/// The ABSENCE of a fork is what is asserted, because the pass is identical
/// either way — the matrix that forks all five and finds nothing to check on
/// either way — the matrix that forks all seven and finds nothing to check on
/// each of them passes too, and is the only thing this contract would have
/// done differently. `vm.activeFork()` reverts when nothing is selected, so
/// the low-level call failing IS "no network was reached".
///
/// It runs the whole inherited entry point rather than handing the matrix an
/// empty array, so the derivation is inside what is asserted: a fork opened
/// while deriving would touch the same five endpoints for the same nothing.
/// while deriving would touch the same seven endpoints for the same nothing.
///
/// The empty released set is asserted rather than assumed, because it is the
/// premise and not the property. The first release gives this contract a
Expand Down
14 changes: 8 additions & 6 deletions test/src/lib/LibRainDeploy.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,18 @@ contract LibRainDeployTest is Test {
);
}

/// `supportedNetworks` MUST return exactly 5 networks in the expected
/// `supportedNetworks` MUST return exactly 7 networks in the expected
/// order matching the library constants.
function testSupportedNetworks() external pure {
string[] memory networks = LibRainDeploy.supportedNetworks();
assertEq(networks.length, 5);
assertEq(networks.length, 7);
assertEq(networks[0], LibRainDeploy.ARBITRUM_ONE);
assertEq(networks[1], LibRainDeploy.BASE);
assertEq(networks[2], LibRainDeploy.BASE_SEPOLIA);
assertEq(networks[3], LibRainDeploy.FLARE);
assertEq(networks[4], LibRainDeploy.POLYGON);
assertEq(networks[3], LibRainDeploy.ETHEREUM);
assertEq(networks[4], LibRainDeploy.FLARE);
assertEq(networks[5], LibRainDeploy.HYPEREVM);
assertEq(networks[6], LibRainDeploy.POLYGON);
}

/// PROPERTY: `[rpc_endpoints]` and `[etherscan]` in `foundry.toml` are
Expand Down Expand Up @@ -1223,7 +1225,7 @@ contract LibRainDeployTest is Test {
///
/// Two networks rather than `supportedNetworks()`. What is under test is
/// that the loop visits every network it is given, which two prove as well
/// as five; the roster itself is `testSupportedNetworks`'s job. These are
/// as seven; the roster itself is `testSupportedNetworks`'s job. These are
/// the two networks the rest of this suite forks, so the test does not
/// depend on the reliability of RPC endpoints nothing else here touches.
function testCheckResolvedAddressesOnNetworksEachNetwork() external {
Expand Down Expand Up @@ -1273,7 +1275,7 @@ contract LibRainDeployTest is Test {
/// just as happily — and the mismatch case above is one network, so it
/// cannot tell them apart either. What separates them is a target that
/// answers differently on a LATER network, which is exactly the deployment
/// this matrix exists for: one chain of five holding a value nobody looked
/// this matrix exists for: one chain of seven holding a value nobody looked
/// at.
///
/// The first network is the one the target agrees on, so nothing fails
Expand Down
Loading