|
| 1 | +# AllocationManager |
| 2 | + |
| 3 | +## Prerequisites |
| 4 | + |
| 5 | +- [The Mechanics of Allocating and Slashing Unique Stake](https://forum.eigenlayer.xyz/t/the-mechanics-of-allocating-and-slashing-unique-stake/13870) |
| 6 | + |
| 7 | +## Overview |
| 8 | +The AllocationManager contract manages the allocation and reallocation of operators' slashable stake across various strategies and operator sets. It enforces allocation and deallocation delays and handles the slashing process initiated by AVSs. |
| 9 | + |
| 10 | +## Parameterization |
| 11 | + |
| 12 | +- `ALLOCATION_CONFIGURATION_DELAY`: The delay in seconds before allocations take effect. |
| 13 | + - Mainnet: `21 days`. Very TBD |
| 14 | + - Testnet: `1 hour`. Very TBD |
| 15 | + - Public Devnet: `10 minutes` |
| 16 | +- `DEALLOCATION_DELAY`: The delay in seconds before deallocations take effect. |
| 17 | + - Mainnet: `17.5 days`. Slightly TBD |
| 18 | + - Testnet: `3 days`. Very TBD |
| 19 | + - Public Devnet: `1 days` |
| 20 | + |
| 21 | +## `setAllocationDelay` |
| 22 | + |
| 23 | +```solidity |
| 24 | +/** |
| 25 | + * @notice Called by operators or the delegation manager to set their allocation delay. |
| 26 | + * @param operator The operator to set the delay on behalf of. |
| 27 | + * @param delay The allocation delay in seconds. |
| 28 | + */ |
| 29 | +function setAllocationDelay(address operator, uint32 delay) external; |
| 30 | +
|
| 31 | +These functions allow operators to set their allocation delay. The first variant is called by the DelegationManager upon operator registration for all new operators created after the slashing release. The second variant is called by operators themselves to update their allocation delay or set it for the first time if they joined before the slashing release. |
| 32 | +
|
| 33 | +The allocation delay takes effect in `ALLOCATION_CONFIGURATION_DELAY` seconds. |
| 34 | +
|
| 35 | +The allocation delay can be any positive uint32. |
| 36 | +
|
| 37 | +The allocation delay's primary purpose is to give stakers delegated to an operator the chance to withdraw their stake before the operator can change the risk profile to something they're not comfortable with. |
| 38 | +
|
| 39 | +## `modifyAllocations` |
| 40 | +
|
| 41 | +```solidity |
| 42 | +/** |
| 43 | + * @notice struct used to modify the allocation of slashable magnitude to list of operatorSets |
| 44 | + * @param strategy the strategy to allocate magnitude for |
| 45 | + * @param expectedMaxMagnitude the expected max magnitude of the operator used to combat against race conditions with slashing |
| 46 | + * @param operatorSets the operatorSets to allocate magnitude for |
| 47 | + * @param magnitudes the magnitudes to allocate for each operatorSet |
| 48 | + */ |
| 49 | +struct MagnitudeAllocation { |
| 50 | + IStrategy strategy; |
| 51 | + uint64 expectedMaxMagnitude; |
| 52 | + OperatorSet[] operatorSets; |
| 53 | + uint64[] magnitudes; |
| 54 | +} |
| 55 | +
|
| 56 | +/** |
| 57 | + * @notice Modifies the propotions of slashable stake allocated to a list of operatorSets for a set of strategies |
| 58 | + * @param allocations array of magnitude adjustments for multiple strategies and corresponding operator sets |
| 59 | + * @dev Updates encumberedMagnitude for the updated strategies |
| 60 | + * @dev msg.sender is used as operator |
| 61 | + */ |
| 62 | +function modifyAllocations(MagnitudeAllocation[] calldata allocations) external |
| 63 | +``` |
| 64 | + |
| 65 | +This function is called by operators to adjust the proportions of their slashable stake allocated to different operator sets for different strategies. |
| 66 | + |
| 67 | +The operator provides their expected max magnitude for each strategy they're adjusting the allocation for. This is used to combat race conditions with slashings for the strategy, which may result in larger than expected slashable proportions allocated to operator sets. |
| 68 | + |
| 69 | +Each `(operator, operatorSet, strategy)` tuple can have at most 1 pending modification at a time. The function will revert is there is a pending modification for any of the tuples in the input. |
| 70 | + |
| 71 | +The contract keeps track of the total magnitude in pending allocations, active allocations, and pending deallocations. This is called the **_encumbered magnitude_** for a strategy. The contract verifies that the allocations made in this call do not make the encumbered magnitude exceed the operator's max magnitude for the strategy. If the encumbered magnitude exceeds the max magnitude, the function reverts. |
| 72 | + |
| 73 | +Any _allocations_ (i.e. increases in the proportion of slashable stake allocated to an AVS) take effect after the operator's allocation delay. The allocation delay must be set for the operator before they can call this function. |
| 74 | + |
| 75 | +Any _deallocations_ (i.e. decreases in the proportion of slashable stake allocated to an AVS) take effect after `DEALLOCATION_DELAY` seconds. This enables AVSs enough time to update their view of stakes to the new proportions and have any tasks created against previous stakes to expire. |
| 76 | + |
| 77 | +## `clearDeallocationQueue` |
| 78 | + |
| 79 | +```solidity |
| 80 | +/** |
| 81 | + * @notice This function takes a list of strategies and adds all completable deallocations for each strategy, |
| 82 | + * updating the encumberedMagnitude of the operator as needed. |
| 83 | + * |
| 84 | + * @param operator address to complete deallocations for |
| 85 | + * @param strategies a list of strategies to complete deallocations for |
| 86 | + * @param numToComplete a list of number of pending deallocations to complete for each strategy |
| 87 | + * |
| 88 | + * @dev can be called permissionlessly by anyone |
| 89 | + */ |
| 90 | +function clearDeallocationQueue( |
| 91 | + address operator, |
| 92 | + IStrategy[] calldata strategies, |
| 93 | + uint16[] calldata numToComplete |
| 94 | +) external; |
| 95 | +``` |
| 96 | + |
| 97 | +This function is used to complete pending deallocations for a list of strategies for an operator. The function takes a list of strategies and the number of pending deallocations to complete for each strategy. For each strategy, the function completes pending deallocations if their effect timestamps have passed. |
| 98 | + |
| 99 | +Completing a deallocation decreases the encumbered magnitude for the strategy, allowing them to make allocations with that magnitude. Encumbered magnitude must be decreased only upon completion because pending deallocations can be slashed before they are completable. |
| 100 | + |
| 101 | +## `slashOperator` |
| 102 | + |
| 103 | +```solidity |
| 104 | +/** |
| 105 | + * @notice Struct containing parameters to slashing |
| 106 | + * @param operator the address to slash |
| 107 | + * @param operatorSetId the ID of the operatorSet the operator is being slashed on behalf of |
| 108 | + * @param strategies the set of strategies to slash |
| 109 | + * @param wadsToSlash the parts in 1e18 to slash, this will be proportional to the operator's |
| 110 | + * slashable stake allocation for the operatorSet |
| 111 | + * @param description the description of the slashing provided by the AVS for legibility |
| 112 | + */ |
| 113 | +struct SlashingParams { |
| 114 | + address operator; |
| 115 | + uint32 operatorSetId; |
| 116 | + IStrategy[] strategies; |
| 117 | + uint256[] wadsToSlash; |
| 118 | + string description; |
| 119 | +} |
| 120 | +
|
| 121 | +/** |
| 122 | + * @notice Called by an AVS to slash an operator for given operatorSetId, list of strategies, and wadToSlash. |
| 123 | + * For each given (operator, operatorSetId, strategy) tuple, bipsToSlash |
| 124 | + * bips of the operatorSet's slashable stake allocation will be slashed |
| 125 | + * |
| 126 | + * @param operator the address to slash |
| 127 | + * @param operatorSetId the ID of the operatorSet the operator is being slashed on behalf of |
| 128 | + * @param strategies the set of strategies to slash |
| 129 | + * @param wadToSlash the parts in 1e18 to slash, this will be proportional to the |
| 130 | + * operator's slashable stake allocation for the operatorSet |
| 131 | + * @param description the description of the slashing provided by the AVS for legibility |
| 132 | + */ |
| 133 | +function slashOperator( |
| 134 | + SlashingParams calldata params |
| 135 | +) external |
| 136 | +``` |
| 137 | + |
| 138 | +This function is called by AVSs to slash an operator for a given operator set and list of strategies. The AVS provides the proportion of the operator's slashable stake allocation to slash for each strategy. The proportion is given in parts in 1e18 and is with respect to the operator's _current_ slashable stake allocation for the operator set (i.e. `wadsToSlash=5e17` means 50% of the operator's slashable stake allocation for the operator set will be slashed). The AVS also provides a description of the slashing for legibility by outside integrations. |
| 139 | + |
| 140 | +Slashing is instant and irreversable. Slashed funds remain unrecoverable in the protocol but will be burned/redistributed in a future release. Slashing by one operatorSet does not effect the slashable stake allocation of other operatorSets for the same operator and strategy. |
| 141 | + |
| 142 | +Slashing updates storage in a way that instantly updates all view functions to reflect the correct values. |
| 143 | + |
| 144 | +## View Functions |
| 145 | + |
| 146 | +### `getMinDelegatedAndSlashableOperatorSharesBefore` |
| 147 | + |
| 148 | +```solidity |
| 149 | +/** |
| 150 | + * @notice returns the minimum operatorShares and the slashableOperatorShares for an operator, list of strategies, |
| 151 | + * and an operatorSet before a given timestamp. This is used to get the shares to weight operators by given ones slashing window. |
| 152 | + * @param operatorSet the operatorSet to get the shares for |
| 153 | + * @param operators the operators to get the shares for |
| 154 | + * @param strategies the strategies to get the shares for |
| 155 | + * @param beforeTimestamp the timestamp to get the shares at |
| 156 | + */ |
| 157 | +function getMinDelegatedAndSlashableOperatorSharesBefore( |
| 158 | + OperatorSet calldata operatorSet, |
| 159 | + address[] calldata operators, |
| 160 | + IStrategy[] calldata strategies, |
| 161 | + uint32 beforeTimestamp |
| 162 | +) external view returns (uint256[][] memory, uint256[][] memory) |
| 163 | +``` |
| 164 | + |
| 165 | +This function returns the minimum operator shares and the slashable operator shares for an operator, list of strategies, and an operator set before a given timestamp. This is used by AVSs to pessimistically estimate the operator's slashable stake allocation for a given strategy and operator set within their slashability windows. If an AVS calls this function every week and creates tasks that are slashable for a week after they're created, then `beforeTimestamp` should be 2 weeks in the future to account for the latest task that may be created against stale stakes. More on this in new docs soon. |
| 166 | + |
| 167 | +### Additional View Functions |
| 168 | + |
| 169 | +See the [AllocationManager Interface](../../../src/contracts/interfaces/IAllocationManager.sol) for additional view functions. |
0 commit comments