Skip to content

Comments

2026 02 11 deploy#91

Merged
thedavidmeister merged 6 commits intomainfrom
2026-02-11-deploy
Feb 11, 2026
Merged

2026 02 11 deploy#91
thedavidmeister merged 6 commits intomainfrom
2026-02-11-deploy

Conversation

@thedavidmeister
Copy link
Contributor

@thedavidmeister thedavidmeister commented Feb 11, 2026

Motivation

Solution

Checks

By submitting this for review, I'm confirming I've done the following:

  • made this PR as small as possible
  • unit-tested any new functionality
  • linked any relevant issues or PRs
  • included screenshots (if this involves a front-end change)

Summary by CodeRabbit

  • New Features

    • Multi-network deployment support added for Arbitrum, Base, Flare, and Polygon
  • Tests

    • Added deployment verification tests for contract integrity
  • Chores

    • Updated development configuration with RPC endpoints and Etherscan settings for multiple networks
    • Integrated deployment library for simplified multi-network deployment workflows
    • Added environment configuration to .gitignore

@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

Warning

Rate limit exceeded

@thedavidmeister has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 56 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

This PR introduces multi-network deployment infrastructure for the MetaBoard contract. Changes include a new deployment library and test suite, refactored deployment script using abstracted deployment functions, updated CI/CD workflow with explicit Nix commands and environment variables, and configuration updates supporting multiple networks (Arbitrum, Base, Flare, Polygon).

Changes

Cohort / File(s) Summary
Configuration & Tooling
.gas-snapshot, .gitignore, foundry.toml, .gitmodules
Added .env to .gitignore; introduced new submodule reference for lib/rain.deploy; added foundry.toml sections for remappings, fuzz runs, rpc_endpoints, and etherscan configuration for multiple networks; minor gas snapshot metric adjustments.
Deployment Infrastructure
lib/rain.deploy, src/lib/deploy/LibMetaBoardDeploy.sol
Added new git submodule and LibMetaBoardDeploy library containing precommitted deployment address and code hash constants for idempotent verification.
Deployment Script & Tests
script/Deploy.sol, test/lib/deploy/LibMetaBoardDeploy.t.sol
Refactored deployment script to use LibRainDeploy.deployAndBroadcastToSupportedNetworks abstraction instead of direct vm.startBroadcast; added new test contract verifying deployed address and code hash match library constants.
CI/CD Workflow
.github/workflows/manual-sol-artifacts.yml
Removed per-network input and environment setup; replaced single deploy step with three explicit nix develop commands; switched to fixed CI_DEPLOY_* variables for RPC URLs and Etherscan API keys across multiple networks.

Sequence Diagram

sequenceDiagram
    participant Deploy as Deploy Script
    participant LibRainDeploy as LibRainDeploy
    participant Network as Target Networks<br/>(Arbitrum, Base, etc.)
    participant MetaBoard as MetaBoard Contract
    participant LibMetaBoardDeploy as LibMetaBoardDeploy

    Deploy->>LibRainDeploy: deployAndBroadcastToSupportedNetworks<br/>(networks, creationCode, codehash)
    loop For each Network
        LibRainDeploy->>Network: Deploy MetaBoard
        Network->>MetaBoard: Create Instance
        MetaBoard-->>LibRainDeploy: Deployed Address
        LibRainDeploy->>LibMetaBoardDeploy: Verify against METABOARD_DEPLOYED_ADDRESS<br/>and METABOARD_DEPLOYED_CODEHASH
        LibMetaBoardDeploy-->>LibRainDeploy: Address & Codehash Match
    end
    LibRainDeploy-->>Deploy: Deployment Complete (All Networks)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Update nix/rust #68: Modifies .github/workflows/manual-sol-artifacts.yml with Nix setup and CI deploy/env variable handling changes.
  • fix nix #69: Updates the same GitHub Actions workflow with changes to Nix installer/cache actions.

Suggested reviewers

  • rouzwelt
  • findolor
  • hardyjosh
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title '2026 02 11 deploy' is vague and generic, using only a date and the word 'deploy' without describing what is actually being deployed or the specific change being made. Use a more descriptive title that explains the main change, such as 'Add MetaBoard deployment infrastructure with idempotent verification' or 'Refactor deployment to use LibRainDeploy abstraction'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 2026-02-11-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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
script/Deploy.sol (1)

10-12: ⚠️ Potential issue | 🟡 Minor

Stale comment references deprecated "mumbai" testnet.

The comment mentions "mumbai" which was deprecated. This deploy script now targets multiple mainnets (Arbitrum, Base, Flare, Polygon), so the comment should be updated to reflect the actual deployment targets.

Proposed fix
 /// `@title` Deploy
-/// `@notice` A script that deploys all contracts. This is intended to be run on
-/// every commit by CI to a testnet such as mumbai.
+/// `@notice` A script that deploys all contracts idempotently across supported
+/// networks.
.github/workflows/manual-sol-artifacts.yml (1)

3-5: 🧹 Nitpick | 🔵 Trivial

Empty inputs: block is unnecessary.

The inputs: key with no entries is leftover from the removed network input. It's valid YAML but adds noise.

Proposed fix
 on:
-  workflow_dispatch:
-    inputs:
+  workflow_dispatch:
🤖 Fix all issues with AI agents
In @.gitmodules:
- Around line 4-6: The .gitmodules entry for submodule "lib/rain.deploy" points
to a non-existent URL; update the submodule URL to the correct repository so
cloning and submodule init succeed. Locate the submodule block named
lib/rain.deploy in .gitmodules and replace the url value (currently
https://github.com/rainlanguage/rain.deploy) with the correct upstream URL; then
run git submodule sync --recursive and git submodule update --init --recursive
to propagate the change and verify that the path lib/rain.deploy referenced by
foundry.toml (rain.deploy/=lib/rain.deploy/src/) resolves correctly.

In `@foundry.toml`:
- Around line 26-30: The Flare entry in the [etherscan] table currently only
supplies a key; update the 'flare' object in foundry.toml to include explicit
chain and url fields (add chain = <Flare chain ID> and url = "<Flare block
explorer API endpoint>") so Foundry can verify contracts on Flare; locate the
'flare' entry and set chain to the Flare network's numeric chain ID (e.g., 14)
and url to the official Etherscan-compatible API endpoint for Flare's explorer.

In `@test/lib/deploy/LibMetaBoardDeploy.t.sol`:
- Around line 11-20: The test testDeployAddress calls
vm.createSelectFork(vm.envString("CI_FORK_ETH_RPC_URL")) but CI doesn't define
CI_FORK_ETH_RPC_URL, causing CI failures; update the test to either read the
existing ETH_RPC_URL env var (replace CI_FORK_ETH_RPC_URL usage with ETH_RPC_URL
when calling vm.envString) or guard/skip the test when the env var is absent
(check vm.envString("CI_FORK_ETH_RPC_URL") is non-empty before calling
vm.createSelectFork) so vm.createSelectFork is only invoked in environments with
a fork RPC configured; adjust references in testDeployAddress and keep
assertions against LibMetaBoardDeploy.METABOARD_DEPLOYED_ADDRESS / codehash
unchanged.

Comment on lines +4 to +6
[submodule "lib/rain.deploy"]
path = lib/rain.deploy
url = https://github.com/rainlanguage/rain.deploy
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Check .gitmodules file to see the full context
cat -n .gitmodules

Repository: rainlanguage/rain.metadata

Length of output: 313


🏁 Script executed:

# Attempt to verify the repository exists by checking Git metadata
# Since we can't use gh CLI in sandbox, we'll check if there are any setup docs mentioning submodules
fd -t f -e md -e txt -e rst | head -20 | xargs grep -l "submodule\|git.*init" 2>/dev/null || echo "No obvious setup documentation found mentioning submodules"

Repository: rainlanguage/rain.metadata

Length of output: 128


🌐 Web query:

rain.deploy GitHub repository rainlanguage

💡 Result:

rain.deploy is not a GitHub repository under the rainlanguage org—it’s a command (rain deploy) in AWS’s CloudFormation CLI tool Rain, hosted here: aws-cloudformation/rain. [1][2]

The rainlanguage GitHub organization (Rainlang / Rain Protocol ecosystem) is here, and its repos are separate/unrelated to AWS’s rain deploy tool. [3]


🏁 Script executed:

# Search for any references to rain.deploy in the repository
rg "rain\.deploy" --type-list
rg "rain\.deploy" -t md -t js -t sol -t toml

Repository: rainlanguage/rain.metadata

Length of output: 487


🏁 Script executed:

# Check foundry.toml and Deploy.sol mentioned in the original scratchpad to understand what this submodule should be
fd -t f -e toml -e sol | grep -i "foundry\|deploy" | head -10

Repository: rainlanguage/rain.metadata

Length of output: 179


🌐 Web query:

rainlanguage github organization repositories deploy

💡 Result:

The RainLanguage GitHub organization is rainlanguage (displayed as “rainlang” on GitHub). Its repositories are listed on the org page under the Repositories tab (currently ~125 public repos), including core projects like rain.orderbook, rain.interpreter, and others. [1]

For deployment, the org has a dedicated repository rainlanguage/rain.deploy, described as tooling to deploy Solidity code (Foundry + Nix) to production using the Zoltu deterministic deployment proxy, plus helpers to validate supported networks/dependencies and perform post-deploy bytecode integrity checks. [2]

Sources: [1] [2]


🌐 Web query:

rainlanguage rain.deploy github

💡 Result:

There isn’t a rain.deploy repo/command under the rainlanguage / Rainlang GitHub org (that org is here). [1]

What you’re likely looking for is AWS CloudFormation “Rain”, a CLI tool whose command is rain deploy:

  • GitHub repo: aws-cloudformation/rain (this is where rain deploy lives). [2]
  • Official docs for the command: rain deploy (deploys a CloudFormation stack/changeset from a local template). [3]

Quick install (Go):

go install github.com/aws-cloudformation/rain/cmd/rain@latest

[2]


🌐 Web query:

"rainlanguage/rain.deploy" repository github

💡 Result:

There doesn’t appear to be a GitHub repository named rainlanguage/rain.deploy under the rainlanguage organization (a search of the org page shows many rain.* repos, but not rain.deploy). [1]

If you meant the rain deploy command, that’s part of AWS’s Rain CLI for CloudFormation, in aws-cloudformation/rain (docs: “rain deploy”). [2], [3]

Sources:
[1] (github.com)
[2] (github.com)
[3] (aws-cloudformation.github.io)

Citations:


🏁 Script executed:

# Check if there's a .gitmodules entry with a specific commit hash or branch reference
cat -n .gitmodules | grep -A 5 "rain.deploy"

Repository: rainlanguage/rain.metadata

Length of output: 195


🏁 Script executed:

# Look for any documentation or configuration referencing rain.deploy in foundry.toml or other files
fd -t f -e toml | xargs cat | grep -i "rain.deploy" 2>/dev/null || echo "No rain.deploy references in .toml files"

Repository: rainlanguage/rain.metadata

Length of output: 109


The repository URL https://github.com/rainlanguage/rain.deploy does not exist and will prevent the project from being cloned or built.

The submodule points to a non-existent repository under the rainlanguage organization. This will cause git clone and git submodule update --init --recursive to fail. Verify the correct repository URL and update the submodule path accordingly, as foundry.toml references this dependency directly (rain.deploy/=lib/rain.deploy/src/).

🤖 Prompt for AI Agents
In @.gitmodules around lines 4 - 6, The .gitmodules entry for submodule
"lib/rain.deploy" points to a non-existent URL; update the submodule URL to the
correct repository so cloning and submodule init succeed. Locate the submodule
block named lib/rain.deploy in .gitmodules and replace the url value (currently
https://github.com/rainlanguage/rain.deploy) with the correct upstream URL; then
run git submodule sync --recursive and git submodule update --init --recursive
to propagate the change and verify that the path lib/rain.deploy referenced by
foundry.toml (rain.deploy/=lib/rain.deploy/src/) resolves correctly.

Comment on lines +26 to +30
[etherscan]
arbitrum = { key = "${CI_DEPLOY_ARBITRUM_ETHERSCAN_API_KEY}" }
base = { key = "${CI_DEPLOY_BASE_ETHERSCAN_API_KEY}" }
flare = { key = "${CI_DEPLOY_FLARE_ETHERSCAN_API_KEY}" }
polygon = { key = "${CI_DEPLOY_POLYGON_ETHERSCAN_API_KEY}" } No newline at end of file
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Foundry etherscan configuration chain field required Flare

💡 Result:

In Foundry, the chain field in [etherscan] is required unless the table key is a known chain name (e.g., mainnet, optimism). If you use a custom key like flare, Foundry will error with “chain field required” unless you set chain (or use a key that Foundry recognizes). [1]

For Flare, set the chain id and the explorer API URL explicitly:

[etherscan]
flare = { key = "${ETHERSCAN_API_KEY}", chain = 14, url = "https://flare-explorer.flare.network/api" }
coston2 = { key = "${ETHERSCAN_API_KEY}", chain = 114, url = "https://coston2-explorer.flare.network/api" }

Flare chain IDs: 14 (mainnet) and 114 (Coston2), and their explorer API bases are https://flare-explorer.flare.network/api and https://coston2-explorer.flare.network/api. [2]

Then verify with:

forge verify-contract --chain 14 <address> src/Your.sol:YourContract --verifier etherscan

Sources: [1], [2]


🌐 Web query:

Foundry supported chains etherscan verification auto-resolve

💡 Result:

  • How auto-resolve works (Foundry + Etherscan): when you run forge verify-contract with --verifier etherscan and provide --chain <name|chainId>, Foundry uses the chain identifier to derive the correct Etherscan(-family) API URL automatically, as long as that chain is known/supported. (learnblockchain.cn)
  • “Supported chains”: in practice, most chains that have an Etherscan explorer are supported just by using --chain. (docs.etherscan.io)
  • If the chain is too new / not natively supported: pass an explicit verifier URL, typically using Etherscan V2 with a chainid query param, e.g.
    --verifier-url "https://api.etherscan.io/v2/api?chainid=<CHAIN_ID>" (docs.etherscan.io)
  • Config-based resolution: you can also configure keys per chain alias in foundry.toml under [etherscan], and Foundry resolves the final config from chain/url/key. (docs.etherscan.io)
  • Chain aliases: Foundry’s standard library maintains a registry of chain aliases/IDs/RPC defaults, and the lookup priority is roughly (explicit override) → foundry.toml → env vars → defaults. (etherscan.io)

Citations:


🌐 Web query:

Flare network block explorer API etherscan integration

💡 Result:

To integrate an “Etherscan-style” block-explorer API for Flare, use the Blockscout explorer instance for Flare and swap your Etherscan base URL to the Blockscout /api endpoint:

  • Flare’s Blockscout explorer: https://flare-explorer.flare.network (listed in Flare’s official network overview). [1]
  • Blockscout provides an Etherscan-compatible query API: add /api and keep the familiar module= / action= pattern. [2][3]

Example (Etherscan → Flare/Blockscout)

Etherscan

https://api.etherscan.io/api?module=account&action=txlist&address=0x...&apikey=KEY

Flare (Blockscout)

https://flare-explorer.flare.network/api?module=account&action=txlist&address=0x...&apikey=KEY

This is the standard Blockscout migration approach: host changes; most parameters stay the same. [3]

Where to find endpoint docs

Blockscout instances typically expose live API documentation at /api-docs (and the general module list is in Blockscout’s RPC API docs). [2][3]

If instead you meant Flare’s non-Etherscan “Flare API / API Portal” (managed at api.flare.io with token-based auth), that’s a separate product from the explorer API. [4]

Sources: [1] [2] [3] [4]


Flare requires explicit chain and url in its etherscan config.

Foundry auto-resolves chain details for standard networks like Arbitrum, Base, and Polygon using only the key field. However, Flare is not a standard Foundry-recognized chain and requires explicit chain (chain ID) and url (block explorer API endpoint) fields. Without these, contract verification on Flare will fail.

Proposed fix
-flare = { key = "${CI_DEPLOY_FLARE_ETHERSCAN_API_KEY}" }
+flare = { key = "${CI_DEPLOY_FLARE_ETHERSCAN_API_KEY}", chain = 14, url = "https://flare-explorer.flare.network/api" }
📝 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
[etherscan]
arbitrum = { key = "${CI_DEPLOY_ARBITRUM_ETHERSCAN_API_KEY}" }
base = { key = "${CI_DEPLOY_BASE_ETHERSCAN_API_KEY}" }
flare = { key = "${CI_DEPLOY_FLARE_ETHERSCAN_API_KEY}" }
polygon = { key = "${CI_DEPLOY_POLYGON_ETHERSCAN_API_KEY}" }
[etherscan]
arbitrum = { key = "${CI_DEPLOY_ARBITRUM_ETHERSCAN_API_KEY}" }
base = { key = "${CI_DEPLOY_BASE_ETHERSCAN_API_KEY}" }
flare = { key = "${CI_DEPLOY_FLARE_ETHERSCAN_API_KEY}", chain = 14, url = "https://flare-explorer.flare.network/api" }
polygon = { key = "${CI_DEPLOY_POLYGON_ETHERSCAN_API_KEY}" }
🤖 Prompt for AI Agents
In `@foundry.toml` around lines 26 - 30, The Flare entry in the [etherscan] table
currently only supplies a key; update the 'flare' object in foundry.toml to
include explicit chain and url fields (add chain = <Flare chain ID> and url =
"<Flare block explorer API endpoint>") so Foundry can verify contracts on Flare;
locate the 'flare' entry and set chain to the Flare network's numeric chain ID
(e.g., 14) and url to the official Etherscan-compatible API endpoint for Flare's
explorer.

@thedavidmeister thedavidmeister merged commit a823381 into main Feb 11, 2026
9 checks passed
@github-actions
Copy link
Contributor

@coderabbitai assess this PR size classification for the totality of the PR with the following criterias and report it in your comment:

S/M/L PR Classification Guidelines:

This guide helps classify merged pull requests by effort and complexity rather than just line count. The goal is to assess the difficulty and scope of changes after they have been completed.

Small (S)

Characteristics:

  • Simple bug fixes, typos, or minor refactoring
  • Single-purpose changes affecting 1-2 files
  • Documentation updates
  • Configuration tweaks
  • Changes that require minimal context to review

Review Effort: Would have taken 5-10 minutes

Examples:

  • Fix typo in variable name
  • Update README with new instructions
  • Adjust configuration values
  • Simple one-line bug fixes
  • Import statement cleanup

Medium (M)

Characteristics:

  • Feature additions or enhancements
  • Refactoring that touches multiple files but maintains existing behavior
  • Breaking changes with backward compatibility
  • Changes requiring some domain knowledge to review

Review Effort: Would have taken 15-30 minutes

Examples:

  • Add new feature or component
  • Refactor common utility functions
  • Update dependencies with minor breaking changes
  • Add new component with tests
  • Performance optimizations
  • More complex bug fixes

Large (L)

Characteristics:

  • Major feature implementations
  • Breaking changes or API redesigns
  • Complex refactoring across multiple modules
  • New architectural patterns or significant design changes
  • Changes requiring deep context and multiple review rounds

Review Effort: Would have taken 45+ minutes

Examples:

  • Complete new feature with frontend/backend changes
  • Protocol upgrades or breaking changes
  • Major architectural refactoring
  • Framework or technology upgrades

Additional Factors to Consider

When deciding between sizes, also consider:

  • Test coverage impact: More comprehensive test changes lean toward larger classification
  • Risk level: Changes to critical systems bump up a size category
  • Team familiarity: Novel patterns or technologies increase complexity

Notes:

  • the assessment must be for the totality of the PR, that means comparing the base branch to the last commit of the PR
  • the assessment output must be exactly one of: S, M or L (single-line comment) in format of: SIZE={S/M/L}
  • do not include any additional text, only the size classification
  • your assessment comment must not include tips or additional sections
  • do NOT tag me or anyone else on your comment

@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

Tip

For best results, initiate chat on the files or code changes.

SIZE=M

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.

1 participant