From bcacb3215f3da5aec270a7559557cb54876e3ded Mon Sep 17 00:00:00 2001 From: Yash Patil Date: Thu, 26 Sep 2024 13:01:00 -0700 Subject: [PATCH 1/2] feat: types everywhere feat: types everywhere --- lib/openzeppelin-contracts | 1 + lib/openzeppelin-contracts-upgradeable | 1 + src/contracts/core/DelegationManager.sol | 68 ++++++--------- src/contracts/core/StrategyManager.sol | 48 ++++++----- src/contracts/libraries/SlashingLib.sol | 103 +++++++++++++++++++---- 5 files changed, 139 insertions(+), 82 deletions(-) create mode 160000 lib/openzeppelin-contracts create mode 160000 lib/openzeppelin-contracts-upgradeable diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts new file mode 160000 index 000000000..3b8b4ba82 --- /dev/null +++ b/lib/openzeppelin-contracts @@ -0,0 +1 @@ +Subproject commit 3b8b4ba82c880c31cd3b96dd5e15741d7e26658e diff --git a/lib/openzeppelin-contracts-upgradeable b/lib/openzeppelin-contracts-upgradeable new file mode 160000 index 000000000..6b9807b06 --- /dev/null +++ b/lib/openzeppelin-contracts-upgradeable @@ -0,0 +1 @@ +Subproject commit 6b9807b0639e1dd75e07fa062e9432eb3f35dd8c diff --git a/src/contracts/core/DelegationManager.sol b/src/contracts/core/DelegationManager.sol index 2265b1e4f..b719d0bf3 100644 --- a/src/contracts/core/DelegationManager.sol +++ b/src/contracts/core/DelegationManager.sol @@ -371,7 +371,7 @@ contract DelegationManager is * @param strategy The strategy in which to increase the delegated shares. * @param existingShares The number of deposit shares the staker already has in the strategy. This is the shares amount stored in the * StrategyManager/EigenPodManager for the staker's shares. - * @param addedOwnedShares The number of shares to added to the staker's shares in the strategy + * @param addedShares The shares added to the staker's shares in the strategy * * @dev *If the staker is actively delegated*, then increases the `staker`'s delegated delegatedShares in `strategy`. * Otherwise does nothing. @@ -381,7 +381,7 @@ contract DelegationManager is address staker, IStrategy strategy, Shares existingShares, - OwnedShares addedOwnedShares + Shares addedShares ) external onlyStrategyManagerOrEigenPodManager { // if the staker is delegated to an operator if (isDelegated(staker)) { @@ -394,7 +394,7 @@ contract DelegationManager is staker: staker, strategy: strategy, existingShares: existingShares, - addedOwnedShares: addedOwnedShares, + addedShares: addedShares, totalMagnitude: totalMagnitude }); } @@ -516,7 +516,7 @@ contract DelegationManager is operator: operator, staker: staker, strategy: strategies[i], - existingShares: uint256(0).wrapShares(), + existingShares: Shares(0), addedOwnedShares: ownedShares[i], totalMagnitude: totalMagnitudes[i] }); @@ -589,7 +589,7 @@ contract DelegationManager is * @param staker The staker to increase the depositScalingFactor for * @param strategy The strategy to increase the delegated delegatedShares and the depositScalingFactor for * @param existingShares The number of deposit shares the staker already has in the strategy. - * @param addedOwnedShares The shares added to the staker in the StrategyManager/EigenPodManager + * @param addedShares The shares added to the staker in the StrategyManager/EigenPodManager * @param totalMagnitude The current total magnitude of the operator for the strategy */ function _increaseDelegation( @@ -597,19 +597,20 @@ contract DelegationManager is address staker, IStrategy strategy, Shares existingShares, - OwnedShares addedOwnedShares, + Shares addedShares, uint64 totalMagnitude ) internal { _updateDepositScalingFactor({ staker: staker, strategy: strategy, existingShares: existingShares, - addedOwnedShares: addedOwnedShares, + addedShares: addedShares, totalMagnitude: totalMagnitude }); // based on total magnitude, update operators delegatedShares - DelegatedShares delegatedShares = addedOwnedShares.toDelegatedShares(totalMagnitude); + DelegatedShares delegatedShares = addedShares.toDelegatedShares(totalMagnitude); + // forgefmt: disable-next-line operatorDelegatedShares[operator][strategy] = operatorDelegatedShares[operator][strategy].add(delegatedShares); @@ -666,7 +667,7 @@ contract DelegationManager is // check sharesToWithdraw is valid // but for inputted strategies Shares sharesWithdrawable = shareManager.stakerStrategyShares(staker, strategies[i]); - require(sharesToWithdraw.unwrap() <= sharesWithdrawable.unwrap(), WithdrawalExeedsMax()); + require(sharesToWithdraw.lte(sharesWithdrawable), WithdrawalExeedsMax()); // Similar to `isDelegated` logic if (operator != address(0)) { @@ -742,37 +743,17 @@ contract DelegationManager is IStrategy strategy, uint64 totalMagnitude, Shares existingShares, - OwnedShares addedOwnedShares - ) internal { + Shares addedShares + ) internal returns (uint256 newDepositScalingFactor) { uint256 newDepositScalingFactor; - if (existingShares.unwrap() == 0) { + if (existingShares.isZero()) { newDepositScalingFactor = WAD / totalMagnitude; } else { - // otherwise since - // - // newShares - // = existingShares + addedShares - // = existingPrincipalShares.toDelegatedShares(stakerScalingFactors[staker][strategy).toOwnedShares(totalMagnitude) + addedShares - // - // and it also is - // - // newShares - // = newPrincipalShares.toDelegatedShares(stakerScalingFactors[staker][strategy).toOwnedShares(totalMagnitude) - // = newPrincipalShares * newDepositScalingFactor / WAD * totalMagnitude / WAD - // = (existingPrincipalShares + addedShares) * newDepositScalingFactor / WAD * totalMagnitude / WAD - // - // we can solve for - // - OwnedShares existingOwnedShares = - existingShares - .toDelegatedShares(depositScalingFactors[staker][strategy]) - .toOwnedShares(totalMagnitude); - newDepositScalingFactor = - existingOwnedShares - .add(addedOwnedShares) - .unwrap() - .divWad(existingShares.unwrap() + addedOwnedShares.unwrap()) - .divWad(totalMagnitude); + newDepositScalingFactor = existingShares.calculateNewScalingFactor( + addedShares: addedShares, + oldStakerScalingFactor: depositScalingFactors[staker][strategy], + totalMagnitude: totalMagnitude + ); } // update the staker's depositScalingFactor @@ -854,9 +835,9 @@ contract DelegationManager is } /// @notice a legacy function that returns the total delegated shares for an operator and strategy - function operatorShares(address operator, IStrategy strategy) public view returns (uint256) { + function operatorShares(address operator, IStrategy strategy) public view returns (DelegatedShares) { uint64 totalMagnitude = allocationManager.getTotalMagnitude(operator, strategy); - return operatorDelegatedShares[operator][strategy].toOwnedShares(totalMagnitude).unwrap(); + return operatorDelegatedShares[operator][strategy].toOwnedShares(totalMagnitude); } /** @@ -884,9 +865,10 @@ contract DelegationManager is uint64 totalMagnitude = allocationManager.getTotalMagnitude(operator, strategies[i]); // forgefmt: disable-next-item - ownedShares[i] = shares - .toDelegatedShares(depositScalingFactors[staker][strategies[i]]) - .toOwnedShares(totalMagnitude); + ownedShares[i] = shares.toOwnedShares( + stakerScalingFactor: depositScalingFactors[staker][strategies[i]], + operatorMagnitude: totalMagnitude + ); } } return ownedShares; @@ -911,7 +893,7 @@ contract DelegationManager is OwnedShares[] memory shares = getDelegatableShares(staker, strategies); // if the last shares are 0, remove them - if (shares[strategies.length - 1].unwrap() == 0) { + if (shares[strategies.length - 1].isZero()) { // resize the arrays assembly { mstore(strategies, sub(mload(strategies), 1)) diff --git a/src/contracts/core/StrategyManager.sol b/src/contracts/core/StrategyManager.sol index 6dab5ac34..bd3dd7ed4 100644 --- a/src/contracts/core/StrategyManager.sol +++ b/src/contracts/core/StrategyManager.sol @@ -104,7 +104,7 @@ contract StrategyManager is IStrategy strategy, IERC20 token, uint256 amount - ) external onlyWhenNotPaused(PAUSED_DEPOSITS) nonReentrant returns (OwnedShares shares) { + ) external onlyWhenNotPaused(PAUSED_DEPOSITS) nonReentrant returns (Shares shares) { shares = _depositIntoStrategy(msg.sender, strategy, token, amount); } @@ -135,7 +135,7 @@ contract StrategyManager is address staker, uint256 expiry, bytes memory signature - ) external onlyWhenNotPaused(PAUSED_DEPOSITS) nonReentrant returns (OwnedShares shares) { + ) external onlyWhenNotPaused(PAUSED_DEPOSITS) nonReentrant returns (Shares shares) { require(expiry >= block.timestamp, SignatureExpired()); // calculate struct hash, then increment `staker`'s nonce uint256 nonce = nonces[staker]; @@ -183,6 +183,7 @@ contract StrategyManager is IERC20 token, OwnedShares ownedShares ) external onlyDelegationManager { + // TODO: add Shares type to StrategyBase strategy.withdraw(staker, token, ownedShares.unwrap()); } @@ -237,36 +238,36 @@ contract StrategyManager is * @param staker The address to add shares to * @param token The token that is being deposited (used for indexing) * @param strategy The Strategy in which the `staker` is receiving shares - * @param ownedShares The amount of ownedShares to grant to the `staker` + * @param shares The amount of shares to grant to the `staker` * @dev In particular, this function calls `delegation.increaseDelegatedShares(staker, strategy, shares)` to ensure that all * delegated shares are tracked, increases the stored share amount in `stakerStrategyShares[staker][strategy]`, and adds `strategy` * to the `staker`'s list of strategies, if it is not in the list already. */ - function _addOwnedShares(address staker, IERC20 token, IStrategy strategy, OwnedShares ownedShares) internal { + function _addShares(address staker, IERC20 token, IStrategy strategy, Shares sharesToAdd) internal { // sanity checks on inputs require(staker != address(0), StakerAddressZero()); - require(ownedShares.unwrap() != 0, SharesAmountZero()); + require(!sharesToAdd.isZero(), SharesAmountZero()); Shares existingShares = stakerStrategyShares[staker][strategy]; - // if they dont have existing ownedShares of this strategy, add it to their strats - if (existingShares.unwrap()== 0) { + // if they dont have existing shares of this strategy, add it to their strats + if (existingShares.isZero()) { require(stakerStrategyList[staker].length < MAX_STAKER_STRATEGY_LIST_LENGTH, MaxStrategiesExceeded()); stakerStrategyList[staker].push(strategy); } - // add the returned ownedShares to their existing shares for this strategy - stakerStrategyShares[staker][strategy] = existingShares.add(ownedShares.unwrap()).wrapShares(); + // add the returned shares to their existing shares for this strategy + stakerStrategyShares[staker][strategy] = existingShares.add(sharesToAdd); // Increase shares delegated to operator, if needed delegation.increaseDelegatedShares({ staker: staker, strategy: strategy, existingShares: existingShares, - addedOwnedShares: ownedShares + addedShares: sharesToAdd }); - emit Deposit(staker, token, strategy, ownedShares); + emit Deposit(staker, token, strategy, sharesToAdd); } /** @@ -276,50 +277,51 @@ contract StrategyManager is * @param strategy The Strategy contract to deposit into. * @param token The ERC20 token to deposit. * @param amount The amount of `token` to deposit. - * @return ownedShares The amount of *new* ownedShares in `strategy` that have been credited to the `staker`. + * @return shares The amount of *new* shares in `strategy` that have been credited to the `staker`. */ function _depositIntoStrategy( address staker, IStrategy strategy, IERC20 token, uint256 amount - ) internal onlyStrategiesWhitelistedForDeposit(strategy) returns (OwnedShares ownedShares) { + ) internal onlyStrategiesWhitelistedForDeposit(strategy) returns (Shares shares) { // transfer tokens from the sender to the strategy token.safeTransferFrom(msg.sender, address(strategy), amount); // deposit the assets into the specified strategy and get the equivalent amount of shares in that strategy - ownedShares = strategy.deposit(token, amount).wrapOwned(); + // TODO: should we use Shares type in StrategyBase? + uint256 depositedShares = strategy.deposit(token, amount); // add the returned shares to the staker's existing shares for this strategy - _addOwnedShares(staker, token, strategy, ownedShares); + _addShares(staker, token, strategy, depositedShares); - return ownedShares; + return depositedShares.wrapShares(); } /** - * @notice Decreases the shares that `staker` holds in `strategy` by `shareAmount`. + * @notice Decreases the shares that `staker` holds in `strategy` by `sharesToDecrement`. * @param staker The address to decrement shares from * @param strategy The strategy for which the `staker`'s shares are being decremented - * @param shareAmount The amount of shares to decrement + * @param sharesToDecrement The amount of shares to decrement * @dev If the amount of shares represents all of the staker`s shares in said strategy, * then the strategy is removed from stakerStrategyList[staker] and 'true' is returned. Otherwise 'false' is returned. */ - function _removeShares(address staker, IStrategy strategy, Shares shareAmount) internal returns (bool) { + function _removeShares(address staker, IStrategy strategy, Shares sharesToDecrement) internal returns (bool) { // sanity checks on inputs - require(shareAmount.unwrap() != 0, SharesAmountZero()); + require(!sharesToDecrement.isZero(), SharesAmountZero()); //check that the user has sufficient shares Shares userShares = stakerStrategyShares[staker][strategy]; - require(shareAmount.unwrap() <= userShares.unwrap(), SharesAmountTooHigh()); + require(sharesToDecrement.lte(userShares), SharesAmountTooHigh()); - userShares = userShares.sub(shareAmount.unwrap()).wrapShares(); + userShares = userShares.sub(sharesToDecrement); // subtract the shares from the staker's existing shares for this strategy stakerStrategyShares[staker][strategy] = userShares; // if no existing shares, remove the strategy from the staker's dynamic array of strategies - if (userShares.unwrap() == 0) { + if (userShares.isZero()) { _removeStrategyFromStakerStrategyList(staker, strategy); // return true in the event that the strategy was removed from stakerStrategyList[staker] diff --git a/src/contracts/libraries/SlashingLib.sol b/src/contracts/libraries/SlashingLib.sol index c10aa3ca2..78605b196 100644 --- a/src/contracts/libraries/SlashingLib.sol +++ b/src/contracts/libraries/SlashingLib.sol @@ -10,13 +10,13 @@ uint64 constant WAD = 1e18; /* * There are 3 types of shares: - * 1. ownedShares + * 1. shares * - These can be converted to an amount of tokens given a strategy * - by calling `sharesToUnderlying` on the strategy address (they're already tokens * in the case of EigenPods) * - These are comparable between operators and stakers. * - These live in the storage of StrategyManager strategies: - * - `totalShares` is the total amount of shares delegated to a strategy + * - `totalShares` is the total amount of shares that exist in a strategy * 2. delegatedShares * - These can be converted to shares given an operator and a strategy * - by multiplying by the operator's totalMagnitude for the strategy @@ -25,7 +25,7 @@ uint64 constant WAD = 1e18; * - These live in the storage of the DelegationManager: * - `delegatedShares` is the total amount of delegatedShares delegated to an operator for a strategy * - `withdrawal.delegatedShares` is the amount of delegatedShares in a withdrawal - * 3. shares + * 3. ownedShares * - These can be converted into delegatedShares given a staker and a strategy * - by multiplying by the staker's depositScalingFactor for the strategy * - These values automatically update their conversion into tokens @@ -65,17 +65,24 @@ library SlashingLib { } function toDelegatedShares( - Shares shares, - uint256 depositScalingFactor + OwnedShares ownedShares, + uint256 magnitude ) internal pure returns (DelegatedShares) { - if (depositScalingFactor == 0) { - depositScalingFactor = WAD; - } + // forgefmt: disable-next-item + return ownedShares + .unwrap() + .mulWad(magnitude) + .wrapDelegated(); + } + function toDelegatedShares( + Shares shares, + uint256 magnitude + ) internal pure returns (DelegatedShares) { // forgefmt: disable-next-item return shares .unwrap() - .mulWad(depositScalingFactor) + .mulWad(magnitude) .wrapDelegated(); } @@ -90,15 +97,69 @@ library SlashingLib { .wrapOwned(); } - function toDelegatedShares( - OwnedShares shares, - uint256 magnitude - ) internal pure returns (DelegatedShares) { - // forgefmt: disable-next-item + function toOwnedShares( + Shares shares, + uint64 stakerScalingFactor, + uint64 operatorMagnitude + ) internal pure returns (OwnedShares) { + /** + * ownedShares = shares * stakerScalingFactor * operatorMagnitude + * stakerScalingFactor = storedScalingFactor / WAD + * operatorMagnitude = storedOperatorMagnitude / WAD + * ownedShares = shares * (storedScalingFactor / WAD) * (storedOperatorMagnitude / WAD) + */ return shares .unwrap() - .divWad(magnitude) - .wrapDelegated(); + .mulWad(stakerScalingFactor) + .mulWad(operatorMagnitude) + .wrapOwned(); + } + + function calculateNewDepositScalingFactor( + Shares currentShares, + Shares addedShares, + uint64 stakerScalingFactor, + uint64 operatorMagnitude + ) internal pure returns (uint64) { + /** + * Base Equations: + * (1) newShares = currentShares + addedShares + * (2) newOwnedShares = currentOwnedShares + addedShares + * (3) newOwnedShares = newShares * newStakerScalingFactor * newOperatorMagnitude + * + * Plugging (3) into (2): + * (4) newShares * newStakerScalingFactor * newOperatorMagnitude = currentOwnedShares + addedShares + * + * Solving for newStakerScalingFactor + * (5) newStakerScalingFactor = (ownedShares + addedShares) / (newShares * newOperatorMagnitude) + * + * We also know that the operatorMagnitude remains constant on deposits, thus + * (6) newOperatorMagnitude = oldOperatorMagnitude + * + * Plugging in (6) and (1) into (5): + * (7) newStakerScalingFactor = (ownedShares + addedShares) / ((currentShares + addedShares) * oldOperatorMagnitude) + * Note that magnitudes must be divided by WAD for precision. Thus, + * + * (8) newStakerScalingFactor = (ownedShares + addedShares) / ((currentShares + addedShares) * oldOperatorMagnitude / WAD) + * (9) newStakerScalingFactor = (ownedShares + addedShares) / ((currentShares + addedShares) / WAD) * (oldOperatorMagnitude / WAD)) + */ + + // Step 1: Calculate Numerator + OwnedShares currentOwnedShares = currentShares.toOwnedShares(stakerScalingFactor, operatorMagnitude); + + // Step 2: Compute currentShares + addedShares + uint256 ownedPlusAddedShares = currentOwnedShares.add(addedShares).unwrap(); + + // Step 3: Calculate newStakerScalingFactor + // Note: We divide by operatorMagnitude to preserve + + //TODO: figure out if we only need to do one divWad here + uint256 newStakerScalingFactor = + ownedPlusAddedShares + .divWad(currentShares.unwrap() + addedOwnedShares.unwrap()) + .divWad(operatorMagnitude); + + return newStakerScalingFactor; } // MATH @@ -149,6 +210,16 @@ library SlashingLib { return x.mulDiv(WAD, y); } + // COMPARISONS + + function isZero(Shares x) internal pure returns (bool) { + return x.unwrap() == 0; + } + + function lte(Shares x, Shares y) internal pure returns (bool) { + return x.unwrap() <= y.unwrap(); + } + // TYPE CASTING function unwrap(Shares x) internal pure returns (uint256) { From e1844a1aa773eb90be7ce6d0d9834659253f944e Mon Sep 17 00:00:00 2001 From: Yash Patil Date: Mon, 30 Sep 2024 11:36:48 -0700 Subject: [PATCH 2/2] feat: push --- src/contracts/core/DelegationManager.sol | 17 ++++++----- src/contracts/core/StrategyManager.sol | 7 +++-- .../interfaces/IDelegationManager.sol | 4 +-- src/contracts/interfaces/IStrategyManager.sol | 6 ++-- src/contracts/libraries/SlashingLib.sol | 28 +++++++++++++------ 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/contracts/core/DelegationManager.sol b/src/contracts/core/DelegationManager.sol index b719d0bf3..68b8c0c8e 100644 --- a/src/contracts/core/DelegationManager.sol +++ b/src/contracts/core/DelegationManager.sol @@ -516,8 +516,8 @@ contract DelegationManager is operator: operator, staker: staker, strategy: strategies[i], - existingShares: Shares(0), - addedOwnedShares: ownedShares[i], + existingShares: Shares.wrap(0), + addedShares: ownedShares[i].unwrap().wrapShares(), totalMagnitude: totalMagnitudes[i] }); } @@ -745,14 +745,13 @@ contract DelegationManager is Shares existingShares, Shares addedShares ) internal returns (uint256 newDepositScalingFactor) { - uint256 newDepositScalingFactor; if (existingShares.isZero()) { newDepositScalingFactor = WAD / totalMagnitude; } else { - newDepositScalingFactor = existingShares.calculateNewScalingFactor( - addedShares: addedShares, - oldStakerScalingFactor: depositScalingFactors[staker][strategy], - totalMagnitude: totalMagnitude + newDepositScalingFactor = existingShares.calculateNewDepositScalingFactor( + addedShares, + depositScalingFactors[staker][strategy], + totalMagnitude ); } @@ -866,8 +865,8 @@ contract DelegationManager is // forgefmt: disable-next-item ownedShares[i] = shares.toOwnedShares( - stakerScalingFactor: depositScalingFactors[staker][strategies[i]], - operatorMagnitude: totalMagnitude + depositScalingFactors[staker][strategies[i]], + totalMagnitude ); } } diff --git a/src/contracts/core/StrategyManager.sol b/src/contracts/core/StrategyManager.sol index bd3dd7ed4..a0fcb5dde 100644 --- a/src/contracts/core/StrategyManager.sol +++ b/src/contracts/core/StrategyManager.sol @@ -171,7 +171,8 @@ contract StrategyManager is IERC20 token, OwnedShares ownedShares ) external onlyDelegationManager { - _addOwnedShares(staker, token, strategy, ownedShares); + //TODO: fix + // _addShares(staker, token, strategy, ownedShares); } /// @notice Used by the DelegationManager to convert withdrawn shares to tokens and send them to a recipient @@ -238,7 +239,7 @@ contract StrategyManager is * @param staker The address to add shares to * @param token The token that is being deposited (used for indexing) * @param strategy The Strategy in which the `staker` is receiving shares - * @param shares The amount of shares to grant to the `staker` + * @param sharesToAdd The amount of shares to grant to the `staker` * @dev In particular, this function calls `delegation.increaseDelegatedShares(staker, strategy, shares)` to ensure that all * delegated shares are tracked, increases the stored share amount in `stakerStrategyShares[staker][strategy]`, and adds `strategy` * to the `staker`'s list of strategies, if it is not in the list already. @@ -293,7 +294,7 @@ contract StrategyManager is uint256 depositedShares = strategy.deposit(token, amount); // add the returned shares to the staker's existing shares for this strategy - _addShares(staker, token, strategy, depositedShares); + _addShares(staker, token, strategy, depositedShares.wrapShares()); return depositedShares.wrapShares(); } diff --git a/src/contracts/interfaces/IDelegationManager.sol b/src/contracts/interfaces/IDelegationManager.sol index 189acb111..4ee8390aa 100644 --- a/src/contracts/interfaces/IDelegationManager.sol +++ b/src/contracts/interfaces/IDelegationManager.sol @@ -348,7 +348,7 @@ interface IDelegationManager is ISignatureUtils { * @param strategy The strategy in which to increase the delegated shares. * @param existingShares The number of deposit shares the staker already has in the strategy. This is the shares amount stored in the * StrategyManager/EigenPodManager for the staker's shares. - * @param addedOwnedShares The number of shares to added to the staker's shares in the strategy. This amount will be scaled prior to adding + * @param addedShares The number of shares to added to the staker's shares in the strategy. This amount will be scaled prior to adding * to the operator's scaled shares. * * @dev *If the staker is actively delegated*, then increases the `staker`'s delegated scaled shares in `strategy`. @@ -359,7 +359,7 @@ interface IDelegationManager is ISignatureUtils { address staker, IStrategy strategy, Shares existingShares, - OwnedShares addedOwnedShares + Shares addedShares ) external; /** diff --git a/src/contracts/interfaces/IStrategyManager.sol b/src/contracts/interfaces/IStrategyManager.sol index c0967d9b4..29289688d 100644 --- a/src/contracts/interfaces/IStrategyManager.sol +++ b/src/contracts/interfaces/IStrategyManager.sol @@ -42,7 +42,7 @@ interface IStrategyManager is IShareManager { * @param token Is the token that `staker` deposited. * @param shares Is the number of new shares `staker` has been granted in `strategy`. */ - event Deposit(address staker, IERC20 token, IStrategy strategy, OwnedShares shares); + event Deposit(address staker, IERC20 token, IStrategy strategy, Shares shares); /// @notice Emitted when the `strategyWhitelister` is changed event StrategyWhitelisterChanged(address previousAddress, address newAddress); @@ -65,7 +65,7 @@ interface IStrategyManager is IShareManager { * WARNING: Depositing tokens that allow reentrancy (eg. ERC-777) into a strategy is not recommended. This can lead to attack vectors * where the token balance and corresponding strategy shares are not in sync upon reentrancy. */ - function depositIntoStrategy(IStrategy strategy, IERC20 token, uint256 amount) external returns (OwnedShares shares); + function depositIntoStrategy(IStrategy strategy, IERC20 token, uint256 amount) external returns (Shares shares); /** * @notice Used for depositing an asset into the specified strategy with the resultant shares credited to `staker`, @@ -94,7 +94,7 @@ interface IStrategyManager is IShareManager { address staker, uint256 expiry, bytes memory signature - ) external returns (OwnedShares shares); + ) external returns (Shares shares); /** * @notice Get all details on the staker's deposits and corresponding shares diff --git a/src/contracts/libraries/SlashingLib.sol b/src/contracts/libraries/SlashingLib.sol index 78605b196..76478f380 100644 --- a/src/contracts/libraries/SlashingLib.sol +++ b/src/contracts/libraries/SlashingLib.sol @@ -99,8 +99,8 @@ library SlashingLib { function toOwnedShares( Shares shares, - uint64 stakerScalingFactor, - uint64 operatorMagnitude + uint256 stakerScalingFactor, + uint256 operatorMagnitude ) internal pure returns (OwnedShares) { /** * ownedShares = shares * stakerScalingFactor * operatorMagnitude @@ -118,9 +118,9 @@ library SlashingLib { function calculateNewDepositScalingFactor( Shares currentShares, Shares addedShares, - uint64 stakerScalingFactor, - uint64 operatorMagnitude - ) internal pure returns (uint64) { + uint256 stakerScalingFactor, + uint256 operatorMagnitude + ) internal pure returns (uint256) { /** * Base Equations: * (1) newShares = currentShares + addedShares @@ -145,10 +145,10 @@ library SlashingLib { */ // Step 1: Calculate Numerator - OwnedShares currentOwnedShares = currentShares.toOwnedShares(stakerScalingFactor, operatorMagnitude); + uint256 currentOwnedShares = currentShares.toOwnedShares(stakerScalingFactor, operatorMagnitude).unwrap(); // Step 2: Compute currentShares + addedShares - uint256 ownedPlusAddedShares = currentOwnedShares.add(addedShares).unwrap(); + uint256 ownedPlusAddedShares = currentOwnedShares + addedShares.unwrap(); // Step 3: Calculate newStakerScalingFactor // Note: We divide by operatorMagnitude to preserve @@ -156,7 +156,7 @@ library SlashingLib { //TODO: figure out if we only need to do one divWad here uint256 newStakerScalingFactor = ownedPlusAddedShares - .divWad(currentShares.unwrap() + addedOwnedShares.unwrap()) + .divWad(currentShares.unwrap() + addedShares.unwrap()) .divWad(operatorMagnitude); return newStakerScalingFactor; @@ -168,6 +168,10 @@ library SlashingLib { return x.unwrap() + y; } + function add(Shares x, Shares y) internal pure returns (Shares) { + return (x.unwrap() + y.unwrap()).wrapShares(); + } + function add(DelegatedShares x, uint256 y) internal pure returns (uint256) { return x.unwrap() + y; } @@ -188,6 +192,10 @@ library SlashingLib { return x.unwrap() - y; } + function sub(Shares x, Shares y) internal pure returns (Shares) { + return (x.unwrap() - y.unwrap()).wrapShares(); + } + function sub(DelegatedShares x, uint256 y) internal pure returns (uint256) { return x.unwrap() - y; } @@ -216,6 +224,10 @@ library SlashingLib { return x.unwrap() == 0; } + function isZero(OwnedShares x) internal pure returns (bool) { + return x.unwrap() == 0; + } + function lte(Shares x, Shares y) internal pure returns (bool) { return x.unwrap() <= y.unwrap(); }