@@ -11090,3 +11090,133 @@ contract DelegationManagerUnitTests_Lifecycle is DelegationManagerUnitTests {
11090
11090
assertEq(delegationManager.operatorShares(newOperator, strategy), 0, "new operator shares should be unchanged");
11091
11091
}
11092
11092
}
11093
+
11094
+ contract DelegationManagerUnitTests_ConvertToDepositShares is DelegationManagerUnitTests {
11095
+ using ArrayLib for *;
11096
+
11097
+ function test_convertToDepositShares_noSlashing() public {
11098
+ IStrategy[] memory strategies = new IStrategy[](1);
11099
+ strategies[0] = strategyMock;
11100
+ uint256[] memory shares = uint256(100 ether).toArrayU256();
11101
+
11102
+ // Set the staker deposits in the strategies
11103
+ strategyManagerMock.addDeposit(defaultStaker, strategies[0], shares[0]);
11104
+
11105
+ _checkDepositSharesConvertCorrectly(strategies, shares);
11106
+ }
11107
+
11108
+ function test_convertToDepositShares_withSlashing() public {
11109
+ IStrategy[] memory strategies = new IStrategy[](1);
11110
+ strategies[0] = strategyMock;
11111
+ uint256[] memory shares = uint256(100 ether).toArrayU256();
11112
+
11113
+ // Set the staker deposits in the strategies
11114
+ strategyManagerMock.addDeposit(defaultStaker, strategies[0], shares[0]);
11115
+
11116
+ // register *this contract* as an operator
11117
+ _registerOperatorWithBaseDetails(defaultOperator);
11118
+ _delegateToOperatorWhoAcceptsAllStakers(defaultStaker, defaultOperator);
11119
+ _setOperatorMagnitude(defaultOperator, strategyMock, WAD/3);
11120
+
11121
+ _checkDepositSharesConvertCorrectly(strategies, shares);
11122
+
11123
+ // queue and complete a withdrawal for half the deposit shares
11124
+ (uint256[] memory withdrawableShares,) = delegationManager.getWithdrawableShares(defaultStaker, strategies);
11125
+ _queueAndCompleteWithdrawalForSingleStrategy(strategies[0], shares[0] / 2);
11126
+
11127
+ // queued a withdrawal for half the deposit shares, and added back as withdrawable shares
11128
+ shares[0] = shares[0] / 2 + withdrawableShares[0] / 2;
11129
+ _checkDepositSharesConvertCorrectly(strategies, shares);
11130
+ }
11131
+
11132
+ function test_convertToDepositShares_beaconChainETH() public {
11133
+ IStrategy[] memory strategies = new IStrategy[](1);
11134
+ strategies[0] = beaconChainETHStrategy;
11135
+ uint256[] memory shares = uint256(100 ether).toArrayU256();
11136
+
11137
+ // Set the staker deposits in the strategies
11138
+ eigenPodManagerMock.setPodOwnerShares(defaultStaker, int256(shares[0]));
11139
+
11140
+ uint256[] memory depositShares = delegationManager.convertToDepositShares(defaultStaker, strategies, shares);
11141
+ assertEq(depositShares[0], shares[0], "deposit shares not converted correctly");
11142
+
11143
+ // delegate to an operator and slash
11144
+ _registerOperatorWithBaseDetails(defaultOperator);
11145
+ _delegateToOperatorWhoAcceptsAllStakers(defaultStaker, defaultOperator);
11146
+ _setOperatorMagnitude(defaultOperator, beaconChainETHStrategy, WAD/3);
11147
+
11148
+ _checkDepositSharesConvertCorrectly(strategies, shares);
11149
+
11150
+ // slash on beacon chain by 1/3
11151
+ _decreaseBeaconChainShares(defaultStaker, int256(shares[0]), shares[0]/3);
11152
+
11153
+ _checkDepositSharesConvertCorrectly(strategies, shares);
11154
+
11155
+ // queue and complete a withdrawal for half the deposit shares
11156
+ (uint256[] memory withdrawableShares,) = delegationManager.getWithdrawableShares(defaultStaker, strategies);
11157
+ _queueAndCompleteWithdrawalForSingleStrategy(strategies[0], shares[0] / 2);
11158
+
11159
+ // queued a withdrawal for half the deposit shares, and added back as withdrawable shares
11160
+ shares[0] = shares[0] / 2 + withdrawableShares[0] / 2;
11161
+ _checkDepositSharesConvertCorrectly(strategies, shares);
11162
+ }
11163
+
11164
+ function _checkDepositSharesConvertCorrectly(IStrategy[] memory strategies, uint256[] memory expectedDepositShares) public {
11165
+ (uint256[] memory withdrawableShares,) = delegationManager.getWithdrawableShares(defaultStaker, strategies);
11166
+ // get the deposit shares
11167
+ uint256[] memory depositShares = delegationManager.convertToDepositShares(defaultStaker, strategies, withdrawableShares);
11168
+
11169
+ for (uint256 i = 0; i < strategies.length; i++) {
11170
+ assertApproxEqRel(
11171
+ expectedDepositShares[i],
11172
+ depositShares[i],
11173
+ APPROX_REL_DIFF,
11174
+ "deposit shares not converted correctly"
11175
+ );
11176
+
11177
+ // make sure that the deposit shares are less than or equal to the shares,
11178
+ // so this value is sane to input into `completeQueuedWithdrawals`
11179
+ assertLe(
11180
+ depositShares[i],
11181
+ expectedDepositShares[i],
11182
+ "deposit shares should be less than or equal to expected deposit shares"
11183
+ );
11184
+ }
11185
+
11186
+ // get the deposit shares
11187
+ uint256[] memory oneThirdWithdrawableShares = new uint256[](strategies.length);
11188
+ for (uint256 i = 0; i < strategies.length; i++) {
11189
+ oneThirdWithdrawableShares[i] = withdrawableShares[i]/3;
11190
+ }
11191
+ uint256[] memory oneThirdDepositShares = delegationManager.convertToDepositShares(defaultStaker, strategies, oneThirdWithdrawableShares);
11192
+ for (uint256 i = 0; i < strategies.length; i++) {
11193
+ assertApproxEqRel(
11194
+ expectedDepositShares[i]/3,
11195
+ oneThirdDepositShares[i],
11196
+ APPROX_REL_DIFF,
11197
+ "deposit shares not converted correctly"
11198
+ );
11199
+ }
11200
+ }
11201
+
11202
+ function _queueAndCompleteWithdrawalForSingleStrategy(IStrategy strategy, uint256 shares) public {
11203
+ IStrategy[] memory strategies = new IStrategy[](1);
11204
+ strategies[0] = strategy;
11205
+ uint256[] memory depositShares = uint256(shares).toArrayU256();
11206
+
11207
+ (QueuedWithdrawalParams[] memory queuedWithdrawalParams, Withdrawal memory withdrawal, bytes32 withdrawalRoot) = _setUpQueueWithdrawalsSingleStrat({
11208
+ staker: defaultStaker,
11209
+ withdrawer: defaultStaker,
11210
+ strategy: strategy,
11211
+ depositSharesToWithdraw: shares
11212
+ });
11213
+
11214
+ cheats.prank(defaultStaker);
11215
+ delegationManager.queueWithdrawals(queuedWithdrawalParams);
11216
+
11217
+ cheats.roll(block.number + delegationManager.minWithdrawalDelayBlocks());
11218
+ cheats.prank(defaultStaker);
11219
+ delegationManager.completeQueuedWithdrawal(withdrawal, tokenMock.toArray(), false);
11220
+ }
11221
+ }
11222
+
0 commit comments