diff --git a/docs/middlewareV2/AVSRegistrar.md b/docs/middlewareV2/AVSRegistrar.md new file mode 100644 index 00000000..e817d2b1 --- /dev/null +++ b/docs/middlewareV2/AVSRegistrar.md @@ -0,0 +1,358 @@ +## AVSRegistrar + +| File | Type | Notes | +| -------- | -------- | -------- | +| [`AVSRegistrar.sol`](../../src/middlewareV2/registrar/AVSRegistrar.sol) | Base Contract | Core registrar with hooks for extensibility | +| [`AVSRegistrarWithSocket.sol`](../../src/middlewareV2/registrar/presets/AVSRegistrarWithSocket.sol) | Preset | Adds socket URL management | +| [`AVSRegistrarWithAllowlist.sol`](../../src/middlewareV2/registrar/presets/AVSRegistrarWithAllowlist.sol) | Preset | Restricts registration to allowlisted operators | +| [`AVSRegistrarAsIdentifier.sol`](../../src/middlewareV2/registrar/presets/AVSRegistrarAsIdentifier.sol) | Preset | Serves as the AVS identifier | + +Interfaces: + +| File | Notes | +| -------- | -------- | +| [`IAVSRegistrar.sol`](../../lib/eigenlayer-contracts/src/contracts/interfaces/IAVSRegistrar.sol) | Main interface (in core repo) | +| [`IAVSRegistrarInternal.sol`](../../src/interfaces/IAVSRegistrarInternal.sol) | Errors and events | +| [`ISocketRegistry.sol`](../../src/interfaces/ISocketRegistryV2.sol) | Socket management interface | +| [`IAllowlist.sol`](../../src/interfaces/IAllowlist.sol) | Allowlist management interface | + +--- + +## Overview + +The AVSRegistrar is the primary interface between AVSs and the EigenLayer core protocol for managing operator registration. It enforces that operators have valid keys registered in the `KeyRegistrar` before allowing them to join operator sets. The registrar integrates with the `AllocationManager` to ensure proper stake allocation and operator set membership. + +### Key Features + +- **Access Control**: All registration/deregistration calls must originate from the `AllocationManager` +- **Key Validation**: Ensures operators have registered appropriate keys (ECDSA or BN254) for their operator sets +- **Extensibility**: Provides hooks for custom registration logic +- **Modular Design**: Presets demonstrate common patterns like socket management and access control + +--- + +## AVSRegistrar (Base Contract) + +The base `AVSRegistrar` contract provides core registration functionality with a flexible hooks paradigm for extensibility. + +### Core Functions + +#### `registerOperator` + +```solidity +/** + * @notice Called by the AllocationManager when an operator wants to register + * for one or more operator sets + * @param operator The registering operator + * @param avs The AVS the operator is registering for (must match this.avs()) + * @param operatorSetIds The list of operator set ids being registered for + * @param data Arbitrary data the operator can provide as part of registration + * @dev This method reverts if registration is unsuccessful + */ +function registerOperator( + address operator, + address avs, + uint32[] calldata operatorSetIds, + bytes calldata data +) external virtual onlyAllocationManager; +``` + +Registers an operator to one or more operator sets after validating their keys. + +*Access Control*: +* Only callable by the `AllocationManager` (enforced by modifier) + +*Process*: +1. Calls `_beforeRegisterOperator` hook +2. Validates operator keys via `_validateOperatorKeys` +3. Calls `_afterRegisterOperator` hook +4. Emits `OperatorRegistered` event + +*Reverts*: +* `NotAllocationManager` - If caller is not the AllocationManager +* `KeyNotRegistered` - If operator lacks valid keys for any operator set +* Any custom errors from hook implementations + +#### `deregisterOperator` + +```solidity +/** + * @notice Called by the AllocationManager when an operator is deregistered from + * one or more operator sets + * @param operator The deregistering operator + * @param avs The AVS the operator is deregistering from (must match this.avs()) + * @param operatorSetIds The list of operator set ids being deregistered from + * @dev If this method reverts, it is ignored by the AllocationManager + */ +function deregisterOperator( + address operator, + address avs, + uint32[] calldata operatorSetIds +) external virtual onlyAllocationManager; +``` + +Deregisters an operator from one or more operator sets. + +*Access Control*: +* Only callable by the `AllocationManager` + +*Process*: +1. Calls `_beforeDeregisterOperator` hook +2. Calls `_afterDeregisterOperator` hook +3. Emits `OperatorDeregistered` event + +*Note*: Unlike registration, deregistration failures are ignored by the AllocationManager + +#### `supportsAVS` + +```solidity +/** + * @notice Returns true if the AVS is supported by the registrar + * @param _avs The AVS to check + * @return true if the AVS is supported, false otherwise + */ +function supportsAVS( + address _avs +) public view virtual returns (bool); +``` + +Checks if this registrar supports a given AVS address. + +*Returns*: +* `true` if `_avs` matches the configured AVS address +* `false` otherwise + +### The Hooks Paradigm + +The AVSRegistrar implements a hooks paradigm that enables flexible customization without modifying core logic. This design pattern provides four extension points: + +#### Hook Functions + +```solidity +/** + * @notice Hook called before the operator is registered + * @param operator The operator to register + * @param operatorSetIds The operator sets to register + * @param data The data to register + */ +function _beforeRegisterOperator( + address operator, + uint32[] calldata operatorSetIds, + bytes calldata data +) internal virtual {} + +/** + * @notice Hook called after the operator is registered + * @param operator The operator to register + * @param operatorSetIds The operator sets to register + * @param data The data to register + */ +function _afterRegisterOperator( + address operator, + uint32[] calldata operatorSetIds, + bytes calldata data +) internal virtual {} + +/** + * @notice Hook called before the operator is deregistered + * @param operator The operator to deregister + * @param operatorSetIds The operator sets to deregister + */ +function _beforeDeregisterOperator( + address operator, + uint32[] calldata operatorSetIds +) internal virtual {} + +/** + * @notice Hook called after the operator is deregistered + * @param operator The operator to deregister + * @param operatorSetIds The operator sets to deregister + */ +function _afterDeregisterOperator( + address operator, + uint32[] calldata operatorSetIds +) internal virtual {} +``` + +#### Hook Usage Patterns + +**Before Hooks** are ideal for: +- Access control checks (e.g., allowlist verification) +- Validation of registration data +- Checking operator eligibility +- Enforcing custom requirements + +**After Hooks** are ideal for: +- Storing operator metadata (e.g., socket URLs) +- Updating internal state +- Triggering external notifications +- Recording additional information + +#### Benefits of the Hooks Paradigm + +1. **Composability**: Multiple behaviors can be combined by chaining hook implementations +2. **Reusability**: Common patterns can be extracted into modules +3. **Upgradability**: New functionality can be added without modifying core logic +4. **Separation of Concerns**: Core registration logic remains simple and focused + +### Internal Functions + +#### `_validateOperatorKeys` + +```solidity +/** + * @notice Validates that the operator has registered a key for the given operator sets + * @param operator The operator to validate + * @param operatorSetIds The operator sets to validate + * @dev This function assumes the operator has already registered a key in the Key Registrar + */ +function _validateOperatorKeys( + address operator, + uint32[] calldata operatorSetIds +) internal view; +``` + +Ensures the operator has registered appropriate keys for all specified operator sets. + +*Process*: +* For each operator set ID: + * Constructs the `OperatorSet` struct + * Calls `keyRegistrar.checkKey()` to verify key registration + * Reverts with `KeyNotRegistered` if check fails + +--- + +## AVSRegistrarWithSocket + +Extends the base registrar to capture and store operator socket URLs for off-chain communication. + +### Additional Functionality + +- Inherits from `SocketRegistry` module +- Stores socket URLs in the `_afterRegisterOperator` hook +- Allows operators to update their socket URLs post-registration + +### Registration Data Format + +```solidity +// Socket URL must be ABI-encoded as a string +bytes memory data = abi.encode("https://operator.example.com:8080"); +``` + +### Key Methods (from SocketRegistry) + +```solidity +/** + * @notice Get the socket URL for an operator + * @param operator The operator address + * @return The operator's socket URL + */ +function getOperatorSocket(address operator) external view returns (string memory); + +/** + * @notice Update the socket URL for the calling operator + * @param operator The operator address (must be msg.sender) + * @param socket The new socket URL + */ +function updateSocket(address operator, string memory socket) external; +``` + +--- + +## AVSRegistrarWithAllowlist + +Adds permissioned registration by maintaining per-operator-set allowlists. + +### Additional Functionality + +- Inherits from `Allowlist` module with `OwnableUpgradeable` +- Checks allowlist in the `_beforeRegisterOperator` hook +- Admin can manage allowlists via standard functions + +### Initialization + +```solidity +/** + * @notice Initialize the allowlist with an admin + * @param admin The address that can manage the allowlist + */ +function initialize(address admin) public override initializer; +``` + +### Key Methods (from Allowlist) + +```solidity +/** + * @notice Add an operator to the allowlist for a specific operator set + * @param operatorSet The operator set to update + * @param operator The operator to add + * @dev Only callable by owner + */ +function addOperatorToAllowlist( + OperatorSet memory operatorSet, + address operator +) external onlyOwner; + +/** + * @notice Remove an operator from the allowlist + * @param operatorSet The operator set to update + * @param operator The operator to remove + * @dev Only callable by owner + */ +function removeOperatorFromAllowlist( + OperatorSet memory operatorSet, + address operator +) external onlyOwner; + +/** + * @notice Check if an operator is allowed for a specific operator set + * @param operatorSet The operator set to check + * @param operator The operator to check + * @return true if allowed, false otherwise + */ +function isOperatorAllowed( + OperatorSet memory operatorSet, + address operator +) public view returns (bool); +``` + +--- + +## AVSRegistrarAsIdentifier + +A specialized registrar that serves as both the registrar and the AVS identifier in the EigenLayer protocol. + +### Key Differences + +- The registrar contract address becomes the AVS address +- Manages AVS metadata and permissions during initialization +- Integrates with `PermissionController` for admin management + +### Initialization + +```solidity +/** + * @notice Initialize the AVS with metadata and admin + * @param admin The address that will control the AVS + * @param metadataURI The metadata URI for the AVS + */ +function initialize(address admin, string memory metadataURI) public initializer; +``` + +*Initialization Process*: +1. Updates AVS metadata URI in the AllocationManager +2. Sets itself as the AVS registrar +3. Initiates admin transfer via PermissionController + +### Use Cases + +This preset is ideal when: +- You want a single contract to represent your AVS +- You need simplified deployment and management +- You want the registrar to be the primary AVS identity + +### Benefits + +1. **Simplified Architecture**: One less contract to deploy and manage +2. **Clear Identity**: The registrar IS the AVS +3. **Integrated Permissions**: Admin control is built into initialization \ No newline at end of file diff --git a/docs/middlewareV2/OperatorTableCalculator.md b/docs/middlewareV2/OperatorTableCalculator.md new file mode 100644 index 00000000..0d7b13de --- /dev/null +++ b/docs/middlewareV2/OperatorTableCalculator.md @@ -0,0 +1,255 @@ +## OperatorTableCalculator + +| File | Type | Notes | +| -------- | -------- | +| [`ECDSATableCalculatorBase.sol`](../../src/middlewareV2/tableCalculator/ECDSATableCalculatorBase.sol) | Abstract | Base functionality for ECDSA operator tables | +| [`BN254TableCalculatorBase.sol`](../../src/middlewareV2/tableCalculator/BN254TableCalculatorBase.sol) | Abstract | Base functionality for BN254 operator tables | + +Interfaces: + +| File | Notes | +| -------- | -------- | +| [`IOperatorTableCalculator.sol`](../../lib/eigenlayer-contracts/src/contracts/interfaces/IOperatorTableCalculator.sol) | Base interface for all calculators (in core repo) | +| [`IECDSATableCalculator.sol`](../../src/interfaces/IECDSATableCalculator.sol) | ECDSA-specific interface | +| [`IBN254TableCalculator.sol`](../../src/interfaces/IBN254TableCalculator.sol) | BN254-specific interface | + +--- + +## Overview + +The OperatorTableCalculator contracts are responsible for calculating stake weights of operator. These stake weights are aggregated and transported using the [Eigenlayer Multichain Protocol](https://github.com/eigenfoundation/ELIPs/blob/main/ELIPs/ELIP-008.md). In order to utilize the multichain protocol, an AVS *MUST* deploy an `OperatorTableCalculator` and register it in the `CrossChainRegistry` in EigenLayer core. See our [core documentation](https://github.com/Layr-Labs/eigenlayer-contracts/tree/release-dev/multichain/docs/multichain#common-user-flows) for this process. + +The base contracts (`ECDSATableCalculatorBase` and `BN254TableCalculatorBase`) provide the core logic for table calculation to be consumed by EigenLayer core, while leaving weight calculation as an unimplemented method to be implemented by derived contracts. + +### Stake Weighting + +It is up to the AVS to define each operator's weights array in an operatorSet. Some examples include: + +- A single array evaluated purely on slashable stake `[slashable_stake]` +- An array of 2 values can be used for evaluating on slashable and delegated stake `[slashable_stake, delegated_stake]` +- An array of several values can be used for evaluating stake on multiple strategies `[slashable_stake_stETH, slashable_stake_USDC, slashable_stake_EIGEN]` + +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 the calculator would return 300 for the stake weight of the operator. + + +--- + +## ECDSATableCalculatorBase + +The `ECDSATableCalculatorBase` provides base functionality for calculating ECDSA operator tables. It handles operator key retrieval and table construction. + +### Core Functions + +#### `calculateOperatorTable` + +```solidity +/** + * @notice A struct that contains information about a single operator + * @param pubkey The address of the signing ECDSA key of the operator and not the operator address itself. + * This is read from the KeyRegistrar contract. + * @param weights The weights of the operator for a single operatorSet + * @dev The `weights` array can be defined as a list of arbitrary groupings. For example, + * it can be [slashable_stake, delegated_stake, strategy_i_stake, ...] + * @dev The `weights` array should be the same length for each operator in the operatorSet. + */ +struct ECDSAOperatorInfo { + address pubkey; + uint256[] weights; +} + +/** + * @notice calculates the operatorInfos for a given operatorSet + * @param operatorSet the operatorSet to calculate the operator table for + * @return operatorInfos the list of operatorInfos for the given operatorSet + * @dev The output of this function is converted to bytes via the `calculateOperatorTableBytes` function + */ +function calculateOperatorTable( + OperatorSet calldata operatorSet +) external view returns (ECDSAOperatorInfo[] memory operatorInfos); +``` + +Calculates and returns an array of `ECDSAOperatorInfo` structs containing public keys and weights for all operators in the operatorSet who have registered ECDSA keys. + +*Effects*: +* None (view function) + +*Process*: +* Calls `_getOperatorWeights` to retrieve operator addresses and their weights +* For each operator with a registered ECDSA key: + * Retrieves the ECDSA address (public key) from the `KeyRegistrar` + * Creates an `ECDSAOperatorInfo` struct with the public key and weights +* Returns only operators with registered keys + +#### `calculateOperatorTableBytes` + +```solidity +/** + * @notice Calculates the operator table bytes for a given operatorSet + * @param operatorSet The operatorSet to calculate the operator table for + * @return operatorTableBytes The encoded operator table bytes + */ +function calculateOperatorTableBytes( + OperatorSet calldata operatorSet +) external view returns (bytes memory operatorTableBytes); +``` + +Returns the ABI-encoded bytes representation of the operator table, which is used by the `CrossChainRegistry` to calculate the operatorTable. + +*Returns*: +* ABI-encoded array of `ECDSAOperatorInfo` structs + +### Abstract Methods + +#### `_getOperatorWeights` + +```solidity +/** + * @notice Abstract function to get the operator weights for a given operatorSet + * @param operatorSet The operatorSet to get the weights for + * @return operators The addresses of the operators in the operatorSet + * @return weights The weights for each operator in the operatorSet + */ +function _getOperatorWeights( + OperatorSet calldata operatorSet +) internal view virtual returns (address[] memory operators, uint256[][] memory weights); +``` + +Must be implemented by derived contracts to define the weight calculation strategy. See [stakeWeighting](#stake-weighting) for more information. + +An example integration is in [`ECDSATableCalculator`](../../src/middlewareV2/tableCalculator/ECDSATableCalculator.sol) + +--- + +## BN254TableCalculatorBase + +The `BN254TableCalculatorBase` provides base functionality for calculating BN254 operator tables. + +### Core Functions + +#### `calculateOperatorTable` + +```solidity +/** + * @notice A struct that contains information about a single operator + * @param pubkey The G1 public key of the operator. + * @param weights The weights of the operator for a single operatorSet. + * @dev The `weights` array can be defined as a list of arbitrary groupings. For example, + * it can be [slashable_stake, delegated_stake, strategy_i_stake, ...] + */ +struct BN254OperatorInfo { + BN254.G1Point pubkey; + uint256[] weights; +} + +/** + * @notice A struct that contains information about all operators for a given operatorSet + * @param operatorInfoTreeRoot The root of the operatorInfo tree. Each leaf is a `BN254OperatorInfo` struct + * @param numOperators The number of operators in the operatorSet. + * @param aggregatePubkey The aggregate G1 public key of the operators in the operatorSet. + * @param totalWeights The total weights of the operators in the operatorSet. + * + * @dev The operatorInfoTreeRoot is the root of a merkle tree that contains the operatorInfos for each operator in the operatorSet. + * It is calculated in this function and used by the `IBN254CertificateVerifier` to verify stakes against the non-signing operators + * + * @dev Retrieval of the `aggregatePubKey` depends on maintaining a key registry contract, see `BN254TableCalculatorBase` for an example implementation. + * + * @dev The `totalWeights` array should be the same length as each individual `weights` array in `operatorInfos`. + */ +struct BN254OperatorSetInfo { + bytes32 operatorInfoTreeRoot; + uint256 numOperators; + BN254.G1Point aggregatePubkey; + uint256[] totalWeights; +} + +/** + * @notice calculates the operatorInfos for a given operatorSet + * @param operatorSet the operatorSet to calculate the operator table for + * @return operatorSetInfo the operatorSetInfo for the given operatorSet + * @dev The output of this function is converted to bytes via the `calculateOperatorTableBytes` function + */ +function calculateOperatorTable( + OperatorSet calldata operatorSet +) external view returns (BN254OperatorSetInfo memory operatorSetInfo); +``` + +Calculates and returns a `BN254OperatorSetInfo` struct containing: +- A merkle tree root of operator information +- The total number of operators +- An aggregate BN254 public key +- Total weights across all operators + +*Effects*: +* None (view function) + +*Process*: +* Calls `_getOperatorWeights` to retrieve operator addresses and their weights +* For each operator with a registered BN254 key: + * Retrieves the BN254 G1 point from the `KeyRegistrar` + * Adds the operator's weights to the total weights + * Creates a merkle leaf from the operator info + * Adds the G1 point to the aggregate public key +* Constructs a merkle tree from all operator info leaves +* Returns the complete operator set information + +BN254 tables take advantage of signature aggregation. As such, we add operator's weights to the total weights. We generate a merkle root that contains individual operator stakes (`BN254OperatorInfo`) to lower transport costs. See the core [`BN254CertificateVerifier`](https://github.com/Layr-Labs/eigenlayer-contracts/blob/release-dev/multichain/docs/multichain/destination/CertificateVerifier.md) for more information on the caching and verification scheme. + +#### `calculateOperatorTableBytes` + +```solidity +/** + * @notice Calculates the operator table bytes for a given operatorSet + * @param operatorSet The operatorSet to calculate the operator table for + * @return operatorTableBytes The encoded operator table bytes + */ +function calculateOperatorTableBytes( + OperatorSet calldata operatorSet +) external view returns (bytes memory operatorTableBytes); +``` + +Returns the ABI-encoded bytes representation of the operator table, which is used by the `CrossChainRegistry` to calculate the operatorTable. + +*Returns*: +* ABI-encoded `BN254OperatorSetInfo` struct + +#### `getOperatorInfos` + +```solidity +/** + * @notice Get the operatorInfos for a given operatorSet + * @param operatorSet the operatorSet to get the operatorInfos for + * @return operatorInfos the operatorInfos for the given operatorSet + */ +function getOperatorInfos( + OperatorSet calldata operatorSet +) external view returns (BN254OperatorInfo[] memory operatorInfos); +``` + +Returns an array of `BN254OperatorInfo` structs for all operators in the operatorSet who have registered BN254 keys. + +*Effects*: +* None (view function) + +### Abstract Methods + +#### `_getOperatorWeights` + +```solidity +/** + * @notice Abstract function to get the operator weights for a given operatorSet + * @param operatorSet The operatorSet to get the weights for + * @return operators The addresses of the operators in the operatorSet + * @return weights The weights for each operator in the operatorSet + */ +function _getOperatorWeights( + OperatorSet calldata operatorSet +) internal view virtual returns (address[] memory operators, uint256[][] memory weights); +``` + +Must be implemented by derived contracts to define the weight calculation strategy. Similar to ECDSA, weights are a 2D array supporting multiple weight types per operator. + +An example integration is defined in [`BN254TableCalculator`](../../src/middlewareV2/tableCalculator/BN254TableCalculator.sol). diff --git a/docs/middlewareV2/README.md b/docs/middlewareV2/README.md new file mode 100644 index 00000000..0cf9a184 --- /dev/null +++ b/docs/middlewareV2/README.md @@ -0,0 +1,189 @@ +[elip-008]: https://github.com/eigenfoundation/ELIPs/blob/main/ELIPs/ELIP-008.md +[core-multichain-docs]: https://github.com/Layr-Labs/eigenlayer-contracts/tree/release-dev/multichain/docs/multichain + +## MiddlewareV2 + +The middlewareV2 architecture simplifies AVS development by: +1. Utilizing core protocol contracts for operator key storage (`KeyRegistrar`) and task verification (`BN254CertificateVerifier` and `ECDSACertificateVerifier`) +2. Utilizing core contracts for OperatorSet (eg. quorum) membership and strategy composition in the `AllocationManager` +3. Utilizing the EigenLabs-run offchain services to update stakes instead of [`avs-sync](https://github.com/Layr-Labs/avs-sync) + +--- + +### Contents + +* [System Diagram](#system-diagram) +* [AVS Registrar](#avs-registrar) +* [Operator Table Calculator](#operator-table-calculator) + * [`ECSDATableCalculator`](#ecdsatablecalculator) + * [`BN254TableCalculator`](#bn254tablecalculator) +* [Core Contract Integrations](#core-contract-integrations) + * [`KeyRegistrar`](#key-registrar) + * [`AllocationManager`](#allocation-manager) + * [`CertificateVerifier`](#certificate-verifier) +* [Roles and Actors](#roles-and-actors) +* [Migration](#migration) + +--- + +### System Diagram + +```mermaid +classDiagram +direction TD +namespace Middleware-on-Ethereum{ + class OperatorTableCalculator { + StakeCapping + StakeWeighting (Multiplier, Oracle) + ProtocolVotingPowerCalc + } + class AVSAdmin { + metadataURI + Permissions/multisigs/governance + verificationDelay + transportPayments + } + class AVSRegistrar { + registerOperator + deregisterOperator + } + class SlasherEjector { + submitEvidence + slashOperator () + ejectOperator () + } + class RegistrationHooks{ + RegistrationLogic + OperatorCaps + Churn + Sockets + } +} +namespace Ethereum-EigenLayer-Core{ + class AllocationManager { + registerForOperatorSets + deregisterFromOperatorSets + allocateStake + deallocateStake + slashOperator() + } + class KeyRegistrar{ + registerKey + deregisterKey + getKey (operator addr) + isRegistered (operator addr) + } + class CrossChainRegistry{ + setOperatorTableCalculator + getOperatorTableCalculator + makeGenerationReservation + addTransportDestination + calculateOperatorTableBytes() + } +} +namespace TargetChain{ + class OperatorTableUpdater{ + confirmGlobalTableRoot + updateOperatorTable() + } + class CertificateVerifier{ + n Operator Tables + updateOperatorTable() + verifyCert (bool) + } + class AVSConsumer{ + requests Operator task + receives cert () + } +} + +namespace Offchain{ + class Operator { + consumer input + return certificate() + } + class Transport{ + getOperatorTables + n calculateOperatorTableBytes + calculateGlobalStakeTable() + } +} +AllocationManager --> AVSRegistrar +AVSAdmin --> CrossChainRegistry +CrossChainRegistry --> OperatorTableCalculator : Calculates Operator Tables +AVSRegistrar --> RegistrationHooks +RegistrationHooks --> KeyRegistrar +SlasherEjector --> AllocationManager : Slash or eject Operator +CrossChainRegistry --> Transport : Transports Operator tables +Transport --> OperatorTableUpdater: Update global stake root +OperatorTableUpdater --> CertificateVerifier: Update Operator Table +Operator --> AVSConsumer : Produces certificate +Operator <-- AVSConsumer : Requests task +AVS Consumer --> CertificateVerifier : Verifies Certificate +``` + +AVS developers only have to manage deployments of the the following contracts on-chain: +- [`AVSRegistrar`](#avs-registrar) +- [`OperatorTableCalculator`](#operator-table-calculator) +- [`Slasher`](../slashing/SlasherBase.md) +- Admin Functionality + - Rewards Submission + - Ejection *Note: A module for programmatic ejection will be available in a future release*. + +MiddlewareV2 architecture defines standards for the `AVSRegistrar` and `OperatorTableCalculator`. + +See the [`multichain-ELIP`](elip-008) and [`core contracts documentation`](core-multichain-docs) for more information. + +--- + +### AVS Registrar + +The AVS Registrar is the primary interface for managing operator registration and deregistration within an AVS. It integrates with core EigenLayer contracts to ensure operators have valid keys and are properly registered in operator sets. + +| File | Type | Description | +| -------- | -------- | -------- | +| [`AVSRegistrar.sol`](../../src/middlewareV2/registrar/AVSRegistrar.sol) | Proxy | Core registrar contract that handles operator registration/deregistration | +| [`AVSRegistrarWithSocket.sol`](../../src/middlewareV2/registrar/presets/AVSRegistrarWithSocket.sol) | Proxy | Adds socket URL registration for operator communication | +| [`AVSRegistrarWithAllowlist.sol`](../../src/middlewareV2/registrar/presets/AVSRegistrarWithAllowlist.sol) | Proxy | Restricts registration to allowlisted operators | +| [`AVSRegistrarAsIdentifier.sol`](../../src/middlewareV2/registrar/presets/AVSRegistrarAsIdentifier.sol) | Proxy | Serves as the AVS identifier and manages permissions | + +#### Base AVSRegistrar + +The `AVSRegistrar` provides base functionality for AVSs to register and deregister operators to their operatorSet. A single `AVSRegistrar` supports multiple operatorSets. ***This contract expects operator registrations and deregistrations to originate from the `AllocationManager`***. + +See full documentation in [`./AVSRegistrar.md`](./AVSRegistrar.md). + + + +--- + +### Operator Table Calculator + +| File | Type | +| -------- | -------- | +| [`BN254TableCalculatorBase.sol`](../../src/middlewareV2/tableCalculator/BN254TableCalculatorBase.sol) | Abstract Contract | +| [`BN254TableCalculator.sol`](../../src/middlewareV2/tableCalculator/BN254TableCalculator.sol) | Basic table calculator that sums slashable stake across all strategies | +| [`ECDSATableCalculatorBase.sol`](../../src/middlewareV2/tableCalculator/ECDSATableCalculator.sol) | Abstract Contract | +| [`ECDSATableCalculator.sol`](../../src/middlewareV2/tableCalculator/ECDSATableCalculator.sol) | Basic table calculator that sums slashable stake across all strategies | + +These contracts define custom stake weights of operators in an operatorSet. They are segmented by key-type. + +See full documentation in [`/operatorTableCalculator.md`](./OperatorTableCalculator.md). + +--- + +### Core Contract Integrations + +#### Key Registrar + +#### Allocation Manager + +#### Certificate Verifier + +--- + +### Roles and Actors + +--- + +### Migration \ No newline at end of file diff --git a/src/middlewareV2/tableCalculator/BN254TableCalculator.sol b/src/middlewareV2/tableCalculator/BN254TableCalculator.sol index 2ad9fcd8..8ebe2174 100644 --- a/src/middlewareV2/tableCalculator/BN254TableCalculator.sol +++ b/src/middlewareV2/tableCalculator/BN254TableCalculator.sol @@ -12,6 +12,7 @@ import "./BN254TableCalculatorBase.sol"; /** * @title BN254TableCalculator * @notice Implementation that calculates BN254 operator tables using the sum of the minimum slashable stake weights + * @dev This contract assumes that slashable stake is values the **same** across all strategies. */ contract BN254TableCalculator is BN254TableCalculatorBase { // Immutables diff --git a/src/middlewareV2/tableCalculator/ECDSATableCalculator.sol b/src/middlewareV2/tableCalculator/ECDSATableCalculator.sol index 192ae11e..bd00d74a 100644 --- a/src/middlewareV2/tableCalculator/ECDSATableCalculator.sol +++ b/src/middlewareV2/tableCalculator/ECDSATableCalculator.sol @@ -12,6 +12,7 @@ import "./ECDSATableCalculatorBase.sol"; /** * @title ECDSATableCalculator * @notice Implementation that calculates ECDSA operator tables using the sum of the minimum slashable stake weights + * @dev This contract assumes that slashable stake is values the **same** across all strategies. */ contract ECDSATableCalculator is ECDSATableCalculatorBase { // Immutables