Skip to content

Commit

Permalink
refactor: add burnableShares for epm storage
Browse files Browse the repository at this point in the history
  • Loading branch information
8sunyuan committed Jan 6, 2025
1 parent d54bc21 commit 557efde
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 18 deletions.
7 changes: 3 additions & 4 deletions src/contracts/core/DelegationManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +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.increaseBurnableShares(strategy, totalDepositSharesToBurn);
}
IShareManager shareManager = _getShareManager(strategy);
// NOTE: for beaconChainETHStrategy, increased burnable shares currently have no mechanism for burning
shareManager.increaseBurnableShares(strategy, totalDepositSharesToBurn);
}

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

/// @inheritdoc IStrategyManager
/// @inheritdoc IShareManager
function increaseBurnableShares(IStrategy strategy, uint256 addedSharesToBurn) external onlyDelegationManager {
burnableShares[strategy] += addedSharesToBurn;
emit BurnableSharesIncreased(strategy, addedSharesToBurn);
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/interfaces/IDelegationManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ interface IDelegationManager is ISignatureUtils, IDelegationManagerErrors, IDele

/**
* @notice Decreases the operators shares in storage after a slash and increases the burnable shares by calling
* into the StrategyManager. Burnable shares for the beaconChainETHStrategy/EigenPodManager are specifically not handled.
* 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 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;
}
10 changes: 0 additions & 10 deletions src/contracts/interfaces/IStrategyManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,6 @@ interface IStrategyManager is IStrategyManagerErrors, IStrategyManagerEvents, IS
bytes memory signature
) external returns (uint256 shares);

/**
* @notice Increases burnable Strategy shares for the given strategy when an operator is slashed.
* @notice Increase the amount of burnable shares for a given Strategy. This is called by the DelegationManager
* when an operator is slashed in EigenLayer. The shares can be burned in a separate transaction calling `burnShares`.
* @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;

/**
* @notice Burns Strategy shares for the given strategy by calling into the strategy to transfer
* to the default burn 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;
}
46 changes: 45 additions & 1 deletion src/test/unit/EigenPodManagerUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -521,4 +521,48 @@ contract EigenPodManagerUnitTests_BeaconChainETHBalanceUpdateTests is EigenPodMa
assertEq(eigenPodManager.podOwnerDepositShares(defaultStaker), int(sharesBefore), "Shares should not be adjusted");
assertTrue(eigenPodManager.beaconChainSlashingFactor(defaultStaker) <= prevSlashingFactor, "bcsf should always decrease");
}
}
}

contract EigenPodManagerUnitTests_increaseBurnableShares is EigenPodManagerUnitTests {
function testFuzz_onlyDelegationManager(address invalidCaller) public filterFuzzedAddressInputs(invalidCaller) {
cheats.assume(invalidCaller != address(delegationManagerMock));
cheats.prank(invalidCaller);
cheats.expectRevert(IEigenPodManagerErrors.OnlyDelegationManager.selector);
eigenPodManager.increaseBurnableShares(beaconChainETHStrategy, 1 ether);
}

function testFuzz_singleDeposit(uint256 increasedBurnableShares) public {
cheats.expectEmit(true, true, true, true, address(eigenPodManager));
emit BurnableETHSharesIncreased(increasedBurnableShares);

cheats.prank(address(delegationManagerMock));
eigenPodManager.increaseBurnableShares(beaconChainETHStrategy, increasedBurnableShares);

assertEq(eigenPodManager.burnableETHShares(), increasedBurnableShares, "Burnable shares not updated correctly");
}

function testFuzz_existingDeposit(
uint256 existingBurnableShares,
uint256 increasedBurnableShares
) public {
// prevent overflow
cheats.assume(existingBurnableShares < type(uint256).max - increasedBurnableShares);

cheats.expectEmit(true, true, true, true, address(eigenPodManager));
emit BurnableETHSharesIncreased(existingBurnableShares);
cheats.prank(address(delegationManagerMock));
eigenPodManager.increaseBurnableShares(beaconChainETHStrategy, existingBurnableShares);

assertEq(eigenPodManager.burnableETHShares(), existingBurnableShares, "Burnable shares not setup correctly");

cheats.expectEmit(true, true, true, true, address(eigenPodManager));
emit BurnableETHSharesIncreased(increasedBurnableShares);
cheats.prank(address(delegationManagerMock));
eigenPodManager.increaseBurnableShares(beaconChainETHStrategy, increasedBurnableShares);

assertEq(
eigenPodManager.burnableETHShares(),
existingBurnableShares + increasedBurnableShares, "Burnable shares not updated correctly"
);
}
}

0 comments on commit 557efde

Please sign in to comment.