Skip to content

Commit

Permalink
refactor: async burning (#1001)
Browse files Browse the repository at this point in the history
* refactor: burning

* chore: fmt

* chore: update storage report

* chore: update readme

* refactor: add burnableShares for epm storage

* chore: update storage report
  • Loading branch information
8sunyuan authored Jan 6, 2025
1 parent ad4f21e commit c44f725
Show file tree
Hide file tree
Showing 20 changed files with 267 additions and 132 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ surya mdreport surya_report.md ./src/contracts/**/*.sol
make bindings
```

### Generate updated Storage Report

To update the storage reports in `/docs/storage-report` run:

```bash
make storage-report
```

## Deployments

### Current Mainnet Deployment
Expand Down
2 changes: 1 addition & 1 deletion docs/core/AllocationManager.md
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ Once slashing is processed for a strategy, [slashed stake is burned via the `Del
* If the `allocation` now has a `currentMagnitude` of 0:
* Removes `strategy` from the `allocatedStrategies[operator][operatorSetKey]` list
* If this list now has a length of 0, remove `operatorSetKey` from `allocatedSets[operator]`
* Calls [`DelegationManager.burnOperatorShares`](./DelegationManager.md#burnoperatorshares)
* Calls [`DelegationManager.slashOperatorShares`](./DelegationManager.md#slashoperatorshares)
* Emit an `OperatorSlashed` event

*Requirements*:
Expand Down
4 changes: 3 additions & 1 deletion docs/storage-report/EigenPodManager.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
|---------------------------------+----------------------------------------------------------------------------+------+--------+-------+--------------------------------------------------------|
| _beaconChainSlashingFactor | mapping(address => struct IEigenPodManagerTypes.BeaconChainSlashingFactor) | 157 | 0 | 32 | src/contracts/pods/EigenPodManager.sol:EigenPodManager |
|---------------------------------+----------------------------------------------------------------------------+------+--------+-------+--------------------------------------------------------|
| __gap | uint256[43] | 158 | 0 | 1376 | src/contracts/pods/EigenPodManager.sol:EigenPodManager |
| burnableETHShares | uint256 | 158 | 0 | 32 | src/contracts/pods/EigenPodManager.sol:EigenPodManager |
|---------------------------------+----------------------------------------------------------------------------+------+--------+-------+--------------------------------------------------------|
| __gap | uint256[42] | 159 | 0 | 1344 | src/contracts/pods/EigenPodManager.sol:EigenPodManager |
|---------------------------------+----------------------------------------------------------------------------+------+--------+-------+--------------------------------------------------------|
| _status | uint256 | 201 | 0 | 32 | src/contracts/pods/EigenPodManager.sol:EigenPodManager |
|---------------------------------+----------------------------------------------------------------------------+------+--------+-------+--------------------------------------------------------|
Expand Down
4 changes: 3 additions & 1 deletion docs/storage-report/EigenPodManagerStorage.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
|---------------------------------+----------------------------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------|
| _beaconChainSlashingFactor | mapping(address => struct IEigenPodManagerTypes.BeaconChainSlashingFactor) | 6 | 0 | 32 | src/contracts/pods/EigenPodManagerStorage.sol:EigenPodManagerStorage |
|---------------------------------+----------------------------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------|
| __gap | uint256[43] | 7 | 0 | 1376 | src/contracts/pods/EigenPodManagerStorage.sol:EigenPodManagerStorage |
| burnableETHShares | uint256 | 7 | 0 | 32 | src/contracts/pods/EigenPodManagerStorage.sol:EigenPodManagerStorage |
|---------------------------------+----------------------------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------|
| __gap | uint256[42] | 8 | 0 | 1344 | src/contracts/pods/EigenPodManagerStorage.sol:EigenPodManagerStorage |
╰---------------------------------+----------------------------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------╯

4 changes: 3 additions & 1 deletion docs/storage-report/StrategyManager.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
|----------------------------------------------------------+------------------------------------------------------------+------+--------+-------+--------------------------------------------------------|
| __deprecated_thirdPartyTransfersForbidden | mapping(contract IStrategy => bool) | 211 | 0 | 32 | src/contracts/core/StrategyManager.sol:StrategyManager |
|----------------------------------------------------------+------------------------------------------------------------+------+--------+-------+--------------------------------------------------------|
| __gap | uint256[39] | 212 | 0 | 1248 | src/contracts/core/StrategyManager.sol:StrategyManager |
| burnableShares | mapping(contract IStrategy => uint256) | 212 | 0 | 32 | src/contracts/core/StrategyManager.sol:StrategyManager |
|----------------------------------------------------------+------------------------------------------------------------+------+--------+-------+--------------------------------------------------------|
| __gap | uint256[38] | 213 | 0 | 1216 | src/contracts/core/StrategyManager.sol:StrategyManager |
╰----------------------------------------------------------+------------------------------------------------------------+------+--------+-------+--------------------------------------------------------╯

4 changes: 3 additions & 1 deletion docs/storage-report/StrategyManagerStorage.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
|----------------------------------------------------------+------------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------|
| __deprecated_thirdPartyTransfersForbidden | mapping(contract IStrategy => bool) | 10 | 0 | 32 | src/contracts/core/StrategyManagerStorage.sol:StrategyManagerStorage |
|----------------------------------------------------------+------------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------|
| __gap | uint256[39] | 11 | 0 | 1248 | src/contracts/core/StrategyManagerStorage.sol:StrategyManagerStorage |
| burnableShares | mapping(contract IStrategy => uint256) | 11 | 0 | 32 | src/contracts/core/StrategyManagerStorage.sol:StrategyManagerStorage |
|----------------------------------------------------------+------------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------|
| __gap | uint256[38] | 12 | 0 | 1216 | src/contracts/core/StrategyManagerStorage.sol:StrategyManagerStorage |
╰----------------------------------------------------------+------------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------╯

4 changes: 2 additions & 2 deletions src/contracts/core/AllocationManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ contract AllocationManager is

_updateMaxMagnitude(params.operator, params.strategies[i], info.maxMagnitude);

// 6. Decrease and burn operators shares in the DelegationManager
delegation.burnOperatorShares({
// 6. Slash operators shares in the DelegationManager
delegation.slashOperatorShares({
operator: params.operator,
strategy: params.strategies[i],
prevMaxMagnitude: prevMaxMagnitude,
Expand Down
10 changes: 4 additions & 6 deletions src/contracts/core/DelegationManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ contract DelegationManager is
}

/// @inheritdoc IDelegationManager
function burnOperatorShares(
function slashOperatorShares(
address operator,
IStrategy strategy,
uint64 prevMaxMagnitude,
Expand Down Expand Up @@ -307,11 +307,9 @@ contract DelegationManager is
sharesToDecrease: operatorSharesSlashed
});

// NOTE: native ETH shares will be burned by a different mechanism in a future release
if (strategy != beaconChainETHStrategy) {
strategyManager.burnShares(strategy, totalDepositSharesToBurn);
emit OperatorSharesBurned(operator, strategy, totalDepositSharesToBurn);
}
IShareManager shareManager = _getShareManager(strategy);
// NOTE: for beaconChainETHStrategy, increased burnable shares currently have no mechanism for burning
shareManager.increaseBurnableShares(strategy, totalDepositSharesToBurn);
}

/**
Expand Down
13 changes: 12 additions & 1 deletion src/contracts/core/StrategyManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,19 @@ contract StrategyManager is
strategy.withdraw(staker, token, shares);
}

/// @inheritdoc IShareManager
function increaseBurnableShares(IStrategy strategy, uint256 addedSharesToBurn) external onlyDelegationManager {
burnableShares[strategy] += addedSharesToBurn;
emit BurnableSharesIncreased(strategy, addedSharesToBurn);
}

/// @inheritdoc IStrategyManager
function burnShares(IStrategy strategy, uint256 sharesToBurn) external onlyDelegationManager {
function burnShares(
IStrategy strategy
) external nonReentrant {
uint256 sharesToBurn = burnableShares[strategy];
burnableShares[strategy] = 0;
emit BurnableSharesDecreased(strategy, sharesToBurn);
// burning shares is functionally the same as withdrawing but with different destination address
strategy.withdraw(DEFAULT_BURN_ADDRESS, strategy.underlyingToken(), sharesToBurn);
}
Expand Down
5 changes: 4 additions & 1 deletion src/contracts/core/StrategyManagerStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ abstract contract StrategyManagerStorage is IStrategyManager {
/// @dev Do not remove, deprecated storage.
mapping(IStrategy strategy => bool) private __deprecated_thirdPartyTransfersForbidden;

/// @notice Returns the amount of `shares` that have been slashed on EigenLayer but not burned yet.
mapping(IStrategy strategy => uint256) public burnableShares;

// Construction

/**
Expand All @@ -85,5 +88,5 @@ abstract contract StrategyManagerStorage is IStrategyManager {
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[39] private __gap;
uint256[38] private __gap;
}
9 changes: 3 additions & 6 deletions src/contracts/interfaces/IDelegationManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,6 @@ interface IDelegationManagerEvents is IDelegationManagerTypes {
/// @notice Emitted whenever an operator's shares are decreased for a given strategy. Note that shares is the delta in the operator's shares.
event OperatorSharesDecreased(address indexed operator, address staker, IStrategy strategy, uint256 shares);

/// @notice Emitted whenever an operator's shares are burned for a given strategy
event OperatorSharesBurned(address indexed operator, IStrategy strategy, uint256 shares);

/// @notice Emitted when @param staker delegates to @param operator.
event StakerDelegated(address indexed staker, address indexed operator);

Expand Down Expand Up @@ -353,8 +350,8 @@ interface IDelegationManager is ISignatureUtils, IDelegationManagerErrors, IDele
) external;

/**
* @notice Decreases the operators shares in storage after a slash and burns the corresponding Strategy shares
* by calling into the StrategyManager or EigenPodManager to burn the shares.
* @notice Decreases the operators shares in storage after a slash and increases the burnable shares by calling
* into either the StrategyManager or EigenPodManager (if the strategy is beaconChainETH).
* @param operator The operator to decrease shares for
* @param strategy The strategy to decrease shares for
* @param prevMaxMagnitude the previous maxMagnitude of the operator
Expand All @@ -363,7 +360,7 @@ interface IDelegationManager is ISignatureUtils, IDelegationManagerErrors, IDele
* @dev Note: Assumes `prevMaxMagnitude <= newMaxMagnitude`. This invariant is maintained in
* the AllocationManager.
*/
function burnOperatorShares(
function slashOperatorShares(
address operator,
IStrategy strategy,
uint64 prevMaxMagnitude,
Expand Down
6 changes: 6 additions & 0 deletions src/contracts/interfaces/IEigenPodManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ interface IEigenPodManagerEvents {
event BeaconChainSlashingFactorDecreased(
address staker, uint64 prevBeaconChainSlashingFactor, uint64 newBeaconChainSlashingFactor
);

/// @notice Emitted when an operator is slashed and shares to be burned are increased
event BurnableETHSharesIncreased(uint256 shares);
}

interface IEigenPodManagerTypes {
Expand Down Expand Up @@ -161,4 +164,7 @@ interface IEigenPodManager is
function beaconChainSlashingFactor(
address staker
) external view returns (uint64);

/// @notice Returns the accumulated amount of beacon chain ETH Strategy shares
function burnableETHShares() external view returns (uint256);
}
9 changes: 9 additions & 0 deletions src/contracts/interfaces/IShareManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,13 @@ interface IShareManager {
/// @dev strategy must be beaconChainETH when talking to the EigenPodManager
/// @dev returns 0 if the user has negative shares
function stakerDepositShares(address user, IStrategy strategy) external view returns (uint256 depositShares);

/**
* @notice Increase the amount of burnable shares for a given Strategy. This is called by the DelegationManager
* when an operator is slashed in EigenLayer.
* @param strategy The strategy to burn shares in.
* @param addedSharesToBurn The amount of added shares to burn.
* @dev This function is only called by the DelegationManager when an operator is slashed.
*/
function increaseBurnableShares(IStrategy strategy, uint256 addedSharesToBurn) external;
}
15 changes: 11 additions & 4 deletions src/contracts/interfaces/IStrategyManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ interface IStrategyManagerEvents {

/// @notice Emitted when a strategy is removed from the approved list of strategies for deposit
event StrategyRemovedFromDepositWhitelist(IStrategy strategy);

/// @notice Emitted when an operator is slashed and shares to be burned are increased
event BurnableSharesIncreased(IStrategy strategy, uint256 shares);

/// @notice Emitted when shares are burned
event BurnableSharesDecreased(IStrategy strategy, uint256 shares);
}

/**
Expand Down Expand Up @@ -109,12 +115,13 @@ interface IStrategyManager is IStrategyManagerErrors, IStrategyManagerEvents, IS
) external returns (uint256 shares);

/**
* @notice Burns Strategy shares for the given strategy by calling into the strategy to transfer to the default burn address.
* @notice Burns Strategy shares for the given strategy by calling into the strategy to transfer
* to the default burn address.
* @param strategy The strategy to burn shares in.
* @param sharesToBurn The amount of shares to burn.
* @dev This function is only called by the DelegationManager when an operator is slashed.
*/
function burnShares(IStrategy strategy, uint256 sharesToBurn) external;
function burnShares(
IStrategy strategy
) external;

/**
* @notice Owner-only function to change the `strategyWhitelister` address.
Expand Down
6 changes: 6 additions & 0 deletions src/contracts/pods/EigenPodManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,12 @@ contract EigenPodManager is
}
}

/// @inheritdoc IShareManager
function increaseBurnableShares(IStrategy, uint256 addedSharesToBurn) external onlyDelegationManager {
burnableETHShares += addedSharesToBurn;
emit BurnableETHSharesIncreased(addedSharesToBurn);
}

// INTERNAL FUNCTIONS

function _deployPod() internal returns (IEigenPod) {
Expand Down
5 changes: 4 additions & 1 deletion src/contracts/pods/EigenPodManagerStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ abstract contract EigenPodManagerStorage is IEigenPodManager {
/// Note: this is specifically updated when the staker's beacon chain balance decreases
mapping(address staker => BeaconChainSlashingFactor) internal _beaconChainSlashingFactor;

/// @notice Returns the amount of `shares` that have been slashed on EigenLayer but not burned yet.
uint256 public burnableETHShares;

constructor(IETHPOSDeposit _ethPOS, IBeacon _eigenPodBeacon, IDelegationManager _delegationManager) {
ethPOS = _ethPOS;
eigenPodBeacon = _eigenPodBeacon;
Expand All @@ -89,5 +92,5 @@ abstract contract EigenPodManagerStorage is IEigenPodManager {
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[43] private __gap;
uint256[42] private __gap;
}
2 changes: 1 addition & 1 deletion src/test/mocks/DelegationManagerMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ contract DelegationManagerMock is Test {
isOperator[operator] = _isOperatorReturnValue;
}

function burnOperatorShares(
function slashOperatorShares(
address operator,
IStrategy strategy,
uint64 prevMaxMagnitude,
Expand Down
Loading

0 comments on commit c44f725

Please sign in to comment.