From 04541cc52041e8cdcb13258f7a8063e7f4fe667a Mon Sep 17 00:00:00 2001 From: danoctavian Date: Sat, 26 Aug 2023 09:30:10 +0300 Subject: [PATCH] fix PR issues --- contracts/interfaces/ICoverProducts.sol | 7 +++ .../mocks/Claims/CLMockCoverProducts.sol | 50 ++++++++++++++- .../mocks/Incidents/ICMockCoverProducts.sol | 53 +++++++++++++++- .../StakingPool/SPMockStakingProducts.sol | 14 ++--- .../StakingProductsMockCoverProducts.sol | 62 +++++++++++++++---- .../modules/assessment/IndividualClaims.sol | 3 +- contracts/modules/cover/Cover.sol | 14 +---- contracts/modules/cover/CoverProducts.sol | 27 +++++++- .../modules/legacy/LegacyPooledStaking.sol | 53 ---------------- .../modules/staking/StakingPoolFactory.sol | 2 - contracts/modules/staking/StakingProducts.sol | 16 ++--- contracts/modules/staking/StakingViewer.sol | 4 -- test/integration/setup.js | 8 +-- test/unit/IndividualClaims/setup.js | 5 -- 14 files changed, 200 insertions(+), 118 deletions(-) diff --git a/contracts/interfaces/ICoverProducts.sol b/contracts/interfaces/ICoverProducts.sol index 92c3df3ed0..a37bbfc73f 100644 --- a/contracts/interfaces/ICoverProducts.sol +++ b/contracts/interfaces/ICoverProducts.sol @@ -43,6 +43,8 @@ interface ICoverProducts { function requirePoolIsAllowed(uint[] calldata productIds, uint poolId) external view; + function getProductWithType(uint productId) external view returns (Product memory, ProductType memory); + /* === MUTATIVE FUNCTIONS ==== */ function setProductTypes(ProductTypeParam[] calldata productTypes) external; @@ -76,4 +78,9 @@ interface ICoverProducts { // Misc error CapacityReductionRatioAbove100Percent(); + + function getPriceAndCapacityRatios(uint[] calldata productIds) external view returns ( + uint[] memory _initialPrices, + uint[] memory _capacityReductionRatios + ); } \ No newline at end of file diff --git a/contracts/mocks/Claims/CLMockCoverProducts.sol b/contracts/mocks/Claims/CLMockCoverProducts.sol index 1f2126c5ef..12ab048088 100644 --- a/contracts/mocks/Claims/CLMockCoverProducts.sol +++ b/contracts/mocks/Claims/CLMockCoverProducts.sol @@ -3,10 +3,11 @@ pragma solidity ^0.8.18; import "../../interfaces/ICover.sol"; +import "../../interfaces/ICoverProducts.sol"; import "../../interfaces/ICoverNFT.sol"; -contract CLMockCoverProducts { +contract CLMockCoverProducts is ICoverProducts { Product[] internal _products; mapping(uint => uint) capacityFactors; @@ -37,4 +38,51 @@ contract CLMockCoverProducts { function addProduct(Product calldata product) external { _products.push(product); } + + function productsCount() external view returns (uint) { + return _products.length; + } + + function allowedPoolsCount(uint /* productId */ ) external pure returns (uint) { + revert("Unsupported"); + } + + function isPoolAllowed(uint /* productId */, uint /* poolId */) external pure returns (bool) { + revert("Unsupported"); + } + + function requirePoolIsAllowed(uint[] calldata /* productIds */, uint /* poolId */) external pure { + revert("Unsupported"); + } + + function getProducts() external pure returns (Product[] memory) { + revert("Unsupported"); + } + + function productTypesCount() external pure returns (uint) { + revert("Unsupported"); + } + + function getPriceAndCapacityRatios(uint[] calldata /* productIds */ ) external pure returns ( + uint[] memory /* _initialPrices */, + uint[] memory /* _capacityReductionRatios */ + ) { + revert("Unsupported"); + } + + function productNames(uint /* productId */) external pure returns (string memory) { + revert("Unsupported"); + } + + function getProductWithType(uint /* productId */ ) external pure returns (Product memory, ProductType memory) { + revert("Unsupported"); + } + + function setProductTypes(ProductTypeParam[] calldata /* productTypes */ ) external pure { + revert("Unsupported"); + } + + function setProducts(ProductParam[] calldata /* params */ ) external pure { + revert("Unsupported"); + } } \ No newline at end of file diff --git a/contracts/mocks/Incidents/ICMockCoverProducts.sol b/contracts/mocks/Incidents/ICMockCoverProducts.sol index 7bb458c989..76e3d0db07 100644 --- a/contracts/mocks/Incidents/ICMockCoverProducts.sol +++ b/contracts/mocks/Incidents/ICMockCoverProducts.sol @@ -3,9 +3,10 @@ pragma solidity ^0.8.18; import "../../interfaces/ICover.sol"; +import "../../interfaces/ICoverProducts.sol"; import "../../interfaces/ICoverNFT.sol"; -contract ICMockCoverProducts { +contract ICMockCoverProducts is ICoverProducts { struct BurnStakeCalledWith { uint coverId; @@ -36,6 +37,7 @@ contract ICMockCoverProducts { uint public constant PRICE_CURVE_EXPONENT = 7; uint public constant MAX_PRICE_PERCENTAGE = 1e20; + /* ========== VIEWS ========== */ function products(uint id) external view returns (Product memory) { return _products[id]; @@ -45,6 +47,55 @@ contract ICMockCoverProducts { return _productTypes[id]; } + function productTypesCount() external view returns (uint) { + return _productTypes.length; + } + + function productsCount() public view returns (uint) { + return _products.length; + } + + function getProducts() external view returns (Product[] memory) { + return _products; + } + + function allowedPoolsCount(uint /* productId */) external pure returns (uint) { + revert("Unsupported"); + } + + function getPriceAndCapacityRatios(uint[] calldata /* productIds */ ) external pure returns ( + uint[] memory /* _initialPrices */, + uint[] memory /* _capacityReductionRatios */ + ) { + revert("Unsupported"); + } + + function isPoolAllowed(uint /* productId */, uint /* poolId */) external pure returns (bool) { + revert("Unsupported"); + } + + function productNames(uint /* productId */) external pure returns (string memory) { + revert("Unsupported"); + } + + function getProductWithType(uint productId) external override view returns (Product memory product, ProductType memory) { + product = _products[productId]; + return (product, _productTypes[product.productType]); + } + + + function requirePoolIsAllowed(uint[] calldata /* productIds */, uint /* poolId */ ) external pure { + revert("Unsupported"); + } + + function setProducts(ProductParam[] calldata /* params */ ) external pure { + revert("Unsupported"); + } + + function setProductTypes(ProductTypeParam[] calldata /* productTypes */ ) external pure { + revert("Unsupported"); + } + function addProductType( uint8 claimMethod, uint16 gracePeriod, diff --git a/contracts/mocks/StakingPool/SPMockStakingProducts.sol b/contracts/mocks/StakingPool/SPMockStakingProducts.sol index c9759df795..2af1ee21ea 100644 --- a/contracts/mocks/StakingPool/SPMockStakingProducts.sol +++ b/contracts/mocks/StakingPool/SPMockStakingProducts.sol @@ -47,7 +47,7 @@ contract SPMockStakingProducts is IStakingProducts, MasterAwareV2, Multicall { coverProductsContract = _coverProductsContract; } - function getStakingPool(uint poolId) internal view returns (IStakingPool stakingPoolAddress) { + function stakingPool(uint poolId) public view returns (IStakingPool stakingPoolAddress) { stakingPoolAddress = IStakingPool(StakingPoolLibrary.getAddress(stakingPoolFactory, poolId)); } @@ -82,7 +82,7 @@ contract SPMockStakingProducts is IStakingProducts, MasterAwareV2, Multicall { function recalculateEffectiveWeights(uint poolId, uint[] calldata productIds) external { - IStakingPool _stakingPool = getStakingPool(poolId); + IStakingPool _stakingPool = stakingPool(poolId); ( uint globalCapacityRatio, @@ -115,7 +115,7 @@ contract SPMockStakingProducts is IStakingProducts, MasterAwareV2, Multicall { function setProducts(uint poolId, StakedProductParam[] memory params) external { - IStakingPool _stakingPool = getStakingPool(poolId); + IStakingPool _stakingPool = stakingPool(poolId); if (msg.sender != _stakingPool.manager()) { revert OnlyManager(); @@ -238,7 +238,7 @@ contract SPMockStakingProducts is IStakingProducts, MasterAwareV2, Multicall { uint capacityReductionRatio ) public view returns (uint effectiveWeight) { - IStakingPool _stakingPool = getStakingPool(poolId); + IStakingPool _stakingPool = stakingPool(poolId); return _getEffectiveWeight( _stakingPool, @@ -507,12 +507,6 @@ contract SPMockStakingProducts is IStakingProducts, MasterAwareV2, Multicall { // none :) } - function stakingPool(uint poolId) public view returns (IStakingPool) { - return IStakingPool( - StakingPoolLibrary.getAddress(address(stakingPoolFactory), poolId) - ); - } - function createStakingPool( bool /* isPrivatePool */, uint /* initialPoolFee */, diff --git a/contracts/mocks/StakingProducts/StakingProductsMockCoverProducts.sol b/contracts/mocks/StakingProducts/StakingProductsMockCoverProducts.sol index ceaef1493a..8818f01ba7 100644 --- a/contracts/mocks/StakingProducts/StakingProductsMockCoverProducts.sol +++ b/contracts/mocks/StakingProducts/StakingProductsMockCoverProducts.sol @@ -5,12 +5,13 @@ pragma solidity ^0.8.18; import "../../interfaces/IStakingPool.sol"; import "../../interfaces/ICover.sol"; import "../../interfaces/IStakingProducts.sol"; +import "../../interfaces/ICoverProducts.sol"; import "../../interfaces/IStakingPoolFactory.sol"; -contract StakingProductsMockCoverProducts { +contract StakingProductsMockCoverProducts is ICoverProducts { - mapping(uint => Product) public products; - mapping(uint => ProductType) public productTypes; + mapping(uint => Product) public _products; + mapping(uint => ProductType) public _productTypes; mapping(uint => mapping(uint => bool)) public allowedPools; uint public productsCount; mapping(uint => uint) private _allowedPoolsCount; @@ -21,7 +22,7 @@ contract StakingProductsMockCoverProducts { } function setProduct(Product memory _product, uint id) public { - products[id] = _product; + _products[id] = _product; productsCount++; } @@ -29,15 +30,15 @@ contract StakingProductsMockCoverProducts { return _allowedPoolsCount[productId]; } - function setProducts(Product[] memory _products, uint[] memory productIds) public { - for (uint i = 0; i < _products.length; i++) { - products[productIds[i]] = _products[i]; - productsCount++; - } - } +// function setProducts(Product[] memory newProducts, uint[] memory productIds) public { +// for (uint i = 0; i < newProducts.length; i++) { +// _products[productIds[i]] = newProducts[i]; +// productsCount++; +// } +// } function setProductType(ProductType calldata product, uint id) public { - productTypes[id] = product; + _productTypes[id] = product; } function initializeStaking( @@ -75,4 +76,43 @@ contract StakingProductsMockCoverProducts { } } } + + function products(uint id) external view returns (Product memory) { + return _products[id]; + } + + function productTypes(uint id) external view returns (ProductType memory) { + return _productTypes[id]; + } + + function getProducts() external pure returns (Product[] memory) { + revert("Unsupported"); + } + + function productTypesCount() external pure returns (uint) { + revert("Unsupported"); + } + + function getPriceAndCapacityRatios(uint[] calldata /* productIds */ ) external pure returns ( + uint[] memory /* _initialPrices */, + uint[] memory /* _capacityReductionRatios */ + ) { + revert("Unsupported"); + } + + function productNames(uint /* productId */) external pure returns (string memory) { + revert("Unsupported"); + } + + function getProductWithType(uint /* productId */ ) external pure returns (Product memory, ProductType memory) { + revert("Unsupported"); + } + + function setProductTypes(ProductTypeParam[] calldata /* productTypes */ ) external pure { + revert("Unsupported"); + } + + function setProducts(ProductParam[] calldata /* params */ ) external pure { + revert("Unsupported"); + } } diff --git a/contracts/modules/assessment/IndividualClaims.sol b/contracts/modules/assessment/IndividualClaims.sol index 1e1ba700d6..8855c4691b 100644 --- a/contracts/modules/assessment/IndividualClaims.sol +++ b/contracts/modules/assessment/IndividualClaims.sol @@ -269,8 +269,7 @@ contract IndividualClaims is IIndividualClaims, MasterAwareV2 { CoverSegment memory segment = cover().coverSegmentWithRemainingAmount(coverId, segmentId); { - Product memory product = coverProductsContract.products(coverData.productId); - ProductType memory productType = coverProductsContract.productTypes(product.productType); + (, ProductType memory productType) = coverProductsContract.getProductWithType(coverData.productId); require( productType.claimMethod == uint8(ClaimMethod.IndividualClaims), diff --git a/contracts/modules/cover/Cover.sol b/contracts/modules/cover/Cover.sol index 822c8ad285..5a72ebb39e 100644 --- a/contracts/modules/cover/Cover.sol +++ b/contracts/modules/cover/Cover.sol @@ -28,6 +28,8 @@ contract Cover is ICover, MasterAwareV2, IStakingPoolBeacon, ReentrancyGuard, Mu /* ========== STATE VARIABLES ========== */ + Product[] internal _products; + mapping(uint => CoverData) private _coverData; // cover id => segment id => pool allocations array @@ -658,20 +660,10 @@ contract Cover is ICover, MasterAwareV2, IStakingPoolBeacon, ReentrancyGuard, Mu ) { _globalMinPriceRatio = GLOBAL_MIN_PRICE_RATIO; _globalCapacityRatio = GLOBAL_CAPACITY_RATIO; - _capacityReductionRatios = new uint[](productIds.length); - _initialPrices = new uint[](productIds.length); - ICoverProducts _coverProducts = coverProducts(); - for (uint i = 0; i < productIds.length; i++) { - uint productId = productIds[i]; - if (productId >= _coverProducts.productsCount()) { - revert ProductDoesntExist(); - } + (_initialPrices, _capacityReductionRatios) = _coverProducts.getPriceAndCapacityRatios(productIds); - _initialPrices[i] = uint(_coverProducts.products(productId).initialPriceRatio); - _capacityReductionRatios[i] = uint(_coverProducts.products(productId).capacityReductionRatio); - } } function isCoverAssetSupported(uint assetId, uint productCoverAssetsBitmap) internal view returns (bool) { diff --git a/contracts/modules/cover/CoverProducts.sol b/contracts/modules/cover/CoverProducts.sol index fd1a2381ed..f8ed5c3604 100644 --- a/contracts/modules/cover/CoverProducts.sol +++ b/contracts/modules/cover/CoverProducts.sol @@ -63,7 +63,7 @@ contract CoverProducts is ICoverProducts, MasterAwareV2, Multicall { return _productTypes.length; } - function productsCount() external view returns (uint) { + function productsCount() public view returns (uint) { return _products.length; } @@ -71,6 +71,31 @@ contract CoverProducts is ICoverProducts, MasterAwareV2, Multicall { return _products; } + function getProductWithType(uint productId) external override view returns (Product memory product, ProductType memory) { + product = _products[productId]; + return (product, _productTypes[product.productType]); + } + + function getPriceAndCapacityRatios(uint[] calldata productIds) external view returns ( + uint[] memory _initialPrices, + uint[] memory _capacityReductionRatios + ) { + _capacityReductionRatios = new uint[](productIds.length); + _initialPrices = new uint[](productIds.length); + + for (uint i = 0; i < productIds.length; i++) { + uint productId = productIds[i]; + + uint _productsCount = _products.length; + if (productId >= _productsCount) { + revert ProductDoesntExist(); + } + + _initialPrices[i] = uint(_products[productId].initialPriceRatio); + _capacityReductionRatios[i] = uint(_products[productId].capacityReductionRatio); + } + } + /* ========== PRODUCT CONFIGURATION ========== */ function setProducts(ProductParam[] calldata productParams) external override onlyAdvisoryBoard { diff --git a/contracts/modules/legacy/LegacyPooledStaking.sol b/contracts/modules/legacy/LegacyPooledStaking.sol index 3377a480e2..e0d67bf3f9 100644 --- a/contracts/modules/legacy/LegacyPooledStaking.sol +++ b/contracts/modules/legacy/LegacyPooledStaking.sol @@ -787,57 +787,4 @@ contract LegacyPooledStaking is IPooledStaking, MasterAwareV2, PricesV1 { internalContracts[uint(ID.MR)] = master.getLatestAddress("MR"); internalContracts[uint(ID.TK)] = payable(master.tokenAddress()); } - - function getProducts( - address stakerAddress, - uint deposit - ) internal view returns (ProductInitializationParams[] memory) { - - uint stakedProductsCount = stakers[stakerAddress].contracts.length; - uint migratedProductCount = 0; - - uint[] memory productIds = new uint[](stakedProductsCount); - uint[] memory stakes = new uint[](stakedProductsCount); - uint[] memory prices = new uint[](stakedProductsCount); - - for (uint i = 0; i < stakedProductsCount; i++) { - address productAddress = stakers[stakerAddress].contracts[i]; - - uint productId; - try productsV1.getNewProductId(productAddress) returns (uint id) { - productId = id; - } catch { - continue; - } - - uint stake = stakerContractStake(stakerAddress, productAddress); - if (stake == 0) { - continue; - } - - uint price = getV1PriceForProduct(productId); - if (price == type(uint96).max) { - continue; - } - - productIds[migratedProductCount] = productId; - stakes[migratedProductCount] = stake; - prices[migratedProductCount] = price; - migratedProductCount++; - - } - - ProductInitializationParams[] memory products = new ProductInitializationParams[](migratedProductCount); - - for (uint i = 0; i < migratedProductCount; i++) { - products[i] = ProductInitializationParams( - productIds[i], // productId - uint8(100 * stakes[i] / deposit), // weight (0-100) - uint96(prices[i]), // initialPrice with a 100_00 denominator - uint96(prices[i]) // targetPrice with a 100_00 denominator - ); - } - - return products; - } } diff --git a/contracts/modules/staking/StakingPoolFactory.sol b/contracts/modules/staking/StakingPoolFactory.sol index 40ffda03ba..b9f36ad8c1 100644 --- a/contracts/modules/staking/StakingPoolFactory.sol +++ b/contracts/modules/staking/StakingPoolFactory.sol @@ -13,8 +13,6 @@ contract StakingPoolFactory is IStakingPoolFactory { // temporary beacon address storage to avoid constructor arguments in the proxy address public beacon; - address public coverAddress; - constructor(address _operator) { operator = _operator; } diff --git a/contracts/modules/staking/StakingProducts.sol b/contracts/modules/staking/StakingProducts.sol index 67b0fe6690..4ae5a1f31c 100644 --- a/contracts/modules/staking/StakingProducts.sol +++ b/contracts/modules/staking/StakingProducts.sol @@ -56,10 +56,6 @@ contract StakingProducts is IStakingProducts, MasterAwareV2, Multicall { stakingPoolFactory = _stakingPoolFactory; } - function getStakingPool(uint poolId) internal view returns (IStakingPool stakingPoolAddress) { - stakingPoolAddress = IStakingPool(StakingPoolLibrary.getAddress(stakingPoolFactory, poolId)); - } - function getProductTargetWeight(uint poolId, uint productId) external view override returns (uint) { return uint(_products[poolId][productId].targetWeight); } @@ -91,7 +87,7 @@ contract StakingProducts is IStakingProducts, MasterAwareV2, Multicall { function recalculateEffectiveWeights(uint poolId, uint[] calldata productIds) external { - IStakingPool _stakingPool = getStakingPool(poolId); + IStakingPool _stakingPool = stakingPool(poolId); ( uint globalCapacityRatio, @@ -125,7 +121,7 @@ contract StakingProducts is IStakingProducts, MasterAwareV2, Multicall { function recalculateEffectiveWeightsForAllProducts(uint poolId) external { uint productsCount = coverProducts().productsCount(); - IStakingPool _stakingPool = getStakingPool(poolId); + IStakingPool _stakingPool = stakingPool(poolId); // initialize array for all possible products uint[] memory productIdsRaw = new uint[](productsCount); @@ -177,7 +173,7 @@ contract StakingProducts is IStakingProducts, MasterAwareV2, Multicall { function setProducts(uint poolId, StakedProductParam[] memory params) external { - IStakingPool _stakingPool = getStakingPool(poolId); + IStakingPool _stakingPool = stakingPool(poolId); if (msg.sender != _stakingPool.manager()) { revert OnlyManager(); @@ -325,7 +321,7 @@ contract StakingProducts is IStakingProducts, MasterAwareV2, Multicall { uint capacityReductionRatio ) public view returns (uint effectiveWeight) { - IStakingPool _stakingPool = getStakingPool(poolId); + IStakingPool _stakingPool = stakingPool(poolId); return _getEffectiveWeight( _stakingPool, @@ -676,10 +672,6 @@ contract StakingProducts is IStakingProducts, MasterAwareV2, Multicall { return ITokenController(internalContracts[uint(ID.TC)]); } - function cover() internal view returns (ICover) { - return ICover(coverContract); - } - function coverProducts() internal view returns (ICoverProducts) { return ICoverProducts(getInternalContractAddress(ID.CP)); } diff --git a/contracts/modules/staking/StakingViewer.sol b/contracts/modules/staking/StakingViewer.sol index 4375e28373..1a314e14a6 100644 --- a/contracts/modules/staking/StakingViewer.sol +++ b/contracts/modules/staking/StakingViewer.sol @@ -88,10 +88,6 @@ contract StakingViewer is Multicall { stakingPoolFactory = _stakingPoolFactory; } - function cover() internal view returns (ICover) { - return ICover(master.contractAddresses('CO')); - } - function stakingProducts() internal view returns (IStakingProducts) { return IStakingProducts(master.contractAddresses('SP')); } diff --git a/test/integration/setup.js b/test/integration/setup.js index 5eedd7a6dc..21e2c52265 100644 --- a/test/integration/setup.js +++ b/test/integration/setup.js @@ -172,7 +172,6 @@ async function setup() { // 2. deploy Cover, StakingProducts, CoverProducts and TokenController proxies let cover = await deployProxy('Stub'); let stakingProducts = await deployProxy('Stub'); - let coverProducts = await deployProxy('Stub'); let tc = await deployProxy('Stub'); // 3. deploy StakingPool implementation @@ -186,9 +185,6 @@ async function setup() { await upgradeProxy(stakingProducts.address, 'StakingProducts', [cover.address, spf.address]); stakingProducts = await ethers.getContractAt('StakingProducts', stakingProducts.address); - await upgradeProxy(coverProducts.address, 'CoverProducts', []); - coverProducts = await ethers.getContractAt('CoverProducts', coverProducts.address); - // TODO: get rid of DisposableTokenController and use TokenController instead with owner as operator await upgradeProxy(tc.address, 'DisposableTokenController', [qd.address, lcr.address, spf.address, tk.address]); tc = await ethers.getContractAt('DisposableTokenController', tc.address); @@ -199,12 +195,14 @@ async function setup() { await coverNFT.changeOperator(cover.address); await cover.changeMasterAddress(master.address); await stakingProducts.changeMasterAddress(master.address); - await coverProducts.changeMasterAddress(master.address); const ci = await deployProxy('IndividualClaims', [tk.address, coverNFT.address]); const cg = await deployProxy('YieldTokenIncidents', [tk.address, coverNFT.address]); const as = await deployProxy('Assessment', [tk.address]); const cl = await deployProxy('CoverMigrator', [qd.address, productsV1.address]); + const coverProducts = await deployProxy('CoverProducts'); + + await coverProducts.changeMasterAddress(master.address); const contractType = code => { const upgradable = ['MC', 'P1', 'CR']; diff --git a/test/unit/IndividualClaims/setup.js b/test/unit/IndividualClaims/setup.js index d664dcb331..8a6b9d097d 100644 --- a/test/unit/IndividualClaims/setup.js +++ b/test/unit/IndividualClaims/setup.js @@ -52,10 +52,6 @@ async function setup() { const coverProducts = await CoverProducts.deploy(); await coverProducts.deployed(); - const Distributor = await ethers.getContractFactory('CLMockDistributor'); - const distributor = await Distributor.deploy(individualClaims.address); - await distributor.deployed(); - const masterInitTxs = await Promise.all([ master.setLatestAddress(hex('TC'), tokenController.address), master.setLatestAddress(hex('MR'), memberRoles.address), @@ -125,7 +121,6 @@ async function setup() { assessment, cover, coverProducts, - distributor, coverNFT, master, memberRoles,