You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**Motivation:**
Update core contracts to support redistribution.
**Modifications:**
We add a new contract, `SlashingWithdrawalRouter`, which handles the
redistribution withdrawal queue.
**AllocationManager**:
- Inherit `Deprecated_OwnableUpgradeable`
- Add a `createRedistributableOperatorSet` function, which creates an
operatorSet with a 1-time settable `redistributionRecipient`. Normal
operator sets have a `redistributionRecipient` of the default Burna
address
- `slashOperator` now aggregates all magnitudes and then make a _single_
call to the `DelegationManager` for a slash
- New view functions for introspection:
-- `getRedistributionRecipient`: gets the `redistributionRecipient` of
an operatorSet. Non-redistributing operatorSets will return the
`defaultBurnAddress`
-- `isRedistributingOperatorSet`: whether an operatorSet is
redistributable
-- `getSlashCount`: the number of slashes an operatorSet has done
-- `isOperatorRedistributable`: whether an operator is registered to a
redistributable operatorSet
**DelegationManager:**
- Update internal method of `slashOperator` to take in `slashId` and
`operatorSet`.
**ShareManager (SM, EPM):**
- `IncreaseBurnableShares` function is updated to take in an
`operatorSet`, `slashId`
**StrategyBase:**
- Return `amountOut` upon withdrawal. This enables programmatic handling
of redistributed funds
**SemVerMixin:**
- Update to only return the first character for `majorVersion`
**General Size Modifications:**
- The `AllocationManager` and `DelegationManager` inherit from
`Deprecated_OwnableUpgradeable`, which saves ~400B from both of these
contracts.
- The `DelegationManager` and `AllocationManager` use internal methods
to conserve space. We likely can get rid of these modifications due to
the `Deprecated_OwnableUpgradeable` handling the majority of these
**Result:**
*After your change, what will change.*
**Use this template to draft changelog and submit PR to review by the team**
4
-
5
3
## Release Manager
6
4
7
-
@0xClandestine
8
-
5
+
@0xClandestine@ypatil12
9
6
10
7
## Highlights
11
8
12
-
🚀 New Features – Highlight major new functionality
13
-
- ...
14
-
- ...
9
+
🚀 New features
15
10
16
-
⛔ Breaking Changes – Call out backward-incompatible changes.
17
-
- ...
18
-
- ...
11
+
- Redistribution is a feature that gives Service Builders a means to not just burn, but repurpose slashed funds.
12
+
- We introduce a new operatorSet creation mechanism: [`AllocationManager.createRedistributingOperatorSets`](../docs/core/AllocationManager.md#createredistributingoperatorsets), which allows slashed funds to be redistributed to a `RedistributionRecipient`. *Note: The redistribution recipient can be set only once and is immutable*.
13
+
-*All slashed funds will now be routed to individual `SlashEscrow` contracts.* The release of funds from escrow is gated by the `SlashEscrowFactory`. The `SlashEscrowFactory` deploys individual `SlashEscrow` contracts per slash, enforces a global delay for all escrowed funds, and handles pausing/unpausing of escrowed funds.
14
+
- The original `createOperatorSets` function still exists. This function creates operatorSets whose slashed funds will eventually be burned. There is no mechanism to convert an operatorSet to be redistributing.
15
+
- See [ELIP-006](https://github.com/eigenfoundation/ELIPs/blob/main/ELIPs/ELIP-006.md) for a full description.
19
16
20
-
📌 Deprecations – Mention features that are being phased out.
21
-
- ...
22
-
- ...
17
+
⛔ Breaking changes
18
+
- Funds marked for burning now go through a 4-day escrow period via `SlashEscrow` contracts. These funds are burned by calling [`SlashEscrowFactory.releaseSlashEscrow`](../docs/core/SlashEscrowFactory.md#releaseslashescrow).
- The pre-redistribution burn pathway [`StrategyManager.decreaseBurnableShares`](../docs/core/StrategyManager.md#burnshares) will be deprecated in an upgrade *after* the redistribution release. This function can still be used to burn shares that have been slashed at any point prior to the redistribution upgrade.
27
22
28
-
🔧 Improvements – Enhancements to existing features.
29
-
-...
30
-
-...
23
+
🛠️ Security Updates
24
+
-The slashing of burned funds is no longer instantaneous. All slashed funds (burned or redistributed) now go through a 4-day escrow delay. The eventual burning or redistribution of slashed funds can be paused by the `PauserMultisig`.
25
+
-The upgradability of the `SlashEscrowFactory` is controlled by the `CommunityMultisig`. The contract will have a separate `ProxyAdmin` from the rest of the EigenLayer core protocol. Each individual `SlashEscrow` contract is an immutable clone.
31
26
32
-
🐛 Bug Fixes – List resolved issues.
33
-
- ...
34
-
- ...
27
+
🔧 Improvements
28
+
- The [`AllocationManager.slashOperator`](../docs/core/AllocationManager.md#slashoperator) function now returns a `slashId` and array of `shares` to be burned/redistributed. **The function selector remains the same.**
29
+
- OperatorSets now have a `slashCount` field, which returns the number of slashes completed by the operatorSet. This value only reflects the number of slashes after the redistribution upgrade.
30
+
-`StrategyBase` returns an `amountOut` upon withdrawal to comply with standard ERC-4626 vaults.
31
+
- The `AllocationManager` and `DelegationManager` no longer use ownable. Thus, they now inherit the `Deprecated_OwnableUpgradeable` mixin in its place to reduce codesize.
35
32
33
+
🐛 Bug Fixes
34
+
-`SemVerMixin` is updated to only return the first character of `majorVersion`. We currently return `1.` and will return `1` after this upgrade.
36
35
37
-
## Changelog
38
-
39
-
Copy the one that's auto generated from github by default to here, and submit PR for review
40
36
37
+
## Changelog
41
38
42
-
- merged PRs in diff from last release
43
-
- contributors
44
-
- etc
39
+
- feat(draft): `AllocationManager` redistribution support [PR #1346](https://github.com/layr-labs/eigenlayer-contracts/pull/1346)
- feat: simplify removeDepositShares in StrategyManager [PR #1373](https://github.com/layr-labs/eigenlayer-contracts/pull/1373)
67
+
- feat(draft): `AllocationManager` redistribution support [PR #1346](https://github.com/layr-labs/eigenlayer-contracts/pull/1346)
68
+
- ci: add explicit permissions to workflows to mitigate security concerns [PR #1392](https://github.com/layr-labs/eigenlayer-contracts/pull/1392)
69
+
- ci: remove branch constraint for foundry coverage job
70
+
- docs: add release managers to changelogs
71
+
- docs: add templates for changelog and release notes [PR #1382](https://github.com/layr-labs/eigenlayer-contracts/pull/1382)
72
+
- docs: add doc for steps to write deploy scripts [PR #1380](https://github.com/layr-labs/eigenlayer-contracts/pull/1380)
73
+
- ci: add testnet envs sepolia and hoodi to validate-deployment-scripts [PR #1378](https://github.com/layr-labs/eigenlayer-contracts/pull/1378)
74
+
- docs: update MAINTENANCE to include practices of merging multiple release-dev branches
75
+
- docs: updating readme for dead links, readability, new language, and more [PR #1377](https://github.com/layr-labs/eigenlayer-contracts/pull/1377)
76
+
- docs: bump deployment matrix to top of README [PR #1376](https://github.com/layr-labs/eigenlayer-contracts/pull/1376)
77
+
- ci: add CI to auto validate deployment scripts [PR #1360](https://github.com/layr-labs/eigenlayer-contracts/pull/1360)
78
+
- chore: update readme for v1.4.1 [PR #1361](https://github.com/layr-labs/eigenlayer-contracts/pull/1361)
79
+
- ci: add cron to auto remove stale branches [PR #1348](https://github.com/layr-labs/eigenlayer-contracts/pull/1348)
80
+
- chore: Update README for Holesky v1.4.2 release [PR #1351](https://github.com/layr-labs/eigenlayer-contracts/pull/1351)
81
+
- docs: remove fork-pr instructions from CONTRIBUTING.md and MAINTENANCE.md
82
+
- ci: disable delete unauthorized branches
83
+
- docs: update addresses for mainnet [PR #1341](https://github.com/layr-labs/eigenlayer-contracts/pull/1341)
Every `OperatorSet` corresponds to a single AVS, as indicated by the `avs` parameter. On creation, the AVS provides an `id` (unique to that AVS), as well as a list of `strategies` the `OperatorSet` includes. Together, the `avs` and `id` form the `key` that uniquely identifies a given `OperatorSet`. Operators can register to and deregister from operator sets. In combination with allocating slashable magnitude, operator set registration forms the basis of operator slashability (discussed further in [Allocations and Slashing](#allocations-and-slashing)).
174
+
Every `OperatorSet` corresponds to a single AVS, as indicated by the `avs` parameter. On creation, the AVS provides an `id` (unique to that AVS), as well as a list of `strategies` the `OperatorSet` includes. Together, the `avs` and `id` form the `key` that uniquely identifies a given `OperatorSet`. Operators can register to and deregister from operator sets. In combination with allocating slashable magnitude, operator set registration forms the basis of operator slashability (discussed further in [Allocations and Slashing](#allocations-and-slashing)). There are two types of operatorSets, redistributing and non-redistributing.
_Note: this method can be called directly by an AVS, or by a caller authorized by the AVS. See [`PermissionController.md`](../permissions/PermissionController.md) for details._
239
241
240
-
AVSs use this method to create new operator sets. An AVS can create as many operator sets as they desire, depending on their needs. Once created, operators can [allocate slashable stake to](#modifyallocations) and [register for](#registerforoperatorsets) these operator sets.
242
+
AVSs use this method to create new operator sets. An AVS can create as many operator sets as they desire, depending on their needs. Once created, operators can [allocate slashable stake to](#modifyallocations) and [register for](#registerforoperatorsets) these operator sets. The `redistributionRecipient` is the `DEFAULT_BURN_ADDRESS`, where slashed funds are sent.
241
243
242
244
On creation, the `avs` specifies an `operatorSetId` unique to the AVS. Together, the `avs` address and `operatorSetId` create a `key` that uniquely identifies this operator set throughout the `AllocationManager`.
243
245
@@ -254,6 +256,38 @@ Optionally, the `avs` can provide a list of `strategies`, specifying which strat
254
256
* AVS MUST have registered metadata via calling `updateAVSMetadataURI`
255
257
* For each `CreateSetParams` element:
256
258
* Each `params.operatorSetId` MUST NOT already exist in `_operatorSets[avs]`
259
+
260
+
#### `createRedistributingOperatorSets`
261
+
262
+
```solidity
263
+
/**
264
+
* @notice Allows an AVS to create new redistributing operator sets, defining strategies and the redistribution recipient the operator set uses
265
+
*/
266
+
function createRedistributingOperatorSets(
267
+
address avs,
268
+
CreateSetParams[] calldata params,
269
+
address[] calldata redistributionRecipients
270
+
)
271
+
external
272
+
checkCanCall(avs)
273
+
```
274
+
275
+
AVSs use this method to create new redistributing operatorSets. Unlike the previous function, slashed funds for this operatorSet are sent to a `redistributionRecipient`. This value is set only once, upon creation. Note that redistributing operatorSets may not have Native ETH, as the protocol does not support native eth redistribution. See [ELIP-006](https://github.com/eigenfoundation/ELIPs/blob/main/ELIPs/ELIP-006.md) for additional context.
276
+
277
+
*Effects*:
278
+
* For each `CreateSetParams` element:
279
+
* For each `params.strategies` element:
280
+
* Add `strategy` to `_operatorSetStrategies[operatorSetKey]`
281
+
* Emits `StrategyAddedToOperatorSet` event
282
+
* Sets the `redistributionRecipient` of the operatorSet
283
+
* Emits the `RedistributionAddressSet`
284
+
285
+
*Requirements*:
286
+
* Caller MUST be authorized, either as the AVS itself or an admin/appointee (see [`PermissionController.md`](../permissions/PermissionController.md))
287
+
* AVS MUST have registered metadata via calling `updateAVSMetadataURI`
288
+
* The `redistributionRecipient` MUST NOT be the 0 address
289
+
* For each `CreateSetParams` element:
290
+
* Each `params.operatorSetId` MUST NOT already exist in `_operatorSets[avs]`
257
291
258
292
#### `addStrategiesToOperatorSet`
259
293
@@ -287,6 +321,7 @@ This function allows an AVS to add slashable strategies to a given operator set.
287
321
* Caller MUST be authorized, either as the AVS itself or an admin/appointee (see [`PermissionController.md`](../permissions/PermissionController.md))
288
322
* The operator set MUST be registered for the AVS
289
323
* Each proposed strategy MUST NOT be registered for the operator set
324
+
* If the operatorSet is redistributing, the `BEACONCHAIN_ETH_STRAT` may not be added, since redistribution is not supported for native eth
290
325
291
326
#### `removeStrategiesFromOperatorSet`
292
327
@@ -717,6 +752,9 @@ struct SlashingParams {
717
752
* - wadsToSlash: Array of proportions to slash from each strategy (must be between 0 and 1e18).
718
753
* - description: Description of why the operator was slashed.
719
754
*
755
+
* @return slashId The ID of the slash.
756
+
* @return shares The amount of shares that were slashed for each strategy.
757
+
*
720
758
* @dev For each strategy:
721
759
* 1. Reduces the operator's current allocation magnitude by wadToSlash proportion.
722
760
* 2. Reduces the strategy's max and encumbered magnitudes proportionally.
@@ -734,6 +772,7 @@ function slashOperator(
734
772
external
735
773
onlyWhenNotPaused(PAUSED_OPERATOR_SLASHING)
736
774
checkCanCall(avs)
775
+
returns (uint256, uint256[] memory)
737
776
```
738
777
739
778
_Note: this method can be called directly by an AVS, or by a caller authorized by the AVS. See [`PermissionController.md`](../permissions/PermissionController.md) for details._
@@ -748,7 +787,7 @@ There are two edge cases to note for this method:
748
787
1. In the process of slashing an `operator` for a given `strategy`, if the `Allocation` being slashed has a `currentMagnitude` of 0, the call will NOT revert. Instead, the `strategy` is skipped and slashing continues with the next `strategy` listed. This is to prevent an edge case where slashing occurs on or around a deallocation's `effectBlock` -- if the call reverted, the entire slash would fail. Skipping allows any valid slashes to be processed without requiring resubmission.
749
788
2. If the `operator` has a pending, non-completable deallocation, the deallocation's `pendingDiff` is reduced proportional to the slash. This ensures that when the deallocation is completed, less `encumberedMagnitude` is freed.
750
789
751
-
Once slashing is processed for a strategy, [slashed stake is burned via the `DelegationManager`](https://github.com/eigenfoundation/ELIPs/blob/main/ELIPs/ELIP-002.md#burning-of-slashed-funds).
790
+
Once slashing is processed for a strategy, [slashed stake is burned or redistributed via the `DelegationManager`](https://github.com/eigenfoundation/ELIPs/blob/main/ELIPs/ELIP-002.md#burning-of-slashed-funds).
752
791
753
792
*Effects*:
754
793
* Given an `operator` and `operatorSet`, then for each `params.strategies` element and its corresponding `allocation`:
@@ -765,6 +804,8 @@ Once slashing is processed for a strategy, [slashed stake is burned via the `Del
765
804
* If this list now has a length of 0, remove `operatorSetKey` from `allocatedSets[operator]`
0 commit comments