From 123054af4d6db364f73f37dc77510ed9c04ad3d5 Mon Sep 17 00:00:00 2001 From: steven Date: Fri, 27 Oct 2023 12:13:58 -0400 Subject: [PATCH 1/6] docs:consistency intra repo and inter repo indicating slasher inactive and under development --- README.md | 4 ++++ src/BLSRegistryCoordinatorWithIndices.sol | 1 + 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index 9d3b2c14..fce493fe 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # AVS Smart Contract Architecture +

+🚧 The Slasher contract is under active development and its interface expected to change. We recommend writing slashing logic without integrating with the Slasher at this point in time. 🚧 +

+ ## Introduction EigenLayer AVSs are a new type of protocol that makes use of EigenLayer’s restaking primitive. AVSs are different from current chains and other smart contract protocols in that they are validated by EigenLayer operators. There are 3 specific types of conditions that AVSs implement in smart contracts onchain: diff --git a/src/BLSRegistryCoordinatorWithIndices.sol b/src/BLSRegistryCoordinatorWithIndices.sol index d139b546..fc2cfbf8 100644 --- a/src/BLSRegistryCoordinatorWithIndices.sol +++ b/src/BLSRegistryCoordinatorWithIndices.sol @@ -378,6 +378,7 @@ contract BLSRegistryCoordinatorWithIndices is EIP712, Initializable, IBLSRegistr BN254.G1Point memory pubkey, string memory socket ) internal virtual returns(uint32[] memory) { + // TODO after slashing: revert registration when operator is slashable in the EigenLayer Slasher // require( // slasher.contractCanSlashOperatorUntilBlock(operator, address(serviceManager)) == type(uint32).max, // "StakeRegistry._registerOperator: operator must be opted into slashing by the serviceManager" From 8e2331fd16b4a05b16c70ac6ed0568d5f275bddd Mon Sep 17 00:00:00 2001 From: Samuel Laferriere Date: Thu, 26 Oct 2023 17:30:38 -0700 Subject: [PATCH 2/6] fix all broken links in README --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index fce493fe..2b837720 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ These two points have been addressed through the Registry Coordinator/Registry A #### Quorums -Quorums are the different divisions of the operator set for an AVS. One can think of a quorum being defined by the token staked for that quorum, although [it is slightly more complicated than that](./StakeRegistry.md#definitions). One often wants to make trust assumptions on quorums, but wants many quorums for the same AVS. +Quorums are the different divisions of the operator set for an AVS. One can think of a quorum being defined by the token staked for that quorum, although [it is slightly more complicated than that](./docs/middleware/StakeRegistry.md#definitions). One often wants to make trust assumptions on quorums, but wants many quorums for the same AVS. One example of the quorum concept is in EigenDA, where we have a single ETH quorum for which LSTs and native beacon chain ETH are accepted as stake and another quorum for each rollup that wants to stake their own token for security. @@ -46,9 +46,9 @@ The Registry Coordinator is a contract that is deployed by each AVS. It handles The registries are contracts that keep track of the attributes of individual operators. For example, we have initially built the -- [StakeRegistry](./StakeRegistry.md) which keeps track of the stakes of different operators for different quorums at different times -- [BLSPubkeyRegistry](./BLSPubkeyRegistry.md) which keeps track of the aggregate public key of different quorums at different times. Note that the AVS contracts use [BLS aggregate signatures](#bls-signature-checker) due to their favorable scalability to large operator sets. -- [IndexRegistry](./IndexRegistry.md) which keeps track of an ordered list of the operators in each quorum at different times. (note that this behavior is likely only needed for EigenDA) +- [StakeRegistry](./docs/middleware/StakeRegistry.md) which keeps track of the stakes of different operators for different quorums at different times +- [BLSPubkeyRegistry](./docs/middleware/BLSPubkeyRegistry.md) which keeps track of the aggregate public key of different quorums at different times. Note that the AVS contracts use [BLS aggregate signatures](#bls-signature-checker) due to their favorable scalability to large operator sets. +- [IndexRegistry](./docs/middleware/IndexRegistry.md) which keeps track of an ordered list of the operators in each quorum at different times. (note that this behavior is likely only needed for EigenDA) Registries are meant to be read from and indexed by offchain AVS actors (operators and AVS coordinators). A registry coordinator has 1 or more registries connected to it and all of them are called when an operator registers or deregisters. They are a plug and play system that are meant to be added to the RegistryCoordinator as needed. AVSs should create registries they need for their purpose. @@ -82,15 +82,15 @@ These structs, consecutively, are a history of the `Value` over certain ranges o At the core of many AVSs on EigenLayer (almost all except those that affect Ethereum block production) is the verification of a quorum signature of an AVS's operator set on a certain message and slashing if some quality of that message and other state is true. The registry architecture is optimized for making this signature as cheap as possible to verify (it is still relatively expensive). -The current implementation of this contract is the [BLSSignatureChecker](./BLSSignatureChecker.md). +The current implementation of this contract is the [BLSSignatureChecker](./docs/middleware/BLSSignatureChecker.md). ## Further reading More detailed functional docs have been written on the AVS architecture implemented in the middleware contracts. The recommended order for reading the other docs in this folder is -1. [BLSRegistryCoordinatorWithIndices](./BLSRegistryCoordinatorWithIndices.md) -2. [BLSPublicKeyCompendium](./BLSPublicKeyCompendium.md) and [BLSPublicKeyRegistry](./BLSPubkeyRegistry.md) -3. [StakeRegistry](./StakeRegistry.md) -4. [IndexRegistry](./IndexRegistry.md) -5. [BLSOperatorStateRetriever](./BLSOperatorStateRetriever.md) -6. [BLSSignatureChecker](./BLSSignatureChecker.md) +1. [BLSRegistryCoordinatorWithIndices](./docs/middleware/BLSRegistryCoordinatorWithIndices.md) +2. [BLSPublicKeyCompendium](./docs/middleware/BLSPublicKeyCompendium.md) and [BLSPublicKeyRegistry](./docs/middleware/BLSPubkeyRegistry.md) +3. [StakeRegistry](./docs/middleware/StakeRegistry.md) +4. [IndexRegistry](./docs/middleware/IndexRegistry.md) +5. [BLSOperatorStateRetriever](./docs/middleware/BLSOperatorStateRetriever.md) +6. [BLSSignatureChecker](./docs/middleware/BLSSignatureChecker.md) From 847a9e98df8c2b3717dc90c88985eca867e96eec Mon Sep 17 00:00:00 2001 From: steven Date: Mon, 30 Oct 2023 13:12:28 -0400 Subject: [PATCH 3/6] move docs --- README.md | 24 +++--- .../BLSOperatorStateRetriever.md | 0 docs/{middleware => }/BLSPubkeyRegistry.md | 0 .../BLSPublicKeyCompendium.md | 0 .../BLSRegistryCoordinatorWithIndices.md | 0 docs/{middleware => }/BLSSignatureChecker.md | 0 docs/{middleware => }/IndexRegistry.md | 0 docs/{middleware => }/StakeRegistry.md | 0 docs/middleware/README.md | 86 ------------------- 9 files changed, 12 insertions(+), 98 deletions(-) rename docs/{middleware => }/BLSOperatorStateRetriever.md (100%) rename docs/{middleware => }/BLSPubkeyRegistry.md (100%) rename docs/{middleware => }/BLSPublicKeyCompendium.md (100%) rename docs/{middleware => }/BLSRegistryCoordinatorWithIndices.md (100%) rename docs/{middleware => }/BLSSignatureChecker.md (100%) rename docs/{middleware => }/IndexRegistry.md (100%) rename docs/{middleware => }/StakeRegistry.md (100%) delete mode 100644 docs/middleware/README.md diff --git a/README.md b/README.md index 2b837720..135cc180 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ These two points have been addressed through the Registry Coordinator/Registry A #### Quorums -Quorums are the different divisions of the operator set for an AVS. One can think of a quorum being defined by the token staked for that quorum, although [it is slightly more complicated than that](./docs/middleware/StakeRegistry.md#definitions). One often wants to make trust assumptions on quorums, but wants many quorums for the same AVS. +Quorums are the different divisions of the operator set for an AVS. One can think of a quorum being defined by the token staked for that quorum, although [it is slightly more complicated than that](./docs/StakeRegistry.md#definitions). One often wants to make trust assumptions on quorums, but wants many quorums for the same AVS. One example of the quorum concept is in EigenDA, where we have a single ETH quorum for which LSTs and native beacon chain ETH are accepted as stake and another quorum for each rollup that wants to stake their own token for security. @@ -40,15 +40,15 @@ The Registry Coordinator is a contract that is deployed by each AVS. It handles - Keeping track of what quorums operators are a part of - Handling operator churn (registration/deregistration) - Communicating to registries - The current implementation of this contract is the [BLSRegistryCoordinatorWithIndices](./BLSRegistryCoordinatorWithIndices.md). + The current implementation of this contract is the [BLSRegistryCoordinatorWithIndices](./docs/BLSRegistryCoordinatorWithIndices.md). ### Registries The registries are contracts that keep track of the attributes of individual operators. For example, we have initially built the -- [StakeRegistry](./docs/middleware/StakeRegistry.md) which keeps track of the stakes of different operators for different quorums at different times -- [BLSPubkeyRegistry](./docs/middleware/BLSPubkeyRegistry.md) which keeps track of the aggregate public key of different quorums at different times. Note that the AVS contracts use [BLS aggregate signatures](#bls-signature-checker) due to their favorable scalability to large operator sets. -- [IndexRegistry](./docs/middleware/IndexRegistry.md) which keeps track of an ordered list of the operators in each quorum at different times. (note that this behavior is likely only needed for EigenDA) +- [StakeRegistry](./docs/StakeRegistry.md) which keeps track of the stakes of different operators for different quorums at different times +- [BLSPubkeyRegistry](./docs/BLSPubkeyRegistry.md) which keeps track of the aggregate public key of different quorums at different times. Note that the AVS contracts use [BLS aggregate signatures](#bls-signature-checker) due to their favorable scalability to large operator sets. +- [IndexRegistry](./docs/IndexRegistry.md) which keeps track of an ordered list of the operators in each quorum at different times. (note that this behavior is likely only needed for EigenDA) Registries are meant to be read from and indexed by offchain AVS actors (operators and AVS coordinators). A registry coordinator has 1 or more registries connected to it and all of them are called when an operator registers or deregisters. They are a plug and play system that are meant to be added to the RegistryCoordinator as needed. AVSs should create registries they need for their purpose. @@ -82,15 +82,15 @@ These structs, consecutively, are a history of the `Value` over certain ranges o At the core of many AVSs on EigenLayer (almost all except those that affect Ethereum block production) is the verification of a quorum signature of an AVS's operator set on a certain message and slashing if some quality of that message and other state is true. The registry architecture is optimized for making this signature as cheap as possible to verify (it is still relatively expensive). -The current implementation of this contract is the [BLSSignatureChecker](./docs/middleware/BLSSignatureChecker.md). +The current implementation of this contract is the [BLSSignatureChecker](./docs/BLSSignatureChecker.md). ## Further reading More detailed functional docs have been written on the AVS architecture implemented in the middleware contracts. The recommended order for reading the other docs in this folder is -1. [BLSRegistryCoordinatorWithIndices](./docs/middleware/BLSRegistryCoordinatorWithIndices.md) -2. [BLSPublicKeyCompendium](./docs/middleware/BLSPublicKeyCompendium.md) and [BLSPublicKeyRegistry](./docs/middleware/BLSPubkeyRegistry.md) -3. [StakeRegistry](./docs/middleware/StakeRegistry.md) -4. [IndexRegistry](./docs/middleware/IndexRegistry.md) -5. [BLSOperatorStateRetriever](./docs/middleware/BLSOperatorStateRetriever.md) -6. [BLSSignatureChecker](./docs/middleware/BLSSignatureChecker.md) +1. [BLSRegistryCoordinatorWithIndices](./docs/BLSRegistryCoordinatorWithIndices.md) +2. [BLSPublicKeyCompendium](./docs/BLSPublicKeyCompendium.md) and [BLSPublicKeyRegistry](./docs/middleware/BLSPubkeyRegistry.md) +3. [StakeRegistry](./docs/StakeRegistry.md) +4. [IndexRegistry](./docs/IndexRegistry.md) +5. [BLSOperatorStateRetriever](./docs/BLSOperatorStateRetriever.md) +6. [BLSSignatureChecker](./docs/BLSSignatureChecker.md) diff --git a/docs/middleware/BLSOperatorStateRetriever.md b/docs/BLSOperatorStateRetriever.md similarity index 100% rename from docs/middleware/BLSOperatorStateRetriever.md rename to docs/BLSOperatorStateRetriever.md diff --git a/docs/middleware/BLSPubkeyRegistry.md b/docs/BLSPubkeyRegistry.md similarity index 100% rename from docs/middleware/BLSPubkeyRegistry.md rename to docs/BLSPubkeyRegistry.md diff --git a/docs/middleware/BLSPublicKeyCompendium.md b/docs/BLSPublicKeyCompendium.md similarity index 100% rename from docs/middleware/BLSPublicKeyCompendium.md rename to docs/BLSPublicKeyCompendium.md diff --git a/docs/middleware/BLSRegistryCoordinatorWithIndices.md b/docs/BLSRegistryCoordinatorWithIndices.md similarity index 100% rename from docs/middleware/BLSRegistryCoordinatorWithIndices.md rename to docs/BLSRegistryCoordinatorWithIndices.md diff --git a/docs/middleware/BLSSignatureChecker.md b/docs/BLSSignatureChecker.md similarity index 100% rename from docs/middleware/BLSSignatureChecker.md rename to docs/BLSSignatureChecker.md diff --git a/docs/middleware/IndexRegistry.md b/docs/IndexRegistry.md similarity index 100% rename from docs/middleware/IndexRegistry.md rename to docs/IndexRegistry.md diff --git a/docs/middleware/StakeRegistry.md b/docs/StakeRegistry.md similarity index 100% rename from docs/middleware/StakeRegistry.md rename to docs/StakeRegistry.md diff --git a/docs/middleware/README.md b/docs/middleware/README.md deleted file mode 100644 index 5f824f75..00000000 --- a/docs/middleware/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# AVS Smart Contract Architecture - -## Introduction - -EigenLayer AVSs are a new type of protocol that makes use of EigenLayer’s restaking primitive. AVSs are different from current chains and other smart contract protocols in that they are validated by EigenLayer operators. There are 3 specific types of conditions that AVSs implement in smart contracts onchain: -- Registration/Deregistration conditions: What requirements do operators need to have in order to register for/deregister from the AVS? -- Payment conditions: How much does a certain operator deserve to be paid for their validation? In what form are they paid? -- Slashing conditions: What behavior is not allowed of operators by the AVS? What exact mechanism should be used to determine this behavior onchain? - -The EigenLabs dev team has been building out a smart contract architecture for AVSs to provide a base for AVSs to build on top of for their specific use case. They have been using it internally for the first AVS on EigenLayer: EigenDA. - -## The Registry Coordinator and Registries - -![Registry Architecture](../images/registry_architecture.png) - -There are two things that matter in terms of operators’ onchain interaction with AVS contracts: -- What qualities of operators need to be kept track of onchain? (e.g. stake, BLS pubkeys, etc.) -- Registration/Deregistration conditions - -These two points have been addressed through the Registry Coordinator/Registry Architecture. - -### Definitions - -#### Quorums - -Quorums are the different divisions of the operator set for an AVS. One can think of a quorum being defined by the token staked for that quorum, although [it is slightly more complicated than that](./StakeRegistry.md#definitions). One often wants to make trust assumptions on quorums, but wants many quorums for the same AVS. - -One example of the quorum concept is in EigenDA, where we have a single ETH quorum for which LSTs and native beacon chain ETH are accepted as stake and another quorum for each rollup that wants to stake their own token for security. - -### RegistryCoordinator -The Registry Coordinator is a contract that is deployed by each AVS. It handles -- Keeping track of what quorums operators are a part of -- Handling operator churn (registration/deregistration) -- Communicating to registries -The current implementation of this contract is the [BLSRegistryCoordinatorWithIndices](./BLSRegistryCoordinatorWithIndices.md). - - -### Registries -The registries are contracts that keep track of the attributes of individual operators. For example, we have initially built the -- [StakeRegistry](./StakeRegistry.md) which keeps track of the stakes of different operators for different quorums at different times -- [BLSPubkeyRegistry](./BLSPubkeyRegistry.md) which keeps track of the aggregate public key of different quorums at different times. Note that the AVS contracts use [BLS aggregate signatures](#bls-signature-checker) due to their favorable scalability to large operator sets. -- [IndexRegistry](./IndexRegistry.md) which keeps track of an ordered list of the operators in each quorum at different times. (note that this behavior is likely only needed for EigenDA) -Registries are meant to be read from and indexed by offchain AVS actors (operators and AVS coordinators). - -A registry coordinator has 1 or more registries connected to it and all of them are called when an operator registers or deregisters. They are a plug and play system that are meant to be added to the RegistryCoordinator as needed. AVSs should create registries they need for their purpose. - -### Note on (active) block ranges - -Note that the registry contract implementations use lists structs similar to the following type (with the `Value` type altered): -```solidity -struct ValueUpdateA { - Value value; - uint32 updateBlockNumber; // when the value started being valid - uint32 nextUpdateBlockNumber; // then the value stopped being valid or 0, if the value is still valid -} -``` -or -```solidity -struct ValueUpdateB { - Value value; - uint32 toBlockNumber; // when the value expired -} -``` - -These structs, consecutively, are a history of the `Value` over certain ranges of blocks. These are (aptly) called block ranges, and *active* block ranges for the `ValueUpdate` that contains the current block number. - -## TODO: Service Manager - -## BLS Signature Checker - -At the core of many AVSs on EigenLayer (almost all except those that affect Ethereum block production) is the verification of a quorum signature of an AVS's operator set on a certain message and slashing if some quality of that message and other state is true. The registry architecture is optimized for making this signature as cheap as possible to verify (it is still relatively expensive). - -The current implementation of this contract is the [BLSSignatureChecker](./BLSSignatureChecker.md). - -## Further reading - -More detailed functional docs have been written on the AVS architecture implemented in the middleware contracts. The recommended order for reading the other docs in this folder is - -1. [BLSRegistryCoordinatorWithIndices](./BLSRegistryCoordinatorWithIndices.md) -2. [BLSPublicKeyCompendium](./BLSPublicKeyCompendium.md) and [BLSPublicKeyRegistry](./BLSPubkeyRegistry.md) -3. [StakeRegistry](./StakeRegistry.md) -4. [IndexRegistry](./IndexRegistry.md) -5. [BLSOperatorStateRetriever](./BLSOperatorStateRetriever.md) -6. [BLSSignatureChecker](./BLSSignatureChecker.md) - - From db348e198dfbcd11bc30fe741e0bd78356dd9150 Mon Sep 17 00:00:00 2001 From: steven Date: Mon, 30 Oct 2023 13:17:51 -0400 Subject: [PATCH 4/6] fix: typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 135cc180..b479b650 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ The current implementation of this contract is the [BLSSignatureChecker](./docs/ More detailed functional docs have been written on the AVS architecture implemented in the middleware contracts. The recommended order for reading the other docs in this folder is 1. [BLSRegistryCoordinatorWithIndices](./docs/BLSRegistryCoordinatorWithIndices.md) -2. [BLSPublicKeyCompendium](./docs/BLSPublicKeyCompendium.md) and [BLSPublicKeyRegistry](./docs/middleware/BLSPubkeyRegistry.md) +2. [BLSPublicKeyCompendium](./docs/BLSPublicKeyCompendium.md) and [BLSPublicKeyRegistry](./docs/BLSPubkeyRegistry.md) 3. [StakeRegistry](./docs/StakeRegistry.md) 4. [IndexRegistry](./docs/IndexRegistry.md) 5. [BLSOperatorStateRetriever](./docs/BLSOperatorStateRetriever.md) From 1485f1a9ee3c3051c677698506135e7914a51cc5 Mon Sep 17 00:00:00 2001 From: steven Date: Tue, 31 Oct 2023 12:40:49 -0400 Subject: [PATCH 5/6] docs: add comments about slasher --- src/BLSRegistryCoordinatorWithIndices.sol | 6 ------ src/StakeRegistry.sol | 8 -------- src/interfaces/IServiceManager.sol | 3 ++- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/BLSRegistryCoordinatorWithIndices.sol b/src/BLSRegistryCoordinatorWithIndices.sol index 43954b2b..81d420ce 100644 --- a/src/BLSRegistryCoordinatorWithIndices.sol +++ b/src/BLSRegistryCoordinatorWithIndices.sol @@ -363,12 +363,6 @@ contract BLSRegistryCoordinatorWithIndices is EIP712, Initializable, IBLSRegistr BN254.G1Point memory pubkey, string memory socket ) internal virtual returns(uint32[] memory) { - // TODO after slashing: revert registration when operator is slashable in the EigenLayer Slasher - // require( - // slasher.contractCanSlashOperatorUntilBlock(operator, address(serviceManager)) == type(uint32).max, - // "StakeRegistry._registerOperator: operator must be opted into slashing by the serviceManager" - // ); - // get the quorum bitmap from the quorum numbers uint256 quorumBitmap = BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers); require(quorumBitmap <= MAX_QUORUM_BITMAP, "BLSRegistryCoordinatorWithIndices._registerOperatorWithCoordinator: quorumBitmap exceeds of max bitmap size"); diff --git a/src/StakeRegistry.sol b/src/StakeRegistry.sol index 9c45023b..1dd6d9d0 100644 --- a/src/StakeRegistry.sol +++ b/src/StakeRegistry.sol @@ -114,14 +114,6 @@ contract StakeRegistry is VoteWeigherBase, StakeRegistryStorage { ++quorumNumber; } } - - // TODO after slashing enabled: record stake updates in the EigenLayer Slasher - // for (uint i = 0; i < operators.length;) { - // serviceManager.recordStakeUpdate(operators[i], uint32(block.number), serviceManager.latestServeUntilBlock(), prevElements[i]); - // unchecked { - // ++i; - // } - // } } /******************************************************************************* diff --git a/src/interfaces/IServiceManager.sol b/src/interfaces/IServiceManager.sol index c1077aaf..c4766358 100644 --- a/src/interfaces/IServiceManager.sol +++ b/src/interfaces/IServiceManager.sol @@ -14,7 +14,8 @@ interface IServiceManager { function slasher() external view returns (ISlasher); /// @notice function that causes the ServiceManager to freeze the operator on EigenLayer, through a call to the Slasher contract - /// @dev this function should contain slashing logic, to make sure operators are not needlessly being slashed + /// @dev this function should contain slashing logic, that to make sure operators are not needlessly being slashed + /// THIS IS ONLY A TEMPORARY PLACE HOLDER UNTIL SLASHING IS FULLY IMPLEMENTED function freezeOperator(address operator) external; /// @notice required since the registry contract will call this function to permission its upgrades to be done by the same owner as the service manager From 68ef7c9134b0c2f52a53d7d6cfd2aebce2962dce Mon Sep 17 00:00:00 2001 From: steven Date: Tue, 31 Oct 2023 12:58:14 -0400 Subject: [PATCH 6/6] fix: typo --- src/interfaces/IServiceManager.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/IServiceManager.sol b/src/interfaces/IServiceManager.sol index c4766358..1dc4fe72 100644 --- a/src/interfaces/IServiceManager.sol +++ b/src/interfaces/IServiceManager.sol @@ -14,7 +14,7 @@ interface IServiceManager { function slasher() external view returns (ISlasher); /// @notice function that causes the ServiceManager to freeze the operator on EigenLayer, through a call to the Slasher contract - /// @dev this function should contain slashing logic, that to make sure operators are not needlessly being slashed + /// @dev this function should contain slashing logic to make sure operators are not needlessly being slashed /// THIS IS ONLY A TEMPORARY PLACE HOLDER UNTIL SLASHING IS FULLY IMPLEMENTED function freezeOperator(address operator) external;