From f66de0cce38c29b2db50d8ff88f6b159616ddf15 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 17 Mar 2022 07:36:22 -0700 Subject: [PATCH 1/7] Remove files we can import from set-protocol-v2 and update import statements --- contracts/ManagerCore.sol | 2 +- contracts/extensions/FeeSplitExtension.sol | 6 +- contracts/extensions/IssuanceExtension.sol | 2 +- .../PerpV2LeverageStrategyExtension.sol | 67 +-- .../extensions/StreamingFeeSplitExtension.sol | 2 +- contracts/extensions/TradeExtension.sol | 2 +- .../factories/DelegatedManagerFactory.sol | 5 +- contracts/hooks/SupplyCapIssuanceHook.sol | 2 +- contracts/interfaces/IAccountBalance.sol | 41 -- contracts/interfaces/IBaseManager.sol | 2 +- contracts/interfaces/IBasicIssuanceModule.sol | 2 +- contracts/interfaces/IController.sol | 24 - contracts/interfaces/IIssuanceModule.sol | 41 -- contracts/interfaces/IManagerIssuanceHook.sol | 2 +- .../interfaces/IPerpV2LeverageModule.sol | 45 -- contracts/interfaces/IPriceFeed.sol | 10 - contracts/interfaces/ISetToken.sol | 118 ---- contracts/interfaces/ISetTokenCreator.sol | 32 -- contracts/interfaces/IStreamingFeeModule.sol | 20 - .../interfaces/IStreamingFeeModuleV2.sol | 20 - contracts/interfaces/ITradeModule.sol | 33 -- contracts/interfaces/IUniswapV2Router.sol | 113 ---- contracts/interfaces/IVault.sol | 31 -- contracts/interfaces/IWETH.sol | 8 - contracts/lib/AddressArrayUtils.sol | 225 -------- contracts/lib/BaseExtension.sol | 3 +- contracts/lib/BaseGlobalExtension.sol | 2 +- contracts/lib/StringArrayUtils.sol | 61 -- contracts/manager/BaseManager.sol | 6 +- contracts/manager/DelegatedManager.sol | 2 +- contracts/mocks/AddressArrayUtilsMock.sol | 81 --- contracts/mocks/PerpV2PriceFeedMock.sol | 50 -- contracts/mocks/StandardTokenMock.sol | 42 -- contracts/mocks/StringArrayUtilsMock.sol | 45 -- test/lib/addressArrayUtils.spec.ts | 521 ------------------ test/lib/stringArrayUtils.spec.ts | 121 ---- 36 files changed, 55 insertions(+), 1734 deletions(-) delete mode 100644 contracts/interfaces/IAccountBalance.sol delete mode 100644 contracts/interfaces/IController.sol delete mode 100644 contracts/interfaces/IIssuanceModule.sol delete mode 100644 contracts/interfaces/IPerpV2LeverageModule.sol delete mode 100644 contracts/interfaces/IPriceFeed.sol delete mode 100644 contracts/interfaces/ISetToken.sol delete mode 100644 contracts/interfaces/ISetTokenCreator.sol delete mode 100644 contracts/interfaces/IStreamingFeeModule.sol delete mode 100644 contracts/interfaces/IStreamingFeeModuleV2.sol delete mode 100644 contracts/interfaces/ITradeModule.sol delete mode 100644 contracts/interfaces/IUniswapV2Router.sol delete mode 100644 contracts/interfaces/IVault.sol delete mode 100644 contracts/interfaces/IWETH.sol delete mode 100644 contracts/lib/AddressArrayUtils.sol delete mode 100644 contracts/lib/StringArrayUtils.sol delete mode 100644 contracts/mocks/AddressArrayUtilsMock.sol delete mode 100644 contracts/mocks/PerpV2PriceFeedMock.sol delete mode 100644 contracts/mocks/StandardTokenMock.sol delete mode 100644 contracts/mocks/StringArrayUtilsMock.sol delete mode 100644 test/lib/addressArrayUtils.spec.ts delete mode 100644 test/lib/stringArrayUtils.spec.ts diff --git a/contracts/ManagerCore.sol b/contracts/ManagerCore.sol index 38caa98..9597cff 100644 --- a/contracts/ManagerCore.sol +++ b/contracts/ManagerCore.sol @@ -20,7 +20,7 @@ pragma solidity 0.6.10; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { AddressArrayUtils } from "./lib/AddressArrayUtils.sol"; +import { AddressArrayUtils } from "@setprotocol/set-protocol-v2/contracts/lib/AddressArrayUtils.sol"; /** * @title ManagerCore diff --git a/contracts/extensions/FeeSplitExtension.sol b/contracts/extensions/FeeSplitExtension.sol index 198776c..af92c4b 100644 --- a/contracts/extensions/FeeSplitExtension.sol +++ b/contracts/extensions/FeeSplitExtension.sol @@ -22,13 +22,13 @@ pragma experimental ABIEncoderV2; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; +import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; import { PreciseUnitMath } from "@setprotocol/set-protocol-v2/contracts/lib/PreciseUnitMath.sol"; +import { IIssuanceModule } from "@setprotocol/set-protocol-v2/contracts/interfaces/IIssuanceModule.sol"; +import { IStreamingFeeModule } from "@setprotocol/set-protocol-v2/contracts/interfaces/IStreamingFeeModule.sol"; import { BaseExtension } from "../lib/BaseExtension.sol"; -import { IIssuanceModule } from "../interfaces/IIssuanceModule.sol"; import { IBaseManager } from "../interfaces/IBaseManager.sol"; -import { ISetToken } from "../interfaces/ISetToken.sol"; -import { IStreamingFeeModule } from "../interfaces/IStreamingFeeModule.sol"; import { TimeLockUpgrade } from "../lib/TimeLockUpgrade.sol"; diff --git a/contracts/extensions/IssuanceExtension.sol b/contracts/extensions/IssuanceExtension.sol index 7bdbd0a..a7a9c08 100644 --- a/contracts/extensions/IssuanceExtension.sol +++ b/contracts/extensions/IssuanceExtension.sol @@ -23,11 +23,11 @@ import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; +import { IIssuanceModule } from "@setprotocol/set-protocol-v2/contracts/interfaces/IIssuanceModule.sol"; import { PreciseUnitMath } from "@setprotocol/set-protocol-v2/contracts/lib/PreciseUnitMath.sol"; import { BaseGlobalExtension } from "../lib/BaseGlobalExtension.sol"; import { IDelegatedManager } from "../interfaces/IDelegatedManager.sol"; -import { IIssuanceModule } from "../interfaces/IIssuanceModule.sol"; import { IManagerCore } from "../interfaces/IManagerCore.sol"; /** diff --git a/contracts/extensions/PerpV2LeverageStrategyExtension.sol b/contracts/extensions/PerpV2LeverageStrategyExtension.sol index a7ac5c2..9e58d19 100644 --- a/contracts/extensions/PerpV2LeverageStrategyExtension.sol +++ b/contracts/extensions/PerpV2LeverageStrategyExtension.sol @@ -26,17 +26,18 @@ import { SafeCast } from "@openzeppelin/contracts/utils/SafeCast.sol"; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; import { SignedSafeMath } from "@openzeppelin/contracts/math/SignedSafeMath.sol"; +import { IAccountBalance } from "@setprotocol/set-protocol-v2/contracts/interfaces/IAccountBalance.sol"; import { IPerpV2LeverageModule } from "@setprotocol/set-protocol-v2/contracts/interfaces/IPerpV2LeverageModule.sol"; +import { IPriceFeed } from "@setprotocol/set-protocol-v2/contracts/interfaces/IPriceFeed.sol"; import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; +import { IVault } from "@setprotocol/set-protocol-v2/contracts/interfaces/IVault.sol"; import { PreciseUnitMath } from "@setprotocol/set-protocol-v2/contracts/lib/PreciseUnitMath.sol"; +import { StringArrayUtils } from "@setprotocol/set-protocol-v2/contracts/lib/StringArrayUtils.sol"; import { BaseExtension } from "../lib/BaseExtension.sol"; -import { IAccountBalance } from "../interfaces/IAccountBalance.sol"; import { IBaseManager } from "../interfaces/IBaseManager.sol"; -import { IPriceFeed } from "../interfaces/IPriceFeed.sol"; -import { IVault } from "../interfaces/IVault.sol"; -import { StringArrayUtils } from "../lib/StringArrayUtils.sol"; + /** * @title PerpV2LeverageStrategyExtension @@ -44,7 +45,7 @@ import { StringArrayUtils } from "../lib/StringArrayUtils.sol"; * * Smart contract that enables trustless leverage tokens with USDC as collateral. This extension is paired with the PerpV2LeverageModule from * Set protocol where module interactions are invoked via the IBaseManager contract. Any leveraged token can be constructed as long as the - * market is listed on Perp V2. This extension contract also allows the operator to set an ETH reward to incentivize keepers calling the + * market is listed on Perp V2. This extension contract also allows the operator to set an ETH reward to incentivize keepers calling the * rebalance function at different leverage thresholds. */ contract PerpV2LeverageStrategyExtension is BaseExtension { @@ -95,7 +96,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { // listed on PerpV2 uint256 twapInterval; // TWAP interval to be used to fetch base asset price in seconds // PerpV2 uses a 15 min TWAP interval, i.e. twapInterval = 900 - uint256 basePriceDecimalAdjustment; // Decimal adjustment for the price returned by the PerpV2 oracle for the base asset. + uint256 basePriceDecimalAdjustment; // Decimal adjustment for the price returned by the PerpV2 oracle for the base asset. // Equal to vBaseAsset.decimals() - baseUSDPriceOracle.decimals() address virtualBaseAddress; // Address of virtual base asset (e.g. vETH, vWBTC etc) address virtualQuoteAddress; // Address of virtual USDC quote asset. The Perp V2 system uses USDC for all markets @@ -104,9 +105,9 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { struct MethodologySettings { int256 targetLeverageRatio; // Long term target ratio in precise units (10e18). For short tokens target ratio is negative. // E.g. 2e18 for ETH 2x and -2e18 for ETH -2x. - int256 minLeverageRatio; // For both long and short tokens, if magnitude of current leverage is lower, rebalance target is + int256 minLeverageRatio; // For both long and short tokens, if magnitude of current leverage is lower, rebalance target is // this ratio. In precise units (10e18). E.g. 1.7e17 for ETH 2x and -1.7e17 for ETH -1x. - int256 maxLeverageRatio; // For both long and short tokens, if magniutde of current leverage is higher, rebalance target is + int256 maxLeverageRatio; // For both long and short tokens, if magniutde of current leverage is higher, rebalance target is // this ratio. In precise units (10e18). E.g. 1.7e17 for ETH 2x and -1.7e17 for ETH -1x. uint256 recenteringSpeed; // % at which to rebalance back to target leverage in precise units (10e18). Always a positive number uint256 rebalanceInterval; // Period of time required since last rebalance timestamp in seconds @@ -231,9 +232,9 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { /** * OPERATOR ONLY: Engage to target leverage ratio for the first time. SetToken will open a new base token position on PerpV2. Under the hood, perp would - * mint virtual quote assets (vUSDC) for SetToken and swap them for base token. If target leverage ratio is above max trade size, then TWAP is kicked off. + * mint virtual quote assets (vUSDC) for SetToken and swap them for base token. If target leverage ratio is above max trade size, then TWAP is kicked off. * To complete engage if TWAP, any valid caller must call iterateRebalance until target is met. - * Note: Engage should be called after collateral has been deposited to PerpV2 using `deposit()`. + * Note: Engage should be called after collateral has been deposited to PerpV2 using `deposit()`. */ function engage() external onlyOperator { LeverageInfo memory leverageInfo = _getAndValidateEngageInfo(); @@ -262,7 +263,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { /** * ONLY EOA AND ALLOWED CALLER: Rebalance product. If |min leverage ratio| < |current leverage ratio| < |max leverage ratio|, then rebalance - * can only be called once the rebalance interval has elapsed since last timestamp. If outside the max and min but below incentivized leverage ratio, + * can only be called once the rebalance interval has elapsed since last timestamp. If outside the max and min but below incentivized leverage ratio, * rebalance can be called anytime to bring leverage ratio back to the max or min bounds. The methodology will determine whether to delever or lever. * * Note: If the calculated current leverage ratio is above the incentivized leverage ratio or in TWAP then rebalance cannot be called. Instead, you must call @@ -295,8 +296,8 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { } /** - * ONLY EOA AND ALLOWED CALLER: Iterate a rebalance when in TWAP. TWAP cooldown period must have elapsed. If price moves advantageously, then - * exit without rebalancing and clear TWAP state. This function can only be called when |current leverage ratio| < |incentivized leverage ratio| + * ONLY EOA AND ALLOWED CALLER: Iterate a rebalance when in TWAP. TWAP cooldown period must have elapsed. If price moves advantageously, then + * exit without rebalancing and clear TWAP state. This function can only be called when |current leverage ratio| < |incentivized leverage ratio| * and in TWAP state. */ function iterateRebalance() external onlyEOA onlyAllowedCaller(msg.sender) { @@ -327,9 +328,9 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { /** * ONLY EOA: In case |current leverage ratio| > |incentivized leverage ratio|, the ripcord function can be called by anyone to return leverage ratio - * back to the max leverage ratio. This function typically would only be called during times of high downside/upside volatility and / or normal keeper malfunctions. The + * back to the max leverage ratio. This function typically would only be called during times of high downside/upside volatility and / or normal keeper malfunctions. The * caller of ripcord() will receive a reward in Ether. The ripcord function uses it's own TWAP cooldown period, slippage tolerance and TWAP max trade size which are - * typically looser than in regular rebalances. If chunk rebalance size is above max incentivized trade size, then caller must continue to call this function to pull + * typically looser than in regular rebalances. If chunk rebalance size is above max incentivized trade size, then caller must continue to call this function to pull * the leverage ratio under the incentivized leverage ratio. Incentivized TWAP cooldown period must have elapsed. The function iterateRebalance will not work. */ function ripcord() external onlyEOA { @@ -337,7 +338,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { incentive.incentivizedSlippageTolerance, exchange.incentivizedTwapMaxTradeSize ); - + _validateRipcord(leverageInfo, lastTradeTimestamp); ( int256 chunkRebalanceNotional, ) = _calculateChunkRebalanceNotional(leverageInfo, methodology.maxLeverageRatio); @@ -361,7 +362,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { * virtual base token positions into virtual USDC. If the chunk rebalance size is less than the total notional size, then this function will trade out of base * token position in one go. If chunk rebalance size is above max trade size, then operator must continue to call this function to completely unwind position. * The function iterateRebalance will not work. - * + * * Note: If rebalancing is open to anyone disengage TWAP can be counter traded by a griefing party calling rebalance. Set anyoneCallable to false before disengage to prevent such attacks. */ function disengage() external onlyOperator { @@ -383,7 +384,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { _trade(leverageInfo, chunkRebalanceNotional); _updateDisengageState(); - + emit Disengaged( leverageInfo.currentLeverageRatio, newLeverageRatio, @@ -412,7 +413,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { * * @param _collateralUnits Collateral to withdraw in position units */ - function withdraw(uint256 _collateralUnits) external onlyOperator { + function withdraw(uint256 _collateralUnits) external onlyOperator { bytes memory withdrawCalldata = abi.encodeWithSelector( IPerpV2LeverageModule.withdraw.selector, address(strategy.setToken), @@ -479,7 +480,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { } /** - * OPERATOR ONLY: Set exchange settings and check new settings are valid.Updating exchange settings during rebalances is allowed, as it is not possible + * OPERATOR ONLY: Set exchange settings and check new settings are valid.Updating exchange settings during rebalances is allowed, as it is not possible * to enter an unexpected state while doing so. Note: Need to pass in existing parameters if only changing a few settings. * * @param _newExchangeSettings Struct containing exchange parameters @@ -512,7 +513,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { /* ============ External Getter Functions ============ */ /** - * Get current leverage ratio. Current leverage ratio is defined as the sum of USD values of all SetToken open positions on Perp V2 divided by its account value on + * Get current leverage ratio. Current leverage ratio is defined as the sum of USD values of all SetToken open positions on Perp V2 divided by its account value on * PerpV2. Prices for base and quote asset are retrieved from the Chainlink Price Oracle. * * return currentLeverageRatio Current leverage ratio in precise units (10e18) @@ -568,7 +569,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { (size, ) = _calculateChunkRebalanceNotional(leverageInfo, newLeverageRatio); bool increaseLeverage = newLeverageRatio.abs() > currentLeverageRatio.abs(); - + /* ------------------------------------------------------------------------------ | New LR | increaseLeverage | sellAsset | buyAsset | @@ -705,9 +706,9 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { */ function _getAndValidateEngageInfo() internal view returns(LeverageInfo memory) { ActionInfo memory engageInfo = _createActionInfo(); - + require(engageInfo.accountInfo.collateralBalance > 0, "Collateral balance must be > 0"); - + // Assert base position unit is zero. Asserting base position unit instead of base balance allows us to neglect small dust amounts. require(engageInfo.baseBalance.preciseDiv(strategy.setToken.totalSupply().toInt256()) == 0, "Base position must NOT exist"); @@ -728,7 +729,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { ActionInfo memory actionInfo = _createActionInfo(); require(actionInfo.setTotalSupply > 0, "SetToken must have > 0 supply"); - + // Get current leverage ratio int256 currentLeverageRatio = _calculateCurrentLeverageRatio(actionInfo); @@ -756,16 +757,16 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { int256 rawBasePrice = strategy.baseUSDPriceOracle.getPrice(strategy.twapInterval).toInt256(); uint256 decimals = strategy.baseUSDPriceOracle.decimals(); rebalanceInfo.basePrice = rawBasePrice.mul((10 ** strategy.basePriceDecimalAdjustment).toInt256()); - + // vUSD price is fixed to 1$ rebalanceInfo.quotePrice = PreciseUnitMath.preciseUnit().toInt256(); // Note: getTakerPositionSize returns zero if base balance is less than 10 wei rebalanceInfo.baseBalance = strategy.perpV2AccountBalance.getTakerPositionSize(address(strategy.setToken), strategy.virtualBaseAddress); - + // Note: Fetching quote balance associated with a single position and not the net quote balance rebalanceInfo.quoteBalance = strategy.perpV2AccountBalance.getTakerOpenNotional(address(strategy.setToken), strategy.virtualBaseAddress); - + rebalanceInfo.accountInfo = strategy.perpV2LeverageModule.getAccountInfo(strategy.setToken); // In Perp v2, all virtual tokens have 18 decimals, therefore we do not need to make further adjustments to determine base valuation. @@ -833,7 +834,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { function _validateExchangeSettings(ExchangeSettings memory _settings) internal pure { require(_settings.twapMaxTradeSize != 0, "Max TWAP trade size must not be 0"); require( - _settings.twapMaxTradeSize <= _settings.incentivizedTwapMaxTradeSize, + _settings.twapMaxTradeSize <= _settings.incentivizedTwapMaxTradeSize, "Max TWAP trade size must not be greater than incentivized max TWAP trade size" ); } @@ -920,15 +921,15 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { settling funding (on every trade) owedRealizedPnL <- owedRealizedPnL + pendingFundingPayment pendingFundingPayment <- 0 - - Note: Collateral balance, owedRealizedPnl and pendingFundingPayments belong to the entire account and + + Note: Collateral balance, owedRealizedPnl and pendingFundingPayments belong to the entire account and NOT just the single market managed by this contract. So, while managing multiple positions across multiple markets via multiple separate extension contracts, `totalCollateralValue` should be counted only once. */ int256 totalCollateralValue = _actionInfo.accountInfo.collateralBalance .add(_actionInfo.accountInfo.owedRealizedPnl) .add(_actionInfo.accountInfo.pendingFundingPayments); - + // Note: Both basePositionValue and quoteValue are values that belong to the single market managed by this contract. int256 unrealizedPnl = _actionInfo.basePositionValue.add(_actionInfo.quoteValue); @@ -990,7 +991,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension { int256 totalRebalanceNotional = leverageRatioDifference.preciseDiv(_leverageInfo.currentLeverageRatio).preciseMul(_leverageInfo.action.baseBalance); - uint256 chunkRebalanceNotionalAbs = Math.min(totalRebalanceNotional.abs(), _leverageInfo.twapMaxTradeSize); + uint256 chunkRebalanceNotionalAbs = Math.min(totalRebalanceNotional.abs(), _leverageInfo.twapMaxTradeSize); return ( // Return int256 chunkRebalanceNotional totalRebalanceNotional >= 0 ? chunkRebalanceNotionalAbs.toInt256() : chunkRebalanceNotionalAbs.toInt256().neg(), diff --git a/contracts/extensions/StreamingFeeSplitExtension.sol b/contracts/extensions/StreamingFeeSplitExtension.sol index 2345c25..891764a 100644 --- a/contracts/extensions/StreamingFeeSplitExtension.sol +++ b/contracts/extensions/StreamingFeeSplitExtension.sol @@ -23,12 +23,12 @@ import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; +import { IStreamingFeeModule } from "@setprotocol/set-protocol-v2/contracts/interfaces/IStreamingFeeModuleV2.sol"; import { PreciseUnitMath } from "@setprotocol/set-protocol-v2/contracts/lib/PreciseUnitMath.sol"; import { BaseGlobalExtension } from "../lib/BaseGlobalExtension.sol"; import { IDelegatedManager } from "../interfaces/IDelegatedManager.sol"; import { IManagerCore } from "../interfaces/IManagerCore.sol"; -import { IStreamingFeeModule } from "../interfaces/IStreamingFeeModuleV2.sol"; /** * @title StreamingFeeSplitExtension diff --git a/contracts/extensions/TradeExtension.sol b/contracts/extensions/TradeExtension.sol index 19b1283..b6f9fda 100644 --- a/contracts/extensions/TradeExtension.sol +++ b/contracts/extensions/TradeExtension.sol @@ -15,11 +15,11 @@ pragma solidity 0.6.10; import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; +import { ITradeModule } from "@setprotocol/set-protocol-v2/contracts/interfaces/ITradeModule.sol"; import { BaseGlobalExtension } from "../lib/BaseGlobalExtension.sol"; import { IDelegatedManager } from "../interfaces/IDelegatedManager.sol"; import { IManagerCore } from "../interfaces/IManagerCore.sol"; -import { ITradeModule } from "../interfaces/ITradeModule.sol"; /** * @title TradeExtension diff --git a/contracts/factories/DelegatedManagerFactory.sol b/contracts/factories/DelegatedManagerFactory.sol index 4a8db13..69cea99 100644 --- a/contracts/factories/DelegatedManagerFactory.sol +++ b/contracts/factories/DelegatedManagerFactory.sol @@ -20,14 +20,15 @@ pragma solidity 0.6.10; pragma experimental ABIEncoderV2; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; + +import { AddressArrayUtils } from "@setprotocol/set-protocol-v2/contracts/lib/AddressArrayUtils.sol"; import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; +import { ISetTokenCreator } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetTokenCreator.sol"; -import { AddressArrayUtils } from "../lib/AddressArrayUtils.sol"; import { DelegatedManager } from "../manager/DelegatedManager.sol"; import { IController } from "../interfaces/IController.sol"; import { IDelegatedManager } from "../interfaces/IDelegatedManager.sol"; import { IManagerCore } from "../interfaces/IManagerCore.sol"; -import { ISetTokenCreator } from "../interfaces/ISetTokenCreator.sol"; /** * @title DelegatedManagerFactory diff --git a/contracts/hooks/SupplyCapIssuanceHook.sol b/contracts/hooks/SupplyCapIssuanceHook.sol index a7ed42b..defbe57 100644 --- a/contracts/hooks/SupplyCapIssuanceHook.sol +++ b/contracts/hooks/SupplyCapIssuanceHook.sol @@ -21,9 +21,9 @@ pragma experimental ABIEncoderV2; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; +import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; import { IManagerIssuanceHook } from "../interfaces/IManagerIssuanceHook.sol"; -import { ISetToken } from "../interfaces/ISetToken.sol"; /** diff --git a/contracts/interfaces/IAccountBalance.sol b/contracts/interfaces/IAccountBalance.sol deleted file mode 100644 index a97bbbc..0000000 --- a/contracts/interfaces/IAccountBalance.sol +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright 2021 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ - -pragma solidity 0.6.10; - -pragma experimental ABIEncoderV2; - -interface IAccountBalance { - function getBaseTokens(address trader) external view returns (address[] memory); - function hasOrder(address trader) external view returns (bool); - function getMarginRequirementForLiquidation(address trader) external view returns (int256); - function getTotalDebtValue(address trader) external view returns (uint256); - function getPnlAndPendingFee(address trader) external view returns (int256,int256,uint256); - function getBase(address trader, address baseToken) external view returns (int256); - function getTakerPositionSize(address trader, address baseToken) external view returns (int256 takerPositionSize); - function getTakerOpenNotional(address trader, address baseToken) external view returns (int256 openNotional); - function getQuote(address trader, address baseToken) external view returns (int256); - function getNetQuoteBalanceAndPendingFee(address trader) external view returns (int256, uint256); - function getPositionSize(address trader, address baseToken) external view returns (int256); - function getPositionValue(address trader, address baseToken) external view returns (int256); - function getTotalAbsPositionValue(address trader) external view returns (uint256); - function getClearingHouseConfig() external view returns (address); - function getExchange() external view returns (address); - function getOrderBook() external view returns (address); - function getVault() external view returns (address); -} \ No newline at end of file diff --git a/contracts/interfaces/IBaseManager.sol b/contracts/interfaces/IBaseManager.sol index 301b27f..084a075 100644 --- a/contracts/interfaces/IBaseManager.sol +++ b/contracts/interfaces/IBaseManager.sol @@ -19,7 +19,7 @@ pragma solidity 0.6.10; pragma experimental "ABIEncoderV2"; -import { ISetToken } from "./ISetToken.sol"; +import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; interface IBaseManager { function setToken() external returns(ISetToken); diff --git a/contracts/interfaces/IBasicIssuanceModule.sol b/contracts/interfaces/IBasicIssuanceModule.sol index 597d0d8..815d9bd 100644 --- a/contracts/interfaces/IBasicIssuanceModule.sol +++ b/contracts/interfaces/IBasicIssuanceModule.sol @@ -13,7 +13,7 @@ */ pragma solidity >=0.6.10; -import { ISetToken } from "./ISetToken.sol"; +import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; interface IBasicIssuanceModule { function getRequiredComponentUnitsForIssue( diff --git a/contracts/interfaces/IController.sol b/contracts/interfaces/IController.sol deleted file mode 100644 index 5ea4a0a..0000000 --- a/contracts/interfaces/IController.sol +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright 2020 Set Labs Inc. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - SPDX-License-Identifier: Apache License, Version 2.0 -*/ -pragma solidity 0.6.10; - -interface IController { - function addSet(address _setToken) external; - function feeRecipient() external view returns(address); - function getModuleFee(address _module, uint256 _feeType) external view returns(uint256); - function isModule(address _module) external view returns(bool); - function isSet(address _setToken) external view returns(bool); - function isSystemContract(address _contractAddress) external view returns (bool); - function resourceId(uint256 _id) external view returns(address); -} diff --git a/contracts/interfaces/IIssuanceModule.sol b/contracts/interfaces/IIssuanceModule.sol deleted file mode 100644 index b4d574b..0000000 --- a/contracts/interfaces/IIssuanceModule.sol +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright 2021 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ -pragma solidity 0.6.10; - -import { ISetToken } from "./ISetToken.sol"; - -/** - * @title IDebtIssuanceModule - * @author Set Protocol - * - * Interface for interacting with Debt Issuance module interface. - */ -interface IIssuanceModule { - function updateIssueFee(ISetToken _setToken, uint256 _newIssueFee) external; - function updateRedeemFee(ISetToken _setToken, uint256 _newRedeemFee) external; - function updateFeeRecipient(ISetToken _setToken, address _newRedeemFee) external; - - function initialize( - ISetToken _setToken, - uint256 _maxManagerFee, - uint256 _managerIssueFee, - uint256 _managerRedeemFee, - address _feeRecipient, - address _managerIssuanceHook - ) external; -} diff --git a/contracts/interfaces/IManagerIssuanceHook.sol b/contracts/interfaces/IManagerIssuanceHook.sol index 4a28de1..f9ec2c4 100644 --- a/contracts/interfaces/IManagerIssuanceHook.sol +++ b/contracts/interfaces/IManagerIssuanceHook.sol @@ -17,7 +17,7 @@ */ pragma solidity 0.6.10; -import { ISetToken } from "./ISetToken.sol"; +import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; interface IManagerIssuanceHook { function invokePreIssueHook(ISetToken _setToken, uint256 _issueQuantity, address _sender, address _to) external; diff --git a/contracts/interfaces/IPerpV2LeverageModule.sol b/contracts/interfaces/IPerpV2LeverageModule.sol deleted file mode 100644 index a8f4589..0000000 --- a/contracts/interfaces/IPerpV2LeverageModule.sol +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright 2021 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ -pragma solidity 0.6.10; - -import { ISetToken } from "./ISetToken.sol"; -pragma experimental ABIEncoderV2; - -/** - * @title IPerpV2LeverageModule - * @author Set Protocol - * - * Interface for interacting with Perp V2 leverage module - */ -interface IPerpV2LeverageModule { - struct PositionInfo { - address baseToken; // Virtual token minted by the Perp protocol - int256 baseBalance; // Position size in 10**18 decimals. When negative, position is short - int256 quoteBalance; // vUSDC "debt" minted to open position. When positive, position is short - } - - function trade( - ISetToken _setToken, - address _baseToken, - int256 _baseQuantityUnits, - uint256 _receiveQuoteQuantityUnits - ) external; - - function getPositionInfo(ISetToken _setToken) external view returns (PositionInfo[] memory); - function collateralToken() external view returns (address); -} diff --git a/contracts/interfaces/IPriceFeed.sol b/contracts/interfaces/IPriceFeed.sol deleted file mode 100644 index 496d22c..0000000 --- a/contracts/interfaces/IPriceFeed.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT License -pragma solidity 0.6.10; - -interface IPriceFeed { - function decimals() external view returns (uint8); - - /// @dev Returns the index price of the token. - /// @param interval The interval represents twap interval. - function getPrice(uint256 interval) external view returns (uint256); -} \ No newline at end of file diff --git a/contracts/interfaces/ISetToken.sol b/contracts/interfaces/ISetToken.sol deleted file mode 100644 index dddbcb9..0000000 --- a/contracts/interfaces/ISetToken.sol +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-License-Identifier: Apache License, Version 2.0 -pragma solidity 0.6.10; -pragma experimental "ABIEncoderV2"; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -/** - * @title ISetToken - * @author Set Protocol - * - * Interface for operating with SetTokens. - */ -interface ISetToken is IERC20 { - - /* ============ Enums ============ */ - - enum ModuleState { - NONE, - PENDING, - INITIALIZED - } - - /* ============ Structs ============ */ - /** - * The base definition of a SetToken Position - * - * @param component Address of token in the Position - * @param module If not in default state, the address of associated module - * @param unit Each unit is the # of components per 10^18 of a SetToken - * @param positionState Position ENUM. Default is 0; External is 1 - * @param data Arbitrary data - */ - struct Position { - address component; - address module; - int256 unit; - uint8 positionState; - bytes data; - } - - /** - * A struct that stores a component's cash position details and external positions - * This data structure allows O(1) access to a component's cash position units and - * virtual units. - * - * @param virtualUnit Virtual value of a component's DEFAULT position. Stored as virtual for efficiency - * updating all units at once via the position multiplier. Virtual units are achieved - * by dividing a "real" value by the "positionMultiplier" - * @param componentIndex - * @param externalPositionModules List of external modules attached to each external position. Each module - * maps to an external position - * @param externalPositions Mapping of module => ExternalPosition struct for a given component - */ - struct ComponentPosition { - int256 virtualUnit; - address[] externalPositionModules; - mapping(address => ExternalPosition) externalPositions; - } - - /** - * A struct that stores a component's external position details including virtual unit and any - * auxiliary data. - * - * @param virtualUnit Virtual value of a component's EXTERNAL position. - * @param data Arbitrary data - */ - struct ExternalPosition { - int256 virtualUnit; - bytes data; - } - - - /* ============ Functions ============ */ - - function addComponent(address _component) external; - function removeComponent(address _component) external; - function editDefaultPositionUnit(address _component, int256 _realUnit) external; - function addExternalPositionModule(address _component, address _positionModule) external; - function removeExternalPositionModule(address _component, address _positionModule) external; - function editExternalPositionUnit(address _component, address _positionModule, int256 _realUnit) external; - function editExternalPositionData(address _component, address _positionModule, bytes calldata _data) external; - - function invoke(address _target, uint256 _value, bytes calldata _data) external returns(bytes memory); - - function editPositionMultiplier(int256 _newMultiplier) external; - - function mint(address _account, uint256 _quantity) external; - function burn(address _account, uint256 _quantity) external; - - function lock() external; - function unlock() external; - - function addModule(address _module) external; - function removeModule(address _module) external; - function initializeModule() external; - - function setManager(address _manager) external; - - function manager() external view returns (address); - function moduleStates(address _module) external view returns (ModuleState); - function getModules() external view returns (address[] memory); - - function getDefaultPositionRealUnit(address _component) external view returns(int256); - function getExternalPositionRealUnit(address _component, address _positionModule) external view returns(int256); - function getComponents() external view returns(address[] memory); - function getExternalPositionModules(address _component) external view returns(address[] memory); - function getExternalPositionData(address _component, address _positionModule) external view returns(bytes memory); - function isExternalPositionModule(address _component, address _module) external view returns(bool); - function isComponent(address _component) external view returns(bool); - - function positionMultiplier() external view returns (int256); - function getPositions() external view returns (Position[] memory); - function getTotalComponentRealUnits(address _component) external view returns(int256); - - function isInitializedModule(address _module) external view returns(bool); - function isPendingModule(address _module) external view returns(bool); - function isLocked() external view returns (bool); -} \ No newline at end of file diff --git a/contracts/interfaces/ISetTokenCreator.sol b/contracts/interfaces/ISetTokenCreator.sol deleted file mode 100644 index 051c60f..0000000 --- a/contracts/interfaces/ISetTokenCreator.sol +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright 2021 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ - -pragma solidity 0.6.10; - -interface ISetTokenCreator { - function create( - address[] memory _components, - int256[] memory _units, - address[] memory _modules, - address _manager, - string memory _name, - string memory _symbol - ) - external - returns (address); -} \ No newline at end of file diff --git a/contracts/interfaces/IStreamingFeeModule.sol b/contracts/interfaces/IStreamingFeeModule.sol deleted file mode 100644 index f25c17a..0000000 --- a/contracts/interfaces/IStreamingFeeModule.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: Apache License, Version 2.0 -pragma solidity 0.6.10; -pragma experimental "ABIEncoderV2"; - -import { ISetToken } from "./ISetToken.sol"; - -interface IStreamingFeeModule { - struct FeeState { - address feeRecipient; - uint256 maxStreamingFeePercentage; - uint256 streamingFeePercentage; - uint256 lastStreamingFeeTimestamp; - } - - function getFee(ISetToken _setToken) external view returns (uint256); - function accrueFee(ISetToken _setToken) external; - function updateStreamingFee(ISetToken _setToken, uint256 _newFee) external; - function updateFeeRecipient(ISetToken _setToken, address _newFeeRecipient) external; - function initialize(ISetToken _setToken, FeeState memory _settings) external; -} diff --git a/contracts/interfaces/IStreamingFeeModuleV2.sol b/contracts/interfaces/IStreamingFeeModuleV2.sol deleted file mode 100644 index 68fe15e..0000000 --- a/contracts/interfaces/IStreamingFeeModuleV2.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: Apache License, Version 2.0 -pragma solidity 0.6.10; -pragma experimental "ABIEncoderV2"; - -import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; - -interface IStreamingFeeModule { - struct FeeState { - address feeRecipient; - uint256 maxStreamingFeePercentage; - uint256 streamingFeePercentage; - uint256 lastStreamingFeeTimestamp; - } - - function getFee(ISetToken _setToken) external view returns (uint256); - function accrueFee(ISetToken _setToken) external; - function updateStreamingFee(ISetToken _setToken, uint256 _newFee) external; - function updateFeeRecipient(ISetToken _setToken, address _newFeeRecipient) external; - function initialize(ISetToken _setToken, FeeState memory _settings) external; -} diff --git a/contracts/interfaces/ITradeModule.sol b/contracts/interfaces/ITradeModule.sol deleted file mode 100644 index 95e67c2..0000000 --- a/contracts/interfaces/ITradeModule.sol +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright 2020 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ -pragma solidity 0.6.10; -pragma experimental "ABIEncoderV2"; - -import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; - -interface ITradeModule { - function initialize(ISetToken _setToken) external; - function trade(ISetToken _setToken, - string memory _exchangeName, - address _sendToken, - uint256 _sendQuantity, - address _receiveToken, - uint256 _minReceiveQuantity, - bytes memory _data - ) external; -} \ No newline at end of file diff --git a/contracts/interfaces/IUniswapV2Router.sol b/contracts/interfaces/IUniswapV2Router.sol deleted file mode 100644 index 9d65b26..0000000 --- a/contracts/interfaces/IUniswapV2Router.sol +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright 2020 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ - -pragma solidity 0.6.10; - -interface IUniswapV2Router { - function factory() external pure returns (address); - function WETH() external pure returns (address); - - function addLiquidity( - address tokenA, - address tokenB, - uint amountADesired, - uint amountBDesired, - uint amountAMin, - uint amountBMin, - address to, - uint deadline - ) external returns (uint amountA, uint amountB, uint liquidity); - function addLiquidityETH( - address token, - uint amountTokenDesired, - uint amountTokenMin, - uint amountETHMin, - address to, - uint deadline - ) external payable returns (uint amountToken, uint amountETH, uint liquidity); - function removeLiquidity( - address tokenA, - address tokenB, - uint liquidity, - uint amountAMin, - uint amountBMin, - address to, - uint deadline - ) external returns (uint amountA, uint amountB); - function removeLiquidityETH( - address token, - uint liquidity, - uint amountTokenMin, - uint amountETHMin, - address to, - uint deadline - ) external returns (uint amountToken, uint amountETH); - function removeLiquidityWithPermit( - address tokenA, - address tokenB, - uint liquidity, - uint amountAMin, - uint amountBMin, - address to, - uint deadline, - bool approveMax, uint8 v, bytes32 r, bytes32 s - ) external returns (uint amountA, uint amountB); - function removeLiquidityETHWithPermit( - address token, - uint liquidity, - uint amountTokenMin, - uint amountETHMin, - address to, - uint deadline, - bool approveMax, uint8 v, bytes32 r, bytes32 s - ) external returns (uint amountToken, uint amountETH); - function swapExactTokensForTokens( - uint amountIn, - uint amountOutMin, - address[] calldata path, - address to, - uint deadline - ) external returns (uint[] memory amounts); - function swapTokensForExactTokens( - uint amountOut, - uint amountInMax, - address[] calldata path, - address to, - uint deadline - ) external returns (uint[] memory amounts); - function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) - external - payable - returns (uint[] memory amounts); - function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) - external - returns (uint[] memory amounts); - function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) - external - returns (uint[] memory amounts); - function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) - external - payable - returns (uint[] memory amounts); - - function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); - function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); - function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); - function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); - function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); -} \ No newline at end of file diff --git a/contracts/interfaces/IVault.sol b/contracts/interfaces/IVault.sol deleted file mode 100644 index 3e36654..0000000 --- a/contracts/interfaces/IVault.sol +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright 2021 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ - -pragma solidity 0.6.10; - -interface IVault { - function getBalance(address account) external view returns (int256); - function decimals() external view returns (uint8); - function getFreeCollateral(address trader) external view returns (uint256); - function getFreeCollateralByRatio(address trader, uint24 ratio) external view returns (int256); - function getLiquidateMarginRequirement(address trader) external view returns (int256); - function getSettlementToken() external view returns (address); - function getAccountBalance() external view returns (address); - function getClearingHouse() external view returns (address); - function getExchange() external view returns (address); -} \ No newline at end of file diff --git a/contracts/interfaces/IWETH.sol b/contracts/interfaces/IWETH.sol deleted file mode 100644 index b81ea01..0000000 --- a/contracts/interfaces/IWETH.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: Apache License, Version 2.0 -pragma solidity >=0.6.10; - -interface IWETH { - function deposit() external payable; - function transfer(address to, uint value) external returns (bool); - function withdraw(uint) external; -} \ No newline at end of file diff --git a/contracts/lib/AddressArrayUtils.sol b/contracts/lib/AddressArrayUtils.sol deleted file mode 100644 index fceb948..0000000 --- a/contracts/lib/AddressArrayUtils.sol +++ /dev/null @@ -1,225 +0,0 @@ -/* - Copyright 2020 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ - -pragma solidity 0.6.10; - -/** - * @title AddressArrayUtils - * @author Set Protocol - * - * Utility functions to handle Address Arrays - * - * CHANGELOG: - * - 4/27/21: Added validatePairsWithArray methods - */ -library AddressArrayUtils { - - /** - * Finds the index of the first occurrence of the given element. - * @param A The input array to search - * @param a The value to find - * @return Returns (index and isIn) for the first occurrence starting from index 0 - */ - function indexOf(address[] memory A, address a) internal pure returns (uint256, bool) { - uint256 length = A.length; - for (uint256 i = 0; i < length; i++) { - if (A[i] == a) { - return (i, true); - } - } - return (uint256(-1), false); - } - - /** - * Returns true if the value is present in the list. Uses indexOf internally. - * @param A The input array to search - * @param a The value to find - * @return Returns isIn for the first occurrence starting from index 0 - */ - function contains(address[] memory A, address a) internal pure returns (bool) { - (, bool isIn) = indexOf(A, a); - return isIn; - } - - /** - * Returns true if there are 2 elements that are the same in an array - * @param A The input array to search - * @return Returns boolean for the first occurrence of a duplicate - */ - function hasDuplicate(address[] memory A) internal pure returns(bool) { - require(A.length > 0, "A is empty"); - - for (uint256 i = 0; i < A.length - 1; i++) { - address current = A[i]; - for (uint256 j = i + 1; j < A.length; j++) { - if (current == A[j]) { - return true; - } - } - } - return false; - } - - /** - * @param A The input array to search - * @param a The address to remove - * @return Returns the array with the object removed. - */ - function remove(address[] memory A, address a) - internal - pure - returns (address[] memory) - { - (uint256 index, bool isIn) = indexOf(A, a); - if (!isIn) { - revert("Address not in array."); - } else { - (address[] memory _A,) = pop(A, index); - return _A; - } - } - - /** - * @param A The input array to search - * @param a The address to remove - */ - function removeStorage(address[] storage A, address a) - internal - { - (uint256 index, bool isIn) = indexOf(A, a); - if (!isIn) { - revert("Address not in array."); - } else { - uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here - if (index != lastIndex) { A[index] = A[lastIndex]; } - A.pop(); - } - } - - /** - * Removes specified index from array - * @param A The input array to search - * @param index The index to remove - * @return Returns the new array and the removed entry - */ - function pop(address[] memory A, uint256 index) - internal - pure - returns (address[] memory, address) - { - uint256 length = A.length; - require(index < A.length, "Index must be < A length"); - address[] memory newAddresses = new address[](length - 1); - for (uint256 i = 0; i < index; i++) { - newAddresses[i] = A[i]; - } - for (uint256 j = index + 1; j < length; j++) { - newAddresses[j - 1] = A[j]; - } - return (newAddresses, A[index]); - } - - /** - * Returns the combination of the two arrays - * @param A The first array - * @param B The second array - * @return Returns A extended by B - */ - function extend(address[] memory A, address[] memory B) internal pure returns (address[] memory) { - uint256 aLength = A.length; - uint256 bLength = B.length; - address[] memory newAddresses = new address[](aLength + bLength); - for (uint256 i = 0; i < aLength; i++) { - newAddresses[i] = A[i]; - } - for (uint256 j = 0; j < bLength; j++) { - newAddresses[aLength + j] = B[j]; - } - return newAddresses; - } - - /** - * Validate that address and uint array lengths match. Validate address array is not empty - * and contains no duplicate elements. - * - * @param A Array of addresses - * @param B Array of uint - */ - function validatePairsWithArray(address[] memory A, uint[] memory B) internal pure { - require(A.length == B.length, "Array length mismatch"); - _validateLengthAndUniqueness(A); - } - - /** - * Validate that address and bool array lengths match. Validate address array is not empty - * and contains no duplicate elements. - * - * @param A Array of addresses - * @param B Array of bool - */ - function validatePairsWithArray(address[] memory A, bool[] memory B) internal pure { - require(A.length == B.length, "Array length mismatch"); - _validateLengthAndUniqueness(A); - } - - /** - * Validate that address and string array lengths match. Validate address array is not empty - * and contains no duplicate elements. - * - * @param A Array of addresses - * @param B Array of strings - */ - function validatePairsWithArray(address[] memory A, string[] memory B) internal pure { - require(A.length == B.length, "Array length mismatch"); - _validateLengthAndUniqueness(A); - } - - /** - * Validate that address array lengths match, and calling address array are not empty - * and contain no duplicate elements. - * - * @param A Array of addresses - * @param B Array of addresses - */ - function validatePairsWithArray(address[] memory A, address[] memory B) internal pure { - require(A.length == B.length, "Array length mismatch"); - _validateLengthAndUniqueness(A); - } - - /** - * Validate that address and bytes array lengths match. Validate address array is not empty - * and contains no duplicate elements. - * - * @param A Array of addresses - * @param B Array of bytes - */ - function validatePairsWithArray(address[] memory A, bytes[] memory B) internal pure { - require(A.length == B.length, "Array length mismatch"); - _validateLengthAndUniqueness(A); - } - - /** - * Validate address array is not empty and contains no duplicate elements. - * - * @param A Array of addresses - */ - function _validateLengthAndUniqueness(address[] memory A) internal pure { - require(A.length > 0, "Array length must be > 0"); - require(!hasDuplicate(A), "Cannot duplicate addresses"); - } -} diff --git a/contracts/lib/BaseExtension.sol b/contracts/lib/BaseExtension.sol index dfde30c..40af450 100644 --- a/contracts/lib/BaseExtension.sol +++ b/contracts/lib/BaseExtension.sol @@ -18,7 +18,8 @@ pragma solidity 0.6.10; -import { AddressArrayUtils } from "../lib/AddressArrayUtils.sol"; +import { AddressArrayUtils } from "@setprotocol/set-protocol-v2/contracts/lib/AddressArrayUtils.sol"; + import { IBaseManager } from "../interfaces/IBaseManager.sol"; /** diff --git a/contracts/lib/BaseGlobalExtension.sol b/contracts/lib/BaseGlobalExtension.sol index c5f70fc..b74df29 100644 --- a/contracts/lib/BaseGlobalExtension.sol +++ b/contracts/lib/BaseGlobalExtension.sol @@ -18,9 +18,9 @@ pragma solidity 0.6.10; +import { AddressArrayUtils } from "@setprotocol/set-protocol-v2/contracts/lib/AddressArrayUtils.sol"; import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; -import { AddressArrayUtils } from "../lib/AddressArrayUtils.sol"; import { IDelegatedManager } from "../interfaces/IDelegatedManager.sol"; import { IManagerCore } from "../interfaces/IManagerCore.sol"; diff --git a/contracts/lib/StringArrayUtils.sol b/contracts/lib/StringArrayUtils.sol deleted file mode 100644 index 9ac97f9..0000000 --- a/contracts/lib/StringArrayUtils.sol +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright 2021 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ - -pragma solidity 0.6.10; - -/** - * @title StringArrayUtils - * @author Set Protocol - * - * Utility functions to handle String Arrays - */ -library StringArrayUtils { - - /** - * Finds the index of the first occurrence of the given element. - * @param A The input string to search - * @param a The value to find - * @return Returns (index and isIn) for the first occurrence starting from index 0 - */ - function indexOf(string[] memory A, string memory a) internal pure returns (uint256, bool) { - uint256 length = A.length; - for (uint256 i = 0; i < length; i++) { - if (keccak256(bytes(A[i])) == keccak256(bytes(a))) { - return (i, true); - } - } - return (uint256(-1), false); - } - - /** - * @param A The input array to search - * @param a The string to remove - */ - function removeStorage(string[] storage A, string memory a) - internal - { - (uint256 index, bool isIn) = indexOf(A, a); - if (!isIn) { - revert("String not in array."); - } else { - uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here - if (index != lastIndex) { A[index] = A[lastIndex]; } - A.pop(); - } - } -} diff --git a/contracts/manager/BaseManager.sol b/contracts/manager/BaseManager.sol index fad3b56..e541403 100644 --- a/contracts/manager/BaseManager.sol +++ b/contracts/manager/BaseManager.sol @@ -20,9 +20,9 @@ pragma solidity 0.6.10; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; -import { AddressArrayUtils } from "../lib/AddressArrayUtils.sol"; -import { IAdapter } from "../interfaces/IAdapter.sol"; -import { ISetToken } from "../interfaces/ISetToken.sol"; +import { AddressArrayUtils } from "@setprotocol/set-protocol-v2/contracts/lib/AddressArrayUtils.sol"; +import { IAdapter } from "@setprotocol/set-protocol-v2/contracts/interfaces/IAdapter.sol"; +import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; /** diff --git a/contracts/manager/DelegatedManager.sol b/contracts/manager/DelegatedManager.sol index 4a71d1f..0ad7a7a 100644 --- a/contracts/manager/DelegatedManager.sol +++ b/contracts/manager/DelegatedManager.sol @@ -23,10 +23,10 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; +import { AddressArrayUtils } from "@setprotocol/set-protocol-v2/contracts/lib/AddressArrayUtils.sol"; import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; import { PreciseUnitMath } from "@setprotocol/set-protocol-v2/contracts/lib/PreciseUnitMath.sol"; -import { AddressArrayUtils } from "../lib/AddressArrayUtils.sol"; import { IGlobalExtension } from "../interfaces/IGlobalExtension.sol"; import { MutualUpgradeV2 } from "../lib/MutualUpgradeV2.sol"; diff --git a/contracts/mocks/AddressArrayUtilsMock.sol b/contracts/mocks/AddressArrayUtilsMock.sol deleted file mode 100644 index 206b39f..0000000 --- a/contracts/mocks/AddressArrayUtilsMock.sol +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright 2020 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ - -pragma solidity 0.6.10; -pragma experimental "ABIEncoderV2"; - -import { AddressArrayUtils } from "../lib/AddressArrayUtils.sol"; - - -contract AddressArrayUtilsMock { - using AddressArrayUtils for address[]; - - address[] public storageArray; - - function testIndexOf(address[] memory A, address a) external pure returns (uint256, bool) { - return A.indexOf(a); - } - - function testContains(address[] memory A, address a) external pure returns (bool) { - return A.contains(a); - } - - function testHasDuplicate(address[] memory A) external pure returns (bool) { - return A.hasDuplicate(); - } - - function testRemove(address[] memory A, address a) external pure returns (address[] memory) { - return A.remove(a); - } - - function testRemoveStorage(address a) external { - storageArray.removeStorage(a); - } - - function testPop(address[] memory A, uint256 index) external pure returns (address[] memory, address) { - return A.pop(index); - } - - function testValidatePairsWithArrayUint(address[] memory A, uint[] memory a) external pure { - A.validatePairsWithArray(a); - } - - function testValidatePairsWithArrayBool(address[] memory A, bool[] memory a) external pure { - A.validatePairsWithArray(a); - } - - function testValidatePairsWithArrayString(address[] memory A, string[] memory a) external pure { - A.validatePairsWithArray(a); - } - - function testValidatePairsWithArrayAddress(address[] memory A, address[] memory a) external pure { - A.validatePairsWithArray(a); - } - - function testValidatePairsWithArrayBytes(address[] memory A, bytes[] memory a) external pure { - A.validatePairsWithArray(a); - } - - function setStorageArray(address[] memory A) external { - storageArray = A; - } - - function getStorageArray() external view returns(address[] memory) { - return storageArray; - } -} diff --git a/contracts/mocks/PerpV2PriceFeedMock.sol b/contracts/mocks/PerpV2PriceFeedMock.sol deleted file mode 100644 index f288660..0000000 --- a/contracts/mocks/PerpV2PriceFeedMock.sol +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright 2022 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ - -pragma solidity 0.6.10; - -/** - * Mock PerpV2 Price Feed. - */ -contract PerpV2PriceFeedMock { - uint8 public decimals; - uint256 internal price; - - constructor(uint8 _decimals) public { - decimals = _decimals; - } - - /** - * Typical usage for setting the BaseToken oracle to 100 is: - * - * ``` - * await mockPriceFeed.setPrice(ethers.utils.parseUnits("100", decimals)); - * ``` - */ - function setPrice(uint256 _price) public { - price = _price; - } - - - /** - * Returns the index price of the token. - */ - function getPrice(uint256 /*interval*/) external view returns (uint256) { - return price; - } -} \ No newline at end of file diff --git a/contracts/mocks/StandardTokenMock.sol b/contracts/mocks/StandardTokenMock.sol deleted file mode 100644 index 603217a..0000000 --- a/contracts/mocks/StandardTokenMock.sol +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright 2021 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ - -pragma solidity 0.6.10; - -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - -// mock class using BasicToken -contract StandardTokenMock is ERC20 { - constructor( - address _initialAccount, - uint256 _initialBalance, - string memory _name, - string memory _symbol, - uint8 _decimals - ) - public - ERC20(_name, _symbol) - { - _mint(_initialAccount, _initialBalance); - _setupDecimals(_decimals); - } - - function mint(address to, uint amount) external { - _mint(to, amount); - } -} diff --git a/contracts/mocks/StringArrayUtilsMock.sol b/contracts/mocks/StringArrayUtilsMock.sol deleted file mode 100644 index b89f2a9..0000000 --- a/contracts/mocks/StringArrayUtilsMock.sol +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright 2021 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ - -pragma solidity 0.6.10; -pragma experimental "ABIEncoderV2"; - -import { StringArrayUtils } from "../lib/StringArrayUtils.sol"; - - -contract StringArrayUtilsMock { - using StringArrayUtils for string[]; - - string[] public storageArray; - - function testIndexOf(string[] memory A, string memory a) external pure returns (uint256, bool) { - return A.indexOf(a); - } - - function testRemoveStorage(string memory a) external { - storageArray.removeStorage(a); - } - - function setStorageArray(string[] memory A) external { - storageArray = A; - } - - function getStorageArray() external view returns(string[] memory) { - return storageArray; - } -} \ No newline at end of file diff --git a/test/lib/addressArrayUtils.spec.ts b/test/lib/addressArrayUtils.spec.ts deleted file mode 100644 index 446944a..0000000 --- a/test/lib/addressArrayUtils.spec.ts +++ /dev/null @@ -1,521 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Account, Address } from "@utils/types"; -import { ONE, MAX_UINT_256 } from "@utils/constants"; -import { AddressArrayUtilsMock } from "@utils/contracts"; -import DeployHelper from "@utils/deploys"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect, -} from "@utils/test/index"; - -const expect = getWaffleExpect(); - -describe("AddressArrayUtils", () => { - let accountOne: Account; - let accountTwo: Account; - let accountThree: Account; - let unincludedAccount: Account; - let deployer: DeployHelper; - - let addressArrayUtils: AddressArrayUtilsMock; - - let baseArray: Address[]; - - before(async () => { - [ - accountOne, - accountTwo, - accountThree, - unincludedAccount, - ] = await getAccounts(); - - deployer = new DeployHelper(accountOne.wallet); - addressArrayUtils = await deployer.mocks.deployAddressArrayUtilsMock(); - - baseArray = [accountOne.address, accountTwo.address, accountThree.address]; - }); - - addSnapshotBeforeRestoreAfterEach(); - - describe("#indexOf", async () => { - let subjectArray: Address[]; - let subjectAddress: Address; - - beforeEach(async () => { - subjectArray = baseArray; - subjectAddress = accountTwo.address; - }); - - async function subject(): Promise { - return addressArrayUtils.testIndexOf(subjectArray, subjectAddress); - } - - it("should return the correct index and true", async () => { - const [index, isIn] = await subject(); - - expect(index).to.eq(BigNumber.from(1)); - expect(isIn).to.be.true; - }); - - describe("when passed address is not in array", async () => { - beforeEach(async () => { - subjectAddress = unincludedAccount.address; - }); - - it("should return false and max number index", async () => { - const [index, isIn] = await subject(); - - expect(index).to.eq(MAX_UINT_256); - expect(isIn).to.be.false; - }); - }); - }); - - describe("#contains", async () => { - let subjectArray: Address[]; - let subjectAddress: Address; - - beforeEach(async () => { - subjectArray = baseArray; - subjectAddress = accountTwo.address; - }); - - async function subject(): Promise { - return addressArrayUtils.testContains(subjectArray, subjectAddress); - } - - it("should return the correct index and true", async () => { - const isIn = await subject(); - - expect(isIn).to.be.true; - }); - - describe("when passed address is not in array", async () => { - beforeEach(async () => { - subjectAddress = unincludedAccount.address; - }); - - it("should return false", async () => { - const isIn = await subject(); - - expect(isIn).to.be.false; - }); - }); - }); - - describe("#hasDuplicate", async () => { - let subjectArray: Address[]; - - beforeEach(async () => { - subjectArray = baseArray; - }); - - async function subject(): Promise { - return addressArrayUtils.testHasDuplicate(subjectArray); - } - - it("should return return false", async () => { - const isIn = await subject(); - - expect(isIn).to.be.false; - }); - - describe("when the passed in array has a duplicate in the beginning", async () => { - beforeEach(async () => { - subjectArray = [accountOne.address, accountOne.address, accountThree.address]; - }); - - it("should return true", async () => { - const isIn = await subject(); - - expect(isIn).to.be.true; - }); - }); - - describe("when the passed in array has a duplicate in the end", async () => { - beforeEach(async () => { - subjectArray = [accountOne.address, accountTwo.address, accountOne.address]; - }); - - it("should return true", async () => { - const isIn = await subject(); - - expect(isIn).to.be.true; - }); - }); - - describe("when the passed in array has a duplicate in the middle", async () => { - beforeEach(async () => { - subjectArray = [accountOne.address, accountTwo.address, accountTwo.address]; - }); - - it("should return true", async () => { - const isIn = await subject(); - - expect(isIn).to.be.true; - }); - }); - - describe("when the passed in array is empty", async () => { - beforeEach(async () => { - subjectArray = []; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("A is empty"); - }); - }); - }); - - describe("#remove", async () => { - let subjectArray: Address[]; - let subjectAddress: Address; - - beforeEach(async () => { - subjectArray = baseArray; - subjectAddress = accountTwo.address; - }); - - async function subject(): Promise { - return addressArrayUtils.testRemove(subjectArray, subjectAddress); - } - - it("should return the correct array", async () => { - const array = await subject(); - - expect(JSON.stringify(array)).to.eq(JSON.stringify([accountOne.address, accountThree.address])); - }); - - describe("when passed address is not in array", async () => { - beforeEach(async () => { - subjectAddress = unincludedAccount.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Address not in array."); - }); - }); - }); - - describe("#removeStorage", async () => { - let subjectAddress: Address; - - beforeEach(async () => { - await addressArrayUtils.setStorageArray(baseArray); - subjectAddress = accountTwo.address; - }); - - async function subject(): Promise { - return addressArrayUtils.testRemoveStorage(subjectAddress); - } - - it("should make the correct updates to the storage array", async () => { - await subject(); - - const actualArray = await addressArrayUtils.getStorageArray(); - expect(JSON.stringify(actualArray)).to.eq(JSON.stringify([accountOne.address, accountThree.address])); - }); - - describe("when item being removed is last in array", async () => { - beforeEach(async () => { - subjectAddress = accountThree.address; - }); - - it("should just pop off last item", async () => { - await subject(); - - const actualArray = await addressArrayUtils.getStorageArray(); - expect(JSON.stringify(actualArray)).to.eq(JSON.stringify([accountOne.address, accountTwo.address])); - }); - }); - - describe("when passed address is not in array", async () => { - beforeEach(async () => { - subjectAddress = unincludedAccount.address; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Address not in array."); - }); - }); - }); - - describe("#pop", async () => { - let subjectArray: Address[]; - let subjectIndex: BigNumber; - - beforeEach(async () => { - subjectArray = baseArray; - subjectIndex = ONE; - }); - - async function subject(): Promise { - return addressArrayUtils.testPop(subjectArray, subjectIndex); - } - - it("should return the correct array and removed address", async () => { - const [array, address] = await subject(); - - expect(JSON.stringify(array)).to.eq(JSON.stringify([accountOne.address, accountThree.address])); - expect(address).to.eq(accountTwo.address); - }); - - describe("when index is > than array length", async () => { - beforeEach(async () => { - subjectIndex = ONE.mul(5); - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Index must be < A length"); - }); - }); - }); - - describe("#validatePairsWithArray (uint)", async () => { - let subjectArray: Address[]; - let subjectUintArray: BigNumber[]; - - beforeEach(async () => { - subjectArray = baseArray; - subjectUintArray = [BigNumber.from(1), BigNumber.from(2), BigNumber.from(3)]; - }); - - async function subject(): Promise { - return addressArrayUtils.testValidatePairsWithArrayUint(subjectArray, subjectUintArray); - } - - it("should validate equal non-zero length arrays when subject array has no duplicates", async () => { - await subject(); - }); - - describe("when array lengths do not match", async () => { - beforeEach(async () => { - subjectUintArray = [BigNumber.from(1), BigNumber.from(2)]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Array length mismatch"); - }); - }); - - describe("when arrays are zero length", async () => { - beforeEach(async () => { - subjectArray = []; - subjectUintArray = []; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Array length must be > 0"); - }); - }); - - describe("when calling address array contains duplicates", async () => { - beforeEach(async () => { - subjectArray = [accountOne.address, accountOne.address, accountThree.address]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Cannot duplicate addresses"); - }); - }); - }); - - describe("#validatePairsWithArray (bool)", async () => { - let subjectArray: Address[]; - let subjectBoolArray: boolean[]; - - beforeEach(async () => { - subjectArray = baseArray; - subjectBoolArray = [true, false, true]; - }); - - async function subject(): Promise { - return addressArrayUtils.testValidatePairsWithArrayBool(subjectArray, subjectBoolArray); - } - - it("should validate equal non-zero length arrays when subject array has no duplicates", async () => { - await subject(); - }); - - describe("when array lengths do not match", async () => { - beforeEach(async () => { - subjectBoolArray = [true, false]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Array length mismatch"); - }); - }); - - describe("when arrays are zero length", async () => { - beforeEach(async () => { - subjectArray = []; - subjectBoolArray = []; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Array length must be > 0"); - }); - }); - - describe("when calling address array contains duplicates", async () => { - beforeEach(async () => { - subjectArray = [accountOne.address, accountOne.address, accountThree.address]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Cannot duplicate addresses"); - }); - }); - }); - - describe("#validatePairsWithArray (string)", async () => { - let subjectArray: Address[]; - let subjectStringArray: string[]; - - beforeEach(async () => { - subjectArray = baseArray; - subjectStringArray = ["a", "b", "c"]; - }); - - async function subject(): Promise { - return addressArrayUtils.testValidatePairsWithArrayString(subjectArray, subjectStringArray); - } - - it("should validate equal non-zero length arrays when subject array has no duplicates", async () => { - await subject(); - }); - - describe("when array lengths do not match", async () => { - beforeEach(async () => { - subjectStringArray = ["a", "b"]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Array length mismatch"); - }); - }); - - describe("when arrays are zero length", async () => { - beforeEach(async () => { - subjectArray = []; - subjectStringArray = []; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Array length must be > 0"); - }); - }); - - describe("when calling address array contains duplicates", async () => { - beforeEach(async () => { - subjectArray = [accountOne.address, accountOne.address, accountThree.address]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Cannot duplicate addresses"); - }); - }); - }); - - describe("#validatePairsWithArray (address)", async () => { - let subjectArray: Address[]; - let subjectAddressArray: Address[]; - - beforeEach(async () => { - subjectArray = baseArray; - subjectAddressArray = baseArray; - }); - - async function subject(): Promise { - return addressArrayUtils.testValidatePairsWithArrayAddress(subjectArray, subjectAddressArray); - } - - it("should validate equal non-zero length arrays when subject array has no duplicates", async () => { - await subject(); - }); - - describe("when array lengths do not match", async () => { - beforeEach(async () => { - subjectAddressArray = [baseArray[0], baseArray[1]]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Array length mismatch"); - }); - }); - - describe("when arrays are zero length", async () => { - beforeEach(async () => { - subjectArray = []; - subjectAddressArray = []; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Array length must be > 0"); - }); - }); - - describe("when calling address array contains duplicates", async () => { - beforeEach(async () => { - subjectArray = [accountOne.address, accountOne.address, accountThree.address]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Cannot duplicate addresses"); - }); - }); - }); - - describe("#validatePairsWithArray (bytes)", async () => { - let subjectArray: Address[]; - let subjectBytesArray: string[]; - - beforeEach(async () => { - subjectArray = baseArray; - subjectBytesArray = ["0x", "0x523454", "0x7890"]; - }); - - async function subject(): Promise { - return addressArrayUtils.testValidatePairsWithArrayBytes(subjectArray, subjectBytesArray); - } - - it("should validate equal non-zero length arrays when subject array has no duplicates", async () => { - await subject(); - }); - - describe("when array lengths do not match", async () => { - beforeEach(async () => { - subjectBytesArray = ["0x", "0x523454"]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Array length mismatch"); - }); - }); - - describe("when arrays are zero length", async () => { - beforeEach(async () => { - subjectArray = []; - subjectBytesArray = []; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Array length must be > 0"); - }); - }); - - describe("when calling address array contains duplicates", async () => { - beforeEach(async () => { - subjectArray = [accountOne.address, accountOne.address, accountThree.address]; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("Cannot duplicate addresses"); - }); - }); - }); -}); diff --git a/test/lib/stringArrayUtils.spec.ts b/test/lib/stringArrayUtils.spec.ts deleted file mode 100644 index 5fd5ec2..0000000 --- a/test/lib/stringArrayUtils.spec.ts +++ /dev/null @@ -1,121 +0,0 @@ -import "module-alias/register"; -import { BigNumber } from "ethers"; - -import { Address } from "@utils/types"; -import { MAX_UINT_256 } from "@utils/constants"; -import { StringArrayUtilsMock } from "@utils/contracts/index"; -import DeployHelper from "@utils/deploys"; -import { - addSnapshotBeforeRestoreAfterEach, - getAccounts, - getWaffleExpect, -} from "@utils/test/index"; - -const expect = getWaffleExpect(); - -describe("StringArrayUtils", () => { - let stringOne: string; - let stringTwo: string; - let stringThree: string; - let unincludedString: string; - let deployer: DeployHelper; - - let stringArrayUtils: StringArrayUtilsMock; - - let baseArray: Address[]; - - before(async () => { - - stringOne = "eth"; - stringTwo = "to"; - stringThree = "$10k"; - - unincludedString = "$0"; - - const [ owner ] = await getAccounts(); - - deployer = new DeployHelper(owner.wallet); - stringArrayUtils = await deployer.mocks.deployStringArrayUtilsMock(); - - baseArray = [ stringOne, stringTwo, stringThree ]; - }); - - addSnapshotBeforeRestoreAfterEach(); - - describe("#indexOf", async () => { - let subjectArray: string[]; - let subjectString: string; - - beforeEach(async () => { - subjectArray = baseArray; - subjectString = stringTwo; - }); - - async function subject(): Promise { - return stringArrayUtils.testIndexOf(subjectArray, subjectString); - } - - it("should return the correct index and true", async () => { - const [index, isIn] = await subject(); - - expect(index).to.eq(BigNumber.from(1)); - expect(isIn).to.be.true; - }); - - describe("when passed address is not in array", async () => { - beforeEach(async () => { - subjectString = unincludedString; - }); - - it("should return false and max number index", async () => { - const [index, isIn] = await subject(); - - expect(index).to.eq(MAX_UINT_256); - expect(isIn).to.be.false; - }); - }); - }); - - describe("#removeStorage", async () => { - let subjectString: string; - - beforeEach(async () => { - await stringArrayUtils.setStorageArray(baseArray); - subjectString = stringTwo; - }); - - async function subject(): Promise { - return stringArrayUtils.testRemoveStorage(subjectString); - } - - it("should make the correct updates to the storage array", async () => { - await subject(); - - const actualArray = await stringArrayUtils.getStorageArray(); - expect(JSON.stringify(actualArray)).to.eq(JSON.stringify([ stringOne, stringThree ])); - }); - - describe("when item being removed is last in array", async () => { - beforeEach(async () => { - subjectString = stringThree; - }); - - it("should just pop off last item", async () => { - await subject(); - - const actualArray = await stringArrayUtils.getStorageArray(); - expect(JSON.stringify(actualArray)).to.eq(JSON.stringify([ stringOne, stringTwo ])); - }); - }); - - describe("when passed address is not in array", async () => { - beforeEach(async () => { - subjectString = unincludedString; - }); - - it("should revert", async () => { - await expect(subject()).to.be.revertedWith("String not in array."); - }); - }); - }); -}); From 4fdc915647d51e62bc8ba69b1b6ec327d415d2ad Mon Sep 17 00:00:00 2001 From: cgewecke Date: Fri, 18 Mar 2022 19:04:36 -0700 Subject: [PATCH 2/7] Additional import fixes --- .../PerpV2LeverageStrategyExtension.sol | 8 +++--- .../extensions/StreamingFeeSplitExtension.sol | 2 +- contracts/hooks/SupplyCapIssuanceHook.sol | 4 +-- contracts/interfaces/IBasicIssuanceModule.sol | 25 ------------------- contracts/interfaces/IManagerIssuanceHook.sol | 25 ------------------- contracts/manager/BaseManager.sol | 3 ++- test/extensions/issuanceExtension.spec.ts | 6 ++--- .../perpV2LeverageStrategyExtension.spec.ts | 1 + utils/contracts/index.ts | 5 ++-- utils/deploys/deployMocks.ts | 18 +++---------- utils/deploys/deploySetV2.ts | 12 ++++----- 11 files changed, 24 insertions(+), 85 deletions(-) delete mode 100644 contracts/interfaces/IBasicIssuanceModule.sol delete mode 100644 contracts/interfaces/IManagerIssuanceHook.sol diff --git a/contracts/extensions/PerpV2LeverageStrategyExtension.sol b/contracts/extensions/PerpV2LeverageStrategyExtension.sol index 9e58d19..a7885c0 100644 --- a/contracts/extensions/PerpV2LeverageStrategyExtension.sol +++ b/contracts/extensions/PerpV2LeverageStrategyExtension.sol @@ -26,16 +26,16 @@ import { SafeCast } from "@openzeppelin/contracts/utils/SafeCast.sol"; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; import { SignedSafeMath } from "@openzeppelin/contracts/math/SignedSafeMath.sol"; -import { IAccountBalance } from "@setprotocol/set-protocol-v2/contracts/interfaces/IAccountBalance.sol"; +import { IAccountBalance } from "@setprotocol/set-protocol-v2/contracts/interfaces/external/perp-v2/IAccountBalance.sol"; import { IPerpV2LeverageModule } from "@setprotocol/set-protocol-v2/contracts/interfaces/IPerpV2LeverageModule.sol"; -import { IPriceFeed } from "@setprotocol/set-protocol-v2/contracts/interfaces/IPriceFeed.sol"; import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; -import { IVault } from "@setprotocol/set-protocol-v2/contracts/interfaces/IVault.sol"; +import { IVault } from "@setprotocol/set-protocol-v2/contracts/interfaces/external/perp-v2/IVault.sol"; import { PreciseUnitMath } from "@setprotocol/set-protocol-v2/contracts/lib/PreciseUnitMath.sol"; -import { StringArrayUtils } from "@setprotocol/set-protocol-v2/contracts/lib/StringArrayUtils.sol"; import { BaseExtension } from "../lib/BaseExtension.sol"; import { IBaseManager } from "../interfaces/IBaseManager.sol"; +import { IPriceFeed } from "../interfaces/IPriceFeed.sol"; +import { StringArrayUtils } from "../lib/StringArrayUtils.sol"; diff --git a/contracts/extensions/StreamingFeeSplitExtension.sol b/contracts/extensions/StreamingFeeSplitExtension.sol index 891764a..d85f553 100644 --- a/contracts/extensions/StreamingFeeSplitExtension.sol +++ b/contracts/extensions/StreamingFeeSplitExtension.sol @@ -23,7 +23,7 @@ import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; -import { IStreamingFeeModule } from "@setprotocol/set-protocol-v2/contracts/interfaces/IStreamingFeeModuleV2.sol"; +import { IStreamingFeeModule } from "@setprotocol/set-protocol-v2/contracts/interfaces/IStreamingFeeModule.sol"; import { PreciseUnitMath } from "@setprotocol/set-protocol-v2/contracts/lib/PreciseUnitMath.sol"; import { BaseGlobalExtension } from "../lib/BaseGlobalExtension.sol"; diff --git a/contracts/hooks/SupplyCapIssuanceHook.sol b/contracts/hooks/SupplyCapIssuanceHook.sol index defbe57..97c88a2 100644 --- a/contracts/hooks/SupplyCapIssuanceHook.sol +++ b/contracts/hooks/SupplyCapIssuanceHook.sol @@ -21,9 +21,9 @@ pragma experimental ABIEncoderV2; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; -import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; -import { IManagerIssuanceHook } from "../interfaces/IManagerIssuanceHook.sol"; +import { IManagerIssuanceHook } from "@setprotocol/set-protocol-v2/contracts/interfaces/IManagerIssuanceHook.sol"; +import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; /** diff --git a/contracts/interfaces/IBasicIssuanceModule.sol b/contracts/interfaces/IBasicIssuanceModule.sol deleted file mode 100644 index 815d9bd..0000000 --- a/contracts/interfaces/IBasicIssuanceModule.sol +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright 2020 Set Labs Inc. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - SPDX-License-Identifier: Apache License, Version 2.0 -*/ -pragma solidity >=0.6.10; - -import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; - -interface IBasicIssuanceModule { - function getRequiredComponentUnitsForIssue( - ISetToken _setToken, - uint256 _quantity - ) external returns(address[] memory, uint256[] memory); - function issue(ISetToken _setToken, uint256 _quantity, address _to) external; - function redeem(ISetToken _token, uint256 _quantity, address _to) external; -} \ No newline at end of file diff --git a/contracts/interfaces/IManagerIssuanceHook.sol b/contracts/interfaces/IManagerIssuanceHook.sol deleted file mode 100644 index f9ec2c4..0000000 --- a/contracts/interfaces/IManagerIssuanceHook.sol +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright 2020 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ -pragma solidity 0.6.10; - -import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; - -interface IManagerIssuanceHook { - function invokePreIssueHook(ISetToken _setToken, uint256 _issueQuantity, address _sender, address _to) external; - function invokePreRedeemHook(ISetToken _setToken, uint256 _redeemQuantity, address _sender, address _to) external; -} \ No newline at end of file diff --git a/contracts/manager/BaseManager.sol b/contracts/manager/BaseManager.sol index e541403..a667e3c 100644 --- a/contracts/manager/BaseManager.sol +++ b/contracts/manager/BaseManager.sol @@ -21,9 +21,10 @@ pragma solidity 0.6.10; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { AddressArrayUtils } from "@setprotocol/set-protocol-v2/contracts/lib/AddressArrayUtils.sol"; -import { IAdapter } from "@setprotocol/set-protocol-v2/contracts/interfaces/IAdapter.sol"; import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; +import { IAdapter } from "../interfaces/IAdapter.sol"; + /** * @title BaseManager diff --git a/test/extensions/issuanceExtension.spec.ts b/test/extensions/issuanceExtension.spec.ts index 7499013..e864990 100644 --- a/test/extensions/issuanceExtension.spec.ts +++ b/test/extensions/issuanceExtension.spec.ts @@ -12,7 +12,7 @@ import { IssuanceExtension, ManagerCore } from "@utils/contracts/index"; -import { SetToken, DebtIssuanceModuleV2 } from "@setprotocol/set-protocol-v2/utils/contracts"; +import { SetToken, IssuanceModule } from "@setprotocol/set-protocol-v2/utils/contracts"; import DeployHelper from "@utils/deploys"; import { addSnapshotBeforeRestoreAfterEach, @@ -36,7 +36,7 @@ describe("IssuanceExtension", () => { let setToken: SetToken; let setV2Setup: SystemFixture; - let issuanceModule: DebtIssuanceModuleV2; + let issuanceModule: IssuanceModule; let managerCore: ManagerCore; let delegatedManager: DelegatedManager; @@ -64,7 +64,7 @@ describe("IssuanceExtension", () => { setV2Setup = getSystemFixture(owner.address); await setV2Setup.initialize(); - issuanceModule = await deployer.setV2.deployDebtIssuanceModuleV2(setV2Setup.controller.address); + issuanceModule = await deployer.setV2.deployIssuanceModule(setV2Setup.controller.address); await setV2Setup.controller.addModule(issuanceModule.address); managerCore = await deployer.managerCore.deployManagerCore(); diff --git a/test/extensions/perpV2LeverageStrategyExtension.spec.ts b/test/extensions/perpV2LeverageStrategyExtension.spec.ts index 964e64c..e6f577c 100644 --- a/test/extensions/perpV2LeverageStrategyExtension.spec.ts +++ b/test/extensions/perpV2LeverageStrategyExtension.spec.ts @@ -67,6 +67,7 @@ describe("PerpV2LeverageStrategyExtension", () => { let customTargetLeverageRatio: any; let customMinLeverageRatio: any; let basePriceDecimalAdjustment: BigNumber; + let maxPerpPositionsPerSet: BigNumber; let leverageStrategyExtension: PerpV2LeverageStrategyExtension; let positionLib: PositionV2; diff --git a/utils/contracts/index.ts b/utils/contracts/index.ts index baa32bc..a42ac51 100644 --- a/utils/contracts/index.ts +++ b/utils/contracts/index.ts @@ -1,6 +1,5 @@ export { BaseExtensionMock } from "../../typechain/BaseExtensionMock"; export { BaseGlobalExtensionMock } from "../../typechain/BaseGlobalExtensionMock"; -export { AddressArrayUtilsMock } from "../../typechain/AddressArrayUtilsMock"; export { BaseManager } from "../..//typechain/BaseManager"; export { ChainlinkAggregatorMock } from "../../typechain/ChainlinkAggregatorMock"; export { DelegatedManager } from "../../typechain/DelegatedManager"; @@ -13,8 +12,8 @@ export { MutualUpgradeV2Mock } from "../../typechain/MutualUpgradeV2Mock"; export { PerpV2LeverageStrategyExtension } from "../../typechain/PerpV2LeverageStrategyExtension"; export { FeeSplitExtension } from "../../typechain/FeeSplitExtension"; export { PerpV2PriceFeedMock } from "../../typechain/PerpV2PriceFeedMock"; -export { StandardTokenMock } from "../../typechain/StandardTokenMock"; -export { StringArrayUtilsMock } from "../../typechain/StringArrayUtilsMock"; +// TODO: remove +// export { StringArrayUtilsMock } from "../../typechain/StringArrayUtilsMock"; export { SupplyCapIssuanceHook } from "../../typechain/SupplyCapIssuanceHook"; export { TradeExtension } from "../../typechain/TradeExtension"; export { IssuanceExtension } from "../../typechain/IssuanceExtension"; diff --git a/utils/deploys/deployMocks.ts b/utils/deploys/deployMocks.ts index fd6f4c2..05c8cb9 100644 --- a/utils/deploys/deployMocks.ts +++ b/utils/deploys/deployMocks.ts @@ -1,23 +1,20 @@ import { Signer, BigNumber } from "ethers"; import { Address } from "../types"; import { - AddressArrayUtilsMock, BaseExtensionMock, BaseGlobalExtensionMock, ManagerMock, ModuleMock, MutualUpgradeMock, - StandardTokenMock, - StringArrayUtilsMock, PerpV2PriceFeedMock } from "../contracts/index"; import { ChainlinkAggregatorMock, - ContractCallerMock + ContractCallerMock, + StandardTokenMock } from "@setprotocol/set-protocol-v2/typechain"; -import { AddressArrayUtilsMock__factory } from "../../typechain/factories/AddressArrayUtilsMock__factory"; import { BaseExtensionMock__factory } from "../../typechain/factories/BaseExtensionMock__factory"; import { BaseGlobalExtensionMock__factory } from "../../typechain/factories/BaseGlobalExtensionMock__factory"; import { ManagerMock__factory } from "../../typechain/factories/ManagerMock__factory"; @@ -27,8 +24,7 @@ import { ContractCallerMock__factory } from "@setprotocol/set-protocol-v2/dist/t import { MutualUpgradeMock__factory } from "../../typechain/factories/MutualUpgradeMock__factory"; import { MutualUpgradeV2Mock__factory } from "../../typechain/factories/MutualUpgradeV2Mock__factory"; import { PerpV2PriceFeedMock__factory } from "../../typechain/factories/PerpV2PriceFeedMock__factory"; -import { StandardTokenMock__factory } from "../../typechain/factories/StandardTokenMock__factory"; -import { StringArrayUtilsMock__factory } from "../../typechain/factories/StringArrayUtilsMock__factory"; +import { StandardTokenMock__factory } from "@setprotocol/set-protocol-v2/dist/typechain"; export default class DeployMocks { private _deployerSigner: Signer; @@ -53,10 +49,6 @@ export default class DeployMocks { return await new ModuleMock__factory(this._deployerSigner).deploy(controller); } - public async deployAddressArrayUtilsMock(): Promise { - return await new AddressArrayUtilsMock__factory(this._deployerSigner).deploy(); - } - public async deployMutualUpgradeMock(owner: Address, methodologist: string): Promise { return await new MutualUpgradeMock__factory(this._deployerSigner).deploy(owner, methodologist); } @@ -79,10 +71,6 @@ export default class DeployMocks { return await new ChainlinkAggregatorMock__factory(this._deployerSigner).deploy(decimals); } - public async deployStringArrayUtilsMock(): Promise { - return await new StringArrayUtilsMock__factory(this._deployerSigner).deploy(); - } - public async deployContractCallerMock(): Promise { return await new ContractCallerMock__factory(this._deployerSigner).deploy(); } diff --git a/utils/deploys/deploySetV2.ts b/utils/deploys/deploySetV2.ts index c6223dc..cf17bc3 100644 --- a/utils/deploys/deploySetV2.ts +++ b/utils/deploys/deploySetV2.ts @@ -6,9 +6,9 @@ import { import { SetToken } from "@setprotocol/set-protocol-v2/typechain/SetToken"; import { SetToken__factory } from "@setprotocol/set-protocol-v2/dist/typechain/factories/SetToken__factory"; import { DebtIssuanceModule } from "@setprotocol/set-protocol-v2/typechain/DebtIssuanceModule"; -import { DebtIssuanceModule__factory } from "@setprotocol/set-protocol-v2/dist/typechain/factories/DebtIssuanceModule__factory"; -import { DebtIssuanceModuleV2 } from "@setprotocol/set-protocol-v2/typechain/DebtIssuanceModuleV2"; -import { DebtIssuanceModuleV2__factory } from "@setprotocol/set-protocol-v2/dist/typechain/factories/DebtIssuanceModuleV2__factory"; +import { DebtIssuanceModule__factory } from "@setprotocol/set-protocol-v2/typechain/factories/DebtIssuanceModule__factory"; +import { IssuanceModule } from "@setprotocol/set-protocol-v2/typechain/IssuanceModule"; +import { IssuanceModule__factory } from "@setprotocol/set-protocol-v2/typechain/factories/IssuanceModule__factory"; export default class DeploySetV2 { private _deployerSigner: Signer; @@ -25,10 +25,10 @@ export default class DeploySetV2 { ); } - public async deployDebtIssuanceModuleV2( + public async deployIssuanceModule( controller: Address, - ): Promise { - return await new DebtIssuanceModuleV2__factory(this._deployerSigner).deploy( + ): Promise { + return await new IssuanceModule__factory(this._deployerSigner).deploy( controller, ); } From ed783ab9b2eb428437aa2bc451d173371d2dfb6a Mon Sep 17 00:00:00 2001 From: cgewecke Date: Fri, 18 Mar 2022 19:05:30 -0700 Subject: [PATCH 3/7] Restore needed interfaces / contracts --- contracts/interfaces/IPriceFeed.sol | 10 ++++ contracts/lib/StringArrayUtils.sol | 61 +++++++++++++++++++++++++ contracts/mocks/PerpV2PriceFeedMock.sol | 50 ++++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 contracts/interfaces/IPriceFeed.sol create mode 100644 contracts/lib/StringArrayUtils.sol create mode 100644 contracts/mocks/PerpV2PriceFeedMock.sol diff --git a/contracts/interfaces/IPriceFeed.sol b/contracts/interfaces/IPriceFeed.sol new file mode 100644 index 0000000..832646f --- /dev/null +++ b/contracts/interfaces/IPriceFeed.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT License +pragma solidity 0.6.10; + +interface IPriceFeed { + function decimals() external view returns (uint8); + + /// @dev Returns the index price of the token. + /// @param interval The interval represents twap interval. + function getPrice(uint256 interval) external view returns (uint256); +} diff --git a/contracts/lib/StringArrayUtils.sol b/contracts/lib/StringArrayUtils.sol new file mode 100644 index 0000000..9ac97f9 --- /dev/null +++ b/contracts/lib/StringArrayUtils.sol @@ -0,0 +1,61 @@ +/* + Copyright 2021 Set Labs Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache License, Version 2.0 +*/ + +pragma solidity 0.6.10; + +/** + * @title StringArrayUtils + * @author Set Protocol + * + * Utility functions to handle String Arrays + */ +library StringArrayUtils { + + /** + * Finds the index of the first occurrence of the given element. + * @param A The input string to search + * @param a The value to find + * @return Returns (index and isIn) for the first occurrence starting from index 0 + */ + function indexOf(string[] memory A, string memory a) internal pure returns (uint256, bool) { + uint256 length = A.length; + for (uint256 i = 0; i < length; i++) { + if (keccak256(bytes(A[i])) == keccak256(bytes(a))) { + return (i, true); + } + } + return (uint256(-1), false); + } + + /** + * @param A The input array to search + * @param a The string to remove + */ + function removeStorage(string[] storage A, string memory a) + internal + { + (uint256 index, bool isIn) = indexOf(A, a); + if (!isIn) { + revert("String not in array."); + } else { + uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here + if (index != lastIndex) { A[index] = A[lastIndex]; } + A.pop(); + } + } +} diff --git a/contracts/mocks/PerpV2PriceFeedMock.sol b/contracts/mocks/PerpV2PriceFeedMock.sol new file mode 100644 index 0000000..b38a567 --- /dev/null +++ b/contracts/mocks/PerpV2PriceFeedMock.sol @@ -0,0 +1,50 @@ +/* + Copyright 2022 Set Labs Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache License, Version 2.0 +*/ + +pragma solidity 0.6.10; + +/** + * Mock PerpV2 Price Feed. + */ +contract PerpV2PriceFeedMock { + uint8 public decimals; + uint256 internal price; + + constructor(uint8 _decimals) public { + decimals = _decimals; + } + + /** + * Typical usage for setting the BaseToken oracle to 100 is: + * + * ``` + * await mockPriceFeed.setPrice(ethers.utils.parseUnits("100", decimals)); + * ``` + */ + function setPrice(uint256 _price) public { + price = _price; + } + + + /** + * Returns the index price of the token. + */ + function getPrice(uint256 /*interval*/) external view returns (uint256) { + return price; + } +} From d7275c9bd1b1708136599dee2bed4209301ac311 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Fri, 18 Mar 2022 19:58:51 -0700 Subject: [PATCH 4/7] Import StringArrayUtils from set-protocol-v2 --- .../PerpV2LeverageStrategyExtension.sol | 3 +- contracts/interfaces/IPriceFeed.sol | 2 +- contracts/lib/StringArrayUtils.sol | 61 ------------------- contracts/mocks/PerpV2PriceFeedMock.sol | 2 +- utils/contracts/index.ts | 2 - 5 files changed, 3 insertions(+), 67 deletions(-) delete mode 100644 contracts/lib/StringArrayUtils.sol diff --git a/contracts/extensions/PerpV2LeverageStrategyExtension.sol b/contracts/extensions/PerpV2LeverageStrategyExtension.sol index a7885c0..d3f020b 100644 --- a/contracts/extensions/PerpV2LeverageStrategyExtension.sol +++ b/contracts/extensions/PerpV2LeverageStrategyExtension.sol @@ -31,12 +31,11 @@ import { IPerpV2LeverageModule } from "@setprotocol/set-protocol-v2/contracts/in import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; import { IVault } from "@setprotocol/set-protocol-v2/contracts/interfaces/external/perp-v2/IVault.sol"; import { PreciseUnitMath } from "@setprotocol/set-protocol-v2/contracts/lib/PreciseUnitMath.sol"; +import { StringArrayUtils } from "@setprotocol/set-protocol-v2/contracts/lib/StringArrayUtils.sol"; import { BaseExtension } from "../lib/BaseExtension.sol"; import { IBaseManager } from "../interfaces/IBaseManager.sol"; import { IPriceFeed } from "../interfaces/IPriceFeed.sol"; -import { StringArrayUtils } from "../lib/StringArrayUtils.sol"; - /** diff --git a/contracts/interfaces/IPriceFeed.sol b/contracts/interfaces/IPriceFeed.sol index 832646f..496d22c 100644 --- a/contracts/interfaces/IPriceFeed.sol +++ b/contracts/interfaces/IPriceFeed.sol @@ -7,4 +7,4 @@ interface IPriceFeed { /// @dev Returns the index price of the token. /// @param interval The interval represents twap interval. function getPrice(uint256 interval) external view returns (uint256); -} +} \ No newline at end of file diff --git a/contracts/lib/StringArrayUtils.sol b/contracts/lib/StringArrayUtils.sol deleted file mode 100644 index 9ac97f9..0000000 --- a/contracts/lib/StringArrayUtils.sol +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright 2021 Set Labs Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - SPDX-License-Identifier: Apache License, Version 2.0 -*/ - -pragma solidity 0.6.10; - -/** - * @title StringArrayUtils - * @author Set Protocol - * - * Utility functions to handle String Arrays - */ -library StringArrayUtils { - - /** - * Finds the index of the first occurrence of the given element. - * @param A The input string to search - * @param a The value to find - * @return Returns (index and isIn) for the first occurrence starting from index 0 - */ - function indexOf(string[] memory A, string memory a) internal pure returns (uint256, bool) { - uint256 length = A.length; - for (uint256 i = 0; i < length; i++) { - if (keccak256(bytes(A[i])) == keccak256(bytes(a))) { - return (i, true); - } - } - return (uint256(-1), false); - } - - /** - * @param A The input array to search - * @param a The string to remove - */ - function removeStorage(string[] storage A, string memory a) - internal - { - (uint256 index, bool isIn) = indexOf(A, a); - if (!isIn) { - revert("String not in array."); - } else { - uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here - if (index != lastIndex) { A[index] = A[lastIndex]; } - A.pop(); - } - } -} diff --git a/contracts/mocks/PerpV2PriceFeedMock.sol b/contracts/mocks/PerpV2PriceFeedMock.sol index b38a567..075aa4c 100644 --- a/contracts/mocks/PerpV2PriceFeedMock.sol +++ b/contracts/mocks/PerpV2PriceFeedMock.sol @@ -47,4 +47,4 @@ contract PerpV2PriceFeedMock { function getPrice(uint256 /*interval*/) external view returns (uint256) { return price; } -} +} \ No newline at end of file diff --git a/utils/contracts/index.ts b/utils/contracts/index.ts index a42ac51..d98c7d7 100644 --- a/utils/contracts/index.ts +++ b/utils/contracts/index.ts @@ -12,8 +12,6 @@ export { MutualUpgradeV2Mock } from "../../typechain/MutualUpgradeV2Mock"; export { PerpV2LeverageStrategyExtension } from "../../typechain/PerpV2LeverageStrategyExtension"; export { FeeSplitExtension } from "../../typechain/FeeSplitExtension"; export { PerpV2PriceFeedMock } from "../../typechain/PerpV2PriceFeedMock"; -// TODO: remove -// export { StringArrayUtilsMock } from "../../typechain/StringArrayUtilsMock"; export { SupplyCapIssuanceHook } from "../../typechain/SupplyCapIssuanceHook"; export { TradeExtension } from "../../typechain/TradeExtension"; export { IssuanceExtension } from "../../typechain/IssuanceExtension"; From 35e5fb8e81fff8407011c664cf9aba72647268a3 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 24 Mar 2022 16:08:35 -0700 Subject: [PATCH 5/7] Fix duplicate var declaration in PerpStrategyAdapter tests --- test/extensions/perpV2LeverageStrategyExtension.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/extensions/perpV2LeverageStrategyExtension.spec.ts b/test/extensions/perpV2LeverageStrategyExtension.spec.ts index e6f577c..964e64c 100644 --- a/test/extensions/perpV2LeverageStrategyExtension.spec.ts +++ b/test/extensions/perpV2LeverageStrategyExtension.spec.ts @@ -67,7 +67,6 @@ describe("PerpV2LeverageStrategyExtension", () => { let customTargetLeverageRatio: any; let customMinLeverageRatio: any; let basePriceDecimalAdjustment: BigNumber; - let maxPerpPositionsPerSet: BigNumber; let leverageStrategyExtension: PerpV2LeverageStrategyExtension; let positionLib: PositionV2; From 66e81170b2a779ae1a86e586691d2a96d0c20b10 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Thu, 24 Mar 2022 16:16:51 -0700 Subject: [PATCH 6/7] Fix additional import paths --- utils/deploys/deploySetV2.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/deploys/deploySetV2.ts b/utils/deploys/deploySetV2.ts index cf17bc3..e2f1955 100644 --- a/utils/deploys/deploySetV2.ts +++ b/utils/deploys/deploySetV2.ts @@ -6,9 +6,9 @@ import { import { SetToken } from "@setprotocol/set-protocol-v2/typechain/SetToken"; import { SetToken__factory } from "@setprotocol/set-protocol-v2/dist/typechain/factories/SetToken__factory"; import { DebtIssuanceModule } from "@setprotocol/set-protocol-v2/typechain/DebtIssuanceModule"; -import { DebtIssuanceModule__factory } from "@setprotocol/set-protocol-v2/typechain/factories/DebtIssuanceModule__factory"; +import { DebtIssuanceModule__factory } from "@setprotocol/set-protocol-v2/dist/typechain/factories/DebtIssuanceModule__factory"; import { IssuanceModule } from "@setprotocol/set-protocol-v2/typechain/IssuanceModule"; -import { IssuanceModule__factory } from "@setprotocol/set-protocol-v2/typechain/factories/IssuanceModule__factory"; +import { IssuanceModule__factory } from "@setprotocol/set-protocol-v2/dist/typechain/factories/IssuanceModule__factory"; export default class DeploySetV2 { private _deployerSigner: Signer; From e9c4a2b736fadebcb355f21182b8bd2a8cf3b18a Mon Sep 17 00:00:00 2001 From: cgewecke Date: Fri, 25 Mar 2022 16:22:38 -0700 Subject: [PATCH 7/7] Fix ManagerFactory IController import --- contracts/factories/DelegatedManagerFactory.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/factories/DelegatedManagerFactory.sol b/contracts/factories/DelegatedManagerFactory.sol index 69cea99..eca3e9c 100644 --- a/contracts/factories/DelegatedManagerFactory.sol +++ b/contracts/factories/DelegatedManagerFactory.sol @@ -22,11 +22,11 @@ pragma experimental ABIEncoderV2; import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { AddressArrayUtils } from "@setprotocol/set-protocol-v2/contracts/lib/AddressArrayUtils.sol"; +import { IController } from "@setprotocol/set-protocol-v2/contracts/interfaces/IController.sol"; import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol"; import { ISetTokenCreator } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetTokenCreator.sol"; import { DelegatedManager } from "../manager/DelegatedManager.sol"; -import { IController } from "../interfaces/IController.sol"; import { IDelegatedManager } from "../interfaces/IDelegatedManager.sol"; import { IManagerCore } from "../interfaces/IManagerCore.sol";