-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
633 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,86 +1,240 @@ | ||
# BLSRegistryCoordinatorWithIndices | ||
## BLSRegistryCoordinatorWithIndices | ||
|
||
This contract is deployed for every AVS and serves as the main entrypoint for operators to register and deregister from the AVS. In addition, it is where the AVS defines its operator churn parameters. | ||
| File | Type | Proxy? | | ||
| -------- | -------- | -------- | | ||
| [`BLSRegistryCoordinatorWithIndices.sol`](../src/BLSRegistryCoordinatorWithIndices.sol) | Singleton | Transparent proxy | | ||
|
||
## Flows | ||
TODO | ||
|
||
### registerOperator | ||
<!-- The `BLSRegistryCoordinatorWithIndices` is the primary entry point for operators as they register for and deregister from an AVS's quorums. When operators register or deregister, the registry coordinator updates that operator's currently-registered quorums, and pushes the registration/deregistration to each of the three registries it controls: | ||
* `BLSPubkeyRegistry`: tracks the aggregate BLS pubkey hash for the operators registered to each quorum. Also maintains a history of these aggregate pubkey hashes. | ||
* `StakeRegistry`: interfaces with the EigenLayer core contracts to track historical state of operators per quorum. | ||
* `IndexRegistry`: assigns indices to operators within each quorum, and tracks historical indices and operators per quorum. Used primarily by offchain infrastructure to fetch ordered lists of operators in quorums. | ||
When registering the operator must provide | ||
1. The quorums they are registering for | ||
2. Their BLS public key that they registered with the [BLSPubkeyCompendium](./BLSPublicKeyCompendium.md) | ||
3. The socket (ip:port) at which AVS offchain actors should make requests | ||
Both the registry coordinator and each of the registries maintain historical state for the specific information they track. This historical state tracking can be used to query state at a particular block, which is primarily used in offchain infrastructure. --> | ||
|
||
The RegistryCoordinator then | ||
1. Registers the operator's BLS public key with the [BLSPubkeyRegistry](BLSPubkeyRegistry.md) and notes the hash of their public key as their operator id | ||
2. Registers the operator with the [StakeRegistry](./StakeRegistry.md) | ||
3. Registers the operator with the [IndexRegistry](./IndexRegistry.md) | ||
4. Stores the quorum bitmap of the operator using the following struct: | ||
#### High-level Concepts | ||
|
||
This document organizes methods according to the following themes (click each to be taken to the relevant section): | ||
* [Registering and Deregistering](#registering-and-deregistering) | ||
* [Updating Registered Operators](#updating-registered-operators) | ||
* [System Configuration](#system-configuration) | ||
|
||
#### Important State Variables | ||
|
||
TODO | ||
|
||
<!-- * `EigenPodManager`: | ||
* `mapping(address => IEigenPod) public ownerToPod`: Tracks the deployed `EigenPod` for each Staker | ||
* `mapping(address => int256) public podOwnerShares`: Keeps track of the actively restaked beacon chain ETH for each Staker. | ||
* In some cases, a beacon chain balance update may cause a Staker's balance to drop below zero. This is because when queueing for a withdrawal in the `DelegationManager`, the Staker's current shares are fully removed. If the Staker's beacon chain balance drops after this occurs, their `podOwnerShares` may go negative. This is a temporary change to account for the drop in balance, and is ultimately corrected when the withdrawal is finally processed. | ||
* Since balances on the consensus layer are stored only in Gwei amounts, the EigenPodManager enforces the invariant that `podOwnerShares` is always a whole Gwei amount for every staker, i.e. `podOwnerShares[staker] % 1e9 == 0` always. --> | ||
|
||
#### Important Definitions | ||
|
||
TODO | ||
|
||
<!-- * "Pod Owner": A Staker who has deployed an `EigenPod` is a Pod Owner. The terms are used interchangeably in this document. | ||
* Pod Owners can only deploy a single `EigenPod`, but can restake any number of beacon chain validators from the same `EigenPod`. | ||
* Pod Owners can delegate their `EigenPodManager` shares to Operators (via `DelegationManager`). | ||
* These shares correspond to the amount of provably-restaked beacon chain ETH held by the Pod Owner via their `EigenPod`. --> | ||
|
||
--- | ||
|
||
### Registering and Deregistering | ||
|
||
These methods allow operators to register for/deregister from one or more quorums, and are the primary entry points to the middleware contracts as a whole: | ||
* [`registerOperator`](#registeroperator) | ||
* [`registerOperatorWithChurn`](#registeroperatorwithchurn) | ||
* [`deregisterOperator`](#deregisteroperator) | ||
* [`ejectOperator`](#ejectoperator) | ||
|
||
#### `registerOperator` | ||
|
||
```solidity | ||
function registerOperator( | ||
bytes calldata quorumNumbers, | ||
string calldata socket | ||
) | ||
external | ||
onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) | ||
``` | ||
/** | ||
* @notice Data structure for storing info on quorum bitmap updates where the `quorumBitmap` is the bitmap of the | ||
* quorums the operator is registered for starting at (inclusive)`updateBlockNumber` and ending at (exclusive) `nextUpdateBlockNumber` | ||
* @dev nextUpdateBlockNumber is initialized to 0 for the latest update | ||
*/ | ||
struct QuorumBitmapUpdate { | ||
uint32 updateBlockNumber; | ||
uint32 nextUpdateBlockNumber; | ||
uint192 quorumBitmap; | ||
} | ||
|
||
Allows an operator to register for one or more quorums, if they | ||
|
||
*Effects*: | ||
* | ||
|
||
*Requirements*: | ||
* | ||
|
||
#### `registerOperatorWithChurn` | ||
|
||
```solidity | ||
function registerOperatorWithChurn( | ||
bytes calldata quorumNumbers, | ||
string calldata socket, | ||
OperatorKickParam[] calldata operatorKickParams, | ||
SignatureWithSaltAndExpiry memory churnApproverSignature | ||
) | ||
external | ||
onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) | ||
``` | ||
|
||
Operators can be registered for certain quorums and later register for other (non-overlapping) quorums. | ||
TODO | ||
|
||
*Effects*: | ||
* | ||
|
||
*Requirements*: | ||
* | ||
|
||
### If quorum full | ||
#### `deregisterOperator` | ||
|
||
The following struct is defined for each quorum | ||
```solidity | ||
function deregisterOperator( | ||
bytes calldata quorumNumbers | ||
) | ||
external | ||
onlyWhenNotPaused(PAUSED_DEREGISTER_OPERATOR) | ||
``` | ||
/** | ||
* @notice Data structure for storing operator set params for a given quorum. Specifically the | ||
* `maxOperatorCount` is the maximum number of operators that can be registered for the quorum | ||
* `kickBIPsOfOperatorStake` is the multiple (in basis points) of stake that a new operator must have, as compared the operator that they are kicking out of the quorum | ||
* `kickBIPsOfTotalStake` is the fraction (in basis points) of the total stake of the quorum that an operator needs to be below to be kicked. | ||
*/ | ||
struct OperatorSetParam { | ||
uint32 maxOperatorCount; | ||
uint16 kickBIPsOfOperatorStake; | ||
uint16 kickBIPsOfTotalStake; | ||
} | ||
|
||
TODO | ||
|
||
*Effects*: | ||
* | ||
|
||
*Requirements*: | ||
* | ||
|
||
#### `ejectOperator` | ||
|
||
```solidity | ||
function ejectOperator( | ||
address operator, | ||
bytes calldata quorumNumbers | ||
) | ||
external | ||
onlyEjector | ||
``` | ||
|
||
If any of the quorums is full (number of operators in it is `maxOperatorCount`), the newly registering operator must provide the public key of another operator to be kicked. The new and kicked operator must satisfy the two conditions: | ||
1. the new operator has an amount of stake that is at least `kickBIPsOfOperatorStake` multiple of the kicked operator's stake | ||
2. the kicked operator has less than `kickBIPsOfTotalStake` fraction of the quorum's total stake | ||
TODO | ||
|
||
*Effects*: | ||
* | ||
|
||
*Requirements*: | ||
* | ||
|
||
--- | ||
|
||
### Updating Registered Operators | ||
|
||
TODO | ||
|
||
The provided operators are deregistered from the respective quorums that are full which the registering operator is registering for. Since the operators being kicked may not be the operators with the least stake, the RegistryCoordinator requires that the provided operators are signed off by a permissioned address called a `churnApprover`. Note that the quorum operator caps are due to the cost of BLS signature (dis)aggregation onchain. | ||
#### `updateOperators` | ||
|
||
Operators register with a list of | ||
```solidity | ||
function updateOperators( | ||
address[] calldata operators | ||
) | ||
external | ||
onlyWhenNotPaused(PAUSED_UPDATE_OPERATOR) | ||
``` | ||
/** | ||
* @notice Data structure for the parameters needed to kick an operator from a quorum with number `quorumNumber`, used during registration churn. | ||
* Specifically the `operator` is the address of the operator to kick, `pubkey` is the BLS public key of the operator, | ||
*/ | ||
struct OperatorKickParam { | ||
uint8 quorumNumber; | ||
address operator; | ||
BN254.G1Point pubkey; | ||
} | ||
|
||
TODO | ||
|
||
*Effects*: | ||
* | ||
|
||
*Requirements*: | ||
* | ||
|
||
#### `updateSocket` | ||
|
||
```solidity | ||
function updateSocket(string memory socket) external | ||
``` | ||
|
||
TODO | ||
|
||
*Effects*: | ||
* | ||
|
||
*Requirements*: | ||
* | ||
|
||
--- | ||
|
||
### System Configuration | ||
|
||
TODO | ||
|
||
#### `createQuorum` | ||
|
||
```solidity | ||
function createQuorum( | ||
OperatorSetParam memory operatorSetParams, | ||
uint96 minimumStake, | ||
IStakeRegistry.StrategyParams[] memory strategyParams | ||
) | ||
external | ||
virtual | ||
onlyServiceManagerOwner | ||
``` | ||
For each quorum they need to kick operators from. This list, along with the id of the registering operator needs to be signed (along with a salt and expiry) by an actor known as the *churnApprover*. Operators will make a request to the churnApprover offchain before registering for their signature, if needed. | ||
|
||
### deregisterOperator | ||
TODO | ||
|
||
When deregistering, an operator provides | ||
1. The quorums they registered for | ||
2. Their BLS public key | ||
3. The ids of the operators that must swap indices with the [deregistering operator in the IndexRegistry](./IndexRegistry.md#deregisteroperator). | ||
*Effects*: | ||
* | ||
|
||
The RegistryCoordinator then deregisters the operator with the BLSPubkeyRegistry, StakeRegistry, and IndexRegistry. It then ends the block range for its stored quorum bitmap for the operator. | ||
*Requirements*: | ||
* | ||
|
||
Operators can deregister from a subset of quorums that they are registered for. | ||
#### `setOperatorSetParams` | ||
|
||
```solidity | ||
function setOperatorSetParams( | ||
uint8 quorumNumber, | ||
OperatorSetParam memory operatorSetParams | ||
) | ||
external | ||
onlyServiceManagerOwner | ||
quorumExists(quorumNumber) | ||
``` | ||
|
||
TODO | ||
|
||
*Effects*: | ||
* | ||
|
||
*Requirements*: | ||
* | ||
|
||
#### `setChurnApprover` | ||
|
||
```solidity | ||
function setChurnApprover(address _churnApprover) external onlyServiceManagerOwner | ||
``` | ||
|
||
TODO | ||
|
||
*Effects*: | ||
* | ||
|
||
*Requirements*: | ||
* | ||
|
||
#### `setEjector` | ||
|
||
```solidity | ||
function setEjector(address _ejector) external onlyServiceManagerOwner | ||
``` | ||
|
||
## Upstream Dependencies | ||
TODO | ||
|
||
Operators register and deregister with the AVS for certain quorums through this contract. | ||
*Effects*: | ||
* | ||
|
||
EigenLabs intends to run the EigenDA churnApprover. | ||
*Requirements*: | ||
* |
This file was deleted.
Oops, something went wrong.
File renamed without changes.
Oops, something went wrong.