Skip to content

feat: add zeus deploy/migration scripts#99

Open
seanmcgary wants to merge 9 commits into
masterfrom
sm-zeusSetup
Open

feat: add zeus deploy/migration scripts#99
seanmcgary wants to merge 9 commits into
masterfrom
sm-zeusSetup

Conversation

@seanmcgary

Copy link
Copy Markdown
Member

Summary

Onboard existing Sepolia contract deployments onto Zeus for versioned release management.

  • Install zeus-templates as a forge submodule and configure foundry.toml remappings
  • Capture existing deployed addresses in deployment.json files for both environments:
    • sepolia-dev: EigenKMSRegistrar (Eth Sepolia, chain 11155111)
    • base-sepolia-dev: EigenKMSCommitmentRegistry (Base Sepolia, chain 84532)
  • Create Env.sol library providing type-safe access to deployed contracts and environment config
  • Add register-only init releases (v0.1.0-sepolia-init, v0.1.0-base-sepolia-init) that emit ZeusDeploy events for existing addresses without performing new deployments

Motivation

Contracts were previously deployed manually via ad-hoc scripts. This PR brings them under Zeus management so that future upgrades follow a structured, versioned release flow with proper state tracking.

Changes

File Purpose
.zeus Zeus config pointing to metadata repo
contracts/lib/zeus-templates Submodule for EOADeployer/MultisigBuilder base contracts
foundry.toml Add zeus-templates/ remapping + no_match_path for releases
contracts/script/deploys/*/deployment.json Captured state of existing deployments
contracts/script/releases/Env.sol Type-safe environment access library
contracts/script/releases/v0.1.0-*/ Register-only init scripts + upgrade.json metadata

Deployed Addresses Captured

Ethereum Sepolia (EigenKMSRegistrar):

  • Proxy: 0xfe0c3c2db3b767f768f9000d48193f0ee0bfc07d
  • Impl: 0x7065a2442449450f072b106c26c037f2c13baead
  • ProxyAdmin: 0x396453d3f233da7771f292a5aa9dcfb59c87241e

Base Sepolia (EigenKMSCommitmentRegistry):

  • Proxy: 0xfe0c3c2db3b767f768f9000d48193f0ee0bfc07d
  • Impl: 0x7065a2442449450f072b106c26c037f2c13baead
  • ProxyAdmin: 0x396453d3f233da7771f292a5aa9dcfb59c87241e

@claude

claude Bot commented May 15, 2026

Copy link
Copy Markdown

Claude finished @seanmcgary's task in 2m 39s —— View job


Code Review: feat: add zeus deploy/migration scripts

  • Gather context and read changed files
  • Review code quality
  • Review security
  • Review testing coverage
  • Review documentation
  • Post final review

Summary

This PR correctly implements the Zeus onboarding pattern for existing Sepolia deployments — the register-only init approach (no actual deployments, just ZeusDeploy event emission) is the right pattern for capturing pre-Zeus state. Overall the structure is solid. A few issues worth addressing before merge.


🔴 High Priority

Identical proxy/impl/ProxyAdmin addresses on both chains

Both deployment.json files contain the exact same addresses:

Proxy:      0xfe0c3c2db3b767f768f9000d48193f0ee0bfc07d
Impl:       0x7065a2442449450f072b106c26c037f2c13baead
ProxyAdmin: 0x396453d3f233da7771f292a5aa9dcfb59c87241e

for two different contracts (EigenKMSRegistrar on Sepolia, EigenKMSCommitmentRegistry on Base Sepolia). This is possible if the same EOA deployed at the same nonce on both chains (CREATE is nonce-deterministic), but it's highly unusual and should be explicitly confirmed. If incorrect, Zeus will track wrong state, and future upgrades will target the wrong contracts.

Action: Verify these addresses on-chain via Etherscan/Basescan and add a comment to both deployment.json files (or the PR description) explicitly confirming "same deployer/nonce on both chains" so future maintainers don't raise this same question.


🟡 Medium Priority

Zeus CLI is an undocumented global dependency

package.json was added in one commit then removed (chore: remove local zeus dependency (installed globally)). Zeus CLI is now assumed to be installed globally, but this requirement is not documented anywhere — not in CLAUDE.md, README, or any developer setup guide. Developers and CI pipelines will silently fail.

Action: Document the npm install -g @layr-labs/zeus-cli requirement in CLAUDE.md or a developer setup guide. Fix this →

Missing RPC endpoints for target networks in foundry.toml

foundry.toml defines endpoints for mainnet and holesky only:

[rpc_endpoints]
mainnet = "${RPC_MAINNET}"
holesky = "${RPC_HOLESKY}"

The release scripts target sepolia (chain 11155111) and base_sepolia (chain 84532), but no RPC entries exist for these. Running forge script --network sepolia will fail without explicitly passing --rpc-url. Fix this →


🟠 Low Priority

Dead code: _envU256 in Env.sol

contracts/script/releases/Env.sol:101-103 defines _envU256 but it's never called from anywhere in the library or the release scripts. Fix this →

Cross-environment keys in a shared Env.sol

Env.sol combines sepolia-only keys (allocationManager, keyRegistrar, permissionController) and base-sepolia-only keys (ecdsaCertificateVerifier, bn254CertificateVerifier) in one library. Calling the wrong accessor in the wrong environment will return zero address silently (depends on how ZEnvHelpers.state().envAddress() handles missing keys). At minimum, NatSpec comments on these functions should document which environment each accessor applies to.

/// @dev Only available in sepolia-dev environment
function allocationManager() internal view returns (address) { ... }

/// @dev Only available in base-sepolia-dev environment  
function ecdsaCertificateVerifier() internal view returns (address) { ... }

testScript() validation is minimal

Both 1-registerContracts.s.sol scripts only assert addresses are non-zero — they don't verify contracts exist at those addresses (e.g. address(x).code.length > 0) or that proxy→impl mappings are correct. For an init script capturing real deployed state, verifying on-chain contract existence would give stronger guarantees.


📋 Design / Documentation

Planning documents committed to the codebase

docs/superpowers/plans/2026-05-15-zeus-onboarding.md (472 lines) and docs/superpowers/specs/2026-05-15-zeus-onboarding-design.md (209 lines) are implementation artifacts — checklists and design notes for work that's now complete. They don't help future maintainers understand the system. Consider removing them or moving the persistent design rationale to the PR description (it's already there). The CLAUDE.md guidance explicitly discourages keeping artifacts that don't add long-term value.

COMMIT field is empty string

Both deployment.json files have "COMMIT": "". This is understandable for pre-Zeus deployments, but worth adding a comment in the PR description that this is intentional (no git commit hash available for manually deployed contracts).

no_match_path excludes release scripts from CI compilation

foundry.toml:33 excludes contracts/script/releases/**/*.sol from compilation. This is intentional (as noted in the commit message), but it means compilation errors in release scripts won't surface in forge build or CI. Consider adding a dedicated CI step or Makefile target to compile release scripts separately: forge build --no-match-path '' or similar.


✅ What's Done Well

  • The register-only init pattern (no new deployments, just ZeusDeploy event registration) is the correct approach for onboarding pre-existing contracts
  • Env.sol follows the established EigenLayer Zeus library pattern cleanly
  • The DeployedProxy/DeployedImpl enum sentinel pattern prevents accidental misuse of proxy vs impl accessors
  • zeus-templates added as a proper forge submodule rather than vendored
  • Release scripts are correctly gated under no_match_path to avoid polluting the standard build
  • Both upgrade.json files correctly declare "from": "0.0.0" which matches the pre-Zeus genesis state

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