Skip to content

Commit 2133681

Browse files
committed
docs: natspec ECDSAStakeRegistry
1 parent e8d1c91 commit 2133681

10 files changed

+479
-365
lines changed
Lines changed: 204 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,99 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity ^0.8.27;
33

4+
import {IERC1271Upgradeable} from
5+
"@openzeppelin-upgrades/contracts/interfaces/IERC1271Upgradeable.sol";
46
import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol";
7+
import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol";
8+
import {IDelegationManager} from
9+
"eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol";
510

6-
struct StrategyParams {
7-
IStrategy strategy; // The strategy contract reference
8-
uint96 multiplier; // The multiplier applied to the strategy
11+
// TODO: many of these errors do not have test coverage.
12+
13+
interface IECDSAStakeRegistryErrors {
14+
/// @notice Thrown when the lengths of the signers array and signatures array do not match.
15+
error LengthMismatch();
16+
/// @notice Thrown when encountering an invalid length for the signers or signatures array.
17+
error InvalidLength();
18+
/// @notice Thrown when encountering an invalid signature.
19+
error InvalidSignature();
20+
/// @notice Thrown when the threshold update is greater than BPS.
21+
error InvalidThreshold();
22+
/// @notice Thrown when missing operators in an update.
23+
error MustUpdateAllOperators();
24+
/// @notice Thrown when reference blocks must be for blocks that have already been confirmed.
25+
error InvalidReferenceBlock();
26+
/// @notice Thrown when operator weights were out of sync and the signed weight exceed the total.
27+
error InvalidSignedWeight();
28+
/// @notice Thrown when the total signed stake fails to meet the required threshold.
29+
error InsufficientSignedStake();
30+
/// @notice Thrown when an individual signer's weight fails to meet the required threshold.
31+
error InsufficientWeight();
32+
/// @notice Thrown when the quorum is invalid.
33+
error InvalidQuorum();
34+
/// @notice Thrown when the system finds a list of items unsorted.
35+
error NotSorted();
36+
/// @notice Thrown when registering an already registered operator.
37+
error OperatorAlreadyRegistered();
38+
/// @notice Thrown when de-registering or updating the stake for an unregisted operator.
39+
error OperatorNotRegistered();
940
}
1041

11-
struct Quorum {
12-
StrategyParams[] strategies; // An array of strategy parameters to define the quorum
42+
interface IECDSAStakeRegistryTypes {
43+
/// @notice Parameters for a strategy and its weight multiplier.
44+
/// @param strategy The strategy contract reference.
45+
/// @param multiplier The multiplier applied to the strategy.
46+
struct StrategyParams {
47+
IStrategy strategy;
48+
uint96 multiplier;
49+
}
50+
51+
/// @notice Configuration for a quorum's strategies.
52+
/// @param strategies An array of strategy parameters defining the quorum.
53+
struct Quorum {
54+
StrategyParams[] strategies;
55+
}
1356
}
1457

15-
interface IECDSAStakeRegistry {
58+
interface IECDSAStakeRegistryEvents is IECDSAStakeRegistryTypes {
1659
/// @notice Emitted when the system registers an operator
17-
/// @param _operator The address of the registered operator
18-
/// @param _avs The address of the associated AVS
19-
event OperatorRegistered(address indexed _operator, address indexed _avs);
60+
/// @param operator The address of the registered operator
61+
/// @param avs The address of the associated AVS
62+
event OperatorRegistered(address indexed operator, address indexed avs);
2063

2164
/// @notice Emitted when the system deregisters an operator
22-
/// @param _operator The address of the deregistered operator
23-
/// @param _avs The address of the associated AVS
24-
event OperatorDeregistered(address indexed _operator, address indexed _avs);
65+
/// @param operator The address of the deregistered operator
66+
/// @param avs The address of the associated AVS
67+
event OperatorDeregistered(address indexed operator, address indexed avs);
2568

2669
/// @notice Emitted when the system updates the quorum
27-
/// @param _old The previous quorum configuration
28-
/// @param _new The new quorum configuration
29-
event QuorumUpdated(Quorum _old, Quorum _new);
70+
/// @param previous The previous quorum configuration
71+
/// @param current The new quorum configuration
72+
event QuorumUpdated(Quorum previous, Quorum current);
3073

3174
/// @notice Emitted when the weight to join the operator set updates
32-
/// @param _old The previous minimum weight
33-
/// @param _new The new minimumWeight
34-
event MinimumWeightUpdated(uint256 _old, uint256 _new);
75+
/// @param previous The previous minimum weight
76+
/// @param current The new minimumWeight
77+
event MinimumWeightUpdated(uint256 previous, uint256 current);
3578

3679
/// @notice Emitted when the weight required to be an operator changes
3780
/// @param oldMinimumWeight The previous weight
3881
/// @param newMinimumWeight The updated weight
3982
event UpdateMinimumWeight(uint256 oldMinimumWeight, uint256 newMinimumWeight);
4083

4184
/// @notice Emitted when the system updates an operator's weight
42-
/// @param _operator The address of the operator updated
85+
/// @param operator The address of the operator updated
4386
/// @param oldWeight The operator's weight before the update
4487
/// @param newWeight The operator's weight after the update
45-
event OperatorWeightUpdated(address indexed _operator, uint256 oldWeight, uint256 newWeight);
88+
event OperatorWeightUpdated(address indexed operator, uint256 oldWeight, uint256 newWeight);
4689

4790
/// @notice Emitted when the system updates the total weight
4891
/// @param oldTotalWeight The total weight before the update
4992
/// @param newTotalWeight The total weight after the update
5093
event TotalWeightUpdated(uint256 oldTotalWeight, uint256 newTotalWeight);
5194

5295
/// @notice Emits when setting a new threshold weight.
53-
event ThresholdWeightUpdated(uint256 _thresholdWeight);
96+
event ThresholdWeightUpdated(uint256 thresholdWeight);
5497

5598
/// @notice Emitted when an operator's signing key is updated
5699
/// @param operator The address of the operator whose signing key was updated
@@ -63,43 +106,145 @@ interface IECDSAStakeRegistry {
63106
address indexed newSigningKey,
64107
address oldSigningKey
65108
);
66-
/// @notice Indicates when the lengths of the signers array and signatures array do not match.
67-
68-
error LengthMismatch();
69-
70-
/// @notice Indicates encountering an invalid length for the signers or signatures array.
71-
error InvalidLength();
72-
73-
/// @notice Indicates encountering an invalid signature.
74-
error InvalidSignature();
75-
76-
/// @notice Thrown when the threshold update is greater than BPS
77-
error InvalidThreshold();
78-
79-
/// @notice Thrown when missing operators in an update
80-
error MustUpdateAllOperators();
81-
82-
/// @notice Reference blocks must be for blocks that have already been confirmed
83-
error InvalidReferenceBlock();
84-
85-
/// @notice Indicates operator weights were out of sync and the signed weight exceed the total
86-
error InvalidSignedWeight();
87-
88-
/// @notice Indicates the total signed stake fails to meet the required threshold.
89-
error InsufficientSignedStake();
90-
91-
/// @notice Indicates an individual signer's weight fails to meet the required threshold.
92-
error InsufficientWeight();
93-
94-
/// @notice Indicates the quorum is invalid
95-
error InvalidQuorum();
96-
97-
/// @notice Indicates the system finds a list of items unsorted
98-
error NotSorted();
99-
100-
/// @notice Thrown when registering an already registered operator
101-
error OperatorAlreadyRegistered();
109+
}
102110

103-
/// @notice Thrown when de-registering or updating the stake for an unregisted operator
104-
error OperatorNotRegistered();
111+
interface IECDSAStakeRegistry is
112+
IECDSAStakeRegistryErrors,
113+
IECDSAStakeRegistryEvents,
114+
IERC1271Upgradeable
115+
{
116+
/// ACTIONS
117+
118+
/// @notice Registers a new operator using a provided operators signature and signing key.
119+
/// @param operatorSignature Contains the operator's signature, salt, and expiry.
120+
/// @param signingKey The signing key to add to the operator's history.
121+
function registerOperatorWithSignature(
122+
ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature,
123+
address signingKey
124+
) external;
125+
126+
/// @notice Deregisters an existing operator.
127+
function deregisterOperator() external;
128+
129+
/// @notice Updates the signing key for an operator.
130+
/// @param newSigningKey The new signing key to set for the operator.
131+
/// @dev Only callable by the operator themselves.
132+
function updateOperatorSigningKey(
133+
address newSigningKey
134+
) external;
135+
136+
/// @notice Updates the StakeRegistry's view of operators' stakes.
137+
/// @param operators A list of operator addresses to update.
138+
/// @dev Queries stakes from the Eigenlayer core DelegationManager contract.
139+
function updateOperators(
140+
address[] memory operators
141+
) external;
142+
143+
/// @notice Updates the quorum configuration and the set of operators.
144+
/// @param quorum The new quorum configuration, including strategies and their new weights.
145+
/// @param operators The list of operator addresses to update stakes for.
146+
function updateQuorumConfig(
147+
IECDSAStakeRegistryTypes.Quorum memory quorum,
148+
address[] memory operators
149+
) external;
150+
151+
/// @notice Updates the weight an operator must have to join the operator set.
152+
/// @param newMinimumWeight The new weight an operator must have to join the operator set.
153+
/// @param operators The list of operators to update after changing the minimum weight.
154+
function updateMinimumWeight(
155+
uint256 newMinimumWeight,
156+
address[] memory operators
157+
) external;
158+
159+
/// @notice Sets a new cumulative threshold weight for message validation.
160+
/// @param thresholdWeight The updated threshold weight required to validate a message.
161+
function updateStakeThreshold(
162+
uint256 thresholdWeight
163+
) external;
164+
165+
/// VIEW
166+
167+
/// @notice Retrieves the current stake quorum details.
168+
/// @return The current quorum of strategies and weights.
169+
function quorum() external view returns (IECDSAStakeRegistryTypes.Quorum memory);
170+
171+
/// @notice Retrieves the latest signing key for a given operator.
172+
/// @param operator The address of the operator.
173+
/// @return The latest signing key of the operator.
174+
function getLatestOperatorSigningKey(
175+
address operator
176+
) external view returns (address);
177+
178+
/// @notice Retrieves the signing key for an operator at a specific block.
179+
/// @param operator The address of the operator.
180+
/// @param blockNumber The block number to query at.
181+
/// @return The signing key of the operator at the given block.
182+
function getOperatorSigningKeyAtBlock(
183+
address operator,
184+
uint256 blockNumber
185+
) external view returns (address);
186+
187+
/// @notice Retrieves the last recorded weight for a given operator.
188+
/// @param operator The address of the operator.
189+
/// @return The latest weight of the operator.
190+
function getLastCheckpointOperatorWeight(
191+
address operator
192+
) external view returns (uint256);
193+
194+
/// @notice Retrieves the last recorded total weight across all operators.
195+
/// @return The latest total weight.
196+
function getLastCheckpointTotalWeight() external view returns (uint256);
197+
198+
/// @notice Retrieves the last recorded threshold weight.
199+
/// @return The latest threshold weight.
200+
function getLastCheckpointThresholdWeight() external view returns (uint256);
201+
202+
/// @notice Returns whether an operator is currently registered.
203+
/// @param operator The operator address to check.
204+
/// @return Whether the operator is registered.
205+
function operatorRegistered(
206+
address operator
207+
) external view returns (bool);
208+
209+
/// @notice Returns the minimum weight required for operator participation.
210+
/// @return The minimum weight threshold.
211+
function minimumWeight() external view returns (uint256);
212+
213+
/// @notice Retrieves the operator's weight at a specific block number.
214+
/// @param operator The address of the operator.
215+
/// @param blockNumber The block number to query at.
216+
/// @return The weight of the operator at the given block.
217+
function getOperatorWeightAtBlock(
218+
address operator,
219+
uint32 blockNumber
220+
) external view returns (uint256);
221+
222+
/// @notice Retrieves the operator's weight.
223+
/// @param operator The address of the operator.
224+
/// @return The current weight of the operator.
225+
function getOperatorWeight(
226+
address operator
227+
) external view returns (uint256);
228+
229+
/// @notice Updates operators for a specific quorum.
230+
/// @param operatorsPerQuorum Array of operator addresses per quorum.
231+
/// @param data Additional data (unused but kept for interface compatibility).
232+
function updateOperatorsForQuorum(
233+
address[][] memory operatorsPerQuorum,
234+
bytes memory data
235+
) external;
236+
237+
/// @notice Retrieves the total weight at a specific block number.
238+
/// @param blockNumber The block number to query at.
239+
/// @return The total weight at the given block.
240+
function getLastCheckpointTotalWeightAtBlock(
241+
uint32 blockNumber
242+
) external view returns (uint256);
243+
244+
/// @notice Retrieves the threshold weight at a specific block number.
245+
/// @param blockNumber The block number to query at.
246+
/// @return The threshold weight at the given block.
247+
function getLastCheckpointThresholdWeightAtBlock(
248+
uint32 blockNumber
249+
) external view returns (uint256);
105250
}

src/unaudited/ECDSAServiceManagerBase.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy
1212
import {IStakeRegistry} from "../interfaces/IStakeRegistry.sol";
1313
import {IRewardsCoordinator} from
1414
"eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol";
15-
import {Quorum} from "../interfaces/IECDSAStakeRegistry.sol";
15+
import {IECDSAStakeRegistryTypes} from "../interfaces/IECDSAStakeRegistry.sol";
1616
import {ECDSAStakeRegistry} from "../unaudited/ECDSAStakeRegistry.sol";
1717
import {IAVSRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IAVSRegistrar.sol";
1818
import {IAllocationManager} from
@@ -197,7 +197,7 @@ abstract contract ECDSAServiceManagerBase is IServiceManager, OwnableUpgradeable
197197
* @return strategies An array of addresses representing the strategies in the current quorum.
198198
*/
199199
function _getRestakeableStrategies() internal view virtual returns (address[] memory) {
200-
Quorum memory quorum = ECDSAStakeRegistry(stakeRegistry).quorum();
200+
IECDSAStakeRegistryTypes.Quorum memory quorum = ECDSAStakeRegistry(stakeRegistry).quorum();
201201
address[] memory strategies = new address[](quorum.strategies.length);
202202
for (uint256 i = 0; i < quorum.strategies.length; i++) {
203203
strategies[i] = address(quorum.strategies[i].strategy);
@@ -226,7 +226,7 @@ abstract contract ECDSAServiceManagerBase is IServiceManager, OwnableUpgradeable
226226
function _getOperatorRestakedStrategies(
227227
address _operator
228228
) internal view virtual returns (address[] memory) {
229-
Quorum memory quorum = ECDSAStakeRegistry(stakeRegistry).quorum();
229+
IECDSAStakeRegistryTypes.Quorum memory quorum = ECDSAStakeRegistry(stakeRegistry).quorum();
230230
uint256 count = quorum.strategies.length;
231231
IStrategy[] memory strategies = new IStrategy[](count);
232232
for (uint256 i; i < count; i++) {

0 commit comments

Comments
 (0)