@etherisc/gif-next 0.0.2-ce8407f-016 → 0.0.2-cf68d0c-530

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/README.md +108 -1
  2. package/artifacts/contracts/components/BaseComponent.sol/BaseComponent.dbg.json +4 -0
  3. package/artifacts/contracts/components/BaseComponent.sol/BaseComponent.json +327 -0
  4. package/artifacts/contracts/components/Distribution.sol/Distribution.dbg.json +4 -0
  5. package/artifacts/contracts/components/Distribution.sol/Distribution.json +670 -0
  6. package/artifacts/contracts/components/IBaseComponent.sol/IBaseComponent.dbg.json +1 -1
  7. package/artifacts/contracts/components/IBaseComponent.sol/IBaseComponent.json +39 -0
  8. package/artifacts/contracts/components/IDistributionComponent.sol/IDistributionComponent.dbg.json +4 -0
  9. package/artifacts/contracts/components/IDistributionComponent.sol/IDistributionComponent.json +204 -0
  10. package/artifacts/contracts/components/IPoolComponent.sol/IPoolComponent.dbg.json +4 -0
  11. package/artifacts/contracts/components/IPoolComponent.sol/IPoolComponent.json +249 -0
  12. package/artifacts/contracts/components/IProductComponent.sol/IProductComponent.dbg.json +4 -0
  13. package/artifacts/contracts/components/IProductComponent.sol/IProductComponent.json +157 -0
  14. package/artifacts/contracts/components/Pool.sol/Pool.dbg.json +4 -0
  15. package/artifacts/contracts/components/Pool.sol/Pool.json +790 -0
  16. package/artifacts/contracts/components/Product.sol/Product.dbg.json +4 -0
  17. package/artifacts/contracts/components/Product.sol/Product.json +775 -0
  18. package/artifacts/contracts/experiment/cloning/Cloner.sol/Cloner.dbg.json +4 -0
  19. package/artifacts/contracts/experiment/cloning/Cloner.sol/Cloner.json +66 -0
  20. package/artifacts/contracts/experiment/cloning/Cloner.sol/Mock1.dbg.json +4 -0
  21. package/artifacts/contracts/experiment/cloning/Cloner.sol/Mock1.json +24 -0
  22. package/artifacts/contracts/experiment/cloning/Cloner.sol/Mock2.dbg.json +4 -0
  23. package/artifacts/contracts/experiment/cloning/Cloner.sol/Mock2.json +42 -0
  24. package/artifacts/contracts/experiment/errors/Require.sol/Require.dbg.json +1 -1
  25. package/artifacts/contracts/experiment/errors/Revert.sol/Revert.dbg.json +1 -1
  26. package/artifacts/contracts/experiment/inheritance/A.sol/A.dbg.json +1 -1
  27. package/artifacts/contracts/experiment/inheritance/A.sol/AShared.dbg.json +1 -1
  28. package/artifacts/contracts/experiment/inheritance/B.sol/B.dbg.json +1 -1
  29. package/artifacts/contracts/experiment/inheritance/C.sol/C.dbg.json +1 -1
  30. package/artifacts/contracts/experiment/inheritance/IA.sol/IA.dbg.json +1 -1
  31. package/artifacts/contracts/experiment/inheritance/IA.sol/ISharedA.dbg.json +1 -1
  32. package/artifacts/contracts/experiment/inheritance/IB.sol/IB.dbg.json +1 -1
  33. package/artifacts/contracts/experiment/inheritance/IC.sol/IC.dbg.json +1 -1
  34. package/artifacts/contracts/experiment/statemachine/Dummy.sol/LifeCycleModule.dbg.json +1 -1
  35. package/artifacts/contracts/experiment/statemachine/Dummy.sol/LifeCycleModule.json +2 -2
  36. package/artifacts/contracts/experiment/statemachine/ISM.sol/ISM.dbg.json +1 -1
  37. package/artifacts/contracts/experiment/statemachine/ISM.sol/ISMEE.dbg.json +1 -1
  38. package/artifacts/contracts/experiment/statemachine/SM.sol/SM.dbg.json +1 -1
  39. package/artifacts/contracts/experiment/statemachine/SM.sol/SM.json +2 -2
  40. package/artifacts/contracts/experiment/statemachine/SimpleStateMachine.sol/SimpleStateMachine.dbg.json +1 -1
  41. package/artifacts/contracts/experiment/statemachine/SimpleStateMachine.sol/SimpleStateMachine.json +2 -2
  42. package/artifacts/contracts/experiment/types/TypeA.sol/TypeALib.dbg.json +1 -1
  43. package/artifacts/contracts/experiment/types/TypeB.sol/TypeBLib.dbg.json +1 -1
  44. package/artifacts/contracts/instance/AccessManagedSimple.sol/AccessManagedSimple.dbg.json +1 -1
  45. package/artifacts/contracts/instance/AccessManagerSimple.sol/AccessManagerSimple.dbg.json +1 -1
  46. package/artifacts/contracts/instance/AccessManagerSimple.sol/AccessManagerSimple.json +15 -2
  47. package/artifacts/contracts/instance/IAccessManagerSimple.sol/IAccessManagerSimple.dbg.json +1 -1
  48. package/artifacts/contracts/instance/IInstance.sol/IInstance.dbg.json +1 -1
  49. package/artifacts/contracts/instance/IInstance.sol/IInstance.json +435 -1
  50. package/artifacts/contracts/instance/IInstanceService.sol/IInstanceService.dbg.json +4 -0
  51. package/artifacts/contracts/instance/IInstanceService.sol/IInstanceService.json +480 -0
  52. package/artifacts/contracts/instance/Instance.sol/Instance.dbg.json +1 -1
  53. package/artifacts/contracts/instance/Instance.sol/Instance.json +491 -495
  54. package/artifacts/contracts/instance/InstanceAccessManager.sol/InstanceAccessManager.dbg.json +1 -1
  55. package/artifacts/contracts/instance/InstanceAccessManager.sol/InstanceAccessManager.json +34 -34
  56. package/artifacts/contracts/instance/InstanceReader.sol/InstanceReader.dbg.json +1 -1
  57. package/artifacts/contracts/instance/InstanceReader.sol/InstanceReader.json +438 -33
  58. package/artifacts/contracts/instance/InstanceService.sol/InstanceService.dbg.json +1 -1
  59. package/artifacts/contracts/instance/InstanceService.sol/InstanceService.json +726 -16
  60. package/artifacts/contracts/instance/InstanceServiceManager.sol/InstanceServiceManager.dbg.json +4 -0
  61. package/artifacts/contracts/instance/InstanceServiceManager.sol/InstanceServiceManager.json +468 -0
  62. package/artifacts/contracts/instance/base/ComponentServiceBase.sol/ComponentServiceBase.dbg.json +4 -0
  63. package/artifacts/contracts/instance/base/ComponentServiceBase.sol/ComponentServiceBase.json +481 -0
  64. package/artifacts/contracts/instance/base/IInstanceBase.sol/IInstanceBase.dbg.json +4 -0
  65. package/artifacts/contracts/instance/base/IInstanceBase.sol/IInstanceBase.json +113 -0
  66. package/artifacts/contracts/instance/base/IKeyValueStore.sol/IKeyValueStore.dbg.json +1 -1
  67. package/artifacts/contracts/instance/base/IKeyValueStore.sol/IKeyValueStore.json +0 -77
  68. package/artifacts/contracts/instance/base/ILifecycle.sol/ILifecycle.dbg.json +1 -1
  69. package/artifacts/contracts/instance/base/KeyValueStore.sol/KeyValueStore.dbg.json +1 -1
  70. package/artifacts/contracts/instance/base/KeyValueStore.sol/KeyValueStore.json +10 -244
  71. package/artifacts/contracts/instance/base/Lifecycle.sol/Lifecycle.dbg.json +1 -1
  72. package/artifacts/contracts/instance/base/Lifecycle.sol/Lifecycle.json +2 -2
  73. package/artifacts/contracts/instance/module/IAccess.sol/IAccess.dbg.json +1 -1
  74. package/artifacts/contracts/instance/module/IBundle.sol/IBundle.dbg.json +1 -1
  75. package/artifacts/contracts/instance/module/IDistribution.sol/IDistribution.dbg.json +1 -1
  76. package/artifacts/contracts/instance/module/IPolicy.sol/IPolicy.dbg.json +1 -1
  77. package/artifacts/contracts/instance/module/IRisk.sol/IRisk.dbg.json +1 -1
  78. package/artifacts/contracts/instance/module/ISetup.sol/ISetup.dbg.json +1 -1
  79. package/artifacts/contracts/instance/module/ITreasury.sol/ITreasury.dbg.json +1 -1
  80. package/artifacts/contracts/instance/service/ComponentOwnerService.sol/ComponentOwnerService.dbg.json +4 -0
  81. package/artifacts/contracts/instance/service/ComponentOwnerService.sol/ComponentOwnerService.json +827 -0
  82. package/artifacts/contracts/instance/service/DistributionService.sol/DistributionService.dbg.json +4 -0
  83. package/artifacts/contracts/instance/service/DistributionService.sol/DistributionService.json +641 -0
  84. package/artifacts/contracts/instance/service/DistributionServiceManager.sol/DistributionServiceManager.dbg.json +4 -0
  85. package/artifacts/contracts/instance/service/DistributionServiceManager.sol/DistributionServiceManager.json +428 -0
  86. package/artifacts/contracts/instance/service/IComponentOwnerService.sol/IComponentOwnerService.dbg.json +4 -0
  87. package/artifacts/contracts/instance/service/IComponentOwnerService.sol/IComponentOwnerService.json +466 -0
  88. package/artifacts/contracts/instance/service/IDistributionService.sol/IDistributionService.dbg.json +4 -0
  89. package/artifacts/contracts/instance/service/IDistributionService.sol/IDistributionService.json +446 -0
  90. package/artifacts/contracts/instance/service/IPoolService.sol/IPoolService.dbg.json +4 -0
  91. package/artifacts/contracts/instance/service/IPoolService.sol/IPoolService.json +561 -0
  92. package/artifacts/contracts/instance/service/IProductService.sol/IProductService.dbg.json +4 -0
  93. package/artifacts/contracts/instance/service/IProductService.sol/IProductService.json +751 -0
  94. package/artifacts/contracts/registry/ChainNft.sol/ChainNft.dbg.json +1 -1
  95. package/artifacts/contracts/registry/ChainNft.sol/ChainNft.json +47 -2
  96. package/artifacts/contracts/registry/IRegistry.sol/IRegistry.dbg.json +1 -1
  97. package/artifacts/contracts/registry/IRegistry.sol/IRegistry.json +292 -103
  98. package/artifacts/contracts/registry/IRegistryService.sol/IRegistryService.dbg.json +1 -1
  99. package/artifacts/contracts/registry/IRegistryService.sol/IRegistryService.json +123 -15
  100. package/artifacts/contracts/registry/ITransferInterceptor.sol/ITransferInterceptor.dbg.json +1 -1
  101. package/artifacts/contracts/registry/Registry.sol/Registry.dbg.json +1 -1
  102. package/artifacts/contracts/registry/Registry.sol/Registry.json +249 -143
  103. package/artifacts/contracts/registry/RegistryService.sol/RegistryService.dbg.json +1 -1
  104. package/artifacts/contracts/registry/RegistryService.sol/RegistryService.json +272 -48
  105. package/artifacts/contracts/registry/RegistryServiceManager.sol/RegistryServiceManager.dbg.json +1 -1
  106. package/artifacts/contracts/registry/RegistryServiceManager.sol/RegistryServiceManager.json +79 -30
  107. package/artifacts/contracts/registry/TokenRegistry.sol/TokenRegistry.dbg.json +4 -0
  108. package/artifacts/contracts/registry/TokenRegistry.sol/TokenRegistry.json +410 -0
  109. package/artifacts/contracts/shared/ContractDeployerLib.sol/ContractDeployerLib.dbg.json +1 -1
  110. package/artifacts/contracts/shared/ERC165.sol/ERC165.dbg.json +1 -1
  111. package/artifacts/contracts/shared/ERC165.sol/ERC165.json +2 -2
  112. package/artifacts/contracts/shared/INftOwnable.sol/INftOwnable.dbg.json +1 -1
  113. package/artifacts/contracts/shared/IRegisterable.sol/IRegisterable.dbg.json +1 -1
  114. package/artifacts/contracts/shared/IService.sol/IService.dbg.json +4 -0
  115. package/artifacts/contracts/{instance/base → shared}/IService.sol/IService.json +1 -1
  116. package/artifacts/contracts/shared/IVersionable.sol/IVersionable.dbg.json +1 -1
  117. package/artifacts/contracts/shared/NftOwnable.sol/NftOwnable.dbg.json +1 -1
  118. package/artifacts/contracts/shared/NftOwnable.sol/NftOwnable.json +2 -2
  119. package/artifacts/contracts/shared/ProxyManager.sol/ProxyManager.dbg.json +1 -1
  120. package/artifacts/contracts/shared/ProxyManager.sol/ProxyManager.json +2 -2
  121. package/artifacts/contracts/shared/Registerable.sol/Registerable.dbg.json +1 -1
  122. package/artifacts/contracts/shared/Registerable.sol/Registerable.json +6 -6
  123. package/artifacts/contracts/shared/RegisterableUpgradable.sol/RegisterableUpgradable.dbg.json +4 -0
  124. package/artifacts/contracts/shared/RegisterableUpgradable.sol/RegisterableUpgradable.json +442 -0
  125. package/artifacts/contracts/shared/Service.sol/Service.dbg.json +4 -0
  126. package/artifacts/contracts/{instance/base/ServiceBase.sol/ServiceBase.json → shared/Service.sol/Service.json} +2 -2
  127. package/artifacts/contracts/shared/TokenHandler.sol/TokenHandler.dbg.json +1 -1
  128. package/artifacts/contracts/shared/TokenHandler.sol/TokenHandler.json +2 -2
  129. package/artifacts/contracts/shared/UpgradableProxyWithAdmin.sol/UpgradableProxyWithAdmin.dbg.json +1 -1
  130. package/artifacts/contracts/shared/UpgradableProxyWithAdmin.sol/UpgradableProxyWithAdmin.json +2 -2
  131. package/artifacts/contracts/shared/Versionable.sol/Versionable.dbg.json +1 -1
  132. package/artifacts/contracts/test/TestFee.sol/TestFee.dbg.json +1 -1
  133. package/artifacts/contracts/test/TestFee.sol/TestFee.json +4 -4
  134. package/artifacts/contracts/test/TestRegisterable.sol/TestRegisterable.dbg.json +1 -1
  135. package/artifacts/contracts/test/TestRegisterable.sol/TestRegisterable.json +6 -6
  136. package/artifacts/contracts/test/TestRoleId.sol/TestRoleId.dbg.json +1 -1
  137. package/artifacts/contracts/test/TestRoleId.sol/TestRoleId.json +111 -5
  138. package/artifacts/contracts/test/TestService.sol/TestService.dbg.json +1 -1
  139. package/artifacts/contracts/test/TestService.sol/TestService.json +17 -17
  140. package/artifacts/contracts/test/TestToken.sol/TestUsdc.dbg.json +1 -1
  141. package/artifacts/contracts/test/TestToken.sol/TestUsdc.json +91 -53
  142. package/artifacts/contracts/test/TestVersion.sol/TestVersion.dbg.json +1 -1
  143. package/artifacts/contracts/test/TestVersion.sol/TestVersion.json +2 -2
  144. package/artifacts/contracts/test/TestVersionable.sol/TestVersionable.dbg.json +1 -1
  145. package/artifacts/contracts/test/TestVersionable.sol/TestVersionable.json +2 -2
  146. package/artifacts/contracts/test/Usdc.sol/USDC.dbg.json +1 -1
  147. package/artifacts/contracts/test/Usdc.sol/USDC.json +91 -53
  148. package/artifacts/contracts/types/AddressSet.sol/LibAddressSet.dbg.json +1 -1
  149. package/artifacts/contracts/types/Blocknumber.sol/BlocknumberLib.dbg.json +1 -1
  150. package/artifacts/contracts/types/ChainId.sol/ChainIdLib.dbg.json +1 -1
  151. package/artifacts/contracts/types/DistributorType.sol/DistributorTypeLib.dbg.json +1 -1
  152. package/artifacts/contracts/types/Fee.sol/FeeLib.dbg.json +1 -1
  153. package/artifacts/contracts/types/Fee.sol/FeeLib.json +4 -4
  154. package/artifacts/contracts/types/Key32.sol/Key32Lib.dbg.json +1 -1
  155. package/artifacts/contracts/types/NftId.sol/NftIdLib.dbg.json +1 -1
  156. package/artifacts/contracts/types/NftIdSet.sol/LibNftIdSet.dbg.json +1 -1
  157. package/artifacts/contracts/types/NumberId.sol/NumberIdLib.dbg.json +1 -1
  158. package/artifacts/contracts/types/ObjectType.sol/ObjectTypeLib.dbg.json +1 -1
  159. package/artifacts/contracts/types/Referral.sol/ReferralLib.dbg.json +1 -1
  160. package/artifacts/contracts/types/RiskId.sol/RiskIdLib.dbg.json +1 -1
  161. package/artifacts/contracts/types/RoleId.sol/RoleIdLib.dbg.json +1 -1
  162. package/artifacts/contracts/types/RoleId.sol/RoleIdLib.json +2 -2
  163. package/artifacts/contracts/types/StateId.sol/StateIdLib.dbg.json +1 -1
  164. package/artifacts/contracts/types/StateId.sol/StateIdLib.json +2 -2
  165. package/artifacts/contracts/types/Timestamp.sol/TimestampLib.dbg.json +1 -1
  166. package/artifacts/contracts/types/UFixed.sol/MathLib.dbg.json +4 -0
  167. package/artifacts/contracts/types/UFixed.sol/MathLib.json +10 -0
  168. package/artifacts/contracts/types/UFixed.sol/UFixedLib.dbg.json +4 -0
  169. package/artifacts/contracts/types/UFixed.sol/{UFixedMathLib.json → UFixedLib.json} +3 -3
  170. package/artifacts/contracts/types/Version.sol/VersionLib.dbg.json +1 -1
  171. package/artifacts/contracts/types/Version.sol/VersionLib.json +2 -2
  172. package/artifacts/contracts/types/Version.sol/VersionPartLib.dbg.json +1 -1
  173. package/artifacts/contracts/types/Version.sol/VersionPartLib.json +22 -3
  174. package/contracts/components/BaseComponent.sol +91 -0
  175. package/contracts/components/Distribution.sol +166 -0
  176. package/contracts/components/IBaseComponent.sol +8 -2
  177. package/contracts/components/IDistributionComponent.sol +46 -0
  178. package/contracts/components/IPoolComponent.sol +62 -0
  179. package/contracts/components/IProductComponent.sol +35 -0
  180. package/contracts/components/Pool.sol +258 -0
  181. package/contracts/components/Product.sol +297 -0
  182. package/contracts/experiment/cloning/Cloner.sol +47 -0
  183. package/contracts/instance/AccessManagedSimple.sol +9 -8
  184. package/contracts/instance/AccessManagerSimple.sol +12 -2
  185. package/contracts/instance/IAccessManagerSimple.sol +1 -1
  186. package/contracts/instance/IInstance.sol +28 -1
  187. package/contracts/instance/IInstanceService.sol +30 -0
  188. package/contracts/instance/Instance.sol +61 -10
  189. package/contracts/instance/InstanceAccessManager.sol +3 -3
  190. package/contracts/instance/InstanceReader.sol +63 -8
  191. package/contracts/instance/InstanceService.sol +131 -18
  192. package/contracts/instance/InstanceServiceManager.sol +56 -0
  193. package/contracts/instance/base/ComponentServiceBase.sol +39 -0
  194. package/contracts/instance/base/IInstanceBase.sol +23 -0
  195. package/contracts/instance/base/IKeyValueStore.sol +5 -4
  196. package/contracts/instance/base/KeyValueStore.sol +4 -20
  197. package/contracts/instance/module/IAccess.sol +2 -2
  198. package/contracts/instance/module/ISetup.sol +3 -1
  199. package/contracts/instance/module/ITreasury.sol +1 -1
  200. package/contracts/instance/service/ComponentOwnerService.sol +317 -0
  201. package/contracts/instance/service/DistributionService.sol +96 -0
  202. package/contracts/instance/service/DistributionServiceManager.sol +53 -0
  203. package/contracts/instance/service/IComponentOwnerService.sol +20 -0
  204. package/contracts/instance/service/IDistributionService.sol +12 -0
  205. package/contracts/instance/service/IPoolService.sol +37 -0
  206. package/contracts/instance/service/IProductService.sol +107 -0
  207. package/contracts/registry/ChainNft.sol +40 -25
  208. package/contracts/registry/IRegistry.sol +43 -22
  209. package/contracts/registry/IRegistryService.sol +16 -12
  210. package/contracts/registry/Registry.sol +163 -165
  211. package/contracts/registry/RegistryService.sol +168 -138
  212. package/contracts/registry/RegistryServiceManager.sol +39 -2
  213. package/contracts/registry/TokenRegistry.sol +111 -0
  214. package/contracts/shared/ERC165.sol +7 -3
  215. package/contracts/shared/IRegisterable.sol +1 -1
  216. package/contracts/{instance/base → shared}/IService.sol +3 -3
  217. package/contracts/shared/ProxyManager.sol +3 -3
  218. package/contracts/shared/Registerable.sol +3 -2
  219. package/contracts/shared/RegisterableUpgradable.sol +16 -0
  220. package/contracts/shared/Service.sol +54 -0
  221. package/contracts/shared/TokenHandler.sol +2 -2
  222. package/contracts/shared/UpgradableProxyWithAdmin.sol +2 -2
  223. package/contracts/shared/Versionable.sol +1 -1
  224. package/contracts/test/TestFee.sol +2 -2
  225. package/contracts/test/TestRoleId.sol +6 -6
  226. package/contracts/test/TestService.sol +3 -5
  227. package/contracts/types/Fee.sol +3 -3
  228. package/contracts/types/RoleId.sol +17 -4
  229. package/contracts/types/StateId.sol +4 -0
  230. package/contracts/types/UFixed.sol +128 -12
  231. package/contracts/types/Version.sol +4 -1
  232. package/package.json +4 -3
  233. package/artifacts/contracts/instance/base/IService.sol/IService.dbg.json +0 -4
  234. package/artifacts/contracts/instance/base/ServiceBase.sol/ServiceBase.dbg.json +0 -4
  235. package/artifacts/contracts/registry/IChainNft.sol/IChainNft.dbg.json +0 -4
  236. package/artifacts/contracts/registry/IChainNft.sol/IChainNft.json +0 -457
  237. package/artifacts/contracts/types/UFixed.sol/UFixedMathLib.dbg.json +0 -4
  238. package/contracts/instance/base/ServiceBase.sol +0 -44
  239. package/contracts/registry/IChainNft.sol +0 -22
@@ -1,169 +1,187 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  pragma solidity ^0.8.20;
3
3
 
4
- import {IERC20Metadata} from "@openzeppelin5/contracts/token/ERC20/extensions/IERC20Metadata.sol";
4
+ import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
5
+ import {AccessManagedUpgradeable} from "@openzeppelin/contracts-upgradeable/access/manager/AccessManagedUpgradeable.sol";
5
6
 
6
- import {IRegistry} from "../registry/IRegistry.sol";
7
- // import {IInstance} from "../instance/IInstance.sol";
7
+ import {IRegistry} from "./IRegistry.sol";
8
+ import {IInstance} from "../instance/IInstance.sol";
8
9
 
9
10
  import {ContractDeployerLib} from "../shared/ContractDeployerLib.sol";
10
11
  // import {IComponent, IComponentModule} from "../../contracts/instance/module/component/IComponent.sol";
11
12
  // import {IPool} from "../../contracts/instance/module/pool/IPoolModule.sol";
12
13
  import {IBaseComponent} from "../../contracts/components/IBaseComponent.sol";
13
- // import {IPoolComponent} from "../../contracts/components/IPoolComponent.sol";
14
- // import {IProductComponent} from "../../contracts/components/IProductComponent.sol";
15
- // import {IDistributionComponent} from "../../contracts/components/IDistributionComponent.sol";
14
+ import {IPoolComponent} from "../../contracts/components/IPoolComponent.sol";
15
+ import {IProductComponent} from "../../contracts/components/IProductComponent.sol";
16
+ import {IDistributionComponent} from "../../contracts/components/IDistributionComponent.sol";
16
17
 
17
18
  import {IVersionable} from "../../contracts/shared/IVersionable.sol";
18
19
  import {Versionable} from "../../contracts/shared/Versionable.sol";
19
20
  import {IRegisterable} from "../../contracts/shared/IRegisterable.sol";
20
21
 
21
- import {RoleId} from "../../contracts/types/RoleId.sol";
22
- import {ObjectType, REGISTRY, TOKEN, SERVICE, PRODUCT, ORACLE, POOL, TOKEN, INSTANCE, DISTRIBUTION, POLICY, BUNDLE} from "../../contracts/types/ObjectType.sol";
22
+ import {RoleId, PRODUCT_OWNER_ROLE, POOL_OWNER_ROLE, ORACLE_OWNER_ROLE} from "../../contracts/types/RoleId.sol";
23
+ import {ObjectType, REGISTRY, SERVICE, PRODUCT, ORACLE, POOL, INSTANCE, DISTRIBUTION, POLICY, BUNDLE} from "../../contracts/types/ObjectType.sol";
23
24
  import {StateId, ACTIVE, PAUSED} from "../../contracts/types/StateId.sol";
24
25
  import {NftId, NftIdLib, zeroNftId} from "../../contracts/types/NftId.sol";
25
26
  import {Fee, FeeLib} from "../../contracts/types/Fee.sol";
26
27
  import {Version, VersionPart, VersionLib} from "../../contracts/types/Version.sol";
27
28
 
28
- import {ServiceBase} from "../../contracts/instance/base/ServiceBase.sol";
29
- import {IService} from "../../contracts/instance/base/IService.sol";
29
+ import {Service} from "../shared/Service.sol";
30
+ import {IService} from "../shared/IService.sol";
30
31
  import {IRegistryService} from "./IRegistryService.sol";
31
- import {Registry} from "../registry/Registry.sol";
32
+ import {Registry} from "./Registry.sol";
33
+ import {ChainNft} from "./ChainNft.sol";
32
34
 
33
35
  contract RegistryService is
34
- ServiceBase,
36
+ AccessManagedUpgradeable,
37
+ Service,
35
38
  IRegistryService
36
39
  {
37
40
  using NftIdLib for NftId;
38
41
 
42
+ // TODO move errors to interface contract
43
+ error SelfRegistration();
39
44
  error NotRegistryOwner();
40
- error MissingAllowance();
41
45
 
42
- error NotToken();
43
46
  error NotService();
44
- error NotComponent();
45
47
  error NotInstance();
46
-
47
- error InvalidAddress(address registerableAddress);
48
+ error NotProduct();
49
+ error NotPool();
50
+ error NotDistribution();
51
+
52
+ error UnexpectedRegisterableType(ObjectType expected, ObjectType found);
53
+ error NotRegisterableOwner(address expectedOwner);
54
+ error RegisterableOwnerIsZero();
55
+ error RegisterableOwnerIsRegistered();
48
56
  error InvalidInitialOwner(address initialOwner);
49
- error SelfRegistration();
50
- error InvalidType(ObjectType objectType);
57
+ error InvalidAddress(address registerableAddress);
51
58
 
59
+ // Initial value for constant variable has to be compile-time constant
60
+ // TODO define types as constants?
61
+ //ObjectType public constant SERVICE_TYPE = REGISTRY();
52
62
  string public constant NAME = "RegistryService";
53
63
 
54
64
  // TODO update to real hash when registry is stable
55
65
  bytes32 public constant REGISTRY_CREATION_CODE_HASH = bytes32(0);
56
66
 
57
- address constant public NFT_LOCK_ADDRESS = address(0x1);
67
+ address public constant NFT_LOCK_ADDRESS = address(0x1);
58
68
 
59
69
  /// @dev
60
70
  // msg.sender - ONLY registry owner
61
- // CAN register ANY non IRegisterable address
62
- // CAN register ONLY valid object-parent types combinations for TOKEN
63
71
  // CAN NOT register itself
64
- // IMPORTANT: MUST NOT call untrusted contract inbetween calls to registry/instance (trusted contracts)
65
- // motivation: registry/instance state may change during external call
66
- // TODO it may be usefull to have transferable token nft in order to delist token, make it invalid for new beginings
67
- // TODO: MUST prohibit registration of precompiles addresses
68
- function registerToken(address tokenAddress)
69
- external
70
- returns(NftId nftId)
72
+ // CAN register ONLY valid object-parent types combinations for SERVICE
73
+ // CAN register ONLY IRegisterable address he owns
74
+ // IMPORTANT: MUST NOT check owner before calling external contract
75
+ function registerService(IService service)
76
+ external
77
+ // TODO restrict access - registryService.registerService must use accessmanager for checking permissions as
78
+ // services are not always owned by registry owner - actually only registry service is owned by registry owner
79
+
80
+ returns(
81
+ IRegistry.ObjectInfo memory info,
82
+ bytes memory data
83
+ )
71
84
  {
72
- IRegisterable registerable = IRegisterable(tokenAddress);
73
- bool isRegisterable;
74
-
75
- // registryOwner can not register IRegisterable as TOKEN
76
- try registerable.supportsInterface(type(IRegisterable).interfaceId) returns(bool result) {
77
- isRegisterable = result;
78
- } catch {
79
- isRegisterable = false;
85
+
86
+ // CAN revert if no ERC165 support -> will revert with empty message
87
+ if(!service.supportsInterface(type(IService).interfaceId)) {
88
+ revert NotService();
80
89
  }
81
90
 
82
- if(isRegisterable) {
83
- revert NotToken();
84
- }
91
+ (
92
+ info,
93
+ data
94
+ ) = _getAndVerifyContractInfo(service, SERVICE(), msg.sender);
95
+
96
+ info.nftId = _registry.register(info);
97
+ service.linkToRegisteredNftId();
98
+ return (
99
+ info,
100
+ data
101
+ );
102
+ }
85
103
 
86
- NftId registryNftId = _registry.getNftId(address(_registry));
87
- if(msg.sender != _registry.ownerOf(registryNftId)) {
88
- revert NotRegistryOwner();
104
+ // If msg.sender is approved service:
105
+ // 1) add owner arg (service MUST pass it's msg.sender as owner)
106
+ // 2) check service allowance
107
+ // 3) comment self registrstion check
108
+ //function registerInstance(IRegisterable instance, address owner)
109
+ function registerInstance(IRegisterable instance)
110
+ external
111
+ returns(
112
+ IRegistry.ObjectInfo memory info,
113
+ bytes memory data
114
+ )
115
+ {
116
+ if(!instance.supportsInterface(type(IInstance).interfaceId)) {
117
+ revert NotInstance();
89
118
  }
90
119
 
91
- IRegistry.ObjectInfo memory info = IRegistry.ObjectInfo(
92
- zeroNftId(), // any value
93
- registryNftId, // parent nft id
94
- TOKEN(),
95
- false, // isInterceptor
96
- tokenAddress,
97
- NFT_LOCK_ADDRESS,
98
- "" // any value
99
- );
120
+ (
121
+ info,
122
+ data
123
+ ) = _getAndVerifyContractInfo(instance, INSTANCE(), msg.sender);
100
124
 
101
- nftId = _registry.register(info);
125
+ info.nftId = _registry.register(info);
126
+ instance.linkToRegisteredNftId(); // asume safe
127
+
128
+ return (
129
+ info,
130
+ data
131
+ );
102
132
  }
103
133
 
104
- /// @dev
105
- // msg.sender - ONLY registry owner
106
- // CAN register ONLY valid object-parent types combinations for SERVICE
107
- // CAN register ONLY IRegisterable address he owns
108
- // CAN NOT register itself
109
- // IMPORTANT: MUST NOT check owner before calling external contract
110
- function registerService(IService service)
134
+ function registerProduct(IBaseComponent product, address owner)
111
135
  external
136
+ restricted
112
137
  returns(
113
138
  IRegistry.ObjectInfo memory info,
114
139
  bytes memory data
115
140
  )
116
141
  {
117
- if(service.supportsInterface(type(IService).interfaceId) == false) {
118
- revert NotService();
119
- }
142
+ // CAN revert if no ERC165 support -> will revert with empty message
143
+ if(!product.supportsInterface(type(IProductComponent).interfaceId)) {
144
+ revert NotProduct();
145
+ }
120
146
 
121
147
  (
122
148
  info,
123
149
  data
124
- ) = _getAndVerifyContractInfo(service, SERVICE(), msg.sender);
150
+ ) = _getAndVerifyContractInfo(product, PRODUCT(), owner);
125
151
 
126
- NftId registryNftId = _registry.getNftId(address(_registry));
127
- if(msg.sender != _registry.ownerOf(registryNftId)) {
128
- revert NotRegistryOwner();
129
- }
152
+ NftId serviceNftId = _registry.getNftId(msg.sender);
130
153
 
131
- info.initialOwner = NFT_LOCK_ADDRESS;//registry.getLockAddress();
132
154
  info.nftId = _registry.register(info);
133
- service.linkToRegisteredNftId();
155
+ // TODO unsafe, let component or its owner derive nftId latter, when state assumptions and modifications of GIF contracts are finished
156
+ product.linkToRegisteredNftId();
134
157
 
135
158
  return (
136
159
  info,
137
160
  data
138
- );
161
+ );
139
162
  }
140
163
 
141
- // anybody can register component if instance gives a corresponding role
142
- //function registerComponent(IBaseComponent component, ObjectType componentType)
143
- function registerComponent(IBaseComponent component, ObjectType componentType, address owner)
164
+ function registerPool(IBaseComponent pool, address owner)
144
165
  external
166
+ restricted
145
167
  returns(
146
168
  IRegistry.ObjectInfo memory info,
147
169
  bytes memory data
148
170
  )
149
171
  {
150
- if(!component.supportsInterface(type(IBaseComponent).interfaceId)) {
151
- revert NotComponent();
172
+ if(!pool.supportsInterface(type(IPoolComponent).interfaceId)) {
173
+ revert NotPool();
152
174
  }
153
175
 
154
176
  (
155
177
  info,
156
178
  data
157
- ) = _getAndVerifyContractInfo(component, componentType, owner);
179
+ ) = _getAndVerifyContractInfo(pool, POOL(), owner);
158
180
 
159
181
  NftId serviceNftId = _registry.getNftId(msg.sender);
160
182
 
161
- if(!_registry.allowance(serviceNftId, componentType)) {
162
- revert MissingAllowance();
163
- }
164
-
165
183
  info.nftId = _registry.register(info);
166
- component.linkToRegisteredNftId();
184
+ pool.linkToRegisteredNftId();
167
185
 
168
186
  return (
169
187
  info,
@@ -171,58 +189,53 @@ contract RegistryService is
171
189
  );
172
190
  }
173
191
 
174
- // TODO: when called by approved service: add owner arg (service must pass it's msg.sender as owner) & check service allowance
175
- //function registerInstance(IRegisterable instance, address owner)
176
- function registerInstance(IRegisterable instance)
177
- external
192
+ function registerDistribution(IBaseComponent distribution, address owner)
193
+ external
194
+ restricted
178
195
  returns(
179
196
  IRegistry.ObjectInfo memory info,
180
197
  bytes memory data
181
198
  )
182
199
  {
183
- // TODO reactivate later
184
- // if(instance.supportsInterface(type(IInstance).interfaceId) == false) {
185
- // revert NotInstance();
186
- // }
187
-
188
- // (
189
- // info,
190
- // data
191
- // ) = _getAndVerifyContractInfo(instance, INSTANCE(), msg.sender);// owner);
192
-
193
- // info.nftId = _registry.register(info);
194
- // instance.linkToRegisteredNftId();
195
-
196
- // return (
197
- // info,
198
- // data
199
- // );
200
+ if(!distribution.supportsInterface(type(IDistributionComponent).interfaceId)) {
201
+ revert NotDistribution();
202
+ }
203
+
204
+ (
205
+ info,
206
+ data
207
+ ) = _getAndVerifyContractInfo(distribution, DISTRIBUTION(), owner);
208
+
209
+ NftId serviceNftId = _registry.getNftId(msg.sender);
210
+
211
+ info.nftId = _registry.register(info);
212
+ distribution.linkToRegisteredNftId();
213
+
214
+ return (
215
+ info,
216
+ data
217
+ );
200
218
  }
201
219
 
202
220
  function registerPolicy(IRegistry.ObjectInfo memory info)
203
- external
221
+ external
222
+ restricted
204
223
  returns(NftId nftId)
205
224
  {
206
225
  NftId senderNftId = _registry.getNftId(msg.sender);
207
226
 
208
- if(_registry.allowance(senderNftId, POLICY()) == false) {
209
- revert MissingAllowance();
210
- }
211
-
212
227
  _verifyObjectInfo(info, POLICY());
213
228
 
214
229
  nftId = _registry.register(info);
215
230
  }
216
231
 
217
232
  function registerBundle(IRegistry.ObjectInfo memory info)
218
- external
233
+ external
234
+ restricted
219
235
  returns(NftId nftId)
220
236
  {
221
- NftId senderNftId = _registry.getNftId(msg.sender);
222
237
 
223
- if(_registry.allowance(senderNftId, BUNDLE()) == false) {
224
- revert MissingAllowance();
225
- }
238
+ NftId senderNftId = _registry.getNftId(msg.sender);
226
239
 
227
240
  _verifyObjectInfo(info, BUNDLE());
228
241
 
@@ -231,9 +244,12 @@ contract RegistryService is
231
244
 
232
245
 
233
246
  // From IService
234
- function getName() public pure override(IService, ServiceBase) returns(string memory) {
247
+ function getName() public pure override(IService, Service) returns(string memory) {
235
248
  return NAME;
236
249
  }
250
+ //function getType() public pure override(IService, ServiceBase) returns(ObjectType serviceType) {
251
+ // return SERVICE_TYPE;
252
+ //}
237
253
 
238
254
 
239
255
  // from Versionable
@@ -245,12 +261,19 @@ contract RegistryService is
245
261
  // registry is getting instantiated and locked to registry service address forever
246
262
  function _initialize(
247
263
  address owner,
248
- bytes memory registryByteCodeWithInitCode
264
+ bytes memory data
249
265
  )
250
266
  internal
251
267
  initializer
252
268
  virtual override
253
269
  {
270
+ (
271
+ address initialAuthority,
272
+ bytes memory registryByteCodeWithInitCode
273
+ ) = abi.decode(data, (address, bytes));
274
+
275
+ __AccessManaged_init(initialAuthority);
276
+
254
277
  bytes memory encodedConstructorArguments = abi.encode(
255
278
  owner,
256
279
  getMajorVersion());
@@ -259,26 +282,28 @@ contract RegistryService is
259
282
  registryByteCodeWithInitCode,
260
283
  encodedConstructorArguments);
261
284
 
262
- address registryAddress = ContractDeployerLib.deploy(
285
+ IRegistry registry = IRegistry(ContractDeployerLib.deploy(
263
286
  registryCreationCode,
264
- REGISTRY_CREATION_CODE_HASH);
287
+ REGISTRY_CREATION_CODE_HASH));
265
288
 
266
- IRegistry registry = IRegistry(registryAddress);
267
- NftId registryNftId = registry.getNftId(registryAddress);
289
+ NftId registryNftId = registry.getNftId(address(registry));
268
290
 
269
- _initializeServiceBase(registryAddress, registryNftId, owner);
270
- linkToRegisteredNftId();
291
+ _initializeService(address(registry), owner);
271
292
 
293
+ // TODO why do registry service proxy need to keep its nftId??? -> no registryServiceNftId checks in implementation
294
+ // if they are -> use registry address to obtain owner of registry service nft (works the same with any registerable and(or) implementation)
295
+ linkToRegisteredNftId();
272
296
  _registerInterface(type(IRegistryService).interfaceId);
273
297
  }
274
298
 
275
299
  // parent check done in registry because of approve()
276
300
  function _getAndVerifyContractInfo(
277
301
  IRegisterable registerable,
278
- ObjectType objectType,
279
- address owner
302
+ ObjectType expectedType, // assume can be valid only
303
+ address expectedOwner // assume can be 0
280
304
  )
281
305
  internal
306
+ view
282
307
  returns(
283
308
  IRegistry.ObjectInfo memory info,
284
309
  bytes memory data
@@ -288,23 +313,33 @@ contract RegistryService is
288
313
  info,
289
314
  data
290
315
  ) = registerable.getInitialInfo();
316
+ info.objectAddress = address(registerable);
291
317
 
292
- if(info.objectAddress != address(registerable)) {
293
- revert InvalidAddress(info.objectAddress);
318
+ if(info.objectType != expectedType) {// type is checked in registry anyway...but service logic may depend on expected value
319
+ revert UnexpectedRegisterableType(expectedType, info.objectType);
294
320
  }
295
321
 
296
- if(
297
- getRegistry().isRegistered(owner) ||
298
- info.initialOwner != owner) { // contract owner protection
299
- revert InvalidInitialOwner(info.initialOwner);
322
+ address owner = info.initialOwner;
323
+
324
+ // solhint-disable-next-line
325
+ if(expectedType == INSTANCE()) {
326
+ // any address may create a new instance via instance service
327
+ } else {
328
+ if(owner != expectedOwner) { // registerable owner protection
329
+ revert NotRegisterableOwner(expectedOwner);
330
+ }
300
331
  }
301
332
 
302
- if(msg.sender == address(registerable)) {
333
+ if(owner == address(registerable)) {
303
334
  revert SelfRegistration();
304
335
  }
336
+
337
+ if(owner == address(0)) {
338
+ revert RegisterableOwnerIsZero();
339
+ }
305
340
 
306
- if(info.objectType != objectType) {
307
- revert InvalidType(info.objectType);
341
+ if(getRegistry().isRegistered(owner)) {
342
+ revert RegisterableOwnerIsRegistered();
308
343
  }
309
344
 
310
345
  /*NftId parentNftId = info.parentNftId;
@@ -354,11 +389,6 @@ contract RegistryService is
354
389
  revert InitialOwnerIsRegistry();
355
390
  }*/
356
391
 
357
-
358
- if(info.objectType != objectType) {
359
- revert InvalidType(info.objectType);
360
- }
361
-
362
392
  /*NftId parentNftId = info.parentNftId;
363
393
  IRegistry.ObjectInfo memory parentInfo = getRegistry().getObjectInfo(parentNftId);
364
394
 
@@ -366,4 +396,4 @@ contract RegistryService is
366
396
  revert InvalidParent(parentNftId);
367
397
  }*/
368
398
  }
369
- }
399
+ }
@@ -1,25 +1,39 @@
1
1
  // SPDX-License-Identifier: UNLICENSED
2
2
  pragma solidity ^0.8.20;
3
3
 
4
+ import {AccessManager} from "@openzeppelin/contracts/access/manager/AccessManager.sol";
5
+
6
+ import {ContractDeployerLib} from "../shared/ContractDeployerLib.sol";
7
+
4
8
  import {Registry} from "./Registry.sol";
5
9
  import {IVersionable} from "../shared/IVersionable.sol";
6
10
  import {ProxyManager} from "../shared/ProxyManager.sol";
7
11
  import {RegistryService} from "./RegistryService.sol";
12
+ import {TokenRegistry} from "./TokenRegistry.sol";
8
13
 
9
14
 
10
15
  contract RegistryServiceManager is
11
16
  ProxyManager
12
17
  {
13
- RegistryService private _registryService;
18
+ bytes32 constant public ACCESS_MANAGER_CREATION_CODE_HASH = 0x0;
19
+
20
+ AccessManager private _accessManager;
21
+ RegistryService private _registryService;
22
+ TokenRegistry private _tokenRegistry;
14
23
 
15
24
  /// @dev initializes proxy manager with registry service implementation and deploys registry
16
25
  constructor(
26
+ address accessManager
17
27
  )
18
28
  ProxyManager()
19
29
  {
30
+ _accessManager = AccessManager(accessManager);
31
+
32
+ bytes memory initializationData = abi.encode(accessManager, type(Registry).creationCode);
33
+
20
34
  IVersionable versionable = deploy(
21
35
  address(new RegistryService()),
22
- type(Registry).creationCode);
36
+ initializationData);
23
37
 
24
38
  _registryService = RegistryService(address(versionable));
25
39
 
@@ -28,11 +42,26 @@ contract RegistryServiceManager is
28
42
  address(_registryService.getRegistry()),
29
43
  address(_registryService));
30
44
 
45
+ // deploy token registry
46
+
47
+ // _tokenRegistry = new TokenRegistry(
48
+ // address(_registryService.getRegistry()),
49
+ // address(_registryService));
50
+
31
51
  // implies that after this constructor call only upgrade functionality is available
32
52
  _isDeployed = true;
33
53
  }
34
54
 
35
55
  //--- view functions ----------------------------------------------------//
56
+
57
+ function getAccessManager()
58
+ external
59
+ view
60
+ returns (AccessManager)
61
+ {
62
+ return _accessManager;
63
+ }
64
+
36
65
  function getRegistryService()
37
66
  external
38
67
  view
@@ -40,4 +69,12 @@ contract RegistryServiceManager is
40
69
  {
41
70
  return _registryService;
42
71
  }
72
+
73
+ function getTokenRegistry()
74
+ external
75
+ view
76
+ returns (TokenRegistry)
77
+ {
78
+ return _tokenRegistry;
79
+ }
43
80
  }
@@ -0,0 +1,111 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.20;
3
+
4
+ import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
5
+ import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
6
+
7
+ import {IRegisterable} from "../shared/IRegisterable.sol";
8
+ import {IRegistry} from "./IRegistry.sol";
9
+ import {Version, VersionPart, VersionLib, VersionPartLib} from "../types/Version.sol";
10
+ import {NftOwnable} from "../shared/NftOwnable.sol";
11
+
12
+ /// @title contract to register token per GIF major release.
13
+ contract TokenRegistry is
14
+ NftOwnable
15
+ {
16
+
17
+ string public constant REGISTRY_SERVICE_NAME = "RegistryService";
18
+
19
+ event LogRegistered(address token, string symbol, uint256 decimals);
20
+ event LogTokenStateSet(address token, VersionPart majorVersion, bool active);
21
+
22
+ error NotContract(address account);
23
+ error NotToken(address account);
24
+ error TokenDecimalsZero();
25
+ error TokenMajorVersionInvalid(VersionPart majorVersion);
26
+
27
+ address [] internal _token;
28
+ mapping(address token => bool registered) internal _registered;
29
+ mapping(address token => mapping(VersionPart majorVersion => bool isActive)) internal _active;
30
+
31
+ constructor()
32
+ NftOwnable()
33
+ { }
34
+
35
+
36
+ /// @dev link ownership of token registry to nft owner of registry service
37
+ function linkToNftOwnable(address registryAddress)
38
+ external
39
+ onlyOwner
40
+ {
41
+ IRegistry registry = IRegistry(registryAddress);
42
+ address registryServiceAddress = registry.getServiceAddress(REGISTRY_SERVICE_NAME, registry.getMajorVersion());
43
+
44
+ _linkToNftOwnable(registryAddress, registryServiceAddress);
45
+ }
46
+
47
+ /// @dev token state is informative, registry have no clue about used tokens
48
+ // component owner is responsible for token selection and operations
49
+ // service MUST deny registration of component with inactive token
50
+ function setActive(address token, VersionPart majorVersion, bool active)
51
+ external
52
+ onlyOwner
53
+ {
54
+ // verify that token is registered
55
+ if (!_registered[token]) {
56
+ _registerToken(token);
57
+ }
58
+
59
+ // verify valid major version
60
+ // ensure major version increments is one
61
+ uint256 version = majorVersion.toInt();
62
+ if (version < _registry.getMajorVersionMin().toInt() || version > _registry.getMajorVersionMax().toInt()) {
63
+ revert TokenMajorVersionInvalid(majorVersion);
64
+ }
65
+
66
+ _active[token][majorVersion] = active;
67
+
68
+ emit LogTokenStateSet(token, majorVersion, active);
69
+ }
70
+
71
+ function tokens() external view returns (uint256) {
72
+ return _token.length;
73
+ }
74
+
75
+ function getToken(uint256 idx) external view returns (IERC20Metadata token) {
76
+ return IERC20Metadata(_token[idx]);
77
+ }
78
+
79
+ function isRegistered(address token) external view returns (bool) {
80
+ return _registered[token];
81
+ }
82
+
83
+ function isActive(address token, VersionPart majorVersion) external view returns (bool) {
84
+ return _active[token][majorVersion];
85
+ }
86
+
87
+ /// @dev some sanity checks to prevent unintended registration
88
+ function _registerToken(address token) internal {
89
+
90
+ // MUST be contract
91
+ if(token.code.length == 0) {
92
+ revert NotContract(token);
93
+ }
94
+
95
+ // MUST not be GIF registerable
96
+ if(ERC165Checker.supportsInterface(token, type(IRegisterable).interfaceId)) {
97
+ revert NotToken(token);
98
+ }
99
+
100
+ // MUST have decimals > 0
101
+ IERC20Metadata erc20 = IERC20Metadata(token);
102
+ if(erc20.decimals() == 0) {
103
+ revert TokenDecimalsZero();
104
+ }
105
+
106
+ _registered[token] = true;
107
+ _token.push(token);
108
+
109
+ emit LogRegistered(token, erc20.symbol(), erc20.decimals());
110
+ }
111
+ }