Skip to content

Commit 016b35e

Browse files
wadealexcnadir-akhtar
authored andcommitted
docs: wip slashing docs (#925)
* docs: add slashing docs * chore: bindings * docs: fixed commenting and updated queue withdrawal docs * docs: minor cleanup --------- Co-authored-by: Nadir Akhtar <[email protected]>
1 parent 7cab56c commit 016b35e

File tree

37 files changed

+11549
-768
lines changed

37 files changed

+11549
-768
lines changed

docs/README.md

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
[middleware-repo]: https://github.com/Layr-Labs/eigenlayer-middleware/
2+
[elip-002]: https://github.com/eigenfoundation/ELIPs/blob/main/ELIPs/ELIP-002.md
23

3-
## EigenLayer Docs - v0.4.0 Release
4+
## EigenLayer Docs - v1.0.0 Release
45

5-
This repo contains the EigenLayer core contracts, which enable restaking of liquid staking tokens (LSTs) and beacon chain ETH to secure new services, called AVSs (actively validated services). For more info on AVSs, check out the EigenLayer middleware contracts [here][middleware-repo].
6+
This repo contains the EigenLayer core contracts, which enable restaking of liquid staking tokens (LSTs), beacon chain ETH, and permissionlessly deployed ERC20 Strategies to secure new services called AVSs (actively validated services). For more info on AVSs, check out the EigenLayer middleware contracts [here][middleware-repo].
67

7-
This document provides an overview of system components, contracts, and user roles. Further documentation on the major system contracts can be found in [/core](./core/).
8+
This document provides an overview of system components, contracts, and user roles and is up-to-date with the latest [ELIP-002][elip-002]. Further documentation on the major system contracts can be found in [/core](./core/).
89

910
#### Contents
1011

@@ -14,7 +15,7 @@ This document provides an overview of system components, contracts, and user rol
1415
* [`DelegationManager`](#delegationmanager)
1516
* [`RewardsCoordinator`](#rewardscoordinator)
1617
* [`AVSDirectory`](#avsdirectory)
17-
* [`Slasher`](#slasher)
18+
* [`AllocationManager`](#allocationmanager)
1819
* [Roles and Actors](#roles-and-actors)
1920
* [Common User Flows](#common-user-flows)
2021
* [Depositing Into EigenLayer](#depositing-into-eigenlayer)
@@ -53,7 +54,7 @@ See full documentation in:
5354
These contracts work together to enable restaking for ERC20 tokens supported by EigenLayer:
5455
* The `StrategyManager` acts as the entry and exit point for any supported tokens in EigenLayer. It handles deposits into LST-specific strategies, and manages accounting+interactions between users with restaked LSTs and the `DelegationManager`.
5556
* `StrategyFactory` allows anyone to deploy strategies to support deposits/withdrawals for new ERC20 tokens
56-
* `StrategyBaseTVLLimits` is deployed as multiple separate instances, one for each supported token. When a user deposits into a strategy through the `StrategyManager`, this contract receives the tokens and awards the user with a proportional quantity of shares in the strategy. When a user withdraws, the strategy contract sends the LSTs back to the user.
57+
* `StrategyBaseTVLLimits` is deployed as multiple separate instances, one for each supported token. When a user deposits into a strategy through the `StrategyManager`, this contract receives the tokens and awards the user with a proportional quantity of deposit shares in the strategy. When a user withdraws, the strategy contract sends the LSTs back to the user.
5758

5859
See full documentation in [`/core/StrategyManager.md`](./core/StrategyManager.md).
5960

@@ -63,7 +64,8 @@ See full documentation in [`/core/StrategyManager.md`](./core/StrategyManager.md
6364
| -------- | -------- | -------- |
6465
| [`DelegationManager.sol`](../src/contracts/core/DelegationManager.sol) | Singleton | Transparent proxy |
6566

66-
The `DelegationManager` sits between the `EigenPodManager` and `StrategyManager` to manage delegation and undelegation of Stakers to Operators. Its primary features are to allow Operators to register as Operators (`registerAsOperator`), to keep track of shares being delegated to Operators across different strategies, and to manage withdrawals on behalf of the `EigenPodManager` and `StrategyManager`.
67+
The `DelegationManager` sits between the `EigenPodManager` and `StrategyManager` to manage delegation and undelegation of Stakers to Operators. Its primary features are to allow Operators to register as Operators (`registerAsOperator`), to keep track of delegated shares to Operators across different strategies, and to manage withdrawals on behalf of the `EigenPodManager` and `StrategyManager`.
68+
The `DelegationManager` is tightly coupled with the `AllocationManager` as withdrawable shares for a Staker is dependent on reading state from the `AllocationManager`. That is, a staker's withdrawable shares is decreased in the event their delegated Operator was slashed by an AVS (more specifically an operatorSet but more on this later).
6769

6870
See full documentation in [`/core/DelegationManager.md`](./core/DelegationManager.md).
6971

@@ -86,21 +88,33 @@ See full documentation in [`/core/RewardsCoordinator.md`](./core/RewardsCoordina
8688
| -------- | -------- | -------- |
8789
| [`AVSDirectory.sol`](../src/contracts/core/AVSDirectory.sol) | Singleton | Transparent proxy |
8890

89-
The `AVSDirectory` handles interactions between AVSs and the EigenLayer core contracts. Once registered as an Operator in EigenLayer core (via the `DelegationManager`), Operators can register with one or more AVSs (via the AVS's contracts) to begin providing services to them offchain. As a part of registering with an AVS, the AVS will record this registration in the core contracts by calling into the `AVSDirectory`.
91+
##### Note: This contract is left unchanged for backwards compatability. Operator<>AVS Registrations are to be replaced entirely with the `AllocationManager` and this contract will be deprecated(no longer indexed) in a future release.
92+
93+
The `AVSDirectory` handles interactions between AVSs and the EigenLayer core contracts. Once registered as an Operator in EigenLayer core (via the `DelegationManager`), Operators can register with one or more AVSs (via the AVS's contracts) to begin providing services to them offchain. As a part of registering with an AVS, the AVS will record this registration in the core contracts by calling into the `AVSDirectory`.
9094

9195
See full documentation in [`/core/AVSDirectory.md`](./core/AVSDirectory.md).
9296

9397
For more information on AVS contracts, see the [middleware repo][middleware-repo].
9498

95-
#### Slasher
99+
#### AllocationManager
96100

97101
| File | Type | Proxy |
98102
| -------- | -------- | -------- |
99-
| [`Slasher.sol`](../src/contracts/core/Slasher.sol) | - | - |
103+
| [`AllocationManager.sol`](../src/contracts/core/AllocationManager.sol) | Singleton | Transparent proxy |
104+
105+
The `AllocationManager` is meant to replace the AVSDirectory with the introduction of OperatorSets as well as introduce the core functionality of Slashing. It handles several use cases:
106+
* AVSs can create OperatorSets and can define the EigenLayer Strategies within them
107+
* Operators can register/deregister with AVS operatorSets
108+
* Operators can make slashable security commitments to an operatorSet by allocating a proportion of their total delegated stake for a Strategy to be slashable. Ex. As an operator, I can allocate 50% of my stETH to be slashable by a specific OperatorSet
109+
* AVSs can slash an operator (without being objectively attributable) who has slashable allocations to the AVS's corresponding OperatorSet.
110+
111+
See full documentation in [`/core/AllocationManager.md`](./core/AllocationManager.md).
112+
113+
---
114+
115+
#### Shares Accounting
100116

101-
<p align="center"><b>
102-
🚧 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. Although the Slasher is deployed, it will remain completely paused/unusable during M2. No contracts interact with it, and its design is not finalized. 🚧
103-
</b><p>
117+
TODO
104118

105119
---
106120

docs/core/AVSDirectory.md

Lines changed: 116 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,145 @@
1-
[middleware-repo]: https://github.com/Layr-Labs/eigenlayer-middleware/
1+
# AVSDirectory
22

3-
## AVSDirectory
3+
## Overview
44

5-
| File | Type | Proxy |
6-
| -------- | -------- | -------- |
7-
| [`AVSDirectory.sol`](../../src/contracts/core/AVSDirectory.sol) | Singleton | Transparent proxy |
5+
The AVSDirectory contract is where registration relationships are defined between AVSs, operatorSets, and operators. Registration and deregistration are used in the protocol to activate and deactivate slashable stake allocations. They're also used to make the protocol more legible to external integrations.
86

9-
The `AVSDirectory` handles interactions between AVSs and the EigenLayer core contracts. Once registered as an Operator in EigenLayer core (via the `DelegationManager`), Operators can register with one or more AVSs (via the AVS's contracts) to begin providing services to them offchain. As a part of registering with an AVS, the AVS will record this registration in the core contracts by calling into the `AVSDirectory`.
7+
The slashing release introduces the concept of operatorSets, which are simply an (address, uint32) pair that the define an AVS and an operator set ID. OperatorSets are used to group operators by different tasks and sets of tokens. For example, EigenDA has an ETH/LST operatorSet and an Eigen operatorSet. A bridge may have on operatorSet for all operators that serve a particular chain. Overall, operatorSets are mainly used for protocol legibility.
108

11-
For more information on AVS contracts, see the [middleware repo][middleware-repo].
9+
Functionality is provided for AVSs to migrate from an pre-operatorSet registration model to an operatorSet model. Direct to AVS registration is still supported for AVSs that have not migrated to the operatorSet model, but is slated to be deprecated soon in the future.
1210

13-
Currently, the only interactions between AVSs and the core contracts is to track whether Operators are currently registered for the AVS. This is handled by two methods:
14-
* [`AVSDirectory.registerOperatorToAVS`](#registeroperatortoavs)
15-
* [`AVSDirectory.deregisterOperatorFromAVS`](#deregisteroperatorfromavs)
11+
## `becomeOperatorSetAVS`
12+
```solidity
13+
/**
14+
* @notice Sets the AVS as an operator set AVS, preventing legacy M2 operator registrations.
15+
*
16+
* @dev msg.sender must be the AVS.
17+
*/
18+
function becomeOperatorSetAVS() external;
19+
```
20+
21+
AVSs call this to become an operator set AVS. Once an AVS becomes an operator set AVS, they can no longer register operators via the legacy M2 registration path. This is a seperate function to help avoid accidental migrations to the operator set AVS model.
1622

17-
In a future release, this contract will implement additional interactions that relate to (i) rewarding Operators for the services they provide and (ii) slashing Operators that misbehave. Currently, these features are not implemented.
23+
## `createOperatorSets`
24+
```solidity
25+
/**
26+
* @notice Called by an AVS to create a list of new operatorSets.
27+
*
28+
* @param operatorSetIds The IDs of the operator set to initialize.
29+
*
30+
* @dev msg.sender must be the AVS.
31+
*/
32+
function createOperatorSets(
33+
uint32[] calldata operatorSetIds
34+
) external;
35+
```
1836

19-
---
37+
AVSs use this function to create a list of new operator sets.They must call this function before they add any operators to the operator sets. The operator set IDs must be not already exist.
2038

21-
#### `registerOperatorToAVS`
39+
This can be called before the AVS becomes an operator set AVS. (TODO: we should make this so that it can only be called after the AVS becomes an operator set AVS?)
2240

41+
## `migrateOperatorsToOperatorSets`
2342
```solidity
24-
function registerOperatorToAVS(
25-
address operator,
26-
ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature
27-
)
28-
external
29-
onlyWhenNotPaused(PAUSED_OPERATOR_REGISTER_DEREGISTER_TO_AVS)
43+
/**
44+
* @notice Called by an AVS to migrate operators that have a legacy M2 registration to operator sets.
45+
*
46+
* @param operators The list of operators to migrate
47+
* @param operatorSetIds The list of operatorSets to migrate the operators to
48+
*
49+
* @dev The msg.sender used is the AVS
50+
* @dev The operator can only be migrated at most once per AVS
51+
* @dev The AVS can no longer register operators via the legacy M2 registration path once it begins migration
52+
* @dev The operator is deregistered from the M2 legacy AVS once migrated
53+
*/
54+
function migrateOperatorsToOperatorSets(
55+
address[] calldata operators,
56+
uint32[][] calldata operatorSetIds
57+
) external;
3058
```
3159

32-
Allows the caller (an AVS) to register an `operator` with itself, given the provided signature is valid.
60+
AVSs that launched before the slashing release can use this function to migrate operators that have a legacy M2 registration to operator sets. Each operator can only be migrated once for the AVS and the AVS can no longer register operators via the legacy M2 registration path once it begins migration.
3361

34-
*Effects*:
35-
* Sets the `operator's` status to `REGISTERED` for the AVS
36-
37-
*Requirements*:
38-
* Pause status MUST NOT be set: `PAUSED_OPERATOR_REGISTER_DEREGISTER_TO_AVS`
39-
* `operator` MUST already be a registered Operator (via the `DelegationManager`)
40-
* `operator` MUST NOT already be registered with the AVS
41-
* `operatorSignature` must be a valid, unused, unexpired signature from the `operator`. The signature is an ECDSA signature by the operator over the [`OPERATOR_AVS_REGISTRATION_TYPEHASH`](../../src/contracts/core/DelegationManagerStorage.sol). Expiry is a utc timestamp in seconds. Salt is used only once per signature to prevent replay attacks.
62+
## `registerOperatorToOperatorSets`
63+
```solidity
64+
/**
65+
* @notice Called by AVSs to add an operator to list of operatorSets.
66+
*
67+
* @param operator The address of the operator to be added to the operator set.
68+
* @param operatorSetIds The IDs of the operator sets.
69+
* @param operatorSignature The signature of the operator on their intent to register.
70+
*
71+
* @dev msg.sender is used as the AVS.
72+
*/
73+
function registerOperatorToOperatorSets(
74+
address operator,
75+
uint32[] calldata operatorSetIds,
76+
ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature
77+
) external;
78+
```
4279

43-
*As of M2*:
44-
* Operator registration/deregistration does not have any sort of consequences for the Operator or its shares. Eventually, this will tie into rewards for services and slashing for misbehavior.
80+
AVSs use this function to add an operator to a list of operator sets. The operator's signature is required to confirm their intent to register. If the operator has a slashable stake allocation to the AVS, it takes effect when the operator is registered (and up to `DEALLOCATION_DELAY` seconds after the operator is deregistered).
4581

46-
#### `deregisterOperatorFromAVS`
82+
The operator set must exist before the operator can be added to it and the AVS must be an operator set AVS.
4783

84+
## `deregisterOperatorFromOperatorSets`
4885
```solidity
49-
function deregisterOperatorFromAVS(
50-
address operator
51-
)
52-
external
53-
onlyWhenNotPaused(PAUSED_OPERATOR_REGISTER_DEREGISTER_TO_AVS)
86+
/**
87+
* @notice Called by AVSs to remove an operator from an operator set.
88+
*
89+
* @param operator The address of the operator to be removed from the operator set.
90+
* @param operatorSetIds The IDs of the operator sets.
91+
*
92+
* @dev msg.sender is used as the AVS.
93+
*/
94+
function deregisterOperatorFromOperatorSets(address operator, uint32[] calldata operatorSetIds) external;
5495
```
5596

56-
Allows the caller (an AVS) to deregister an `operator` with itself
97+
AVSs use this function to remove an operator from an operator set. The operator is still slashable for its slashable stake allocation to the AVS until `DEALLOCATION_DELAY` seconds after the operator is deregistered.
98+
99+
The operator must be registered to the operator set before they can be deregistered from it.
57100

58-
*Effects*:
59-
* Sets the `operator's` status to `UNREGISTERED` for the AVS
60101

61-
*Requirements*:
62-
* Pause status MUST NOT be set: `PAUSED_OPERATOR_REGISTER_DEREGISTER_TO_AVS`
63-
* `operator` MUST already be registered with the AVS
102+
## `forceDeregisterFromOperatorSets`
103+
```solidity
104+
/**
105+
* @notice Called by an operator to deregister from an operator set
106+
*
107+
* @param operator The operator to deregister from the operatorSets.
108+
* @param avs The address of the AVS to deregister the operator from.
109+
* @param operatorSetIds The IDs of the operator sets.
110+
* @param operatorSignature the signature of the operator on their intent to deregister or empty if the operator itself is calling
111+
*
112+
* @dev if the operatorSignature is empty, the caller must be the operator
113+
* @dev this will likely only be called in case the AVS contracts are in a state that prevents operators from deregistering
114+
*/
115+
function forceDeregisterFromOperatorSets(
116+
address operator,
117+
address avs,
118+
uint32[] calldata operatorSetIds,
119+
ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature
120+
) external;
121+
```
64122

65-
*As of M2*:
66-
* Operator registration/deregistration does not have any sort of consequences for the Operator or its shares. Eventually, this will tie into rewards for services and slashing for misbehavior.
123+
Operators can use this function to deregister from an operator set without requiring the AVS to sign off on the deregistration. This function is intended to be used in cases where the AVS contracts are in a state that prevents operators from deregistering (either malicious or unintentional).
67124

68-
#### `cancelSalt`
125+
Operators can also deallocate their slashable stake allocation seperately to avoid slashing risk, so this function is mainly for external integrations to interpret the correct state of the protocol.
69126

127+
## `updateAVSMetadataURI`
70128
```solidity
71-
function cancelSalt(bytes32 salt) external
129+
/**
130+
* @notice Called by an AVS to emit an `AVSMetadataURIUpdated` event indicating the information has updated.
131+
*
132+
* @param metadataURI The URI for metadata associated with an AVS.
133+
*
134+
* @dev Note that the `metadataURI` is *never stored* and is only emitted in the `AVSMetadataURIUpdated` event.
135+
*/
136+
function updateAVSMetadataURI(
137+
string calldata metadataURI
138+
) external;
72139
```
73140

74-
Allows the caller (an Operator) to cancel a signature salt before it is used to register for an AVS.
141+
This function allows an AVS to update the metadata URI associated with the AVS. The metadata URI is never stored on-chain and is only emitted in the `AVSMetadataURIUpdated` event.
75142

76-
*Effects*:
77-
* Sets `operatorSaltIsSpent[msg.sender][salt]` to `true`
143+
## View Functions
78144

79-
*Requirements*:
80-
* Salt MUST NOT already be cancelled
145+
See the [AVS Directory Inteface](../../../src/contracts/interfaces/IAVSDirectory.sol) for view functions.

0 commit comments

Comments
 (0)