Skip to content

Commit

Permalink
docs: add docs very wip
Browse files Browse the repository at this point in the history
  • Loading branch information
wadealexc committed Dec 7, 2023
1 parent 7cb2d09 commit cca8420
Show file tree
Hide file tree
Showing 11 changed files with 633 additions and 81 deletions.
278 changes: 216 additions & 62 deletions docs/BLSRegistryCoordinatorWithIndices.md
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*:
*
15 changes: 0 additions & 15 deletions docs/Middleware-registration-operator-flow.md

This file was deleted.

File renamed without changes.
Loading

0 comments on commit cca8420

Please sign in to comment.