From 48d36d90a4200f70285c62540d02ccc1e3808b4b Mon Sep 17 00:00:00 2001 From: gpsanant Date: Fri, 20 Sep 2024 10:33:14 -0700 Subject: [PATCH] reimpl --- src/contracts/core/DelegationManager.sol | 120 ++++++++++++------ .../core/DelegationManagerStorage.sol | 8 +- .../interfaces/IDelegationManager.sol | 16 +-- src/contracts/interfaces/IEigenPod.sol | 2 + src/contracts/interfaces/IEigenPodManager.sol | 10 +- src/contracts/pods/EigenPod.sol | 31 ++++- src/contracts/pods/EigenPodManager.sol | 119 ++++++----------- src/contracts/pods/EigenPodStorage.sol | 2 +- 8 files changed, 174 insertions(+), 134 deletions(-) diff --git a/src/contracts/core/DelegationManager.sol b/src/contracts/core/DelegationManager.sol index f93180dfd6..b05c381fad 100644 --- a/src/contracts/core/DelegationManager.sol +++ b/src/contracts/core/DelegationManager.sol @@ -57,6 +57,11 @@ contract DelegationManager is _; } + modifier onlyEigenPodManager() { + require(msg.sender == address(eigenPodManager), OnlyEigenPodManager()); + _; + } + /** * * INITIALIZING FUNCTIONS @@ -398,37 +403,43 @@ contract DelegationManager is } } - // IGNORE THIS FUNCTION /** - * @notice Decreases a staker's delegated stakeShares for a strategy. - * @param staker The address to increase the delegated scaled shares for their operator. - * @param strategy The strategy in which to decrease the delegated scaled shares. - * @param removedShares The number of shares to decremented for the strategy in the - * StrategyManager/EigenPodManager + * @notice Decreases a native restaker's delegated share balance in a strategy due to beacon chain slashing. This updates their beaconChainScalingFactor. + * Their operator's stakeShares are also updated (if they are delegated). + * @param staker The address to increase the delegated stakeShares for their operator. + * @param existingDepositShares The number of deposit shares the staker already has in the EPM. This does not change upon decreasing shares. + * @param proportionPodBalanceDecrease The proportion of the staker's shares to decrease. This is a fraction of the staker's shares in the strategy. * - * @dev *If the staker is actively delegated*, then decreases the `staker`'s delegated stakeShares in `strategy` by `scaledShares`. Otherwise does nothing. - * @dev Callable only by the StrategyManager or EigenPodManager. + * @dev *If the staker is actively delegated*, then decreases the `staker`'s delegated stakeShares in `strategy` by `proportionPodBalanceDecrease` proportion. Otherwise does nothing. + * @dev Callable only by the EigenPodManager. */ - function decreaseDelegatedShares( - address staker, - IStrategy strategy, - uint256 removedShares - ) external onlyStrategyManagerOrEigenPodManager { - // if the staker is delegated to an operator - // if (isDelegated(staker)) { - // address operator = delegatedTo[staker]; - - // uint64 totalMagnitude = allocationManager.getTotalMagnitude(operator, strategy); - - // // subtract strategy shares from delegated scaled shares - // _decreaseOperatorScaledShares({ - // operator: operator, - // staker: staker, - // strategy: strategy, - // shares: removedShares, - // totalMagnitude: totalMagnitude - // }); - // } + function decreaseBeaconChainScalingFactor( + address staker, + uint256 existingDepositShares, + uint256 proportionPodBalanceDecrease + ) external onlyEigenPodManager { + uint256 stakeSharesBefore = _convertDepositSharesToStakeShares(staker, beaconChainETHStrategy, existingDepositShares); + + // decrease the staker's beaconChainScalingFactor proportionally + beaconChainScalingFactors[staker] = + beaconChainScalingFactors[staker] + * (PRECISION_FACTOR - proportionPodBalanceDecrease) + / PRECISION_FACTOR; + + uint256 stakeSharesAfter = _convertDepositSharesToStakeShares(staker, beaconChainETHStrategy, existingDepositShares); + + // if the staker is delegated to an operators + if (isDelegated(staker)) { + address operator = delegatedTo[staker]; + + // subtract strategy shares from delegated scaled shares + _decreaseOperatorStakeShares({ + operator: operator, + staker: staker, + strategy: beaconChainETHStrategy, + stakeShares: stakeSharesBefore - stakeSharesAfter + }); + } } /** @@ -612,18 +623,15 @@ contract DelegationManager is * @param operator The operator to decrease the delegated delegated shares for * @param staker The staker to decrease the delegated delegated shares for * @param strategy The strategy to decrease the delegated delegated shares for - * @param shares The shares removed from the staker in the StrategyManager/EigenPodManager - * @param totalMagnitude The current total magnitude of the operator for the strategy + * @param stakeShares The stakeShares to be removed from the operator's total delegated */ function _decreaseOperatorStakeShares( address operator, address staker, IStrategy strategy, - uint256 shares, - uint64 totalMagnitude + uint256 stakeShares ) internal { // based on total magnitude, decrement operator's stakeShares - uint256 stakeShares = _convertSharesToStakeShares(shares, totalMagnitude); operatorStakeShares[operator][strategy] -= stakeShares; // TODO: What to do about event wrt scaling? emit OperatorSharesDecreased(operator, staker, strategy, stakeShares); @@ -670,8 +678,7 @@ contract DelegationManager is operator: operator, staker: staker, strategy: strategies[i], - shares: sharesToWithdraw[i], - totalMagnitude: totalMagnitudes[i] + stakeShares: stakeSharesToWithdraw[i] }); } @@ -748,9 +755,11 @@ contract DelegationManager is * 3. depositShares * - These can be converted into stakeShares given a staker and a strategy * - by multiplying by the staker's depositScalingFactor for the strategy + * - additionally, if the strategy is beaconChainETHStrategy, then multiplying by the staker's beaconChainScalingFactor * - These values automatically update their conversion into tokens * - when the staker's depositScalingFactor for the strategy is increased upon new deposits * - or when the staker's operator's total magnitude for the strategy is decreased upon slashing + * - or when the staker's beaconChainScalingFactor is decreased upon beacon chain slashing * - These represent the total amount of shares the staker would have of a strategy if they were never slashed * - These live in the storage of the StrategyManager/EigenPodManager * - `stakerStrategyShares` in the SM is the staker's depositShares that have not been queued for withdrawal in a strategy @@ -766,11 +775,35 @@ contract DelegationManager is } function _convertSharesToDepositShares(address staker, IStrategy strategy, uint256 shares, uint64 totalMagnitude) internal view returns (uint256) { - return shares * PRECISION_FACTOR / _getDepositScalingFactor(staker, strategy) * PRECISION_FACTOR / totalMagnitude; + // scale by depositScalingFactor first + uint256 depositShares = shares * PRECISION_FACTOR / _getDepositScalingFactor(staker, strategy); + // scale by beaconChainScalingFactor if beaconChainETHStrategy + if(strategy == beaconChainETHStrategy) { + depositShares = depositShares * _getBeaconChainScalingFactor(staker) / PRECISION_FACTOR; + } + // finally scale by totalMagnitude + return depositShares * PRECISION_FACTOR / totalMagnitude; } function _convertDepositSharesToShares(address staker, IStrategy strategy, uint256 depositShares, uint64 totalMagnitude) internal view returns (uint256) { - return depositShares * _getDepositScalingFactor(staker, strategy) / PRECISION_FACTOR * totalMagnitude / PRECISION_FACTOR; + // scale by depositScalingFactor first + uint256 shares = depositShares * _getDepositScalingFactor(staker, strategy) / PRECISION_FACTOR; + // scale by beaconChainScalingFactor if beaconChainETHStrategy + if(strategy == beaconChainETHStrategy) { + shares = shares * PRECISION_FACTOR / _getBeaconChainScalingFactor(staker); + } + // finally scale by totalMagnitude + return shares * totalMagnitude / PRECISION_FACTOR; + } + + function _convertDepositSharesToStakeShares(address staker, IStrategy strategy, uint256 depositShares) internal view returns (uint256) { + // scale by depositScalingFactor first + uint256 stakeShares = depositShares * PRECISION_FACTOR / _getDepositScalingFactor(staker, strategy); + // scale by beaconChainScalingFactor if beaconChainETHStrategy + if(strategy == beaconChainETHStrategy) { + stakeShares = stakeShares * _getBeaconChainScalingFactor(staker) / PRECISION_FACTOR; + } + return stakeShares; } /** @@ -823,9 +856,7 @@ contract DelegationManager is depositScalingFactors[staker][strategy] = newDepositScalingFactor; } - /** - * @notice depositScalingFactor should be initialized and lower bounded to 1e18 - */ + /// @notice returns the depositScalingFactor for a staker or PRECISION_FACTOR if it is not set function _getDepositScalingFactor(address staker, IStrategy strategy) internal view returns (uint256) { uint256 currDepositScalingFactor = depositScalingFactors[staker][strategy]; if (currDepositScalingFactor == 0) { @@ -834,6 +865,15 @@ contract DelegationManager is return currDepositScalingFactor; } + /// @notice returns the beaconChainScalingFactor factor for a staker or PRECISION_FACTOR if it is not set + function _getBeaconChainScalingFactor(address staker) internal view returns (uint256) { + uint256 currBeaconChainScalingFactor = beaconChainScalingFactors[staker]; + if (currBeaconChainScalingFactor == 0) { + currBeaconChainScalingFactor = PRECISION_FACTOR; + } + return currBeaconChainScalingFactor; + } + function _getShareManager(IStrategy strategy) internal view returns (IShareManager) { return strategy == beaconChainETHStrategy ? IShareManager(address(eigenPodManager)) : IShareManager(address(strategyManager)); } diff --git a/src/contracts/core/DelegationManagerStorage.sol b/src/contracts/core/DelegationManagerStorage.sol index e2564c806b..240a6c61f3 100644 --- a/src/contracts/core/DelegationManagerStorage.sol +++ b/src/contracts/core/DelegationManagerStorage.sol @@ -114,10 +114,14 @@ abstract contract DelegationManagerStorage is IDelegationManager { */ mapping(IStrategy => uint256) private __deprecated_strategyWithdrawalDelayBlocks; - /// @notice Mapping: staker => strategy => scaling factor used to calculate the staker's shares in the strategy. - /// This is updated upon each deposit based on the staker's currently delegated operator's totalMagnitude. + /// @notice Mapping: staker => strategy => scaling factor used to calculate the staker's shares in the strategy + /// This is updated upon each deposit of a delegated staker. mapping(address => mapping(IStrategy => uint256)) public depositScalingFactors; + /// @notice Mapping: staker => their beacon chain scaling factor used to calculate the staker's withdrawable shares in the strategy. + /// This is updated upon each ending checkpoints that include beacon chain slashing. + mapping(address => uint256) public beaconChainScalingFactors; + constructor( IStrategyManager _strategyManager, ISlasher _slasher, diff --git a/src/contracts/interfaces/IDelegationManager.sol b/src/contracts/interfaces/IDelegationManager.sol index da47c10c6d..5bbc11d6e8 100644 --- a/src/contracts/interfaces/IDelegationManager.sol +++ b/src/contracts/interfaces/IDelegationManager.sol @@ -31,6 +31,8 @@ interface IDelegationManager is ISignatureUtils { error OperatorNotRegistered(); /// @dev Thrown when caller is neither the StrategyManager or EigenPodManager contract. error OnlyStrategyManagerOrEigenPodManager(); + /// @dev Thrown when caller is not the EigenPodManager contract. + error OnlyEigenPodManager(); /// @dev Thrown when an operator attempts to undelegate. error OperatorsCannotUndelegate(); /// @dev Thrown when an account is not actively delegated. @@ -337,18 +339,16 @@ interface IDelegationManager is ISignatureUtils { ) external; /** - * @notice Decreases a staker's delegated share balance in a strategy. Note that before removing from operator shares, - * the delegated shares are scaled according to the operator's total magnitude as part of slashing accounting. Unlike - * `increaseDelegatedShares`, the staker's depositScalingFactor is not updated here. + * @notice Decreases a native restaker's delegated share balance in a strategy due to beacon chain slashing. This updates their beaconChainScalingFactor. + * Their operator's scaled shares are also updated (if they are delegated). * @param staker The address to increase the delegated scaled shares for their operator. - * @param strategy The strategy in which to decrease the delegated scaled shares. - * @param removedShares The number of shares to decremented for the strategy in the - * StrategyManager/EigenPodManager + * @param shares The number of shares of beaconChainETHStrategy the staker has, not including scaling factors or + * @param proportionPodBalanceDecrease The proportion of the staker's shares to decrease. This is a fraction of the staker's shares in the strategy. * * @dev *If the staker is actively delegated*, then decreases the `staker`'s delegated scaled shares in `strategy` by `scaledShares`. Otherwise does nothing. - * @dev Callable only by the StrategyManager or EigenPodManager. + * @dev Callable only by the EigenPodManager. */ - function decreaseDelegatedShares(address staker, IStrategy strategy, uint256 removedShares) external; + function decreaseBeaconChainScalingFactor(address staker, uint256 shares, uint256 proportionPodBalanceDecrease) external; /** * @notice returns the address of the operator that `staker` is delegated to. diff --git a/src/contracts/interfaces/IEigenPod.sol b/src/contracts/interfaces/IEigenPod.sol index 0edb74f9c1..47f5553bfa 100644 --- a/src/contracts/interfaces/IEigenPod.sol +++ b/src/contracts/interfaces/IEigenPod.sol @@ -90,6 +90,8 @@ interface IEigenPod { uint24 proofsRemaining; uint64 podBalanceGwei; int128 balanceDeltasGwei; + uint128 beaconChainBalanceBefore; + uint128 beaconChainBalanceAfter; } /** diff --git a/src/contracts/interfaces/IEigenPodManager.sol b/src/contracts/interfaces/IEigenPodManager.sol index 169618fef3..4002eb51d7 100644 --- a/src/contracts/interfaces/IEigenPodManager.sol +++ b/src/contracts/interfaces/IEigenPodManager.sol @@ -28,6 +28,9 @@ interface IEigenPodManager is IShareManager, IPausable { error SharesNegative(); /// @dev Thrown when the strategy is not the beaconChainETH strategy. error InvalidStrategy(); + /// @dev Thrown when the pods shares are negative and a beacon chain balance update is attempted. + /// The podOwner should complete legacy withdrawal first. + error LegacyWithdrawalsNotCompleted(); /// @notice Emitted to notify the deployment of an EigenPod event PodDeployed(address indexed eigenPod, address indexed podOwner); @@ -72,10 +75,15 @@ interface IEigenPodManager is IShareManager, IPausable { * to ensure that delegated shares are also tracked correctly * @param podOwner is the pod owner whose balance is being updated. * @param sharesDelta is the change in podOwner's beaconChainETHStrategy shares + * @param proportionPodBalanceDecrease is the proportion (of PRECISION_FACTOR) of the podOwner's balance that has changed * @dev Callable only by the podOwner's EigenPod contract. * @dev Reverts if `sharesDelta` is not a whole Gwei amount */ - function recordBeaconChainETHBalanceUpdate(address podOwner, int256 sharesDelta) external; + function recordBeaconChainETHBalanceUpdate( + address podOwner, + int256 sharesDelta, + uint256 proportionPodBalanceDecrease + ) external; /// @notice Returns the address of the `podOwner`'s EigenPod if it has been deployed. function ownerToPod( diff --git a/src/contracts/pods/EigenPod.sol b/src/contracts/pods/EigenPod.sol index a1040ca66c..21f64a210e 100644 --- a/src/contracts/pods/EigenPod.sol +++ b/src/contracts/pods/EigenPod.sol @@ -261,7 +261,7 @@ contract EigenPod is Initializable, ReentrancyGuardUpgradeable, EigenPodPausingC } // Update the EigenPodManager on this pod's new balance - eigenPodManager.recordBeaconChainETHBalanceUpdate(podOwner, int256(totalAmountToBeRestakedWei)); + eigenPodManager.recordBeaconChainETHBalanceUpdate(podOwner, int256(totalAmountToBeRestakedWei), 0); // no decrease } /** @@ -492,8 +492,12 @@ contract EigenPod is Initializable, ReentrancyGuardUpgradeable, EigenPodPausingC // purpose of `lastCheckpointedAt` is to enforce that newly-verified validators are not // eligible to progress already-existing checkpoints - however in this case, no checkpoints exist. activeValidatorCount++; - uint64 lastCheckpointedAt = - currentCheckpointTimestamp == 0 ? lastCheckpointTimestamp : currentCheckpointTimestamp; + uint64 lastCheckpointedAt = lastCheckpointTimestamp; + if (currentCheckpointTimestamp != 0) { + lastCheckpointedAt = currentCheckpointTimestamp; + _currentCheckpoint.beaconChainBalanceBefore += uint128(restakedBalanceGwei); + _currentCheckpoint.beaconChainBalanceAfter += uint128(restakedBalanceGwei); + } // Proofs complete - create the validator in state _validatorPubkeyHashToInfo[pubkeyHash] = ValidatorInfo({ @@ -532,6 +536,10 @@ contract EigenPod is Initializable, ReentrancyGuardUpgradeable, EigenPodPausingC previousAmountGwei: prevBalanceGwei }); + // Update the checkpoint values + _currentCheckpoint.beaconChainBalanceBefore += uint128(prevBalanceGwei); + _currentCheckpoint.beaconChainBalanceAfter += uint128(newBalanceGwei); + emit ValidatorBalanceUpdated(validatorIndex, checkpointTimestamp, newBalanceGwei); } @@ -600,7 +608,9 @@ contract EigenPod is Initializable, ReentrancyGuardUpgradeable, EigenPodPausingC beaconBlockRoot: getParentBlockRoot(uint64(block.timestamp)), proofsRemaining: uint24(activeValidatorCount), podBalanceGwei: podBalanceGwei, - balanceDeltasGwei: 0 + balanceDeltasGwei: 0, + beaconChainBalanceBefore: 0, + beaconChainBalanceAfter: 0 }); // Place checkpoint in storage. If `proofsRemaining` is 0, the checkpoint @@ -635,8 +645,19 @@ contract EigenPod is Initializable, ReentrancyGuardUpgradeable, EigenPodPausingC delete currentCheckpointTimestamp; delete _currentCheckpoint; + // Calculate the slashing proportion + uint256 proportionPodBalanceDecrease = 0; + if (checkpoint.balanceDeltasGwei < 0) { + uint256 totalBefore = withdrawableRestakedExecutionLayerGwei + checkpoint.beaconChainBalanceBefore; + proportionPodBalanceDecrease = uint256(uint128(-checkpoint.balanceDeltasGwei)) * 1e18 / totalBefore; + } + // Update pod owner's shares - eigenPodManager.recordBeaconChainETHBalanceUpdate(podOwner, totalShareDeltaWei); + eigenPodManager.recordBeaconChainETHBalanceUpdate( + podOwner, + totalShareDeltaWei, + proportionPodBalanceDecrease + ); emit CheckpointFinalized(lastCheckpointTimestamp, totalShareDeltaWei); } else { _currentCheckpoint = checkpoint; diff --git a/src/contracts/pods/EigenPodManager.sol b/src/contracts/pods/EigenPodManager.sol index 3828731615..b89dfd0da3 100644 --- a/src/contracts/pods/EigenPodManager.sol +++ b/src/contracts/pods/EigenPodManager.sol @@ -97,46 +97,31 @@ contract EigenPodManager is * to ensure that delegated shares are also tracked correctly * @param podOwner is the pod owner whose balance is being updated. * @param sharesDelta is the change in podOwner's beaconChainETHStrategy shares + * @param proportionPodBalanceDecrease is the proportion (of PRECISION_FACTOR) of the podOwner's balance that has changed * @dev Callable only by the podOwner's EigenPod contract. * @dev Reverts if `sharesDelta` is not a whole Gwei amount */ function recordBeaconChainETHBalanceUpdate( address podOwner, - int256 sharesDelta + int256 sharesDelta, + uint256 proportionPodBalanceDecrease ) external onlyEigenPod(podOwner) nonReentrant { require(podOwner != address(0), InputAddressZero()); require(sharesDelta % int256(GWEI_TO_WEI) == 0, SharesNotMultipleOfGwei()); - int256 currentPodOwnerShares = podOwnerShares[podOwner]; - int256 updatedPodOwnerShares = currentPodOwnerShares + sharesDelta; - podOwnerShares[podOwner] = updatedPodOwnerShares; - - // inform the DelegationManager of the change in delegateable shares - int256 changeInDelegatableShares = _calculateChangeInDelegatableShares({ - sharesBefore: currentPodOwnerShares, - sharesAfter: updatedPodOwnerShares - }); - // skip making a call to the DelegationManager if there is no change in delegateable shares - // or if the currentPodShares < 0 and updatedPodShares is still < 0. Means no update required - // in delegated shares - if (changeInDelegatableShares != 0) { - if (changeInDelegatableShares < 0) { - delegationManager.decreaseDelegatedShares({ - staker: podOwner, - strategy: beaconChainETHStrategy, - removedShares: uint256(-changeInDelegatableShares) - }); - } else { - delegationManager.increaseDelegatedShares({ - staker: podOwner, - strategy: beaconChainETHStrategy, - // existing shares from standpoint of the DelegationManager - existingDepositShares: currentPodOwnerShares < 0 ? 0 : uint256(currentPodOwnerShares), - addedShares: uint256(changeInDelegatableShares) - }); - } + // shares can only be negative if they were due to negative shareDeltas after queued withdrawals in before + // the slashing upgrade. Make people complete queued withdrawals before completing any further checkpoints. + // the only effects podOwner UX, not AVS UX, since the podOwner already has 0 shares in the DM if they + // have a negative shares in EPM. + require(podOwnerShares[podOwner] >= 0, LegacyWithdrawalsNotCompleted()); + if (sharesDelta > 0) { + _addShares(podOwner, uint256(sharesDelta)); + } else if (sharesDelta < 0 && podOwnerShares[podOwner] > 0) { + delegationManager.decreaseBeaconChainScalingFactor( + podOwner, + uint256(podOwnerShares[podOwner]), + proportionPodBalanceDecrease + ); } - emit PodSharesUpdated(podOwner, sharesDelta); - emit NewTotalShares(podOwner, updatedPodOwnerShares); } /** @@ -169,29 +154,12 @@ contract EigenPodManager is */ function addShares( address staker, - IERC20 token, - IStrategy strategy, + IERC20, + IStrategy strategy, uint256 shares - ) external onlyDelegationManager { + ) external onlyDelegationManager { require(strategy == beaconChainETHStrategy, InvalidStrategy()); - require(staker != address(0), InputAddressZero()); - require(int256(shares) >= 0, SharesNegative()); - require(shares % GWEI_TO_WEI == 0, SharesNotMultipleOfGwei()); - int256 currentShares = podOwnerShares[staker]; - int256 updatedShares = currentShares + int256(shares); - podOwnerShares[staker] = updatedShares; - - emit PodSharesUpdated(staker, int256(shares)); - emit NewTotalShares(staker, updatedShares); - - uint256 increaseInDelegateableShares = uint256( - _calculateChangeInDelegatableShares({ - sharesBefore: currentShares, - sharesAfter: updatedShares - }) - ); - - // TODO: ADD SHARES BACK TO DM + _addShares(staker, shares); } /** @@ -264,31 +232,28 @@ contract EigenPodManager is return pod; } - /** - * @notice Calculates the change in a pod owner's delegateable shares as a result of their beacon chain ETH shares changing - * from `sharesBefore` to `sharesAfter`. The key concept here is that negative/"deficit" shares are not delegateable. - */ - function _calculateChangeInDelegatableShares( - int256 sharesBefore, - int256 sharesAfter - ) internal pure returns (int256) { - if (sharesBefore <= 0) { - if (sharesAfter <= 0) { - // if the shares started negative and stayed negative, then there cannot have been an increase in delegateable shares - return 0; - } else { - // if the shares started negative and became positive, then the increase in delegateable shares is the ending share amount - return sharesAfter; - } - } else { - if (sharesAfter <= 0) { - // if the shares started positive and became negative, then the decrease in delegateable shares is the starting share amount - return (-sharesBefore); - } else { - // if the shares started positive and stayed positive, then the change in delegateable shares - // is the difference between starting and ending amounts - return (sharesAfter - sharesBefore); - } + function _addShares( + address staker, + uint256 shares + ) internal { + require(staker != address(0), InputAddressZero()); + require(int256(shares) >= 0, SharesNegative()); + + int256 currentShares = podOwnerShares[staker]; + int256 updatedShares = currentShares + int256(shares); + podOwnerShares[staker] = updatedShares; + + emit PodSharesUpdated(staker, int256(shares)); + emit NewTotalShares(staker, updatedShares); + + if (updatedShares > 0) { + delegationManager.increaseDelegatedShares({ + staker: staker, + strategy: beaconChainETHStrategy, + // existing shares from standpoint of the DelegationManager + existingDepositShares: currentShares < 0 ? 0 : uint256(currentShares), + addedShares: uint256(shares) + }); } } diff --git a/src/contracts/pods/EigenPodStorage.sol b/src/contracts/pods/EigenPodStorage.sol index 096bf539c6..39fb12eff9 100644 --- a/src/contracts/pods/EigenPodStorage.sol +++ b/src/contracts/pods/EigenPodStorage.sol @@ -81,5 +81,5 @@ abstract contract EigenPodStorage is IEigenPod { * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ - uint256[36] private __gap; + uint256[35] private __gap; // Reduced the gap size by 1 to accommodate the new variable }