From 64dd397c291d0b80550aed58a2776deb62b7077b Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Thu, 15 Aug 2024 14:34:59 +0000 Subject: [PATCH 1/7] add new ObjectType FeeInfo (#599) --- contracts/instance/InstanceStore.sol | 14 ++++++++++++-- contracts/instance/base/ObjectLifecycle.sol | 3 ++- contracts/instance/module/IComponents.sol | 11 ++++++++++- contracts/type/ObjectType.sol | 3 +++ 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/contracts/instance/InstanceStore.sol b/contracts/instance/InstanceStore.sol index f15981dd2..bee011796 100644 --- a/contracts/instance/InstanceStore.sol +++ b/contracts/instance/InstanceStore.sol @@ -7,10 +7,10 @@ import {Amount} from "../type/Amount.sol"; import {Key32} from "../type/Key32.sol"; import {NftId} from "../type/NftId.sol"; import {ClaimId} from "../type/ClaimId.sol"; -import {ObjectType, BUNDLE, POLICY, POOL, PREMIUM, PRODUCT, COMPONENT, DISTRIBUTOR} from "../type/ObjectType.sol"; +import {ObjectType, BUNDLE, POLICY, POOL, PREMIUM, PRODUCT, COMPONENT, DISTRIBUTOR, FEE} from "../type/ObjectType.sol"; import {RequestId} from "../type/RequestId.sol"; import {RiskId} from "../type/RiskId.sol"; -import {StateId} from "../type/StateId.sol"; +import {StateId, KEEP_STATE} from "../type/StateId.sol"; import {ReferralId} from "../type/Referral.sol"; import {DistributorType} from "../type/DistributorType.sol"; import {PayoutId} from "../type/PayoutId.sol"; @@ -85,6 +85,16 @@ contract InstanceStore is _update(_toNftKey32(productNftId, PRODUCT()), abi.encode(info), newState); } + + //--- Fee -----------------------------------------------------------// + function createFee(NftId productNftId, IComponents.FeeInfo memory info) external restricted() { + _create(_toNftKey32(productNftId, FEE()), abi.encode(info)); + } + + function updateFee(NftId productNftId, IComponents.FeeInfo memory info) external restricted() { + _update(_toNftKey32(productNftId, FEE()), abi.encode(info), KEEP_STATE()); + } + //--- Pool --------------------------------------------------------------// function createPool( diff --git a/contracts/instance/base/ObjectLifecycle.sol b/contracts/instance/base/ObjectLifecycle.sol index 8736ace38..6eafb5dc2 100644 --- a/contracts/instance/base/ObjectLifecycle.sol +++ b/contracts/instance/base/ObjectLifecycle.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.20; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import {COMPONENT, BUNDLE, POLICY, REQUEST, RISK, CLAIM, PAYOUT, POOL, PREMIUM, PRODUCT, DISTRIBUTION, DISTRIBUTOR, DISTRIBUTOR_TYPE, REFERRAL} from "../../type/ObjectType.sol"; +import {COMPONENT, BUNDLE, POLICY, REQUEST, RISK, CLAIM, PAYOUT, POOL, PREMIUM, PRODUCT, DISTRIBUTION, DISTRIBUTOR, DISTRIBUTOR_TYPE, REFERRAL, FEE} from "../../type/ObjectType.sol"; import {ACTIVE, PAUSED, ARCHIVED, CLOSED, APPLIED, COLLATERALIZED, REVOKED, SUBMITTED, CONFIRMED, DECLINED, EXPECTED, PAID, FULFILLED, FAILED, CANCELLED} from "../../type/StateId.sol"; import {Lifecycle} from "../../shared/Lifecycle.sol"; @@ -99,6 +99,7 @@ contract ObjectLifecycle is // dummy lifecycle only function _setUpProductLifecycle() private { setInitialState(PRODUCT(), ACTIVE()); + setInitialState(FEE(), ACTIVE()); } // dummy lifecycles only diff --git a/contracts/instance/module/IComponents.sol b/contracts/instance/module/IComponents.sol index 7a17fc61e..901f6b142 100644 --- a/contracts/instance/module/IComponents.sol +++ b/contracts/instance/module/IComponents.sol @@ -6,7 +6,6 @@ import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IER import {Amount} from "../../type/Amount.sol"; import {Fee} from "../../type/Fee.sol"; import {NftId} from "../../type/NftId.sol"; -import {RoleId} from "../../type/RoleId.sol"; import {TokenHandler} from "../../shared/TokenHandler.sol"; import {UFixed} from "../../type/UFixed.sol"; @@ -28,6 +27,7 @@ interface IComponents { NftId poolNftId; // mandatory NftId distributionNftId; // 0..1 (optional) NftId [] oracleNftId; // 0..n (optional) + // TODO: remove those fields Fee productFee; // product fee on net premium Fee processingFee; // product fee on payout amounts Fee distributionFee; // distribution fee for sales that do not include commissions @@ -37,6 +37,15 @@ interface IComponents { Fee performanceFee; // pool fee on profits from capital investors } + struct FeeInfo { + Fee productFee; // product fee on net premium + Fee processingFee; // product fee on payout amounts + Fee distributionFee; // distribution fee for sales that do not include commissions + Fee minDistributionOwnerFee; // min fee required by distribution owner (not including commissions for distributors) + Fee poolFee; // pool fee on net premium + Fee stakingFee; // pool fee on staked capital from investor + Fee performanceFee; // pool fee on profits from capital investors + } struct PoolInfo { Amount maxBalanceAmount; // max balance amount allowed for pool diff --git a/contracts/type/ObjectType.sol b/contracts/type/ObjectType.sol index dafd95e78..f2831dc81 100644 --- a/contracts/type/ObjectType.sol +++ b/contracts/type/ObjectType.sol @@ -125,6 +125,9 @@ function ACCOUNTING() pure returns (ObjectType) { return ObjectType.wrap(34); } +function FEE() pure returns (ObjectType) { + return ObjectType.wrap(35); +} /// @dev Object type that includes any other object type. /// Note that eq()/'==' does not take this property into account. From bad4ad5a3c93b1905c7f4d0b1b1e5fef96dfd408 Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Thu, 15 Aug 2024 14:40:56 +0000 Subject: [PATCH 2/7] add read method for feeinfo object (#599) --- contracts/instance/InstanceReader.sol | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/contracts/instance/InstanceReader.sol b/contracts/instance/InstanceReader.sol index cfd9c285f..2477f9aa9 100644 --- a/contracts/instance/InstanceReader.sol +++ b/contracts/instance/InstanceReader.sol @@ -6,7 +6,7 @@ import {ClaimId, ClaimIdLib} from "../type/ClaimId.sol"; import {DistributorType} from "../type/DistributorType.sol"; import {Key32} from "../type/Key32.sol"; import {NftId} from "../type/NftId.sol"; -import {COMPONENT, DISTRIBUTOR, DISTRIBUTION, PREMIUM, PRODUCT, POLICY, POOL, BUNDLE} from "../type/ObjectType.sol"; +import {COMPONENT, DISTRIBUTOR, DISTRIBUTION, FEE, PREMIUM, PRODUCT, POLICY, POOL, BUNDLE} from "../type/ObjectType.sol"; import {PayoutId, PayoutIdLib} from "../type/PayoutId.sol"; import {ReferralId, ReferralStatus, ReferralLib, REFERRAL_OK, REFERRAL_ERROR_UNKNOWN, REFERRAL_ERROR_EXPIRED, REFERRAL_ERROR_EXHAUSTED} from "../type/Referral.sol"; import {RequestId} from "../type/RequestId.sol"; @@ -408,6 +408,17 @@ contract InstanceReader { } } + function getFeeInfo(NftId productNftId) + public + view + returns (IComponents.FeeInfo memory feeInfo) + { + bytes memory data = _store.getData(toFeeKey(productNftId)); + if (data.length > 0) { + return abi.decode(data, (IComponents.FeeInfo)); + } + } + function getPoolInfo(NftId poolNftId) public view @@ -554,6 +565,10 @@ contract InstanceReader { return productNftId.toKey32(PRODUCT()); } + function toFeeKey(NftId productNftId) public pure returns (Key32) { + return productNftId.toKey32(FEE()); + } + // low level function function getInstance() external view returns (IInstance instance) { return _instance; From 5f48c72cd38b57f7c19aa1fd924939bfd1ae9105 Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Thu, 15 Aug 2024 15:41:34 +0000 Subject: [PATCH 3/7] use FeeInfo instead of ProductInfo for fees (#599) --- .../distribution/DistributionService.sol | 6 +- contracts/examples/fire/FireProduct.sol | 4 +- .../examples/unpermissioned/SimpleProduct.sol | 4 ++ contracts/instance/InstanceStore.sol | 1 + contracts/instance/module/IComponents.sol | 8 --- contracts/pool/PoolService.sol | 2 +- contracts/product/BasicProduct.sol | 2 + contracts/product/ClaimService.sol | 4 +- contracts/product/PricingService.sol | 33 +++++----- contracts/product/Product.sol | 12 ++++ contracts/shared/ComponentService.sol | 60 +++++++++---------- 11 files changed, 76 insertions(+), 60 deletions(-) diff --git a/contracts/distribution/DistributionService.sol b/contracts/distribution/DistributionService.sol index 803a6196e..b1ab3c444 100644 --- a/contracts/distribution/DistributionService.sol +++ b/contracts/distribution/DistributionService.sol @@ -77,10 +77,10 @@ contract DistributionService is { NftId productNftId = _getProductNftId(distributionNftId); - IComponents.ProductInfo memory productInfo = instance.getInstanceReader().getProductInfo(productNftId); + IComponents.FeeInfo memory feeInfo = instance.getInstanceReader().getFeeInfo(productNftId); - UFixed variableDistributionFees = productInfo.distributionFee.fractionalFee; - UFixed variableFeesPartsTotal = productInfo.minDistributionOwnerFee.fractionalFee + commissionPercentage; + UFixed variableDistributionFees = feeInfo.distributionFee.fractionalFee; + UFixed variableFeesPartsTotal = feeInfo.minDistributionOwnerFee.fractionalFee + commissionPercentage; if (variableFeesPartsTotal > variableDistributionFees) { revert ErrorDistributionServiceVariableFeesTooHight(variableDistributionFees.toInt1000(), variableFeesPartsTotal.toInt1000()); diff --git a/contracts/examples/fire/FireProduct.sol b/contracts/examples/fire/FireProduct.sol index e4aec27b8..528c82cf8 100644 --- a/contracts/examples/fire/FireProduct.sol +++ b/contracts/examples/fire/FireProduct.sol @@ -107,7 +107,9 @@ contract FireProduct is numberOfOracles: 0, poolNftId: NftIdLib.zero(), distributionNftId: NftIdLib.zero(), - oracleNftId: new NftId[](0), + oracleNftId: new NftId[](0) + }), + IComponents.FeeInfo({ productFee: FeeLib.zero(), processingFee: FeeLib.zero(), distributionFee: FeeLib.zero(), diff --git a/contracts/examples/unpermissioned/SimpleProduct.sol b/contracts/examples/unpermissioned/SimpleProduct.sol index 5fe7977b6..816b730a1 100644 --- a/contracts/examples/unpermissioned/SimpleProduct.sol +++ b/contracts/examples/unpermissioned/SimpleProduct.sol @@ -39,6 +39,7 @@ contract SimpleProduct is string memory name, address token, IComponents.ProductInfo memory productInfo, + IComponents.FeeInfo memory feeInfo, IAuthorization authorization, address initialOwner ) @@ -49,6 +50,7 @@ contract SimpleProduct is name, token, productInfo, + feeInfo, authorization, initialOwner); } @@ -60,6 +62,7 @@ contract SimpleProduct is string memory name, address token, IComponents.ProductInfo memory productInfo, + IComponents.FeeInfo memory feeInfo, IAuthorization authorization, address initialOwner ) @@ -73,6 +76,7 @@ contract SimpleProduct is name, token, productInfo, + feeInfo, authorization, initialOwner); diff --git a/contracts/instance/InstanceStore.sol b/contracts/instance/InstanceStore.sol index bee011796..cabdefb2f 100644 --- a/contracts/instance/InstanceStore.sol +++ b/contracts/instance/InstanceStore.sol @@ -91,6 +91,7 @@ contract InstanceStore is _create(_toNftKey32(productNftId, FEE()), abi.encode(info)); } + // Fee only has one state, so no change change possible function updateFee(NftId productNftId, IComponents.FeeInfo memory info) external restricted() { _update(_toNftKey32(productNftId, FEE()), abi.encode(info), KEEP_STATE()); } diff --git a/contracts/instance/module/IComponents.sol b/contracts/instance/module/IComponents.sol index 901f6b142..ec02f93a5 100644 --- a/contracts/instance/module/IComponents.sol +++ b/contracts/instance/module/IComponents.sol @@ -27,14 +27,6 @@ interface IComponents { NftId poolNftId; // mandatory NftId distributionNftId; // 0..1 (optional) NftId [] oracleNftId; // 0..n (optional) - // TODO: remove those fields - Fee productFee; // product fee on net premium - Fee processingFee; // product fee on payout amounts - Fee distributionFee; // distribution fee for sales that do not include commissions - Fee minDistributionOwnerFee; // min fee required by distribution owner (not including commissions for distributors) - Fee poolFee; // pool fee on net premium - Fee stakingFee; // pool fee on staked capital from investor - Fee performanceFee; // pool fee on profits from capital investors } struct FeeInfo { diff --git a/contracts/pool/PoolService.sol b/contracts/pool/PoolService.sol index 5c0f33677..7e10d1639 100644 --- a/contracts/pool/PoolService.sol +++ b/contracts/pool/PoolService.sol @@ -175,7 +175,7 @@ contract PoolService is { NftId productNftId = registry.getObjectInfo(poolNftId).parentNftId; - Fee memory stakingFee = instanceReader.getProductInfo(productNftId).stakingFee; + Fee memory stakingFee = instanceReader.getFeeInfo(productNftId).stakingFee; ( feeAmount, netAmount diff --git a/contracts/product/BasicProduct.sol b/contracts/product/BasicProduct.sol index e6289b5fb..81f869213 100644 --- a/contracts/product/BasicProduct.sol +++ b/contracts/product/BasicProduct.sol @@ -29,6 +29,7 @@ abstract contract BasicProduct is string memory name, address token, IComponents.ProductInfo memory productInfo, + IComponents.FeeInfo memory feeInfo, IAuthorization authorization, address initialOwner ) @@ -42,6 +43,7 @@ abstract contract BasicProduct is name, token, productInfo, + feeInfo, authorization, initialOwner, ""); // component data diff --git a/contracts/product/ClaimService.sol b/contracts/product/ClaimService.sol index a796961d8..752611f02 100644 --- a/contracts/product/ClaimService.sol +++ b/contracts/product/ClaimService.sol @@ -490,8 +490,8 @@ contract ClaimService is beneficiary = payoutInfo.beneficiary; } - IComponents.ProductInfo memory productInfo = instanceReader.getProductInfo(productNftId); - if(FeeLib.gtz(productInfo.processingFee)) { + IComponents.FeeInfo memory feeInfo = instanceReader.getFeeInfo(productNftId); + if(FeeLib.gtz(feeInfo.processingFee)) { // TODO calculate and set net payout and processing fees } } diff --git a/contracts/product/PricingService.sol b/contracts/product/PricingService.sol index afe6392f2..250f5e253 100644 --- a/contracts/product/PricingService.sol +++ b/contracts/product/PricingService.sol @@ -98,6 +98,7 @@ contract PricingService is { // get configurations for all involed objects IComponents.ProductInfo memory productInfo = reader.getProductInfo(productNftId); + IComponents.FeeInfo memory feeInfo = reader.getFeeInfo(productNftId); IBundle.BundleInfo memory bundleInfo = reader.getBundleInfo(bundleNftId); if(bundleInfo.poolNftId != productInfo.poolNftId) { @@ -107,21 +108,22 @@ contract PricingService is // calculate fixed fees for product, pool, bundle premium = _getFixedFeeAmounts( netPremiumAmount, - productInfo, + feeInfo, bundleInfo ); // calculate variable fees for product, pool, bundle premium = _calculateVariableFeeAmounts( premium, - productInfo, + feeInfo, bundleInfo ); // calculate distribution fee and (if applicable) commission premium = _calculateDistributionOwnerFeeAmount( premium, - productInfo, + feeInfo, + productInfo.distributionNftId, referralId, reader ); @@ -137,7 +139,7 @@ contract PricingService is revert ErrorPricingServiceTargetWalletAmountsMismatch(); } - if (premium.distributionOwnerFeeFixAmount.toInt() < productInfo.minDistributionOwnerFee.fixedFee) { + if (premium.distributionOwnerFeeFixAmount.toInt() < feeInfo.minDistributionOwnerFee.fixedFee) { revert ErrorPricingServiceFeeCalculationMismatch( premium.distributionFeeFixAmount, premium.distributionFeeVarAmount, @@ -164,7 +166,7 @@ contract PricingService is // internal functions function _getFixedFeeAmounts( Amount netPremiumAmount, - IComponents.ProductInfo memory productInfo, + IComponents.FeeInfo memory feeInfo, IBundle.BundleInfo memory bundleInfo ) internal @@ -177,11 +179,11 @@ contract PricingService is premium.netPremiumAmount = netPremiumAmount; premium.fullPremiumAmount = netPremiumAmount; - Amount t = AmountLib.toAmount(productInfo.productFee.fixedFee); + Amount t = AmountLib.toAmount(feeInfo.productFee.fixedFee); premium.productFeeFixAmount = t; premium.fullPremiumAmount = premium.fullPremiumAmount + t; - t = AmountLib.toAmount(productInfo.poolFee.fixedFee); + t = AmountLib.toAmount(feeInfo.poolFee.fixedFee); premium.poolFeeFixAmount = t; premium.fullPremiumAmount = premium.fullPremiumAmount + t; @@ -189,14 +191,14 @@ contract PricingService is premium.bundleFeeFixAmount = t; premium.fullPremiumAmount = premium.fullPremiumAmount + t; - t = AmountLib.toAmount(productInfo.distributionFee.fixedFee); + t = AmountLib.toAmount(feeInfo.distributionFee.fixedFee); premium.distributionFeeFixAmount = t; premium.fullPremiumAmount = premium.fullPremiumAmount + t; } function _calculateVariableFeeAmounts( IPolicy.PremiumInfo memory premium, - IComponents.ProductInfo memory productInfo, + IComponents.FeeInfo memory feeInfo, IBundle.BundleInfo memory bundleInfo ) internal @@ -207,11 +209,11 @@ contract PricingService is { Amount netPremiumAmount = premium.netPremiumAmount; - Amount t = netPremiumAmount.multiplyWith(productInfo.productFee.fractionalFee); + Amount t = netPremiumAmount.multiplyWith(feeInfo.productFee.fractionalFee); premium.productFeeVarAmount = t; premium.fullPremiumAmount = premium.fullPremiumAmount + t; - t = netPremiumAmount.multiplyWith(productInfo.poolFee.fractionalFee); + t = netPremiumAmount.multiplyWith(feeInfo.poolFee.fractionalFee); premium.poolFeeVarAmount = t; premium.fullPremiumAmount = premium.fullPremiumAmount + t; @@ -219,7 +221,7 @@ contract PricingService is premium.bundleFeeVarAmount = t; premium.fullPremiumAmount = premium.fullPremiumAmount + t; - t = netPremiumAmount.multiplyWith(productInfo.distributionFee.fractionalFee); + t = netPremiumAmount.multiplyWith(feeInfo.distributionFee.fractionalFee); premium.distributionFeeVarAmount = t; premium.fullPremiumAmount = premium.fullPremiumAmount + t; @@ -228,7 +230,8 @@ contract PricingService is function _calculateDistributionOwnerFeeAmount( IPolicy.PremiumInfo memory premium, - IComponents.ProductInfo memory productInfo, + IComponents.FeeInfo memory feeInfo, + NftId distributionNftId, // ISetup.DistributionSetupInfo memory distInfo, ReferralId referralId, InstanceReader reader @@ -239,14 +242,14 @@ contract PricingService is { // if the referral is not valid, then the distribution owner gets everything - if (productInfo.distributionNftId.eqz() || ! _distributionService.referralIsValid(productInfo.distributionNftId, referralId)) { + if (distributionNftId.eqz() || ! _distributionService.referralIsValid(distributionNftId, referralId)) { premium.distributionOwnerFeeFixAmount = premium.distributionFeeFixAmount; premium.distributionOwnerFeeVarAmount = premium.distributionFeeVarAmount; premium.premiumAmount = premium.fullPremiumAmount; return premium; } - Fee memory minDistributionOwnerFee = productInfo.minDistributionOwnerFee; + Fee memory minDistributionOwnerFee = feeInfo.minDistributionOwnerFee; // if the referral is valid, the the commission and discount are calculated based in the full premium // the remaing amount goes to the distribution owner diff --git a/contracts/product/Product.sol b/contracts/product/Product.sol index 1f42fb52a..982da79f6 100644 --- a/contracts/product/Product.sol +++ b/contracts/product/Product.sol @@ -41,6 +41,7 @@ abstract contract Product is struct ProductStorage { IComponents.ProductInfo _productInfo; + IComponents.FeeInfo _feeInfo; IComponentService _componentService; IRiskService _riskService; IApplicationService _applicationService; @@ -126,6 +127,15 @@ abstract contract Product is return _getProductStorage()._productInfo; } + function getInitialFeeInfo() + public + virtual + view + returns (IComponents.FeeInfo memory feeInfo) + { + return _getProductStorage()._feeInfo; + } + function _initializeProduct( address registry, @@ -133,6 +143,7 @@ abstract contract Product is string memory name, address token, IComponents.ProductInfo memory productInfo, + IComponents.FeeInfo memory feeInfo, IAuthorization authorization, address initialOwner, bytes memory componentData // writeonly data that will saved in the object info record of the registry @@ -154,6 +165,7 @@ abstract contract Product is ProductStorage storage $ = _getProductStorage(); $._productInfo = productInfo; + $._feeInfo = feeInfo; $._riskService = IRiskService(_getServiceAddress(RISK())); $._applicationService = IApplicationService(_getServiceAddress(APPLICATION())); $._policyService = IPolicyService(_getServiceAddress(POLICY())); diff --git a/contracts/shared/ComponentService.sol b/contracts/shared/ComponentService.sol index 09dfb8769..5378cfd25 100644 --- a/contracts/shared/ComponentService.sol +++ b/contracts/shared/ComponentService.sol @@ -256,25 +256,25 @@ contract ComponentService is nonReentrant() { (NftId productNftId, IInstance instance) = _getAndVerifyActiveComponent(PRODUCT()); - IComponents.ProductInfo memory productInfo = instance.getInstanceReader().getProductInfo(productNftId); + IComponents.FeeInfo memory feeInfo = instance.getInstanceReader().getFeeInfo(productNftId); bool feesChanged = false; // update product fee if required - if(!FeeLib.eq(productInfo.productFee, productFee)) { - _logUpdateFee(productNftId, "ProductFee", productInfo.productFee, productFee); - productInfo.productFee = productFee; + if(!FeeLib.eq(feeInfo.productFee, productFee)) { + _logUpdateFee(productNftId, "ProductFee", feeInfo.productFee, productFee); + feeInfo.productFee = productFee; feesChanged = true; } // update processing fee if required - if(!FeeLib.eq(productInfo.processingFee, processingFee)) { - _logUpdateFee(productNftId, "ProcessingFee", productInfo.processingFee, processingFee); - productInfo.processingFee = processingFee; + if(!FeeLib.eq(feeInfo.processingFee, processingFee)) { + _logUpdateFee(productNftId, "ProcessingFee", feeInfo.processingFee, processingFee); + feeInfo.processingFee = processingFee; feesChanged = true; } if(feesChanged) { - instance.getInstanceStore().updateProduct(productNftId, productInfo, KEEP_STATE()); + instance.getInstanceStore().updateFee(productNftId, feeInfo); emit LogComponentServiceProductFeesUpdated(productNftId); } } @@ -324,26 +324,26 @@ contract ComponentService is virtual { (NftId distributionNftId, IInstance instance) = _getAndVerifyActiveComponent(DISTRIBUTION()); - (NftId productNftId, IComponents.ProductInfo memory productInfo) = _getLinkedProductInfo( + (NftId productNftId, IComponents.FeeInfo memory feeInfo) = _getLinkedFeeInfo( instance.getInstanceReader(), distributionNftId); bool feesChanged = false; // update distributino fee if required - if(!FeeLib.eq(productInfo.distributionFee, distributionFee)) { - _logUpdateFee(productNftId, "DistributionFee", productInfo.distributionFee, distributionFee); - productInfo.distributionFee = distributionFee; + if(!FeeLib.eq(feeInfo.distributionFee, distributionFee)) { + _logUpdateFee(productNftId, "DistributionFee", feeInfo.distributionFee, distributionFee); + feeInfo.distributionFee = distributionFee; feesChanged = true; } // update min distribution owner fee if required - if(!FeeLib.eq(productInfo.minDistributionOwnerFee, minDistributionOwnerFee)) { - _logUpdateFee(productNftId, "MinDistributionOwnerFee", productInfo.minDistributionOwnerFee, minDistributionOwnerFee); - productInfo.minDistributionOwnerFee = minDistributionOwnerFee; + if(!FeeLib.eq(feeInfo.minDistributionOwnerFee, minDistributionOwnerFee)) { + _logUpdateFee(productNftId, "MinDistributionOwnerFee", feeInfo.minDistributionOwnerFee, minDistributionOwnerFee); + feeInfo.minDistributionOwnerFee = minDistributionOwnerFee; feesChanged = true; } if(feesChanged) { - instance.getInstanceStore().updateProduct(productNftId, productInfo, KEEP_STATE()); + instance.getInstanceStore().updateFee(productNftId, feeInfo); emit LogComponentServiceDistributionFeesUpdated(distributionNftId); } } @@ -432,33 +432,33 @@ contract ComponentService is { (NftId poolNftId, IInstance instance) = _getAndVerifyActiveComponent(POOL()); - (NftId productNftId, IComponents.ProductInfo memory productInfo) = _getLinkedProductInfo( + (NftId productNftId, IComponents.FeeInfo memory feeInfo) = _getLinkedFeeInfo( instance.getInstanceReader(), poolNftId); bool feesChanged = false; // update pool fee if required - if(!FeeLib.eq(productInfo.poolFee, poolFee)) { - _logUpdateFee(productNftId, "PoolFee", productInfo.poolFee, poolFee); - productInfo.poolFee = poolFee; + if(!FeeLib.eq(feeInfo.poolFee, poolFee)) { + _logUpdateFee(productNftId, "PoolFee", feeInfo.poolFee, poolFee); + feeInfo.poolFee = poolFee; feesChanged = true; } // update staking fee if required - if(!FeeLib.eq(productInfo.stakingFee, stakingFee)) { - _logUpdateFee(productNftId, "StakingFee", productInfo.stakingFee, stakingFee); - productInfo.stakingFee = stakingFee; + if(!FeeLib.eq(feeInfo.stakingFee, stakingFee)) { + _logUpdateFee(productNftId, "StakingFee", feeInfo.stakingFee, stakingFee); + feeInfo.stakingFee = stakingFee; feesChanged = true; } // update performance fee if required - if(!FeeLib.eq(productInfo.performanceFee, performanceFee)) { - _logUpdateFee(productNftId, "PerformanceFee", productInfo.performanceFee, performanceFee); - productInfo.performanceFee = performanceFee; + if(!FeeLib.eq(feeInfo.performanceFee, performanceFee)) { + _logUpdateFee(productNftId, "PerformanceFee", feeInfo.performanceFee, performanceFee); + feeInfo.performanceFee = performanceFee; feesChanged = true; } if(feesChanged) { - instance.getInstanceStore().updateProduct(productNftId, productInfo, KEEP_STATE()); + instance.getInstanceStore().updateFee(productNftId, feeInfo); emit LogComponentServicePoolFeesUpdated(poolNftId); } } @@ -547,7 +547,7 @@ contract ComponentService is } - function _getLinkedProductInfo( + function _getLinkedFeeInfo( InstanceReader instanceReader, NftId componentNftId ) @@ -555,11 +555,11 @@ contract ComponentService is view returns( NftId productNftId, - IComponents.ProductInfo memory info + IComponents.FeeInfo memory info ) { productNftId = getRegistry().getObjectInfo(componentNftId).parentNftId; - info = instanceReader.getProductInfo(productNftId); + info = instanceReader.getFeeInfo(productNftId); } From 9ead3c7aa94a5ea6bb234610268aec9053c5a3cf Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Thu, 15 Aug 2024 16:23:30 +0000 Subject: [PATCH 4/7] fix feeinfo setup and tests (#599) --- contracts/instance/InstanceAuthorizationV3.sol | 2 ++ contracts/product/IProductComponent.sol | 5 ++++- contracts/shared/ComponentService.sol | 3 +++ test/TestDistribution.t.sol | 12 ++++++------ test/TestPool.t.sol | 16 ++++++++-------- test/TestProduct.t.sol | 17 +++++++++-------- test/base/GifTest.sol | 12 +++++++++++- test/component/pool/PoolRegistration.t.sol | 3 +++ .../component/product/ProductRegistration.t.sol | 5 +++++ .../composeability/ProductWithReinsurance.sol | 2 ++ .../composeability/ProductWithReinsurance.t.sol | 2 ++ .../external/ExternallyManagedPool.t.sol | 2 ++ .../external/ExternallyManagedProduct.sol | 2 ++ test/examples/verifying/VerifyingPool.t.sol | 2 ++ test/examples/verifying/VerifyingProduct.sol | 2 ++ 15 files changed, 63 insertions(+), 24 deletions(-) diff --git a/contracts/instance/InstanceAuthorizationV3.sol b/contracts/instance/InstanceAuthorizationV3.sol index b72796b12..989b4351d 100644 --- a/contracts/instance/InstanceAuthorizationV3.sol +++ b/contracts/instance/InstanceAuthorizationV3.sol @@ -160,6 +160,8 @@ contract InstanceAuthorizationV3 _authorize(functions, InstanceStore.createPool.selector, "createPool"); _authorize(functions, InstanceStore.createProduct.selector, "createProduct"); _authorize(functions, InstanceStore.updateProduct.selector, "updateProduct"); + _authorize(functions, InstanceStore.createFee.selector, "createFee"); + _authorize(functions, InstanceStore.updateFee.selector, "updateFee"); // authorize distribution service role functions = _authorizeForTarget(INSTANCE_STORE_TARGET_NAME, getServiceRole(DISTRIBUTION())); diff --git a/contracts/product/IProductComponent.sol b/contracts/product/IProductComponent.sol index bf3bdd846..ffb63ea0b 100644 --- a/contracts/product/IProductComponent.sol +++ b/contracts/product/IProductComponent.sol @@ -53,7 +53,10 @@ interface IProductComponent is ) external view returns (Amount netPremiumAmount); - /// @dev returns initial pool specific infos for this pool + /// @dev returns initial product specific infos function getInitialProductInfo() external view returns (IComponents.ProductInfo memory info); + + /// @dev returns initial fee infos + function getInitialFeeInfo() external view returns (IComponents.FeeInfo memory info); } diff --git a/contracts/shared/ComponentService.sol b/contracts/shared/ComponentService.sol index 5378cfd25..c94b68a5a 100644 --- a/contracts/shared/ComponentService.sol +++ b/contracts/shared/ComponentService.sol @@ -241,6 +241,9 @@ contract ComponentService is instanceStore.createProduct( productNftId, product.getInitialProductInfo()); + instanceStore.createFee( + productNftId, + product.getInitialFeeInfo()); // authorize instanceAdmin.initializeComponentAuthorization(product); diff --git a/test/TestDistribution.t.sol b/test/TestDistribution.t.sol index 1eaaac331..f2a0b8d97 100644 --- a/test/TestDistribution.t.sol +++ b/test/TestDistribution.t.sol @@ -29,13 +29,13 @@ contract TestDistribution is GifTest { function test_distributionSetFees() public { // GIVEN - just setUp - IComponents.ProductInfo memory productInfo = instanceReader.getProductInfo(productNftId); + IComponents.FeeInfo memory feeInfo = instanceReader.getFeeInfo(productNftId); - Fee memory distributionFee = productInfo.distributionFee; + Fee memory distributionFee = feeInfo.distributionFee; assertEq(distributionFee.fractionalFee.toInt(), 0, "distribution fee not 0 (fractional)"); assertEq(distributionFee.fixedFee, 0, "distribution fee not 0 (fixed)"); - Fee memory minDistributionOwnerFee = productInfo.minDistributionOwnerFee; + Fee memory minDistributionOwnerFee = feeInfo.minDistributionOwnerFee; assertEq(minDistributionOwnerFee.fractionalFee.toInt(), 0, "min distribution owner fee not 0 (fractional)"); assertEq(minDistributionOwnerFee.fixedFee, 0, "min distribution owner fee fee not 0 (fixed)"); @@ -48,12 +48,12 @@ contract TestDistribution is GifTest { vm.stopPrank(); // THEN - productInfo = instanceReader.getProductInfo(productNftId); - distributionFee = productInfo.distributionFee; + feeInfo = instanceReader.getFeeInfo(productNftId); + distributionFee = feeInfo.distributionFee; assertEq(distributionFee.fractionalFee.toInt(), 123, "unexpected distribution fee (fractional))"); assertEq(distributionFee.fixedFee, 456, "unexpected distribution fee not (fixed)"); - minDistributionOwnerFee = productInfo.minDistributionOwnerFee; + minDistributionOwnerFee = feeInfo.minDistributionOwnerFee; assertEq(minDistributionOwnerFee.fractionalFee.toInt(), 12, "unexpected min distribution owner fee (fractional)"); assertEq(minDistributionOwnerFee.fixedFee, 34, "unexpected min distribution owner fee not 0 (fixed)"); } diff --git a/test/TestPool.t.sol b/test/TestPool.t.sol index f4507b1da..e4f9ee7a6 100644 --- a/test/TestPool.t.sol +++ b/test/TestPool.t.sol @@ -114,17 +114,17 @@ contract TestPool is GifTest { function test_poolSetFees() public { // GIVEN setup includes pool and product - IComponents.ProductInfo memory productInfo = instanceReader.getProductInfo(productNftId); + IComponents.FeeInfo memory feeInfo = instanceReader.getFeeInfo(productNftId); - Fee memory poolFee = productInfo.poolFee; + Fee memory poolFee = feeInfo.poolFee; assertEq(poolFee.fractionalFee.toInt(), 0, "pool fee not 0 (fractional)"); assertEq(poolFee.fixedFee, 0, "pool fee not 0 (fixed)"); - Fee memory stakingFee = productInfo.stakingFee; + Fee memory stakingFee = feeInfo.stakingFee; assertEq(stakingFee.fractionalFee.toInt(), 0, "staking fee not 0 (fractional)"); assertEq(stakingFee.fixedFee, 0, "staking fee not 0 (fixed)"); - Fee memory performanceFee = productInfo.performanceFee; + Fee memory performanceFee = feeInfo.performanceFee; assertEq(performanceFee.fractionalFee.toInt(), 0, "performance fee not 0 (fractional)"); assertEq(performanceFee.fixedFee, 0, "performance fee fee not 0 (fixed)"); @@ -136,10 +136,10 @@ contract TestPool is GifTest { pool.setFees(newPoolFee, newStakingFee, newPerformanceFee); vm.stopPrank(); - productInfo = instanceReader.getProductInfo(productNftId); - poolFee = productInfo.poolFee; - stakingFee = productInfo.stakingFee; - performanceFee = productInfo.performanceFee; + feeInfo = instanceReader.getFeeInfo(productNftId); + poolFee = feeInfo.poolFee; + stakingFee = feeInfo.stakingFee; + performanceFee = feeInfo.performanceFee; assertEq(poolFee.fractionalFee.toInt(), 111, "pool fee not 111 (fractional)"); assertEq(poolFee.fixedFee, 222, "pool fee not 222 (fixed)"); diff --git a/test/TestProduct.t.sol b/test/TestProduct.t.sol index 119f7063c..522880cc3 100644 --- a/test/TestProduct.t.sol +++ b/test/TestProduct.t.sol @@ -57,10 +57,11 @@ contract TestProduct is GifTest { assertEq(productInfo.poolNftId.toInt(), pool.getNftId().toInt(), "unexpected pool nft id"); // check fees - Fee memory productFee = productInfo.productFee; + IComponents.FeeInfo memory feeInfo = instanceReader.getFeeInfo(productNftId); + Fee memory productFee = feeInfo.productFee; assertEq(productFee.fractionalFee.toInt(), 0, "product fee not 0"); assertEq(productFee.fixedFee, 0, "product fee not 0"); - Fee memory processingFee = productInfo.processingFee; + Fee memory processingFee = feeInfo.processingFee; assertEq(processingFee.fractionalFee.toInt(), 0, "processing fee not 0"); assertEq(processingFee.fixedFee, 0, "processing fee not 0"); } @@ -68,11 +69,11 @@ contract TestProduct is GifTest { function test_productSetFees() public { - IComponents.ProductInfo memory productInfo = instanceReader.getProductInfo(productNftId); - Fee memory productFee = productInfo.productFee; + IComponents.FeeInfo memory feeInfo = instanceReader.getFeeInfo(productNftId); + Fee memory productFee = feeInfo.productFee; assertEq(productFee.fractionalFee.toInt(), 0, "product fee not 0"); assertEq(productFee.fixedFee, 0, "product fee not 0"); - Fee memory processingFee = productInfo.processingFee; + Fee memory processingFee = feeInfo.processingFee; assertEq(processingFee.fractionalFee.toInt(), 0, "processing fee not 0"); assertEq(processingFee.fixedFee, 0, "processing fee not 0"); @@ -83,12 +84,12 @@ contract TestProduct is GifTest { product.setFees(newProductFee, newProcessingFee); vm.stopPrank(); - productInfo = instanceReader.getProductInfo(productNftId); - productFee = productInfo.productFee; + feeInfo = instanceReader.getFeeInfo(productNftId); + productFee = feeInfo.productFee; assertEq(productFee.fractionalFee.toInt(), 123, "product fee not 123"); assertEq(productFee.fixedFee, 456, "product fee not 456"); - processingFee = productInfo.processingFee; + processingFee = feeInfo.processingFee; assertEq(processingFee.fractionalFee.toInt(), 789, "processing fee not 789"); assertEq(processingFee.fixedFee, 101112, "processing fee not 101112"); } diff --git a/test/base/GifTest.sol b/test/base/GifTest.sol index b857740a1..935dd048e 100644 --- a/test/base/GifTest.sol +++ b/test/base/GifTest.sol @@ -485,6 +485,7 @@ contract GifTest is GifDeployer { "SimpleProduct", address(token), _getSimpleProductInfo(), + _getSimpleFeeInfo(), new SimpleProductAuthorization(name), productOwner // initial owner ); @@ -521,7 +522,16 @@ contract GifTest is GifDeployer { numberOfOracles: 0, poolNftId: NftIdLib.zero(), distributionNftId: NftIdLib.zero(), - oracleNftId: new NftId[](1), + oracleNftId: new NftId[](1) + }); + } + + function _getSimpleFeeInfo() + internal + view + returns (IComponents.FeeInfo memory feeInfo) + { + return IComponents.FeeInfo({ productFee: FeeLib.zero(), processingFee: FeeLib.zero(), distributionFee: FeeLib.zero(), diff --git a/test/component/pool/PoolRegistration.t.sol b/test/component/pool/PoolRegistration.t.sol index 31e07c49f..45e371372 100644 --- a/test/component/pool/PoolRegistration.t.sol +++ b/test/component/pool/PoolRegistration.t.sol @@ -249,6 +249,7 @@ contract TestPoolRegistration is GifTest { "SimpleProduct", address(token), _getSimpleProductInfo(), + _getSimpleFeeInfo(), new BasicProductAuthorization(name), owner); } @@ -279,6 +280,7 @@ contract SimpleProductV4 is SimpleProduct { NftId instanceNftId, address token, IComponents.ProductInfo memory productInfo, + IComponents.FeeInfo memory feeInfo, IAuthorization authorization, address initialOwner ) @@ -288,6 +290,7 @@ contract SimpleProductV4 is SimpleProduct { "SimpleProductV4", token, productInfo, + feeInfo, authorization, initialOwner ) diff --git a/test/component/product/ProductRegistration.t.sol b/test/component/product/ProductRegistration.t.sol index 6888bda34..0233c75b9 100644 --- a/test/component/product/ProductRegistration.t.sol +++ b/test/component/product/ProductRegistration.t.sol @@ -142,6 +142,7 @@ contract TestProductRegistration is GifTest { instanceNftId, address(token), _getSimpleProductInfo(), + _getSimpleFeeInfo(), new BasicProductAuthorization("MyProductV4"), myProductOwner); @@ -215,6 +216,7 @@ contract TestProductRegistration is GifTest { IComponents.ProductInfo memory productInfo = _getSimpleProductInfo(); productInfo.hasDistribution = hasDistribution; productInfo.expectedNumberOfOracles = oracleCount; + IComponents.FeeInfo memory feeInfo = _getSimpleFeeInfo(); return new SimpleProduct( address(registry), @@ -222,6 +224,7 @@ contract TestProductRegistration is GifTest { name, address(token), productInfo, + feeInfo, new BasicProductAuthorization(name), owner); } @@ -254,6 +257,7 @@ contract SimpleProductV4 is SimpleProduct { NftId instanceNftId, address token, IComponents.ProductInfo memory productInfo, + IComponents.FeeInfo memory feeInfo, IAuthorization authorization, address initialOwner ) @@ -263,6 +267,7 @@ contract SimpleProductV4 is SimpleProduct { "SimpleProductV4", token, productInfo, + feeInfo, authorization, initialOwner ) diff --git a/test/examples/composeability/ProductWithReinsurance.sol b/test/examples/composeability/ProductWithReinsurance.sol index fc77ab798..421c0c32d 100644 --- a/test/examples/composeability/ProductWithReinsurance.sol +++ b/test/examples/composeability/ProductWithReinsurance.sol @@ -28,6 +28,7 @@ contract ProductWithReinsurance is NftId instanceNftId, address token, IComponents.ProductInfo memory productInfo, + IComponents.FeeInfo memory feeInfo, IAuthorization authorization, address initialOwner ) @@ -37,6 +38,7 @@ contract ProductWithReinsurance is "ProductWithReinsurance", token, productInfo, + feeInfo, authorization, initialOwner ) diff --git a/test/examples/composeability/ProductWithReinsurance.t.sol b/test/examples/composeability/ProductWithReinsurance.t.sol index 77a515ed6..c485ebdac 100644 --- a/test/examples/composeability/ProductWithReinsurance.t.sol +++ b/test/examples/composeability/ProductWithReinsurance.t.sol @@ -362,6 +362,7 @@ contract ProductWithReinsuranceTest is instanceNftId, address(token), _getProductWithReinsuranceProductInfo(), + _getSimpleFeeInfo(), new ProductWithReinsuranceAuthorization(), productOwner ); @@ -432,6 +433,7 @@ contract ProductWithReinsuranceTest is // solhint-disable-next-line console.log("risk id"); + // solhint-disable-next-line console.logBytes8(RiskId.unwrap(riskReId)); // solhint-disable-next-line diff --git a/test/examples/external/ExternallyManagedPool.t.sol b/test/examples/external/ExternallyManagedPool.t.sol index 56d7cf176..d54bc5bad 100644 --- a/test/examples/external/ExternallyManagedPool.t.sol +++ b/test/examples/external/ExternallyManagedPool.t.sol @@ -412,12 +412,14 @@ contract ExternallyManagedPoolTest is GifTest { IComponents.ProductInfo memory productInfo = _getSimpleProductInfo(); productInfo.hasDistribution = false; productInfo.expectedNumberOfOracles = 0; + IComponents.FeeInfo memory feeInfo = _getSimpleFeeInfo(); emProduct = new ExternallyManagedProduct( address(registry), instanceNftId, address(token), productInfo, + feeInfo, productOwner ); } diff --git a/test/examples/external/ExternallyManagedProduct.sol b/test/examples/external/ExternallyManagedProduct.sol index 3d9711f4c..0e7b31f8f 100644 --- a/test/examples/external/ExternallyManagedProduct.sol +++ b/test/examples/external/ExternallyManagedProduct.sol @@ -31,6 +31,7 @@ contract ExternallyManagedProduct is NftId instanceNftId, address token, IComponents.ProductInfo memory productInfo, + IComponents.FeeInfo memory feeInfo, address initialOwner ) SimpleProduct( @@ -39,6 +40,7 @@ contract ExternallyManagedProduct is "VerifyingProduct", token, productInfo, + feeInfo, new BasicProductAuthorization("ExternallyManagedProduct"), initialOwner ) diff --git a/test/examples/verifying/VerifyingPool.t.sol b/test/examples/verifying/VerifyingPool.t.sol index 4a5a4f8b7..f0e1f4a81 100644 --- a/test/examples/verifying/VerifyingPool.t.sol +++ b/test/examples/verifying/VerifyingPool.t.sol @@ -128,12 +128,14 @@ contract VerifyingPoolTest is GifTest { IComponents.ProductInfo memory productInfo = _getSimpleProductInfo(); productInfo.hasDistribution = false; productInfo.expectedNumberOfOracles = 0; + IComponents.FeeInfo memory feeInfo = _getSimpleFeeInfo(); vProduct = new VerifyingProduct( address(registry), instanceNftId, address(token), productInfo, + feeInfo, productOwner ); } diff --git a/test/examples/verifying/VerifyingProduct.sol b/test/examples/verifying/VerifyingProduct.sol index bf37f55e5..ddc342369 100644 --- a/test/examples/verifying/VerifyingProduct.sol +++ b/test/examples/verifying/VerifyingProduct.sol @@ -33,6 +33,7 @@ contract VerifyingProduct is NftId instanceNftId, address token, IComponents.ProductInfo memory productInfo, + IComponents.FeeInfo memory feeInfo, address initialOwner ) SimpleProduct( @@ -41,6 +42,7 @@ contract VerifyingProduct is "VerifyingProduct", token, productInfo, + feeInfo, new BasicProductAuthorization("VerifyingProduct"), initialOwner ) From f1584afa6b512ae413f8b21a78cc1585983b12c0 Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Thu, 15 Aug 2024 16:28:02 +0000 Subject: [PATCH 5/7] reorder object types (#599) --- contracts/type/ObjectType.sol | 51 ++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/contracts/type/ObjectType.sol b/contracts/type/ObjectType.sol index f2831dc81..d71866342 100644 --- a/contracts/type/ObjectType.sol +++ b/contracts/type/ObjectType.sol @@ -48,86 +48,87 @@ function COMPONENT() pure returns (ObjectType) { return ObjectType.wrap(11); } -function PRODUCT() pure returns (ObjectType) { +function ACCOUNTING() pure returns (ObjectType) { return ObjectType.wrap(12); } -function ORACLE() pure returns (ObjectType) { +function PRODUCT() pure returns (ObjectType) { return ObjectType.wrap(13); } -function DISTRIBUTION() pure returns (ObjectType) { +function FEE() pure returns (ObjectType) { return ObjectType.wrap(14); } -function POOL() pure returns (ObjectType) { +function ORACLE() pure returns (ObjectType) { return ObjectType.wrap(15); } +function DISTRIBUTION() pure returns (ObjectType) { + return ObjectType.wrap(16); +} + +function POOL() pure returns (ObjectType) { + return ObjectType.wrap(17); +} + function APPLICATION() pure returns (ObjectType) { - return ObjectType.wrap(20); + return ObjectType.wrap(18); } function POLICY() pure returns (ObjectType) { - return ObjectType.wrap(21); + return ObjectType.wrap(19); } function PREMIUM() pure returns (ObjectType) { - return ObjectType.wrap(22); + return ObjectType.wrap(20); } function CLAIM() pure returns (ObjectType) { - return ObjectType.wrap(23); + return ObjectType.wrap(21); } function PAYOUT() pure returns (ObjectType) { - return ObjectType.wrap(24); + return ObjectType.wrap(22); } function RISK() pure returns (ObjectType) { - return ObjectType.wrap(25); + return ObjectType.wrap(23); } function PRICE() pure returns (ObjectType) { - return ObjectType.wrap(26); + return ObjectType.wrap(24); } function REQUEST() pure returns (ObjectType) { - return ObjectType.wrap(27); + return ObjectType.wrap(25); } function DISTRIBUTOR_TYPE() pure returns (ObjectType) { - return ObjectType.wrap(28); + return ObjectType.wrap(26); } function DISTRIBUTOR() pure returns (ObjectType) { - return ObjectType.wrap(29); + return ObjectType.wrap(27); } function REFERRAL() pure returns (ObjectType) { - return ObjectType.wrap(30); + return ObjectType.wrap(28); } function BUNDLE() pure returns (ObjectType) { - return ObjectType.wrap(31); + return ObjectType.wrap(29); } function TARGET() pure returns (ObjectType) { - return ObjectType.wrap(32); + return ObjectType.wrap(30); } function STAKE() pure returns (ObjectType) { - return ObjectType.wrap(33); + return ObjectType.wrap(31); } -// TODO: change id for accounting -function ACCOUNTING() pure returns (ObjectType) { - return ObjectType.wrap(34); -} -function FEE() pure returns (ObjectType) { - return ObjectType.wrap(35); -} /// @dev Object type that includes any other object type. /// Note that eq()/'==' does not take this property into account. From 23ee079972cd9c341b970dd92490aad7663012bf Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Fri, 16 Aug 2024 13:23:58 +0000 Subject: [PATCH 6/7] ensure no distribution, product or oracle is linked with product upon initialization (closes #516) --- contracts/shared/ComponentService.sol | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/contracts/shared/ComponentService.sol b/contracts/shared/ComponentService.sol index c94b68a5a..cf1827cd8 100644 --- a/contracts/shared/ComponentService.sol +++ b/contracts/shared/ComponentService.sol @@ -26,7 +26,7 @@ import {Amount, AmountLib} from "../type/Amount.sol"; import {ContractLib} from "../shared/ContractLib.sol"; import {Fee, FeeLib} from "../type/Fee.sol"; import {KEEP_STATE} from "../type/StateId.sol"; -import {NftId} from "../type/NftId.sol"; +import {NftId, NftIdLib} from "../type/NftId.sol"; import {ObjectType, ACCOUNTING, REGISTRY, COMPONENT, DISTRIBUTION, INSTANCE, ORACLE, POOL, PRODUCT} from "../type/ObjectType.sol"; import {Service} from "../shared/Service.sol"; import {TokenHandler} from "../shared/TokenHandler.sol"; @@ -236,11 +236,18 @@ contract ComponentService is // get product IProductComponent product = IProductComponent(productAddress); + + IComponents.ProductInfo memory initialProductInfo = product.getInitialProductInfo(); + // force initialization of linked components with empty values to + // ensure no components are linked upon initialization of the product + initialProductInfo.poolNftId = NftIdLib.zero(); + initialProductInfo.distributionNftId = NftIdLib.zero(); + initialProductInfo.oracleNftId = new NftId[](0); // create info instanceStore.createProduct( productNftId, - product.getInitialProductInfo()); + initialProductInfo); instanceStore.createFee( productNftId, product.getInitialFeeInfo()); From 18b32b05fe32bc4d647cc159208bf59b09820b9e Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Fri, 16 Aug 2024 14:22:01 +0000 Subject: [PATCH 7/7] fix initialization (#516) --- contracts/shared/ComponentService.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/shared/ComponentService.sol b/contracts/shared/ComponentService.sol index cf1827cd8..5a2e66f7f 100644 --- a/contracts/shared/ComponentService.sol +++ b/contracts/shared/ComponentService.sol @@ -242,7 +242,7 @@ contract ComponentService is // ensure no components are linked upon initialization of the product initialProductInfo.poolNftId = NftIdLib.zero(); initialProductInfo.distributionNftId = NftIdLib.zero(); - initialProductInfo.oracleNftId = new NftId[](0); + initialProductInfo.oracleNftId = new NftId[](initialProductInfo.expectedNumberOfOracles); // create info instanceStore.createProduct(