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
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,16 @@ forge test

The contracts in this repo are meant to be deployed by each AVS that wants to use them. The addresses listed below refer to EigenDA's deployment, and are included as an example.

### Current Mainnet Deployment
### Current MiddlewareV2 Testnet Deployment
The following testnet deployment is for our MiddlewareV2 release, deployed on Sepolia. The below table calculators calculate slashable stake for an operatorSet and value all strategies equally. For example, or example, if an operator allocates 100 stETH, 100 wETH, and 100 DAI the calculator would return 300 for the stake weight of the operator. See our [docs](./docs/middlewareV2/README.md) for more information.

| Name | Proxy | Implementation | Notes |
| -------- | -------- | -------- | -------- |
[`BN254TableCalculator`](./src/middlewareV2/tableCalculator/BN254TableCalculator.sol)| N/A | [`0xc2c0bc13571aC5115709C332dc7AE666606b08E8`](https://sepolia.etherscan.io/address/0xc2c0bc13571aC5115709C332dc7AE666606b08E8#code) | Singleton non-upgradeable |
[`ECDSATableCalculator`](./src/middlewareV2/tableCalculator/ECDSATableCalculator.sol)| N/A | [`0x5612Fd146C2d40f1269E0e73945A534ec706dCDc`](https://sepolia.etherscan.io/address/0x5612Fd146C2d40f1269E0e73945A534ec706dCDc#code) | Singleton non-upgradeable |


### Current AVS Mainnet Deployment

The current mainnet deployment is from our M2 mainnet release. You can view the deployed contract addresses below, or check out the code itself on the [`mainnet`](https://github.com/Layr-Labs/eigenlayer-middleware/tree/mainnet) branch.

Expand All @@ -83,7 +92,7 @@ The current mainnet deployment is from our M2 mainnet release. You can view the
[`ProxyAdmin`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/ProxyAdmin.sol) | - | [`0x8247...2E99`](https://etherscan.io/address/0x8247ef5705d3345516286b72bfe6d690197c2e99#code) | |
[`eigenda/EigenDAServiceManager`](https://github.com/Layr-Labs/eigenda/blob/08d8781a2165c159ac9bb502dd61ed6ed340601c/contracts/src/core/EigenDAServiceManager.sol) | [`0x870679e138bcdf293b7ff14dd44b70fc97e12fc0`](https://etherscan.io/address/0x870679e138bcdf293b7ff14dd44b70fc97e12fc0#readProxyContract) | [`0xF5fD...899e`](https://etherscan.io/address/0xf5fd25a90902c27068cf5ebe53be8da693ac899e#code) | Proxy: [`TUP@4.7.1`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.1/contracts/proxy/transparent/TransparentUpgradeableProxy.sol) |

### Current Testnet Deployment
### Current AVS Testnet Deployment

The current testnet deployment is on holesky, is from our M2 beta release. You can view the deployed contract addresses below, or check out the code itself on the [`testnet-holesky`](https://github.com/Layr-Labs/eigenlayer-middleware/tree/testnet-holesky) branch.

Expand Down
66 changes: 49 additions & 17 deletions docs/middlewareV2/AVSRegistrar.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Interfaces:

## Overview

The AVSRegistrar is the interface between AVSs and the EigenLayer core protocol for managing operator registration. It enforces that operators have valid keys registered in the `KeyRegistrar` for a given `operatorSet` before allowing them to register. The `AVSRegistrar` manages multiple operatorSets for a single AVS.
The AVSRegistrar is the interface between AVSs and the EigenLayer core protocol for managing operator registration. It enforces that operators have valid keys registered in the `KeyRegistrar` for a given `operatorSet` before allowing them to register. The `AVSRegistrar` manages multiple operatorSets for a single AVS.

### Key Features

Expand All @@ -36,40 +36,71 @@ The below system diagrams assume the *basic* interaction with the AVSRegistrar.
3. Gating operator registration based on custom stake-weighted parameters

#### Initialization

```mermaid
sequenceDiagram
participant AVSAdmin as AVS Admin
participant AllocationManager
participant AVSRegistrar

AVSAdmin->>AllocationManager: Tx1: set metadataURI
AVSAdmin->>AVSRegistrar: Tx2: deploy AVSRegistrar
AVSAdmin->>AllocationManager: Tx3: set AVSRegistrar
AllocationManager->>AVSRegistrar: Tx3: check supportsAVS()
participant OperatorTableCalculator
participant AllocationManager
participant KeyRegistrar
participant CrossChainRegistry

AVS->>AVSRegistrar: Tx1: Deploy AVSRegistrar
AVS->>AllocationManager: Tx2: updateMetadataURI()
AVS->>AllocationManager: Tx3: setAVSRegistrar(AVSRegistrar)
AllocationManager-->>: check supportsAVS()
AVS->>KeyRegistrar: Tx4: configureOperatorSet(operatorSet, keyMaterial)
```

The `AVSAdmin` is the entity that conducts on-chain operations on behalf of the AVS. It can be a multisig, eoa, or governance contract. In Tx1, when the `metadataURI` is set, the identifier for the AVS in the core protocol is the address of the `AVSAdmin`. For ergonomic purposes, it is possible to have the identifier be the [`AVSRegistrar`](#avsregistrarasidentifier). See the [Core `PermissionController`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/main/docs/permissions/PermissionController.md) for more information on how the admin can be changed.

#### Registration
#### Registration

All registration/deregistration will flow from the `AllocationManager`. The `middlewareV2` architecture no longer requires an AVS to deploy a `KeyRegistrar`. Instead, the `AVSRegistrar` checks key membership in the core `KeyRegistrar` contract.

```mermaid
sequenceDiagram
participant Operator
participant AllocationManager
participant AVSRegistrar

Operator->>AllocationManager: Tx1: Register for opSet
AllocationManager->>AVSRegistrar: Tx1: Send opSets, Data
participant OP as Operator
participant KR as KeyRegistrar
participant AM as AllocationManager
participant AVR as AVSRegistrar

OP->>KR: Tx1: registerKey
OP->>AM: Tx2: registerForOperatorSets
AM-->>AVR: registerForOperatorSets
AVR-->>KR: isRegistered
```

#### Deregistration


```mermaid
sequenceDiagram
participant Operator
participant AllocationManager
participant AVSRegistrar

Operator->>AllocationManager: Tx1: Deregister
AllocationManager->>AVSRegistrar: Tx1: Send Deregistration
AllocationManager-->>AVSRegistrar: Tx1: Send Deregistration
```

#### Operator Key Rotation

Rotation takes a dependency on the `AllocationManager`. In particular, operators are only allowed to deregister their key from an operatorSet if they are not slashable by said operatorSet.

To rotate a key, an operator must deregister from the operatorSet, wait until it is not slashable, deregister its key, and then register a new key. If the operator was not slashable, it can rotate its key without a delay.

```mermaid
sequenceDiagram
participant OP as Operator
participant AM as AllocationManager
participant KR as KeyRegistrar

OP->>AM: Tx1: deregisterFromOperatorSets
Note over OP: Wait 14 days<br>(if previously allocated)
OP->>KR: Tx2: deregisterKey
OP->>AM: Tx3: register new key to operatorSet
```

---
Expand Down Expand Up @@ -143,7 +174,7 @@ function deregisterOperator(
) external virtual onlyAllocationManager;
```

Deregisters an operator from one or more operator sets. This function can be called by an operator OR by the AVSs ejector if it has configured permissions in the [Core `Permission Controller`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/main/docs/permissions/PermissionController.md).
Deregisters an operator from one or more operator sets. This function can be called by on the `AllocationManager` by either the operator OR the AVSs ejector if the AVS has configured permissions in the [Core `Permission Controller`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/main/docs/permissions/PermissionController.md).

*Effects:*
- Emits `OperatorDeregistered` event
Expand Down Expand Up @@ -236,7 +267,6 @@ function _afterDeregisterOperator(
- Triggering external notifications
- Recording additional information


---

## AVSRegistrarWithSocket
Expand Down Expand Up @@ -419,3 +449,5 @@ function initialize(address admin, string memory metadataURI) public initializer
1. Updates AVS metadata URI in the AllocationManager
2. Sets itself as the AVS registrar
3. Initiates admin transfer via PermissionController

---
2 changes: 1 addition & 1 deletion docs/middlewareV2/OperatorTableCalculator.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ In addition, an AVS can build custom calculation methodologies that include:
- Capping the stake of an operator
- Using oracles to price stake

The [`ECDSATableCalculator`](../../src/middlewareV2/tableCalculator/ECDSATableCalculator.sol) and [`BN254TableCalculator`](../../src/middlewareV2/tableCalculator/BN254TableCalculator.sol) value slashable stake equally across all strategies. For example, if an operator allocates 100 stETH, 100 wETH, and 100 USDC the calculator would return 300 for the stake weight of the operator.
The [`ECDSATableCalculator`](../../src/middlewareV2/tableCalculator/ECDSATableCalculator.sol) and [`BN254TableCalculator`](../../src/middlewareV2/tableCalculator/BN254TableCalculator.sol) value slashable stake equally across all strategies. For example, if an operator allocates 100 stETH, 100 wETH, and 100 DAI the calculator would return 300 for the stake weight of the operator.


---
Expand Down
2 changes: 1 addition & 1 deletion lib/eigenlayer-contracts
Submodule eigenlayer-contracts updated 58 files
+53 −36 docs/multichain/destination/CertificateVerifier.md
+36 −46 docs/multichain/destination/OperatorTableUpdater.md
+52 −81 docs/multichain/source/CrossChainRegistry.md
+49 −5 docs/permissions/KeyRegistrar.md
+33 −2 pkg/bindings/BN254CertificateVerifier/binding.go
+32 −1 pkg/bindings/BN254CertificateVerifierStorage/binding.go
+89 −412 pkg/bindings/CrossChainRegistry/binding.go
+76 −399 pkg/bindings/CrossChainRegistryStorage/binding.go
+76 −14 pkg/bindings/ECDSACertificateVerifier/binding.go
+169 −61 pkg/bindings/ECDSACertificateVerifierStorage/binding.go
+32 −1 pkg/bindings/IBN254CertificateVerifier/binding.go
+32 −1 pkg/bindings/IBaseCertificateVerifier/binding.go
+76 −399 pkg/bindings/ICrossChainRegistry/binding.go
+169 −61 pkg/bindings/IECDSACertificateVerifier/binding.go
+44 −34 pkg/bindings/IOperatorTableUpdater/binding.go
+1 −1 pkg/bindings/KeyRegistrar/binding.go
+143 −71 pkg/bindings/OperatorTableUpdater/binding.go
+130 −58 pkg/bindings/OperatorTableUpdaterStorage/binding.go
+2 −20 script/deploy/multichain/deploy_globalRootConfirmerSet.s.sol
+4 −0 script/releases/Env.sol
+6 −2 script/releases/v1.7.0-multichain/1-deploySourceChain.s.sol
+1 −4 script/releases/v1.7.0-multichain/3-deployDestinationChainImpls.s.sol
+46 −19 script/releases/v1.7.0-multichain/4-instantiateDestinationChainProxies.s.sol
+1 −10 script/releases/v1.7.0-multichain/configs/mainnet.toml
+0 −6 script/releases/v1.7.0-multichain/configs/preprod.toml
+0 −6 script/releases/v1.7.0-multichain/configs/testnet.toml
+22 −20 src/contracts/interfaces/IBN254CertificateVerifier.sol
+13 −3 src/contracts/interfaces/IBaseCertificateVerifier.sol
+30 −57 src/contracts/interfaces/ICrossChainRegistry.sol
+49 −20 src/contracts/interfaces/IECDSACertificateVerifier.sol
+29 −20 src/contracts/interfaces/IKeyRegistrar.sol
+26 −18 src/contracts/interfaces/IOperatorTableCalculator.sol
+33 −27 src/contracts/interfaces/IOperatorTableUpdater.sol
+16 −4 src/contracts/multichain/BN254CertificateVerifier.sol
+4 −1 src/contracts/multichain/BN254CertificateVerifierStorage.sol
+34 −127 src/contracts/multichain/CrossChainRegistry.sol
+5 −8 src/contracts/multichain/CrossChainRegistryStorage.sol
+47 −15 src/contracts/multichain/ECDSACertificateVerifier.sol
+4 −1 src/contracts/multichain/ECDSACertificateVerifierStorage.sol
+68 −70 src/contracts/multichain/OperatorTableUpdater.sol
+14 −2 src/contracts/multichain/OperatorTableUpdaterStorage.sol
+0 −9 src/contracts/permissions/KeyRegistrar.sol
+5 −15 src/test/integration/MultichainIntegrationBase.t.sol
+616 −0 src/test/integration/MultichainIntegrationChecks.t.sol
+34 −49 src/test/integration/tests/Multichain_Full_Flow.t.sol
+8 −43 src/test/integration/tests/Multichain_Generation_Reservation_Removal.t.sol
+438 −29 src/test/integration/tests/Multichain_Timing_Tests.t.sol
+51 −1 src/test/mocks/BN254CertificateVerifierMock.sol
+14 −3 src/test/tree/BN254CertificateVerifier.tree
+18 −7 src/test/tree/CrossChainRegistry.tree
+10 −1 src/test/tree/ECDSACertificateVerifierUnit.tree
+4 −2 src/test/tree/OperatorTableUpdaterUnit.tree
+62 −0 src/test/unit/BN254CertificateVerifierUnit.t.sol
+109 −362 src/test/unit/CrossChainRegistryUnit.t.sol
+88 −11 src/test/unit/ECDSACertificateVerifierUnit.t.sol
+0 −53 src/test/unit/KeyRegistrarUnit.t.sol
+0 −892 src/test/unit/Old.t.sol
+298 −92 src/test/unit/OperatorTableUpdaterUnit.t.sol
2 changes: 1 addition & 1 deletion src/middlewareV2/registrar/AVSRegistrar.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ contract AVSRegistrar is Initializable, AVSRegistrarStorage {
) internal view {
for (uint32 i = 0; i < operatorSetIds.length; i++) {
OperatorSet memory operatorSet = OperatorSet({avs: avs, id: operatorSetIds[i]});
require(keyRegistrar.checkKey(operatorSet, operator), KeyNotRegistered());
require(keyRegistrar.isRegistered(operatorSet, operator), KeyNotRegistered());
}
}

Expand Down
11 changes: 3 additions & 8 deletions test/mocks/KeyRegistrarMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,6 @@ contract KeyRegistrarMock is IKeyRegistrar {
_operatorRegistered[operatorSetKey][operator] = _isRegistered;
}

function checkKey(
OperatorSet calldata operatorSet,
address operator
) external view returns (bool) {
return _operatorRegistered[operatorSet.key()][operator];
}

function initialize(
address initialOwner
) external {}
Expand All @@ -51,7 +44,9 @@ contract KeyRegistrarMock is IKeyRegistrar {
function isRegistered(
OperatorSet memory operatorSet,
address operator
) external pure returns (bool) {}
) external view returns (bool) {
return _operatorRegistered[operatorSet.key()][operator];
}

function getOperatorSetCurveType(
OperatorSet memory operatorSet
Expand Down
Loading