From d878d0f57fd0fb7be8f04712e6ed469e06e3e622 Mon Sep 17 00:00:00 2001 From: Matthias Zimmermann Date: Mon, 2 Sep 2024 16:13:52 +0000 Subject: [PATCH] harden caller checks for ComponentService.registerProduct/registerComponent --- contracts/shared/ComponentService.sol | 100 +++++---- contracts/shared/ContractLib.sol | 212 ++++++++++++------ contracts/shared/IComponentService.sol | 7 + contracts/shared/InstanceLinkedComponent.sol | 1 - test/TestDeployAll.t.sol | 37 +-- test/component/pool/PoolRegistration.t.sol | 4 +- .../product/ProductRegistration.t.sol | 15 +- 7 files changed, 216 insertions(+), 160 deletions(-) diff --git a/contracts/shared/ComponentService.sol b/contracts/shared/ComponentService.sol index 29c47d56a..55288481e 100644 --- a/contracts/shared/ComponentService.sol +++ b/contracts/shared/ComponentService.sol @@ -4,7 +4,6 @@ pragma solidity ^0.8.20; import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import {IAccountingService} from "../accounting/IAccountingService.sol"; -import {IComponent} from "../shared/IComponent.sol"; import {IComponents} from "../instance/module/IComponents.sol"; import {IComponentService} from "./IComponentService.sol"; import {IInstance} from "../instance/IInstance.sol"; @@ -15,7 +14,6 @@ import {InstanceStore} from "../instance/InstanceStore.sol"; import {IInstanceService} from "../instance/IInstanceService.sol"; import {IPoolComponent} from "../pool/IPoolComponent.sol"; import {IProductComponent} from "../product/IProductComponent.sol"; -import {IRegisterable} from "../shared/IRegisterable.sol"; import {IRegistry} from "../registry/IRegistry.sol"; import {IRegistryService} from "../registry/IRegistryService.sol"; @@ -29,7 +27,6 @@ import {ObjectType, ACCOUNTING, REGISTRY, COMPONENT, DISTRIBUTION, INSTANCE, ORA import {Service} from "../shared/Service.sol"; import {TokenHandler} from "../shared/TokenHandler.sol"; import {TokenHandlerDeployerLib} from "../shared/TokenHandlerDeployerLib.sol"; -import {VersionPart} from "../type/Version.sol"; contract ComponentService is @@ -73,17 +70,31 @@ contract ComponentService is virtual returns (NftId componentNftId) { - (NftId productNftId, IInstance instance) = _getAndVerifyActiveComponent(COMPONENT()); - NftId instanceNftId = getRegistry().getNftIdForAddress(address(instance)); + // checks + // check sender is registered product + IRegistry registry = getRegistry(); + if (!registry.isObjectType(msg.sender, PRODUCT())) { + revert ErrorComponentServiceCallerNotProduct(msg.sender); + } + + // check provided address is product contract + if (!ContractLib.isInstanceLinkedComponent(address(registry), componentAddress)) { + revert ErrorComponentServiceNotComponent(componentAddress); + } + + NftId productNftId = registry.getNftIdForAddress(msg.sender); + IInstance instance = IInstance( + registry.getObjectAddress( + registry.getParentNftId(productNftId))); componentNftId = _verifyAndRegister( - instanceNftId, instance, componentAddress, - productNftId, - address(0)); + productNftId, // product is parent of component to be registered + address(0)); // token will be inhereited from product } + /// @inheritdoc IComponentService function approveTokenHandler( IERC20Metadata token, @@ -93,7 +104,7 @@ contract ComponentService is virtual { // checks - (NftId componentNftId, IInstance instance) = _getAndVerifyActiveComponent(COMPONENT()); + (NftId componentNftId, IInstance instance) = _getAndVerifyComponent(COMPONENT(), true); TokenHandler tokenHandler = instance.getInstanceReader().getTokenHandler( componentNftId); @@ -102,12 +113,13 @@ contract ComponentService is } + /// @inheritdoc IComponentService function setWallet(address newWallet) external virtual { // checks - (NftId componentNftId, IInstance instance) = _getAndVerifyActiveComponent(COMPONENT()); + (NftId componentNftId, IInstance instance) = _getAndVerifyComponent(COMPONENT(), true); TokenHandler tokenHandler = instance.getInstanceReader().getTokenHandler( componentNftId); @@ -129,6 +141,7 @@ contract ComponentService is locked); } + /// @inheritdoc IComponentService function withdrawFees(Amount amount) external @@ -137,7 +150,7 @@ contract ComponentService is returns (Amount withdrawnAmount) { // checks - (NftId componentNftId, IInstance instance) = _getAndVerifyActiveComponent(COMPONENT()); + (NftId componentNftId, IInstance instance) = _getAndVerifyComponent(COMPONENT(), true); InstanceReader instanceReader = instance.getInstanceReader(); // determine withdrawn amount @@ -182,20 +195,35 @@ contract ComponentService is //-------- product ------------------------------------------------------// + /// @inheritdoc IComponentService function registerProduct(address productAddress, address token) external virtual nonReentrant() returns (NftId productNftId) { - // TODO instance verification - //(NftId instanceNftId,, IInstance instance) = _getAndVerifyCallingInstance(); - NftId instanceNftId = getRegistry().getNftIdForAddress(msg.sender); - IInstance instance = IInstance(msg.sender); + // checks + // check sender is registered instance + IRegistry registry = getRegistry(); + if (!registry.isObjectType(msg.sender, INSTANCE())) { + revert ErrorComponentServiceCallerNotInstance(msg.sender); + } + + // check provided address is product contract + if (!ContractLib.isProduct(address(registry), productAddress)) { + revert ErrorComponentServiceNotProduct(productAddress); + } - productNftId = _verifyAndRegister(instanceNftId, instance, productAddress, instanceNftId, token); + IInstance instance = IInstance(msg.sender); + productNftId = _verifyAndRegister( + instance, + productAddress, + instance.getNftId(), // instance is parent of product to be registered + token); } + + /// @inheritdoc IComponentService function setProductFees( Fee memory productFee, // product fee on net premium Fee memory processingFee // product fee on payout amounts @@ -204,7 +232,7 @@ contract ComponentService is virtual nonReentrant() { - (NftId productNftId, IInstance instance) = _getAndVerifyActiveComponent(PRODUCT()); + (NftId productNftId, IInstance instance) = _getAndVerifyComponent(PRODUCT(), true); IComponents.FeeInfo memory feeInfo = instance.getInstanceReader().getFeeInfo(productNftId); bool feesChanged = false; @@ -228,6 +256,7 @@ contract ComponentService is } } + function _createProduct( InstanceStore instanceStore, NftId productNftId, @@ -282,6 +311,7 @@ contract ComponentService is instanceStore.updateProduct(productNftId, productInfo, KEEP_STATE()); } + function setDistributionFees( Fee memory distributionFee, // distribution fee for sales that do not include commissions Fee memory minDistributionOwnerFee // min fee required by distribution owner (not including commissions for distributors) @@ -289,7 +319,7 @@ contract ComponentService is external virtual { - (NftId distributionNftId, IInstance instance) = _getAndVerifyActiveComponent(DISTRIBUTION()); + (NftId distributionNftId, IInstance instance) = _getAndVerifyComponent(DISTRIBUTION(), true); (NftId productNftId, IComponents.FeeInfo memory feeInfo) = _getLinkedFeeInfo( instance.getInstanceReader(), distributionNftId); bool feesChanged = false; @@ -338,6 +368,7 @@ contract ComponentService is productInfo.numberOfOracles++; instanceStore.updateProduct(productNftId, productInfo, KEEP_STATE()); } + //-------- pool ---------------------------------------------------------// function _createPool( @@ -376,7 +407,7 @@ contract ComponentService is external virtual { - (NftId poolNftId, IInstance instance) = _getAndVerifyActiveComponent(POOL()); + (NftId poolNftId, IInstance instance) = _getAndVerifyComponent(POOL(), true); (NftId productNftId, IComponents.FeeInfo memory feeInfo) = _getLinkedFeeInfo( instance.getInstanceReader(), poolNftId); @@ -409,9 +440,10 @@ contract ComponentService is } } + /// @dev Registers the component represented by the provided address. + /// The caller must ensure componentAddress is IInstanceLinkedComponent. function _verifyAndRegister( - NftId instanceNftId, IInstance instance, address componentAddress, NftId parentNftId, @@ -486,9 +518,8 @@ contract ComponentService is // authorize instanceAdmin.initializeComponentAuthorization(componentAddress, componentType); - // TODO mostly repeats Registry log emit LogComponentServiceRegistered( - instanceNftId, + instance.getNftId(), componentNftId, componentType, address(component), @@ -496,6 +527,7 @@ contract ComponentService is objectInfo.initialOwner); } + function _checkToken(IInstance instance, address token) internal view @@ -513,6 +545,7 @@ contract ComponentService is } } + function _logUpdateFee(NftId productNftId, string memory name, Fee memory feeBefore, Fee memory feeAfter) internal virtual @@ -543,9 +576,9 @@ contract ComponentService is info = instanceReader.getFeeInfo(productNftId); } + /// @dev Based on the provided component address required type the component /// and related instance contract this function reverts iff: - /// - the component contract does not support IInstanceLinkedComponent /// - the component parent does not match with the required parent /// - the component release does not match with the service release /// - the component has already been registered @@ -560,11 +593,6 @@ contract ComponentService is IRegistry.ObjectInfo memory info ) { - // check component interface - if (!ContractLib.supportsInterface(componentAddress, type(IInstanceLinkedComponent).interfaceId)) { - revert ErrorComponentServiceNotInstanceLinkedComponent(componentAddress); - } - component = IInstanceLinkedComponent(componentAddress); info = component.getInitialInfo(); @@ -573,9 +601,7 @@ contract ComponentService is revert ErrorComponentServiceComponentParentInvalid(componentAddress, requiredParent, info.parentNftId); } - // check component release - // TODO check version with registry - //if(info.version != getRelease()) { + // check component release (must match with service release) if(component.getRelease() != getRelease()) { revert ErrorComponentServiceComponentReleaseMismatch(componentAddress, getRelease(), component.getRelease()); } @@ -586,20 +612,11 @@ contract ComponentService is } } + function _setLocked(InstanceAdmin instanceAdmin, address componentAddress, bool locked) internal { instanceAdmin.setTargetLocked(componentAddress, locked); } - function _getAndVerifyActiveComponent(ObjectType expectedType) - internal - view - returns ( - NftId componentNftId, - IInstance instance - ) - { - return _getAndVerifyComponent(expectedType, true); // only active - } function _getAndVerifyComponent(ObjectType expectedType, bool isActive) internal @@ -630,6 +647,7 @@ contract ComponentService is instance = IInstance(instanceAddress); } + function _getDomain() internal pure virtual override returns(ObjectType) { return COMPONENT(); } diff --git a/contracts/shared/ContractLib.sol b/contracts/shared/ContractLib.sol index 993c7f7ec..9f68899b7 100644 --- a/contracts/shared/ContractLib.sol +++ b/contracts/shared/ContractLib.sol @@ -5,11 +5,12 @@ import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165C import {IAccessManager} from "@openzeppelin/contracts/access/manager/IAccessManager.sol"; import {IAccessManaged} from "@openzeppelin/contracts/access/manager/IAccessManaged.sol"; -// import {InstanceAdmin} from "../instance/InstanceAdmin.sol"; -import {IRegistry} from "../registry/IRegistry.sol"; +import {IInstanceLinkedComponent} from "../shared/IInstanceLinkedComponent.sol"; import {IPolicyHolder} from "../shared/IPolicyHolder.sol"; +import {IRegistry} from "../registry/IRegistry.sol"; + import {NftId} from "../type/NftId.sol"; -import {ObjectType, PRODUCT, DISTRIBUTION, ORACLE, POOL, STAKING} from "../type/ObjectType.sol"; +import {ObjectType, INSTANCE, PRODUCT, DISTRIBUTION, ORACLE, POOL, STAKING} from "../type/ObjectType.sol"; import {VersionPart} from "../type/Version.sol"; interface ITargetHelper { @@ -26,39 +27,13 @@ interface ITokenRegistryHelper { library ContractLib { - error ErrorContractLibNotRegistered(address target); - error ErrorContractLibNotComponent(NftId componentNftId, ObjectType objectType); - error ErrorContractLibNotStaking(NftId componentNftId, ObjectType objectType); + error ErrorContractLibCallerNotRegistered(address target); + error ErrorContractLibCallerNotComponent(NftId componentNftId, ObjectType objectType); + error ErrorContractLibParentNotInstance(NftId componentNftId, NftId parentNftId); + error ErrorContractLibParentNotProduct(NftId componentNftId, NftId parentNftId); error ErrorContractLibComponentTypeMismatch(NftId componentNftId, ObjectType expectedType, ObjectType actualType); error ErrorContractLibComponentInactive(NftId componentNftId); - function getAndVerifyComponent( - IRegistry registry, - address target, - ObjectType expectedType, - bool onlyActive - ) - external - view - returns ( - IRegistry.ObjectInfo memory info, - address instance - ) - { - // check target is component - info = _getObjectInfo(registry, target); - if(info.objectType != expectedType) { - revert ErrorContractLibComponentTypeMismatch( - info.nftId, - expectedType, - info.objectType); - } - - // get instance and check component is active - instance = _getInstance(registry, info); - _checkComponentActive(instance, target, info.nftId, onlyActive); - } - function getInfoAndInstance( IRegistry registry, @@ -73,34 +48,42 @@ library ContractLib { ) { info = registry.getObjectInfo(componentNftId); - instance = _getInstance(registry, info); - _checkComponentActive(instance, info.objectAddress, info.nftId, onlyActive); + return _getAndVerifyComponentAndInstance(registry, info, info.objectType, onlyActive); } - function getAndVerifyStaking( + function getAndVerifyAnyComponent( IRegistry registry, - address target + address caller, + bool onlyActive ) external view returns ( - IRegistry.ObjectInfo memory info + IRegistry.ObjectInfo memory callerInfo, + address instance ) { - // check target is component - info = _getObjectInfo(registry, target); - if(info.objectType != STAKING()) { - revert ErrorContractLibNotStaking( - info.nftId, - info.objectType); + // check caller is component + callerInfo = _getAndVerifyObjectInfo(registry, caller); + if(!(callerInfo.objectType == PRODUCT() + || callerInfo.objectType == POOL() + || callerInfo.objectType == DISTRIBUTION() + || callerInfo.objectType == ORACLE()) + ) { + revert ErrorContractLibCallerNotComponent( + callerInfo.nftId, + callerInfo.objectType); } + + return _getAndVerifyComponentAndInstance(registry, callerInfo, callerInfo.objectType, onlyActive); } - function getAndVerifyAnyComponent( + function getAndVerifyComponent( IRegistry registry, - address target, + address caller, + ObjectType expectedType, bool onlyActive ) external @@ -110,24 +93,30 @@ library ContractLib { address instance ) { - // check target is component - info = _getObjectInfo(registry, target); - if(!(info.objectType == PRODUCT() - || info.objectType == POOL() - || info.objectType == DISTRIBUTION() - || info.objectType == ORACLE()) - ) { - revert ErrorContractLibNotComponent( - info.nftId, - info.objectType); - } - - // get instance and check component is active - instance = _getInstance(registry, info); - _checkComponentActive(instance, target, info.nftId, onlyActive); + info = _getAndVerifyObjectInfo(registry, caller); + return _getAndVerifyComponentAndInstance(registry, info, expectedType, onlyActive); } + // TODO cleanup + // function getAndVerifyStaking( + // IRegistry registry, + // address target + // ) + // external + // view + // returns (IRegistry.ObjectInfo memory info) + // { + // // check target is component + // info = _getAndVerifyObjectInfo(registry, target); + // if(info.objectType != STAKING()) { + // revert ErrorContractLibNotStaking( + // info.nftId, + // info.objectType); + // } + // } + + function getInstanceForComponent( IRegistry registry, NftId componentNftId @@ -157,6 +146,7 @@ library ContractLib { chainId, token, release); } + function isPolicyHolder(address target) external view returns (bool) { return ERC165Checker.supportsInterface(target, type(IPolicyHolder).interfaceId); } @@ -188,6 +178,32 @@ library ContractLib { } + function isProduct(address registry, address target) + public + view + returns (bool) + { + if (!isInstanceLinkedComponent(registry, target)) { + return false; + } + + return IInstanceLinkedComponent(target).getInitialInfo().objectType == PRODUCT(); + } + + + function isInstanceLinkedComponent(address registry, address target) + public + view + returns (bool) + { + if (!isContract(target)) { + return false; + } + + return supportsInterface(target, type(IInstanceLinkedComponent).interfaceId); + } + + function isRegistered(address registry, address caller, ObjectType expectedType) public view returns (bool) { NftId nftId = IRegistry(registry).getNftIdForAddress(caller); if (nftId.eqz()) { @@ -224,6 +240,37 @@ library ContractLib { } + function _getAndVerifyComponentAndInstance( + IRegistry registry, + IRegistry.ObjectInfo memory info, + ObjectType expectedType, + bool onlyActive + ) + internal + view + returns ( + IRegistry.ObjectInfo memory, + address instance + ) + { + if(info.objectType != expectedType) { + revert ErrorContractLibComponentTypeMismatch( + info.nftId, + expectedType, + info.objectType); + } + + // get instance and check component is active + instance = getAndVerifyInstance(registry, info); + _checkComponentActive(instance, info.objectAddress, info.nftId, onlyActive); + + return ( + info, + instance + ); + } + + function _checkComponentActive( address instance, address target, @@ -244,36 +291,55 @@ library ContractLib { } - function _getInstance( + /// @dev Given an object info the function returns the instance address. + /// The info may represent a product or any other component. + /// If the parent of the provided info is not registered with the correct type, the function reverts. + function getAndVerifyInstance( IRegistry registry, IRegistry.ObjectInfo memory info ) - internal + public view returns (address instance) { + // get instance for product case if (info.objectType == PRODUCT()) { - return registry.getObjectAddress( + // verify that parent of product is registered instance + IRegistry.ObjectInfo memory instanceInfo = registry.getObjectInfo(info.parentNftId); + if (instanceInfo.objectType != INSTANCE()) { + revert ErrorContractLibParentNotInstance( + info.nftId, + info.parentNftId); + } + + // we have verified that parent object is a registerd instance -> we return the instance address + return instanceInfo.objectAddress; + } + + // not product: verify parent is registered product + info = registry.getObjectInfo(info.parentNftId); + if (info.objectType != PRODUCT()) { + revert ErrorContractLibParentNotProduct( + info.nftId, info.parentNftId); - } - - return registry.getObjectAddress( - registry.getObjectInfo( - info.parentNftId).parentNftId); + } + + // we have verified that parent is registerd product -> we can rely on registry that its parent is an instance + return registry.getObjectAddress(info.parentNftId); } - function _getObjectInfo( + function _getAndVerifyObjectInfo( IRegistry registry, - address target + address caller ) internal view returns (IRegistry.ObjectInfo memory info) { - NftId componentNftId = registry.getNftIdForAddress(target); + NftId componentNftId = registry.getNftIdForAddress(caller); if (componentNftId.eqz()) { - revert ErrorContractLibNotRegistered(target); + revert ErrorContractLibCallerNotRegistered(caller); } info = registry.getObjectInfo(componentNftId); diff --git a/contracts/shared/IComponentService.sol b/contracts/shared/IComponentService.sol index 9be5b6944..1a7d817e7 100644 --- a/contracts/shared/IComponentService.sol +++ b/contracts/shared/IComponentService.sol @@ -16,8 +16,15 @@ import {VersionPart} from "../type/Version.sol"; interface IComponentService is IService { + // registerProduct + error ErrorComponentServiceCallerNotInstance(address caller); + error ErrorComponentServiceNotProduct(address product); error ErrorComponentServiceTokenInvalid(address token); + // registerComponent + error ErrorComponentServiceCallerNotProduct(address caller); + error ErrorComponentServiceNotComponent(address component); + error ErrorComponentServiceNotInstanceLinkedComponent(address component); error ErrorComponentServiceComponentTypeNotSupported(address component, ObjectType invalid); error ErrorComponentServiceComponentParentInvalid(address component, NftId required, NftId actual); diff --git a/contracts/shared/InstanceLinkedComponent.sol b/contracts/shared/InstanceLinkedComponent.sol index 5344c3b7e..496945465 100644 --- a/contracts/shared/InstanceLinkedComponent.sol +++ b/contracts/shared/InstanceLinkedComponent.sol @@ -110,7 +110,6 @@ abstract contract InstanceLinkedComponent is $._componentService = IComponentService(_getServiceAddress(COMPONENT())); // register interfaces - _registerInterface(type(IAccessManaged).interfaceId); _registerInterface(type(IInstanceLinkedComponent).interfaceId); } diff --git a/test/TestDeployAll.t.sol b/test/TestDeployAll.t.sol index cb1be8982..00c697eaf 100644 --- a/test/TestDeployAll.t.sol +++ b/test/TestDeployAll.t.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.20; +import {IRegistry} from "../contracts/registry/IRegistry.sol"; import {GifTest} from "./base/GifTest.sol"; import {InstanceLinkedComponent} from "../contracts/shared/InstanceLinkedComponent.sol"; -import {IRegistry} from "../contracts/registry/IRegistry.sol"; -import {NftId, NftIdLib} from "../contracts/type/NftId.sol"; +import {NftId} from "../contracts/type/NftId.sol"; import {ObjectType} from "../contracts/type/ObjectType.sol"; import {BUNDLE, COMPONENT, DISTRIBUTION, ORACLE, POOL, PRODUCT, POLICY, RISK, REQUEST, SERVICE, STAKING} from "../contracts/type/ObjectType.sol"; -import {RoleId} from "../contracts/type/RoleId.sol"; + contract TestDeployAll is GifTest { @@ -22,36 +22,6 @@ contract TestDeployAll is GifTest { assertTrue(true); } - // function _getTargetText(uint256 idx) internal returns (string memory) { - // address target = registryAdmin.getTargetAddress(idx); - // return string( - // abi.encodePacked( - // "address ", - // _toString(target), - // " ", - // registryAdmin.getTargetInfo(target).name)); - // } - - // function _getRoleText(uint256 idx) internal returns (string memory) { - // RoleId roleId = registryAdmin.getRoleId(idx); - // return string( - // abi.encodePacked( - // "roleId ", - // _toString(roleId.toInt()), - // " ", - // registryAdmin.getRoleInfo(roleId).name, - // " members ", - // _toString(registryAdmin.roleMembers(roleId)))); - // } - - // function _toString(uint256 value) internal pure returns (string memory) { - // return Strings.toString(value); - // } - - // function _toString(address _address) internal pure returns (string memory) { - // return Strings.toHexString(uint256(uint160(_address)), 20); - // } - function test_deploySimpleProduct() public { _checkMockComponent(product, productNftId, instanceNftId, PRODUCT(), "SimpleProduct", productOwner); } @@ -187,5 +157,4 @@ contract TestDeployAll is GifTest { // check owner assertEq(registry.ownerOf(address(component)), componentOwner, "unexpected component owner"); } - } \ No newline at end of file diff --git a/test/component/pool/PoolRegistration.t.sol b/test/component/pool/PoolRegistration.t.sol index 0be59a127..772ce0079 100644 --- a/test/component/pool/PoolRegistration.t.sol +++ b/test/component/pool/PoolRegistration.t.sol @@ -128,7 +128,7 @@ contract TestPoolRegistration is GifTest { // WHEN + THEN vm.expectRevert( abi.encodeWithSelector( - ContractLib.ErrorContractLibNotRegistered.selector, + IComponentService.ErrorComponentServiceCallerNotProduct.selector, poolOwner)); vm.startPrank(poolOwner); @@ -173,7 +173,7 @@ contract TestPoolRegistration is GifTest { // WHEN + THEN vm.expectRevert( abi.encodeWithSelector( - IComponentService.ErrorComponentServiceNotInstanceLinkedComponent.selector, + IComponentService.ErrorComponentServiceNotComponent.selector, address(token))); vm.startPrank(myProductOwner); diff --git a/test/component/product/ProductRegistration.t.sol b/test/component/product/ProductRegistration.t.sol index 77ed9be17..e14ad596a 100644 --- a/test/component/product/ProductRegistration.t.sol +++ b/test/component/product/ProductRegistration.t.sol @@ -94,22 +94,21 @@ contract TestProductRegistration is GifTest { vm.stopPrank(); } - // FIXME: when proper instance verification is added to registerProduct() - // check that non instance fails to register a product - /*function test_productRegisterAttemptViaService() public { + + function test_productRegisterAttemptViaService() public { // GIVEN SimpleProduct myProduct = _deployProductDefault("MyProduct"); // WHEN + THEN vm.expectRevert( abi.encodeWithSelector( - IAccessManaged.AccessManagedUnauthorized.selector, + IComponentService.ErrorComponentServiceCallerNotInstance.selector, address(instanceOwner))); vm.startPrank(instanceOwner); componentService.registerProduct(address(myProduct), address(token)); vm.stopPrank(); - }*/ + } // check that product registration fails for product with a different release than instance @@ -166,10 +165,8 @@ contract TestProductRegistration is GifTest { // WHEN + THEN vm.expectRevert( abi.encodeWithSelector( - IComponentService.ErrorComponentServiceComponentParentInvalid.selector, - address(myPool), - instanceNftId, - myProdNftId)); + IComponentService.ErrorComponentServiceNotProduct.selector, + address(myPool))); vm.startPrank(instanceOwner); instance.registerProduct(address(myPool), address(token));