Skip to content

Commit 0814b72

Browse files
committed
docs: add otc
1 parent 082708e commit 0814b72

File tree

5 files changed

+322
-0
lines changed

5 files changed

+322
-0
lines changed

docs/middlewareV2/AVSRegistrar.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TODO
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
## OperatorTableCalculator
2+
3+
| File | Type | Notes |
4+
| -------- | -------- |
5+
| [`ECDSATableCalculatorBase.sol`](../../src/middlewareV2/tableCalculator/ECDSATableCalculatorBase.sol) | Abstract | Base functionality for ECDSA operator tables |
6+
| [`BN254TableCalculatorBase.sol`](../../src/middlewareV2/tableCalculator/BN254TableCalculatorBase.sol) | Abstract | Base functionality for BN254 operator tables |
7+
8+
Interfaces:
9+
10+
| File | Notes |
11+
| -------- | -------- |
12+
| [`IOperatorTableCalculator.sol`](../../lib/eigenlayer-contracts/src/contracts/interfaces/IOperatorTableCalculator.sol) | Base interface for all calculators (in core repo) |
13+
| [`IECDSATableCalculator.sol`](../../src/interfaces/IECDSATableCalculator.sol) | ECDSA-specific interface |
14+
| [`IBN254TableCalculator.sol`](../../src/interfaces/IBN254TableCalculator.sol) | BN254-specific interface |
15+
16+
---
17+
18+
## Overview
19+
20+
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.
21+
22+
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.
23+
24+
### Stake Weighting
25+
26+
It is up to the AVS to define each operator's weights array in an operatorSet. Some examples include:
27+
28+
- A single array evaluated purely on slashable stake `[slashable_stake]`
29+
- An array of 2 values can be used for evaluating on slashable and delegated stake `[slashable_stake, delegated_stake]`
30+
- An array of several values can be used for evaluating stake on multiple strategies `[slashable_stake_stETH, slashable_stake_USDC, slashable_stake_EIGEN]`
31+
32+
In addition, an AVS can build custom calculation methodologies that include:
33+
- Capping the stake of an operator
34+
- Using oracles to price stake
35+
36+
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.
37+
38+
39+
---
40+
41+
## ECDSATableCalculatorBase
42+
43+
The `ECDSATableCalculatorBase` provides base functionality for calculating ECDSA operator tables. It handles operator key retrieval and table construction.
44+
45+
### Core Functions
46+
47+
#### `calculateOperatorTable`
48+
49+
```solidity
50+
/**
51+
* @notice A struct that contains information about a single operator
52+
* @param pubkey The address of the signing ECDSA key of the operator and not the operator address itself.
53+
* This is read from the KeyRegistrar contract.
54+
* @param weights The weights of the operator for a single operatorSet
55+
* @dev The `weights` array can be defined as a list of arbitrary groupings. For example,
56+
* it can be [slashable_stake, delegated_stake, strategy_i_stake, ...]
57+
* @dev The `weights` array should be the same length for each operator in the operatorSet.
58+
*/
59+
struct ECDSAOperatorInfo {
60+
address pubkey;
61+
uint256[] weights;
62+
}
63+
64+
/**
65+
* @notice calculates the operatorInfos for a given operatorSet
66+
* @param operatorSet the operatorSet to calculate the operator table for
67+
* @return operatorInfos the list of operatorInfos for the given operatorSet
68+
* @dev The output of this function is converted to bytes via the `calculateOperatorTableBytes` function
69+
*/
70+
function calculateOperatorTable(
71+
OperatorSet calldata operatorSet
72+
) external view returns (ECDSAOperatorInfo[] memory operatorInfos);
73+
```
74+
75+
Calculates and returns an array of `ECDSAOperatorInfo` structs containing public keys and weights for all operators in the operatorSet who have registered ECDSA keys.
76+
77+
*Effects*:
78+
* None (view function)
79+
80+
*Process*:
81+
* Calls `_getOperatorWeights` to retrieve operator addresses and their weights
82+
* For each operator with a registered ECDSA key:
83+
* Retrieves the ECDSA address (public key) from the `KeyRegistrar`
84+
* Creates an `ECDSAOperatorInfo` struct with the public key and weights
85+
* Returns only operators with registered keys
86+
87+
#### `calculateOperatorTableBytes`
88+
89+
```solidity
90+
/**
91+
* @notice Calculates the operator table bytes for a given operatorSet
92+
* @param operatorSet The operatorSet to calculate the operator table for
93+
* @return operatorTableBytes The encoded operator table bytes
94+
*/
95+
function calculateOperatorTableBytes(
96+
OperatorSet calldata operatorSet
97+
) external view returns (bytes memory operatorTableBytes);
98+
```
99+
100+
Returns the ABI-encoded bytes representation of the operator table, which is used by the `CrossChainRegistry` to calculate the operatorTable.
101+
102+
*Returns*:
103+
* ABI-encoded array of `ECDSAOperatorInfo` structs
104+
105+
### Abstract Methods
106+
107+
#### `_getOperatorWeights`
108+
109+
```solidity
110+
/**
111+
* @notice Abstract function to get the operator weights for a given operatorSet
112+
* @param operatorSet The operatorSet to get the weights for
113+
* @return operators The addresses of the operators in the operatorSet
114+
* @return weights The weights for each operator in the operatorSet
115+
*/
116+
function _getOperatorWeights(
117+
OperatorSet calldata operatorSet
118+
) internal view virtual returns (address[] memory operators, uint256[][] memory weights);
119+
```
120+
121+
Must be implemented by derived contracts to define the weight calculation strategy. See [stakeWeighting](#stake-weighting) for more information.
122+
123+
An example integration is in [`ECDSATableCalculator`](../../src/middlewareV2/tableCalculator/ECDSATableCalculator.sol)
124+
125+
---
126+
127+
## BN254TableCalculatorBase
128+
129+
The `BN254TableCalculatorBase` provides base functionality for calculating BN254 operator tables.
130+
131+
### Core Functions
132+
133+
#### `calculateOperatorTable`
134+
135+
```solidity
136+
/**
137+
* @notice A struct that contains information about a single operator
138+
* @param pubkey The G1 public key of the operator.
139+
* @param weights The weights of the operator for a single operatorSet.
140+
* @dev The `weights` array can be defined as a list of arbitrary groupings. For example,
141+
* it can be [slashable_stake, delegated_stake, strategy_i_stake, ...]
142+
*/
143+
struct BN254OperatorInfo {
144+
BN254.G1Point pubkey;
145+
uint256[] weights;
146+
}
147+
148+
/**
149+
* @notice A struct that contains information about all operators for a given operatorSet
150+
* @param operatorInfoTreeRoot The root of the operatorInfo tree. Each leaf is a `BN254OperatorInfo` struct
151+
* @param numOperators The number of operators in the operatorSet.
152+
* @param aggregatePubkey The aggregate G1 public key of the operators in the operatorSet.
153+
* @param totalWeights The total weights of the operators in the operatorSet.
154+
*
155+
* @dev The operatorInfoTreeRoot is the root of a merkle tree that contains the operatorInfos for each operator in the operatorSet.
156+
* It is calculated in this function and used by the `IBN254CertificateVerifier` to verify stakes against the non-signing operators
157+
*
158+
* @dev Retrieval of the `aggregatePubKey` depends on maintaining a key registry contract, see `BN254TableCalculatorBase` for an example implementation.
159+
*
160+
* @dev The `totalWeights` array should be the same length as each individual `weights` array in `operatorInfos`.
161+
*/
162+
struct BN254OperatorSetInfo {
163+
bytes32 operatorInfoTreeRoot;
164+
uint256 numOperators;
165+
BN254.G1Point aggregatePubkey;
166+
uint256[] totalWeights;
167+
}
168+
169+
/**
170+
* @notice calculates the operatorInfos for a given operatorSet
171+
* @param operatorSet the operatorSet to calculate the operator table for
172+
* @return operatorSetInfo the operatorSetInfo for the given operatorSet
173+
* @dev The output of this function is converted to bytes via the `calculateOperatorTableBytes` function
174+
*/
175+
function calculateOperatorTable(
176+
OperatorSet calldata operatorSet
177+
) external view returns (BN254OperatorSetInfo memory operatorSetInfo);
178+
```
179+
180+
Calculates and returns a `BN254OperatorSetInfo` struct containing:
181+
- A merkle tree root of operator information
182+
- The total number of operators
183+
- An aggregate BN254 public key
184+
- Total weights across all operators
185+
186+
*Effects*:
187+
* None (view function)
188+
189+
*Process*:
190+
* Calls `_getOperatorWeights` to retrieve operator addresses and their weights
191+
* For each operator with a registered BN254 key:
192+
* Retrieves the BN254 G1 point from the `KeyRegistrar`
193+
* Adds the operator's weights to the total weights
194+
* Creates a merkle leaf from the operator info
195+
* Adds the G1 point to the aggregate public key
196+
* Constructs a merkle tree from all operator info leaves
197+
* Returns the complete operator set information
198+
199+
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.
200+
201+
#### `calculateOperatorTableBytes`
202+
203+
```solidity
204+
/**
205+
* @notice Calculates the operator table bytes for a given operatorSet
206+
* @param operatorSet The operatorSet to calculate the operator table for
207+
* @return operatorTableBytes The encoded operator table bytes
208+
*/
209+
function calculateOperatorTableBytes(
210+
OperatorSet calldata operatorSet
211+
) external view returns (bytes memory operatorTableBytes);
212+
```
213+
214+
Returns the ABI-encoded bytes representation of the operator table, which is used by the `CrossChainRegistry` to calculate the operatorTable.
215+
216+
*Returns*:
217+
* ABI-encoded `BN254OperatorSetInfo` struct
218+
219+
#### `getOperatorInfos`
220+
221+
```solidity
222+
/**
223+
* @notice Get the operatorInfos for a given operatorSet
224+
* @param operatorSet the operatorSet to get the operatorInfos for
225+
* @return operatorInfos the operatorInfos for the given operatorSet
226+
*/
227+
function getOperatorInfos(
228+
OperatorSet calldata operatorSet
229+
) external view returns (BN254OperatorInfo[] memory operatorInfos);
230+
```
231+
232+
Returns an array of `BN254OperatorInfo` structs for all operators in the operatorSet who have registered BN254 keys.
233+
234+
*Effects*:
235+
* None (view function)
236+
237+
### Abstract Methods
238+
239+
#### `_getOperatorWeights`
240+
241+
```solidity
242+
/**
243+
* @notice Abstract function to get the operator weights for a given operatorSet
244+
* @param operatorSet The operatorSet to get the weights for
245+
* @return operators The addresses of the operators in the operatorSet
246+
* @return weights The weights for each operator in the operatorSet
247+
*/
248+
function _getOperatorWeights(
249+
OperatorSet calldata operatorSet
250+
) internal view virtual returns (address[] memory operators, uint256[][] memory weights);
251+
```
252+
253+
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.
254+
255+
An example integration is defined in [`BN254TableCalculator`](../../src/middlewareV2/tableCalculator/BN254TableCalculator.sol).

docs/middlewareV2/README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
[elip-008]: https://github.com/eigenfoundation/ELIPs/blob/main/ELIPs/ELIP-008.md
2+
[core-multichain-docs]: https://github.com/Layr-Labs/eigenlayer-contracts/tree/release-dev/multichain/docs/multichain
3+
4+
## MiddlewareV2
5+
6+
The middlewareV2 architecture utilizes EigenLayer core contracts as a base for new multichain contracts.
7+
8+
---
9+
10+
### Contents
11+
12+
* [System Diagram](#system-diagram)
13+
* [AVS Registrar](#avs-registrar)
14+
* [Operator Table Calculator](#operator-table-calculator)
15+
* [`ECSDATableCalculator`](#ecdsatablecalculator)
16+
* [`BN254TableCalculator`](#bn254tablecalculator)
17+
* [Core Contract Integrations](#core-contract-integrations)
18+
* [`KeyRegistrar`](#key-registrar)
19+
* [`AllocationManager`](#allocation-manager)
20+
* [`CertificateVerifier`](#certificate-verifier)
21+
* [Roles and Actors](#roles-and-actors)
22+
* [Migration](#migration)
23+
24+
---
25+
26+
### System Diagram
27+
28+
---
29+
30+
### AVS Registrar
31+
32+
---
33+
34+
### Operator Table Calculator
35+
36+
| File | Type |
37+
| -------- | -------- |
38+
| [`BN254TableCalculatorBase.sol`](../../src/middlewareV2/tableCalculator/BN254TableCalculatorBase.sol) | Abstract Contract |
39+
| [`BN254TableCalculator.sol`](../../src/middlewareV2/tableCalculator/BN254TableCalculator.sol) | Basic table calculator that sums slashable stake across all strategies |
40+
| [`ECDSATableCalculatorBase.sol`](../../src/middlewareV2/tableCalculator/ECDSATableCalculator.sol) | Abstract Contract |
41+
| [`ECDSATableCalculator.sol`](../../src/middlewareV2/tableCalculator/ECDSATableCalculator.sol) | Basic table calculator that sums slashable stake across all strategies |
42+
43+
44+
These contracts define custom stake weights of operators in an operatorSet. They are segmented by key-type.
45+
46+
See full documentation in [`/operatorTableCalculator.md`](./OperatorTableCalculator.md).
47+
48+
---
49+
50+
### Core Contract Integrations
51+
52+
#### Key Registrar
53+
54+
#### Allocation Manager
55+
56+
#### Certificate Verifier
57+
58+
---
59+
60+
### Roles and Actors
61+
62+
---
63+
64+
### Migration

src/middlewareV2/tableCalculator/BN254TableCalculator.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import "./BN254TableCalculatorBase.sol";
1212
/**
1313
* @title BN254TableCalculator
1414
* @notice Implementation that calculates BN254 operator tables using the sum of the minimum slashable stake weights
15+
* @dev This contract assumes that slashable stake is values the **same** across all strategies.
1516
*/
1617
contract BN254TableCalculator is BN254TableCalculatorBase {
1718
// Immutables

src/middlewareV2/tableCalculator/ECDSATableCalculator.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import "./ECDSATableCalculatorBase.sol";
1212
/**
1313
* @title ECDSATableCalculator
1414
* @notice Implementation that calculates ECDSA operator tables using the sum of the minimum slashable stake weights
15+
* @dev This contract assumes that slashable stake is values the **same** across all strategies.
1516
*/
1617
contract ECDSATableCalculator is ECDSATableCalculatorBase {
1718
// Immutables

0 commit comments

Comments
 (0)