forked from Layr-Labs/eigenlayer-contracts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIAllocationManager.sol
549 lines (484 loc) · 23.4 KB
/
IAllocationManager.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
// SPDX-License-Identifier: BUSL-1.1
pragma solidity >=0.5.0;
import {OperatorSet} from "../libraries/OperatorSetLib.sol";
import "./IPauserRegistry.sol";
import "./IStrategy.sol";
import "./IAVSRegistrar.sol";
interface IAllocationManagerErrors {
/// Input Validation
/// @dev Thrown when `wadToSlash` is zero or greater than 1e18
error InvalidWadToSlash();
/// @dev Thrown when two array parameters have mismatching lengths.
error InputArrayLengthMismatch();
/// Caller
/// @dev Thrown when caller is not authorized to call a function.
error InvalidCaller();
/// Operator Status
/// @dev Thrown when an invalid operator is provided.
error InvalidOperator();
/// @dev Thrown when an operator's allocation delay has yet to be set.
error UninitializedAllocationDelay();
/// @dev Thrown when attempting to slash an operator when they are not slashable.
error OperatorNotSlashable();
/// @dev Thrown when trying to add an operator to a set they are already a member of
error AlreadyMemberOfSet();
/// @dev Thrown when trying to slash/remove an operator from a set they are not a member of
error NotMemberOfSet();
/// Operator Set Status
/// @dev Thrown when an invalid operator set is provided.
error InvalidOperatorSet();
/// @dev Thrown when provided `strategies` are not in ascending order.
error StrategiesMustBeInAscendingOrder();
/// @dev Thrown when trying to add a strategy to an operator set that already contains it.
error StrategyAlreadyInOperatorSet();
/// @dev Thrown when a strategy is referenced that does not belong to an operator set.
error StrategyNotInOperatorSet();
/// Modifying Allocations
/// @dev Thrown when an operator attempts to set their allocation for an operatorSet to the same value
error SameMagnitude();
/// @dev Thrown when an allocation is attempted for a given operator when they have pending allocations or deallocations.
error ModificationAlreadyPending();
/// @dev Thrown when an allocation is attempted that exceeds a given operators total allocatable magnitude.
error InsufficientMagnitude();
}
interface IAllocationManagerTypes {
/**
* @notice Defines allocation information from a strategy to an operator set, for an operator
* @param currentMagnitude the current magnitude allocated from the strategy to the operator set
* @param pendingDiff a pending change in magnitude, if it exists (0 otherwise)
* @param effectBlock the block at which the pending magnitude diff will take effect
*/
struct Allocation {
uint64 currentMagnitude;
int128 pendingDiff;
uint32 effectBlock;
}
/**
* @notice Struct containing allocation delay metadata for a given operator.
* @param delay Current allocation delay
* @param isSet Whether the operator has initially set an allocation delay. Note that this could be false but the
* block.number >= effectBlock in which we consider their delay to be configured and active.
* @param pendingDelay The delay that will take effect after `effectBlock`
* @param effectBlock The block number after which a pending delay will take effect
*/
struct AllocationDelayInfo {
uint32 delay;
bool isSet;
uint32 pendingDelay;
uint32 effectBlock;
}
/**
* @notice Contains registration details for an operator pertaining to an operator set
* @param registered Whether the operator is currently registered for the operator set
* @param slashableUntil If the operator is not registered, they are still slashable until
* this block is reached.
*/
struct RegistrationStatus {
bool registered;
uint32 slashableUntil;
}
/**
* @notice Contains allocation info for a specific strategy
* @param maxMagnitude the maximum magnitude that can be allocated between all operator sets
* @param encumberedMagnitude the currently-allocated magnitude for the strategy
*/
struct StrategyInfo {
uint64 maxMagnitude;
uint64 encumberedMagnitude;
}
/**
* @notice Struct containing parameters to slashing
* @param operator the address to slash
* @param operatorSetId the ID of the operatorSet the operator is being slashed on behalf of
* @param strategies the set of strategies to slash
* @param wadsToSlash the parts in 1e18 to slash, this will be proportional to the operator's
* slashable stake allocation for the operatorSet
* @param description the description of the slashing provided by the AVS for legibility
*/
struct SlashingParams {
address operator;
uint32 operatorSetId;
IStrategy[] strategies;
uint256[] wadsToSlash;
string description;
}
/**
* @notice struct used to modify the allocation of slashable magnitude to an operator set
* @param operatorSet the operator set to modify the allocation for
* @param strategies the strategies to modify allocations for
* @param newMagnitudes the new magnitude to allocate for each strategy to this operator set
*/
struct AllocateParams {
OperatorSet operatorSet;
IStrategy[] strategies;
uint64[] newMagnitudes;
}
/**
* @notice Parameters used to register for an AVS's operator sets
* @param avs the AVS being registered for
* @param operatorSetIds the operator sets within the AVS to register for
* @param data extra data to be passed to the AVS to complete registration
*/
struct RegisterParams {
address avs;
uint32[] operatorSetIds;
bytes data;
}
/**
* @notice Parameters used to deregister from an AVS's operator sets
* @param operator the operator being deregistered
* @param avs the avs being deregistered from
* @param operatorSetIds the operator sets within the AVS being deregistered from
*/
struct DeregisterParams {
address operator;
address avs;
uint32[] operatorSetIds;
}
/**
* @notice Parameters used by an AVS to create new operator sets
* @param operatorSetId the id of the operator set to create
* @param strategies the strategies to add as slashable to the operator set
*/
struct CreateSetParams {
uint32 operatorSetId;
IStrategy[] strategies;
}
}
interface IAllocationManagerEvents is IAllocationManagerTypes {
/// @notice Emitted when operator updates their allocation delay.
event AllocationDelaySet(address operator, uint32 delay, uint32 effectBlock);
/// @notice Emitted when an operator's magnitude is updated for a given operatorSet and strategy
event AllocationUpdated(
address operator, OperatorSet operatorSet, IStrategy strategy, uint64 magnitude, uint32 effectBlock
);
/// @notice Emitted when operator's encumbered magnitude is updated for a given strategy
event EncumberedMagnitudeUpdated(address operator, IStrategy strategy, uint64 encumberedMagnitude);
/// @notice Emitted when an operator's max magnitude is updated for a given strategy
event MaxMagnitudeUpdated(address operator, IStrategy strategy, uint64 maxMagnitude);
/// @notice Emitted when an operator is slashed by an operator set for a strategy
/// `wadSlashed` is the proportion of the operator's total delegated stake that was slashed
event OperatorSlashed(
address operator, OperatorSet operatorSet, IStrategy[] strategies, uint256[] wadSlashed, string description
);
/// @notice Emitted when an AVS configures the address that will handle registration/deregistration
event AVSRegistrarSet(address avs, IAVSRegistrar registrar);
/// @notice Emitted when an AVS updates their metadata URI (Uniform Resource Identifier).
/// @dev The URI is never stored; it is simply emitted through an event for off-chain indexing.
event AVSMetadataURIUpdated(address indexed avs, string metadataURI);
/// @notice Emitted when an operator set is created by an AVS.
event OperatorSetCreated(OperatorSet operatorSet);
/// @notice Emitted when an operator is added to an operator set.
event OperatorAddedToOperatorSet(address indexed operator, OperatorSet operatorSet);
/// @notice Emitted when an operator is removed from an operator set.
event OperatorRemovedFromOperatorSet(address indexed operator, OperatorSet operatorSet);
/// @notice Emitted when a strategy is added to an operator set.
event StrategyAddedToOperatorSet(OperatorSet operatorSet, IStrategy strategy);
/// @notice Emitted when a strategy is removed from an operator set.
event StrategyRemovedFromOperatorSet(OperatorSet operatorSet, IStrategy strategy);
}
interface IAllocationManager is IAllocationManagerErrors, IAllocationManagerEvents {
/**
* @dev Initializes the initial owner and paused status.
*/
function initialize(address initialOwner, uint256 initialPausedStatus) external;
/**
* @notice Called by an AVS to slash an operator in a given operator set
*/
function slashOperator(address avs, SlashingParams calldata params) external;
/**
* @notice Modifies the proportions of slashable stake allocated to an operator set from a list of strategies
* Note that deallocations remain slashable for DEALLOCATION_DELAY blocks therefore when they are cleared they may
* free up less allocatable magnitude than initially deallocated.
* @param operator the operator to modify allocations for
* @param params array of magnitude adjustments for one or more operator sets
* @dev Updates encumberedMagnitude for the updated strategies
*/
function modifyAllocations(address operator, AllocateParams[] calldata params) external;
/**
* @notice This function takes a list of strategies and for each strategy, removes from the deallocationQueue
* all clearable deallocations up to max `numToClear` number of deallocations, updating the encumberedMagnitude
* of the operator as needed.
*
* @param operator address to clear deallocations for
* @param strategies a list of strategies to clear deallocations for
* @param numToClear a list of number of pending deallocations to clear for each strategy
*
* @dev can be called permissionlessly by anyone
*/
function clearDeallocationQueue(
address operator,
IStrategy[] calldata strategies,
uint16[] calldata numToClear
) external;
/**
* @notice Allows an operator to register for one or more operator sets for an AVS. If the operator
* has any stake allocated to these operator sets, it immediately becomes slashable.
* @dev After registering within the ALM, this method calls the AVS Registrar's `IAVSRegistrar.
* registerOperator` method to complete registration. This call MUST succeed in order for
* registration to be successful.
*/
function registerForOperatorSets(address operator, RegisterParams calldata params) external;
/**
* @notice Allows an operator or AVS to deregister the operator from one or more of the AVS's operator sets.
* If the operator has any slashable stake allocated to the AVS, it remains slashable until the
* DEALLOCATION_DELAY has passed.
* @dev After deregistering within the ALM, this method calls the AVS Registrar's `IAVSRegistrar.
* deregisterOperator` method to complete deregistration. Unlike when registering, this call MAY FAIL.
* Failure is permitted to prevent AVSs from being able to maliciously prevent operators from deregistering.
*/
function deregisterFromOperatorSets(
DeregisterParams calldata params
) external;
/**
* @notice Called by the delegation manager OR an operator to set an operator's allocation delay.
* This is set when the operator first registers, and is the number of blocks between an operator
* allocating magnitude to an operator set, and the magnitude becoming slashable.
* @param operator The operator to set the delay on behalf of.
* @param delay the allocation delay in blocks
*/
function setAllocationDelay(address operator, uint32 delay) external;
/**
* @notice Called by an AVS to configure the address that is called when an operator registers
* or is deregistered from the AVS's operator sets. If not set (or set to 0), defaults
* to the AVS's address.
* @param registrar the new registrar address
*/
function setAVSRegistrar(address avs, IAVSRegistrar registrar) external;
/**
* @notice Called by an AVS to emit an `AVSMetadataURIUpdated` event indicating the information has updated.
*
* @param metadataURI The URI for metadata associated with an AVS.
*
* @dev Note that the `metadataURI` is *never stored* and is only emitted in the `AVSMetadataURIUpdated` event.
*/
function updateAVSMetadataURI(address avs, string calldata metadataURI) external;
/**
* @notice Allows an AVS to create new operator sets, defining strategies that the operator set uses
*/
function createOperatorSets(address avs, CreateSetParams[] calldata params) external;
/**
* @notice Allows an AVS to add strategies to an operator set
* @dev Strategies MUST NOT already exist in the operator set
* @param avs the avs to set strategies for
* @param operatorSetId the operator set to add strategies to
* @param strategies the strategies to add
*/
function addStrategiesToOperatorSet(address avs, uint32 operatorSetId, IStrategy[] calldata strategies) external;
/**
* @notice Allows an AVS to remove strategies from an operator set
* @dev Strategies MUST already exist in the operator set
* @param avs the avs to remove strategies for
* @param operatorSetId the operator set to remove strategies from
* @param strategies the strategies to remove
*/
function removeStrategiesFromOperatorSet(
address avs,
uint32 operatorSetId,
IStrategy[] calldata strategies
) external;
/**
*
* VIEW FUNCTIONS
*
*/
/**
* @notice Returns the number of operator sets for the AVS
* @param avs the AVS to query
*/
function getOperatorSetCount(
address avs
) external view returns (uint256);
/**
* @notice Returns the list of operator sets the operator has current or pending allocations/deallocations in
* @param operator the operator to query
* @return the list of operator sets the operator has current or pending allocations/deallocations in
*/
function getAllocatedSets(
address operator
) external view returns (OperatorSet[] memory);
/**
* @notice Returns the list of strategies an operator has current or pending allocations/deallocations from
* given a specific operator set.
* @param operator the operator to query
* @param operatorSet the operator set to query
* @return the list of strategies
*/
function getAllocatedStrategies(
address operator,
OperatorSet memory operatorSet
) external view returns (IStrategy[] memory);
/**
* @notice Returns the current/pending stake allocation an operator has from a strategy to an operator set
* @param operator the operator to query
* @param operatorSet the operator set to query
* @param strategy the strategy to query
* @return the current/pending stake allocation
*/
function getAllocation(
address operator,
OperatorSet memory operatorSet,
IStrategy strategy
) external view returns (Allocation memory);
/**
* @notice Returns the current/pending stake allocations for multiple operators from a strategy to an operator set
* @param operators the operators to query
* @param operatorSet the operator set to query
* @param strategy the strategy to query
* @return each operator's allocation
*/
function getAllocations(
address[] memory operators,
OperatorSet memory operatorSet,
IStrategy strategy
) external view returns (Allocation[] memory);
/**
* @notice Given a strategy, returns a list of operator sets and corresponding stake allocations.
* @dev Note that this returns a list of ALL operator sets the operator has allocations in. This means
* some of the returned allocations may be zero.
* @param operator the operator to query
* @param strategy the strategy to query
* @return the list of all operator sets the operator has allocations for
* @return the corresponding list of allocations from the specific `strategy`
*/
function getStrategyAllocations(
address operator,
IStrategy strategy
) external view returns (OperatorSet[] memory, Allocation[] memory);
/**
* @notice For a strategy, get the amount of magnitude not currently allocated to any operator set
* @param operator the operator to query
* @param strategy the strategy to get allocatable magnitude for
* @return magnitude available to be allocated to an operator set
*/
function getAllocatableMagnitude(address operator, IStrategy strategy) external view returns (uint64);
/**
* @notice Returns the maximum magnitude an operator can allocate for the given strategy
* @dev The max magnitude of an operator starts at WAD (1e18), and is decreased anytime
* the operator is slashed. This value acts as a cap on the max magnitude of the operator.
* @param operator the operator to query
* @param strategy the strategy to get the max magnitude for
* @return the max magnitude for the strategy
*/
function getMaxMagnitude(address operator, IStrategy strategy) external view returns (uint64);
/**
* @notice Returns the maximum magnitude an operator can allocate for the given strategies
* @dev The max magnitude of an operator starts at WAD (1e18), and is decreased anytime
* the operator is slashed. This value acts as a cap on the max magnitude of the operator.
* @param operator the operator to query
* @param strategies the strategies to get the max magnitudes for
* @return the max magnitudes for each strategy
*/
function getMaxMagnitudes(
address operator,
IStrategy[] calldata strategies
) external view returns (uint64[] memory);
/**
* @notice Returns the maximum magnitudes each operator can allocate for the given strategy
* @dev The max magnitude of an operator starts at WAD (1e18), and is decreased anytime
* the operator is slashed. This value acts as a cap on the max magnitude of the operator.
* @param operators the operators to query
* @param strategy the strategy to get the max magnitudes for
* @return the max magnitudes for each operator
*/
function getMaxMagnitudes(
address[] calldata operators,
IStrategy strategy
) external view returns (uint64[] memory);
/**
* @notice Returns the maximum magnitude an operator can allocate for the given strategies
* at a given block number
* @dev The max magnitude of an operator starts at WAD (1e18), and is decreased anytime
* the operator is slashed. This value acts as a cap on the max magnitude of the operator.
* @param operator the operator to query
* @param strategies the strategies to get the max magnitudes for
* @param blockNumber the blockNumber at which to check the max magnitudes
* @return the max magnitudes for each strategy
*/
function getMaxMagnitudesAtBlock(
address operator,
IStrategy[] calldata strategies,
uint32 blockNumber
) external view returns (uint64[] memory);
/**
* @notice Returns the time in blocks between an operator allocating slashable magnitude
* and the magnitude becoming slashable. If the delay has not been set, `isSet` will be false.
* @dev The operator must have a configured delay before allocating magnitude
* @param operator The operator to query
* @return isSet Whether the operator has configured a delay
* @return delay The time in blocks between allocating magnitude and magnitude becoming slashable
*/
function getAllocationDelay(
address operator
) external view returns (bool isSet, uint32 delay);
/**
* @notice Returns a list of all operator sets the operator is registered for
* @param operator The operator address to query.
*/
function getRegisteredSets(
address operator
) external view returns (OperatorSet[] memory operatorSets);
/**
* @notice Returns whether the operator is registered for the operator set
* @param operator The operator to query
* @param operatorSet The operator set to query
*/
function isMemberOfOperatorSet(address operator, OperatorSet memory operatorSet) external view returns (bool);
/**
* @notice Returns whether the operator set exists
*/
function isOperatorSet(
OperatorSet memory operatorSet
) external view returns (bool);
/**
* @notice Returns all the operators registered to an operator set
* @param operatorSet The operatorSet to query.
*/
function getMembers(
OperatorSet memory operatorSet
) external view returns (address[] memory operators);
/**
* @notice Returns the number of operators registered to an operatorSet.
* @param operatorSet The operatorSet to get the member count for
*/
function getMemberCount(
OperatorSet memory operatorSet
) external view returns (uint256);
/**
* @notice Returns the address that handles registration/deregistration for the AVS
* If not set, defaults to the input address (`avs`)
*/
function getAVSRegistrar(
address avs
) external view returns (IAVSRegistrar);
/**
* @notice Returns an array of strategies in the operatorSet.
* @param operatorSet The operatorSet to query.
*/
function getStrategiesInOperatorSet(
OperatorSet memory operatorSet
) external view returns (IStrategy[] memory strategies);
/**
* @notice Returns the minimum amount of stake that will be slashable as of some future block,
* according to each operator's allocation from each strategy to the operator set.
* @dev This method queries actual delegated stakes in the DelegationManager and applies
* each operator's allocation to the stake to produce the slashable stake each allocation
* represents.
* @dev This minimum takes into account `futureBlock`, and will omit any pending magnitude
* diffs that will not be in effect as of `futureBlock`. NOTE that in order to get the true
* minimum slashable stake as of some future block, `futureBlock` MUST be greater than block.number
* @dev NOTE that `futureBlock` should be fewer than `DEALLOCATION_DELAY` blocks in the future,
* or the values returned from this method may not be accurate due to deallocations.
* @param operatorSet the operator set to query
* @param operators the list of operators whose slashable stakes will be returned
* @param strategies the strategies that each slashable stake corresponds to
* @param futureBlock the block at which to get allocation information. Should be a future block.
* @return slashableStake a list of slashable stakes, indexed by [operator][strategy]
*/
function getMinimumSlashableStake(
OperatorSet memory operatorSet,
address[] memory operators,
IStrategy[] memory strategies,
uint32 futureBlock
) external view returns (uint256[][] memory slashableStake);
}