-
Notifications
You must be signed in to change notification settings - Fork 461
feat: substitute calcSlashedAmount for scaleForBurning #1502
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
nadir-akhtar
merged 6 commits into
release-dev/slashing-ux-improvements
from
nadir/remove-scale-for-burning
Dec 1, 2025
Merged
feat: substitute calcSlashedAmount for scaleForBurning #1502
nadir-akhtar
merged 6 commits into
release-dev/slashing-ux-improvements
from
nadir/remove-scale-for-burning
Dec 1, 2025
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35c94c2 to
061c318
Compare
fe0efd1 to
170e3dc
Compare
wadealexc
reviewed
Jul 1, 2025
wadealexc
reviewed
Jul 1, 2025
ypatil12
reviewed
Dec 1, 2025
Collaborator
ypatil12
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we change the base to release-dev/slashing-ux-improvements? Also need to run make bindings after.
ypatil12
approved these changes
Dec 1, 2025
f76315e
into
release-dev/slashing-ux-improvements
9 checks passed
ypatil12
added a commit
that referenced
this pull request
Dec 1, 2025
**Motivation:**
When developing the slashing release, two different functions for
calculating slashed shares were ideated: `calcSlashedAmount` and
`scaleForBurning`. The former is used to calculated slashed "operator
shares," or shares currently delegated to an operator, and the latter
for "queued shares," or shares in the withdrawal queue that are
currently slashable.
Despite the functionality effectively being equivalent (determine how
many of these shares are to be slashed), two different functions were
maintained due to uncertainty as to how to deduplicate them.
During the redistribution release, manual analysis yielded the
conclusion that there is a way to consolidate these two functions. In
order to reduce disparate logic, this PR removes `scaleForBurning` and
replaces it with `calcSlashedAmount`.
_Context:_
`calcSlashedAmount` and `scaleForBurning` both attempt to do the same
thing: return how many shares to slash as a result of an operator's
magnitude change. However, they each go about it in different ways:
* `calcSlashedAmount` reduces an operator's shares by a certain
proportion, specifically by `newMaxMag / prevMaxMag`, then returns that
number of shares.
* `scaleForBurning` calculates the effective shares at the current and
expected max mags, then returns the difference.
Note that the "type" of share entering each equation is not the same:
`calcSlashedAmount` takes in operator shares, whereas `scaleForBurning`
takes in "scaled shares," i.e. shares that are scaled based on staker
deposit scaling factors (DSFs), but do _not_ change based on operator
slashings.
Once this type discrepancy was evident, the next step was to determine
how to convert from one type to the other. Choosing `calcSlashedAmount`
as the natural base function, it became evident that "scaled shares" can
be translated to operator shares by simply _multiplying by the current
operator magnitude_. With that simple change, `calcSlashedAmount` can be
used to calculate shares slashed from both operator shares as well as
queued shares.
Math:
**Variables**
- $s_n$ - The amount of shares in the storage of the {EP,S}M at time n
- $k_n$ - The “staker deposit scaling factor” at time n. This is
initialized to 1.
- $m_n$ - The operator magnitude at time n
- $op_{n}$ - The shares of the operator $op_{n}=s_{n}k_{n}m_{n}$
- $ss_{n}$ - The scaled shares of the operator in storage. This is
stored upon queueing of a withdrawal $ss_{n}=s_{n}k_{n}$. See
`scaleForQueueWithdrawal` in `SlashingLib`
**Scale For Burning**
$ss_{n}(m_{n}-m_{n+1})$
= $s_nk_n(m_{n}-m_{n+1})$
= $s_nk_nm_{n}- s_nk_nm_{n+1}$
= $op_n - s_nk_nm_{n+1}$
**Calc Slashed Amount**
$op_{n} - op_{n}*\frac{m_{n+1}}{m_n}$
= $op_{n} - s_nk_nm_n*\frac{m_{n+1}}{m_n}$
= $op_{n} - s_nk_n{m_{n+1}}$
**Modifications:**
* Removes `scaleForBurning` from `SlashingLib.sol` and replaces its use
with `calcSlashedAmount`
**Result:**
* Cleaned up code
* Clearer logic
---------
Co-authored-by: Nadir Akhtar <[email protected]>
Co-authored-by: Yash Patil <[email protected]>
ypatil12
added a commit
that referenced
this pull request
Dec 2, 2025
# v1.9.0 Slashing UX Improvements ## Release Manager @ypatil12 @eigenmikem @0xClandestine # Overview The Slashing UX improvement release is a tech debt-focused release that improves key parts of the Eigenlayer Core UX. This release will upgrade every core contract. The below release notes cover Core Contracts. ## Highlights 🚀 New Features - The `AllocationManager` has been split into two contracts to address size limitations of the contract. The main contract handles state-mutating operations, while `AllocationManagerView` handles all read-only view functions. **This is not a breaking change for introspection as previous introspection calls fallback to `delegateCall` into the `AllocationManagerView` contract.**. For more information, see the [contract architecture](../docs/core/AllocationManager.md#contract-architecture). - The `ProtocolRegistry` is a new contract that stores all proxy contract addresses, global semver, and has the ability to pause the entire protocol. This contract will be deployed on all chains. - Two new `createOperatorSets` functions (for redistributing and non redistributing operatorSets) have been added that take in a slasher address. This address is the *only* address that can slash an operatorSet. Changing the address is behind a `ALLOCATION_CONFIGURATION_DELAY` (17.5 days on mainnet). ⛔ Breaking Changes - The slasher permissions are set and stored in the `AllocationManager` instead of the `PermissionController`. Only one address can slash an operatorSet; the address is initially set upon creation of the operatorSet. OperatorSets created prior to this release will have their slasher migrated based on the following rules: - If there is no slasher set or the slasher in the `PermissionController` is the 0 address, the AVS address will be set as the slasher - If there are multiple slashers set in the `PermissionController`, the first address will be set as the slasher - Semver (`SemverMixin.sol`) has been removed from all contracts, except from those that inherit the `SignatureUtilsMixin`. The version of the core protocol can be introspected via the `ProtocolRegistry`. 📌 Deprecations The old `createOperatorSets` functions in the leftmost column will be deprecated in Q2 2026 in favor of the newly specified functions. The old functions do not pass in a slasher. The new functions do pass in a slasher. If the old function is used, the slasher of the operatorSet is set to the avs address. | Function | MigrateTo | Notes | | -------- | -------- | -------- | | `createOperatorSets(avs, CreateSetParams[])` | `createOperatorSets(address avs, CreateSetParamsV2[])` | New function takes in a slasher address | | `createRedistributingOperatorSets(avs, CreateSetParams[], redistributionRecipients[])` | `createRedistributingOperatorSets(avs, CreateSetParamsV2[], redistributionRecipients[])` | New function takes in a slasher address | 🔧 Improvements - Added a non-revert `_canCall` in the `PermissionControllerMixin` for space savings. This function is used in the `AllocationManager` and `DelegationManager`. - The allocation delay for a newly created operator is active immediately. This allows operators to make allocations instantly after registering in the core. - The internal `SlashingLib.scaleForBurning` function has been deprecated in favor of `SlashingLib.calcSlashedAmount`, standardizing the calculation of slashed shares across the withdrawal queue and storage. See [PR #1502](#1502) for more information. # Changelog - feat: re-enable forge fmt + foundry v1.5.0 [PR #1669](#1669) - feat: substitute calcSlashedAmount for scaleForBurning [PR #1502](#1502) - fix: `v1.9.0` upgrade script [PR #1666](#1666) - feat: `v1.9.0` upgrade scripts + reusable upgrade helpers [PR #1665](#1665) - chore: update interface natspec for DM [PR #1664](#1664) - feat: slashing commitments [PR #1645](#1645) - feat: remove semver + minor optimizations [PR #1654](#1654) - feat: split `AllocationManager` [PR #1643](#1643) - feat: add protocol registry [PR #1655](#1655) - feat: instant alloc delay from dm [PR #1646](#1646) - chore: remove holesky [PR #1662](#1662) - chore: hardcode foundry ci to v1.3.5 [PR #1658](#1658) - chore: hardcode foundry to v1.3.5 in ci [PR #1657](#1657) - feat(audit): publish Hourglass + Multichain + RMS audit reports [PR #1644](#1644) - docs: add transport frequency for multichain [PR #1642](#1642) - chore: update readMe for multichain/hourglass [PR #1637](#1637)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Motivation:
When developing the slashing release, two different functions for calculating slashed shares were ideated:
calcSlashedAmountandscaleForBurning. The former is used to calculated slashed "operator shares," or shares currently delegated to an operator, and the latter for "queued shares," or shares in the withdrawal queue that are currently slashable.Despite the functionality effectively being equivalent (determine how many of these shares are to be slashed), two different functions were maintained due to uncertainty as to how to deduplicate them.
During the redistribution release, manual analysis yielded the conclusion that there is a way to consolidate these two functions. In order to reduce disparate logic, this PR removes
scaleForBurningand replaces it withcalcSlashedAmount.Context:
calcSlashedAmountandscaleForBurningboth attempt to do the same thing: return how many shares to slash as a result of an operator's magnitude change. However, they each go about it in different ways:calcSlashedAmountreduces an operator's shares by a certain proportion, specifically bynewMaxMag / prevMaxMag, then returns that number of shares.scaleForBurningcalculates the effective shares at the current and expected max mags, then returns the difference.Note that the "type" of share entering each equation is not the same:
calcSlashedAmounttakes in operator shares, whereasscaleForBurningtakes in "scaled shares," i.e. shares that are scaled based on staker deposit scaling factors (DSFs), but do not change based on operator slashings.Once this type discrepancy was evident, the next step was to determine how to convert from one type to the other. Choosing
calcSlashedAmountas the natural base function, it became evident that "scaled shares" can be translated to operator shares by simply multiplying by the current operator magnitude. With that simple change,calcSlashedAmountcan be used to calculate shares slashed from both operator shares as well as queued shares.Math:
Variables
scaleForQueueWithdrawalinSlashingLibScale For Burning
$ss_{n}(m_{n}-m_{n+1})$
=$s_nk_n(m_{n}-m_{n+1})$
=$s_nk_nm_{n}- s_nk_nm_{n+1}$
=$op_n - s_nk_nm_{n+1}$
Calc Slashed Amount
=$op_{n} - s_nk_nm_n*\frac{m_{n+1}}{m_n}$
=$op_{n} - s_nk_n{m_{n+1}}$
Modifications:
scaleForBurningfromSlashingLib.soland replaces its use withcalcSlashedAmountResult: