Skip to content

Conversation

@ypatil12
Copy link
Collaborator

@ypatil12 ypatil12 commented Jun 28, 2025

v1.7.0 Multi Chain

The multichain release enables AVSs to launch their services and make verified Operator outputs available on any EVM chain, meeting their customers where they are. AVSs can specify custom operator weights to be transported to any destination chain. The release has 3 components:

  1. Core Contracts
  2. AVS Contracts
  3. Offchain Infrastructure

The below release notes cover Core Contracts. For more information on the end to end protocol, see our docs and ELIP-008.

Release Manager

@ypatil12 @eigenmikem

Highlights

This multichain release only introduces new standards and contracts. As a result, there are no breaking changes or deprecations.

🚀 New Features

Source Chain Contracts

  • KeyRegistrar: Manages cryptographic keys for operators across different operator sets. It supports both ECDSA and BN254 key types and ensures global uniqueness of keys across all operator sets
  • CrossChainRegistry: Enables AVSs to register to have their operator stakes transported to supported destination chains
  • ReleaseManager: Provides a standardized way for AVSs to publish software artifacts (binaries, docker images, etc.) that operators in their operator sets should upgrade to by specified deadlines

Destination Chain Contracts

  • CertificateVerifier: Proves the offchain execution of a task, via a Certificate, by the operators of an operatorSet. Two types of key material are supported: ECDSA and BN254
  • OperatorTableUpdater: Updates operator tables in the CertificateVerifier to have tasks validated against up-to-date operator stake weights

🔧 Improvements – Enhancements to existing features.

  • The multichain protocol has protocol-ized several AVS-deployed contracts, enabling an simpler AVS developer experience. These include:
    • KeyRegistrar: Manages BLS and ECDSA signing keys. AVSs no longer have to deploy a BLSAPKRegistry
    • CertificateVerifier: Handles signature verification for BLS and ECDSA keys. AVSs no longer have to deploy a BLSSignatureChecker
    • Offchain Multichain Transport: AVSs no longer have to maintain avs-sync to keep operator stakes fresh

Changelog

  • feat: multichain deploy scripts PR #1487
  • feat: operator table updater pauser PR #1501
  • feat: add publishMetadataURI PR #1492
  • refactor: globalRootConfirmerSet -> generator PR #1500
  • fix: circular dependency for initial global root update PR #1499
  • chore: remove stale bindings PR #1498
  • fix: zero length PR #1490
  • docs: multichain docs PR #1488
  • refactor: remove table calculators PR #1493
  • refactor: KeyRegistry unit testing PR #1482
  • feat: disable root PR #1481
  • refactor: ECDSATableCalculator testing PR #1479
  • refactor: operators can deregister keys if not slashable PR #1480
  • refactor: ECDSACertificateVerifier testing PR #1478
  • refactor: Bn254CertificateVerifierUnitTests PR #1476
  • feat: ecdsa table calculator PR #1473
  • feat: ecdsacv views PR #1475
  • refactor: BN254OperatorTableCalculator PR #1463
  • feat: add referenceBlockNumber PR #1472
  • feat: release manager PR #1469
  • feat: ecdsa cert verifier PR #1470
  • feat: add view function for getGlobalConfirmerSetReferenceTimestamp PR #1471
  • chore: add helper view function PR #1465
  • chore: add sig digest functions to interface PR #1464
  • refactor: CrossChainRegistry PR #1457
  • fix: global table update message hash PR #1460
  • refactor: sig verification into library PR #1455
  • fix: OperatorTableUpdater encoding PR #1456
  • chore: add latest referenceTimestamp to OTC interface PR #1454
  • chore: bindings PR #1452
  • feat: add operator table updater to CCR PR #1451
  • chore: multichain deploy scripts PR #1449
  • feat: cross chain registry PR #1439
  • chore: update BN254CertificateVerifier PR #1447
  • feat: bn254 operator table contracts PR #1429
  • feat: KeyRegistrar PR #1421
  • feat: operator table updater PR #1436
  • feat: bn254 certificate verifier PR #1431
  • chore: bindings + interface update PR #1438
  • chore: update multichain interfaces PR #1433
  • feat: multi chain interfaces PR #1423
  • docs: update version matrix PR #1491
  • chore: add multisend parser to scripts directory PR #1486
  • chore: update eigenpod and eigen impls addresses in holesky and hoodi PR #1448

@ypatil12 ypatil12 requested a review from eigenmikem July 1, 2025 17:47
@ypatil12 ypatil12 marked this pull request as ready for review July 1, 2025 18:16
ypatil12 and others added 27 commits July 1, 2025 15:08
**Motivation:**

Add all multi chain interfaces for easier development. 

**Modifications:**

Adds the following:
- `IBN254CertificateVerifier` (implements `IBaseCertificateVerifier`)
- `IECDSACertificateVerifier` (implements `IBaseCertificateVerifier`)
- `IBN254TableCalculator`
- `IECDSATableCalculator`
- `IOperatorTableUpdater`
- `ICrossChainRegistry`

**Result:**

Multichain interfaces. Pending adding of `OperatorTableCalculator`
**Motivation:**

Small typos in multi chain interfaces. Also, we use absolute imports,
which can cause integration difficulties.

**Modifications:**

Fix typos. Use relative imports. 

**Result:**

Cleaner interfaces.
**Motivation:**

We want bindings to get started on offchain. Also need to add
`IOperatorTableCalculator` and update `ICrossChainRegistry` interface.

**Modifications:**

- Bindings
- Add `IOperatorTableCalculator`
- Add `ICrossChainRegistry`

**Result:**

POC ready
**Motivation:**

A BN254 certificate verifier is needed for multichain functionality

**Modifications:**

New core contract: `BN254CertificateVerifier`. It stores operatorTables
and verifies certificates against them.

**Result:**

Core part of multichain release
**Motivation:**

We need an operator table updater contract that will update all operator
tables.

**Modifications:**

Create an `OperatoTableUpdater` contract. This contract serves two
purposes:

1. Updates the `globalTableRoot` with a valid certificate from the
`globalRootConfirmerSet`
2. Updates operator tables for ECDSA and BN254 

Update all interfaces to be `>=0.5.0`. 

Security Assumptions:
1. The `globalTableRoot` cannot overwrite _past_ timestamps. In
addition, it cannot be set for future timestamps
2. `updateOperatorTable` can only be called for referenceTimestamps
after the opSet's stored `latestReferenceTimestamp`

**Result:**

Almost complete multi chain setup

---------

Co-authored-by: Michael <[email protected]>
**Motivation:**

Operator key management should be brought into core and out of
middleware.

**Modifications:**

New core contract, `KeyRegistrar`, that manages operator keys and
supports ECDSA and BN254 signatures.

**Result:**

Simpler for both AVSs and operators.

---------

Co-authored-by: Yash Patil <[email protected]>
**Motivation:**

Implementing the `BN254TableCalculator contracts`. Currently the
calculator weights slashable stake in an operator set by simply adding
all the slashable stake together with no multipliers/linear combination
calculation involved

**Modifications:**

Updates and added to interfaces

**Result:**

Bn254 Table Calc

---------

Co-authored-by: Yash Patil <[email protected]>
**Motivation:**

Minor updates for `BN254CertificateVerifier` 

**Modifications:**

- Update interface
- Use types for `OperatorTableUpdater`
- Remove ownable

**Result:**

Minor Updates
**Motivation:**

CrossChainRegistry contract as defined in the following TDDs:
1.
https://www.notion.so/eigen-labs/TDD-Stake-Table-Generation-19d13c11c3e0804f9c44cb5a5477fe8c#1f813c11c3e080f7bd1ede3b7cc21661
2.
https://www.notion.so/eigen-labs/TDD-Operator-Table-Transport-1f213c11c3e080c29ea5cef3ba953809

**Modifications:**

* `ICrossChainRegistry.sol`
* `CrossChainRegistry.sol`
* `CrossChainRegistryStorage.sol`

**Result:**

CrossChainRegistry
**Motivation:**

We want scripts to deploy multichain. 

**Modifications:**

Added 3 scripts:
1. Deploy Core
2. Deploy Multichain (verifier, table updater)
3. Deploy globalConfirmerOperatorSet

**Result:**

Complete deploy scripts
**Motivation:**

The offchain generation service should be able to retrieve the
`OperatorTableUpdater` on-chain.

**Modifications:**

- Update `_whitelistedChainIDs` to be an enumerable map from `chainID`
to `operatorTableUpdater`
- Update `addChainIDsToWhitelist` to take in a list of
`operatorTableUpdaters`
- Update `getSupportedChains` to return chainIDs and
`operatorTableUpdaters`

**Result:**

Clearer introspection.
**Motivation:**

Update bindings for multichain. 

**Modifications:**

Run `make bindings`

**Result:**

Up to date bindings
**Motivation:**

We want to add `latestReferenceTimestamp` to the interface. 

**Modifications:**

- Add `getLatestReferenceTimestamp` to OTC interface
- On initialization, update the `latestReferenceTimestamp` so that the
first global table root update can use the already set reference
timestamp
- Make bindings

**Result:**

Easier offchain integration
**Motivation:**

The encoding in the `OperatorTableUpdater` was incorrect, as it expected
the `OperatorTableInfo` was in decoded format, but it is first in bytes
then needs to be decoded to `BN254OperatorSetInfo` or
`ECDSAOperatorSetInfo[]`

**Modifications:**

Update the `OperatorTableUpdater` to decode the table to bytes first,
then decode to `BN254OperatorSetInfo` or `ECDSAOperatorSetInfo[]` based
on the `KeyType`.

**Result:**

Correct decoding/encoding
**Motivation:**

*Explain here the context, and why you're making that change. What is
the problem you're trying to solve.*

**Modifications:**

*Describe the modifications you've done.*

**Result:**

*After your change, what will change.*
**Motivation:**

The `messageHash` in the certificate for
`operatorTableUpdater.updateGlobalTableRoot` should be a properly
formatted type hash that takes into account the `referenceTimestamp` and
`globalTableRoot`, so neither can be spoofed.

**Modifications:**

Checks that
```solidity
        require(
            globalTableRootCert.messageHash == getGlobalTableUpdateMessageHash(globalTableRoot, referenceTimestamp),
            InvalidMessageHash()
        );
```

**Result:**

Correct Code
**Motivation:**

Clean up readability of CrossChainRegistry

**Modifications:**

- Add `hasActiveGenerationReservation` modifier
- Remove the `isDelete` parameter from setter functions
- Simplify `removeGenerationReservation`

**Result:**

Cleaner + More Auditable Code
**Motivation:**

`getBN254KeyRegistrationMessageHash` and
`getEDSAKeyRegistrationMessageHash` are not in the `IKeyRegistrar`
interface.

**Modifications:**

- Add functions to interface
- Use functions internally 

**Result:**

Cleaner code
**Motivation:**

Offchain services need a way to encode `keyData`

**Modifications:**

Create a view function `encodeBN254KeyData`

**Result:**

Easier integration
…#1471)

**Motivation:**

The `globalRootConfirmerSet` has its table only updated upon
initialization. We should have a view function in `operatorTableUpdater`

**Modifications:**

Add `getGlobalConfirmerSetReferenceTimestamp`. 

**Result:**

Cleaner introspection
**Motivation:**

Singleton Certificate Verifier is needed for ECDSA signatures.

**Modifications:**

New core multichain contract, `ECDSACertificateVerifier`.

**Result:**

Certificate Verifiers for initial release complete.
**Motivation:**

We want to enable AVSs to publish release metadata on-chain, giving
operators a reliable and verifiable source of truth.

**Modifications:**

* Added a new core contract: `ReleaseManager`.
* AVSs can call `publishRelease(operatorSet, release)` to push release
data.

**Result:**

AVSs can now post release info on-chain, allowing operators to query a
canonical, auditable source for updates.
**Motivation:**

For the aggregator, we need to provide a block.number that is associated
with a reference timestamp to easily index stake weights.

**Modifications:**

Add a `referenceBlockNumber` to `confirmGlobalTableRoot` along with the
following functions:
- `getLatestReferenceBlockNumber`
- `getReferenceBlockNumber(timestamp)`

**Result:**

Easier offchain usage
<!-- 
    🚨 ATTENTION! 🚨 
    
This PR template is REQUIRED. PRs not following this format will be
closed without review.
    
    Requirements:
- PR title must follow commit conventions:
https://www.conventionalcommits.org/en/v1.0.0/
- Label your PR with the correct type (e.g., 🐛 Bug, ✨ Enhancement, 🧪
Test, etc.)
    - Provide clear and specific details in each section
-->

**Motivation:**

*Explain here the context, and why you're making that change. What is
the problem you're trying to solve.*

**Modifications:**

*Describe the modifications you've done.*

**Result:**

*After your change, what will change.*

---------

Co-authored-by: Michael Sun <[email protected]>
**Motivation:**

Multichain needs a table calculator base implementation for ECDSA
signtures.

**Modifications:**

New contracts, `ECDSATableCalculator` and `ECDSATableCalculatorBase`.

**Result:**

Multichain contracts complete
**Motivation:**

Match `Bn254CertificateVerifier` tests with styling. 

**Modifications:**

- Add `isNonsignerCached` view function
- Make `trySignatureVerification` _public_
- Add a contract per function under test
- Use Multichain deployer and mocks properly 

**Result:**

Cleaner tests
ypatil12 and others added 15 commits July 1, 2025 15:08
**Motivation:**

Update `ECDSACertificateVerifier` to follow testing patterns. 

**Modifications:**

- Update tests
- Add functions to interface

**Result:**

Consistent patterns.
**Motivation:**

Operators should be able to deregister their keys in the `KeyRegistrar`
if they aren't slashable

**Modifications:**

Changed permissions on `deregisterKey`

**Result:**

Operators can deregister their keys in the `KeyRegistrar` if they aren't
slashable
**Motivation:**

Update `ECDSATableCalculator` to follow testing patterns. 

**Modifications:**

- Update tests

**Result:**

Consistent patterns.
**Motivation:**

We want to be able to disable a root in case of malicious activity. Here
is the state diagram (we're still evaluating pausers):


![image](https://github.com/user-attachments/assets/2c1a797b-fca4-4abb-8c50-a56f374bea80)


**Modifications:**

- Add disable functionality in `OperatorTableCalculator`. Only
previously posted, valid roots, can be disabled
- Certificate verifiers check `isRootDisabledByTimestamp` to see if root
is valid
- Update typeHash to include `referenceBlockNumber`

**Result:**

Secure code.
**Motivation:**

Update `KeyRegistrar` unit tests

**Modifications:**

- Update bindings
- Add .tree file
- Add `_` to internal storage vars

**Result:**

Updated tests. Full coverage (aside from unreachable else statements)
**Motivation:**

The `BN254` and `ECDSA` table calculators should be in middleware repo

**Modifications:**

- Remove all contracts/tests related to table calculators 
- Middleware PR:
Layr-Labs/eigenlayer-middleware#488

**Result:**

Cleaner separation of code
**Motivation:**

Docs for Multichain Release

**Modifications:**

Add Docs For:
- `CrossChainRegistry`
- `OperatorTableCalculator`
- `OperatorTableUpdater`
- `CertificateVerifier`
- `KeyRegistrar`

- Update Interfaces to be more explicit for verification return types

**Result:**

Docs
**Motivation:**

Prevent 0 length signatures in `ECDSACertificateVerifier` 

**Modifications:**

- Require length of signature is nonzero
- Use require(revert) instead of if() revert

**Result:**

Consistent behavior
**Motivation:**

Remove stale interfaces from multchain 

**Modifications:**

- Remove `IBN254TableCalculator`
- Remove `IECDSATableCalculator`
- Remove old bindings
 
**Result:**

Clearer code
**Motivation:**

`OperatorTableUpdater` currently has a bug where the first global root
update can't be completed due to `BN254CertificateVerifier` requiring a
valid global root.

**Modifications:**

Initialization now adds a dummy global table root.

**Result:**

Bug fixed

---------

Co-authored-by: Yash Patil <[email protected]>
**Motivation:**

For documentation, using `globalRootConfirmerSet` and `generator` is
unclear.

**Modifications:**

Using `generator` everywhere, including code

**Result:**

Clearer code
**Motivation:**

*Explain here the context, and why you're making that change. What is
the problem you're trying to solve.*

**Modifications:**

*Describe the modifications you've done.*

**Result:**

*After your change, what will change.*
**Motivation:**

Currently, `disableRoot` is called by the `owner` of the
`OperatorTableCalculator`. We want to update such that it can be called
by the `pauser`. This is to enable cleaner operations.

**Modifications:**

- Add `Pausable` to `operatorTableCalculator`
- Guard `disableGlobalTableRoot` with `onlyPauser`
- Guard `updateGlobalTableRoot` and `updateOperatorTable` with
`whenNotPaused(index)`

**Result:**

Cleaner disable mechanics.
**Motivation:**

We need deploy scripts for multichain 

**Modifications:**

Adds a `crossChainDeployLib` from:
#1474. This
library uses `createX` for deterministic deployments. In order to keep
the same address on all `destinationChains`, we deploy contracts from
the same multisig on each chain.

Add `testnet-base-sepolia` to CI for deploy scripts. 

Adds a `deploy_globalRootConfirmerSet` script. This script initiates a
global root confirmer set (ie. generator) and updates the `network.toml`
file used in the deploy scripts. It is only intended to be used on
`preprod` and `testnet`.

To distinguish between a source and destination chain we add a
`SOURCE_CHAIN: bool` and `DESTINATION_CHAIN: bool` to the Zeus Config.
We skip parts of the deploy if a chain is not a source or destination.

Deploys the contracts in 5 steps

1. `deploySourceChain.s.sol`: Deploys `KeyRegistrar`, `ReleaseManager`,
`CrossChainRegistry`.
2. `deployDestinationChainProxies.s.sol`: Deploys _empty_ proxy
contracts for `OperatorTableUpdater`, `BN254CertificateVerifier`,
`ECDSACertificateVerifier`. _Note: in order to have deterministic
proxies, we need to ensure the `initCode` is the same. Thus, the
implementation is the same `emptyContract` and the proxyAdmin is
initially the `multichainDeployerMultisig`_.
3. `deployDestinationChainImpls`: Deploys implementations using EOA
4. `instantiateDestinationChainProxies`: Upgrades the proxies to the
actual implementations. Transfer proxy admin to the actual `proxyAdmin`
5. `configureCrossChainRegistry`: Updates the `crossChainRegistry` on
the `SOURCE_CHAIN` to whitelist proper chainIds

**Result:**

Deploy scripts

---------

Co-authored-by: clandestine.eth <[email protected]>
**Motivation:**

Changelog for multichain

**Modifications:**

Generate changeling per guidelines

**Result:**

Release-ready
@ypatil12 ypatil12 force-pushed the release-dev/multichain branch from a10cd52 to 592f311 Compare July 1, 2025 19:08
@ypatil12 ypatil12 merged commit 5f84759 into main Jul 1, 2025
19 checks passed
@ypatil12 ypatil12 deleted the release-dev/multichain branch July 1, 2025 19:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants