@towns-protocol/contracts 0.0.302

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 (396) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +206 -0
  3. package/docs/permitAndStake_integration_guide.md +266 -0
  4. package/docs/swap_integration_guide.md +591 -0
  5. package/package.json +57 -0
  6. package/scripts/common/DeployBase.s.sol +26 -0
  7. package/scripts/common/DeployFacet.s.sol +7 -0
  8. package/scripts/common/Deployer.s.sol +33 -0
  9. package/scripts/common/Interaction.s.sol +51 -0
  10. package/scripts/deployments/diamonds/DeployAppRegistry.s.sol +168 -0
  11. package/scripts/deployments/diamonds/DeployBaseRegistry.s.sol +263 -0
  12. package/scripts/deployments/diamonds/DeployRiverAirdrop.s.sol +203 -0
  13. package/scripts/deployments/diamonds/DeployRiverMigration.s.sol +129 -0
  14. package/scripts/deployments/diamonds/DeployRiverRegistry.s.sol +175 -0
  15. package/scripts/deployments/diamonds/DeploySpace.s.sol +285 -0
  16. package/scripts/deployments/diamonds/DeploySpaceFactory.s.sol +416 -0
  17. package/scripts/deployments/diamonds/DeploySpaceOwner.s.sol +183 -0
  18. package/scripts/deployments/diamonds/DeploySwapRouter.s.sol +176 -0
  19. package/scripts/deployments/diamonds/IDiamondInitHelper.sol +11 -0
  20. package/scripts/deployments/facets/DeployAppAccount.s.sol +51 -0
  21. package/scripts/deployments/facets/DeployAppRegistryFacet.s.sol +69 -0
  22. package/scripts/deployments/facets/DeployArchitect.s.sol +51 -0
  23. package/scripts/deployments/facets/DeployAttestationRegistry.s.sol +36 -0
  24. package/scripts/deployments/facets/DeployBanning.s.sol +30 -0
  25. package/scripts/deployments/facets/DeployChannels.s.sol +35 -0
  26. package/scripts/deployments/facets/DeployCreateSpace.s.sol +42 -0
  27. package/scripts/deployments/facets/DeployDropFacet.s.sol +49 -0
  28. package/scripts/deployments/facets/DeployERC721A.s.sol +48 -0
  29. package/scripts/deployments/facets/DeployERC721ANonTransferable.s.sol +49 -0
  30. package/scripts/deployments/facets/DeployERC721AQueryable.s.sol +30 -0
  31. package/scripts/deployments/facets/DeployEntitlementChecker.s.sol +49 -0
  32. package/scripts/deployments/facets/DeployEntitlementDataQueryable.s.sol +29 -0
  33. package/scripts/deployments/facets/DeployEntitlementsManager.s.sol +33 -0
  34. package/scripts/deployments/facets/DeployExecutorFacet.s.sol +60 -0
  35. package/scripts/deployments/facets/DeployFeatureManager.s.sol +38 -0
  36. package/scripts/deployments/facets/DeployGuardianFacet.s.sol +39 -0
  37. package/scripts/deployments/facets/DeployImplementationRegistry.s.sol +36 -0
  38. package/scripts/deployments/facets/DeployMainnetDelegation.s.sol +43 -0
  39. package/scripts/deployments/facets/DeployMembership.s.sol +77 -0
  40. package/scripts/deployments/facets/DeployMembershipMetadata.s.sol +30 -0
  41. package/scripts/deployments/facets/DeployMembershipToken.s.sol +47 -0
  42. package/scripts/deployments/facets/DeployMerkleAirdrop.s.sol +37 -0
  43. package/scripts/deployments/facets/DeployMetadata.s.sol +39 -0
  44. package/scripts/deployments/facets/DeployMockLegacyArchitect.s.sol +33 -0
  45. package/scripts/deployments/facets/DeployNodeOperator.s.sol +49 -0
  46. package/scripts/deployments/facets/DeployNodeRegistry.s.sol +37 -0
  47. package/scripts/deployments/facets/DeployOperatorRegistry.s.sol +36 -0
  48. package/scripts/deployments/facets/DeployPartnerRegistry.s.sol +41 -0
  49. package/scripts/deployments/facets/DeployPlatformRequirements.s.sol +75 -0
  50. package/scripts/deployments/facets/DeployPrepayFacet.s.sol +31 -0
  51. package/scripts/deployments/facets/DeployPricingModules.s.sol +36 -0
  52. package/scripts/deployments/facets/DeployReferrals.s.sol +34 -0
  53. package/scripts/deployments/facets/DeployReviewFacet.s.sol +31 -0
  54. package/scripts/deployments/facets/DeployRewardsDistributionV2.s.sol +76 -0
  55. package/scripts/deployments/facets/DeployRiverConfig.s.sol +41 -0
  56. package/scripts/deployments/facets/DeployRoles.s.sol +48 -0
  57. package/scripts/deployments/facets/DeploySchemaRegistry.s.sol +35 -0
  58. package/scripts/deployments/facets/DeploySignerFacet.s.sol +47 -0
  59. package/scripts/deployments/facets/DeploySimpleApp.s.sol +10 -0
  60. package/scripts/deployments/facets/DeploySpaceDelegation.s.sol +43 -0
  61. package/scripts/deployments/facets/DeploySpaceEntitlementGated.s.sol +31 -0
  62. package/scripts/deployments/facets/DeploySpaceFactoryInit.s.sol +33 -0
  63. package/scripts/deployments/facets/DeploySpaceOwnerFacet.s.sol +71 -0
  64. package/scripts/deployments/facets/DeployStreamRegistry.s.sol +50 -0
  65. package/scripts/deployments/facets/DeploySwapFacet.s.sol +33 -0
  66. package/scripts/deployments/facets/DeploySwapRouterFacet.s.sol +38 -0
  67. package/scripts/deployments/facets/DeployTipping.s.sol +31 -0
  68. package/scripts/deployments/facets/DeployTokenMigration.s.sol +40 -0
  69. package/scripts/deployments/facets/DeployTownsPoints.s.sol +53 -0
  70. package/scripts/deployments/facets/DeployTreasury.s.sol +30 -0
  71. package/scripts/deployments/facets/DeployUpgradeableBeacon.s.sol +34 -0
  72. package/scripts/deployments/facets/DeployWalletLink.s.sol +56 -0
  73. package/scripts/deployments/facets/DeployXChain.s.sol +35 -0
  74. package/scripts/deployments/utils/DeployAccountFactory.s.sol +40 -0
  75. package/scripts/deployments/utils/DeployEntitlementGatedExample.s.sol +23 -0
  76. package/scripts/deployments/utils/DeployEntrypoint.s.sol +28 -0
  77. package/scripts/deployments/utils/DeployMember.s.sol +95 -0
  78. package/scripts/deployments/utils/DeployMockDiamond.s.sol +7 -0
  79. package/scripts/deployments/utils/DeployMockERC20.s.sol +24 -0
  80. package/scripts/deployments/utils/DeployMockERC721A.s.sol +45 -0
  81. package/scripts/deployments/utils/DeployMockLegacyMembership.s.sol +29 -0
  82. package/scripts/deployments/utils/DeployMockMessenger.s.sol +42 -0
  83. package/scripts/deployments/utils/DeployMockNFT.s.sol +86 -0
  84. package/scripts/deployments/utils/DeployPoapEntitlement.s.sol +16 -0
  85. package/scripts/deployments/utils/DeployProxyBatchDelegation.s.sol +112 -0
  86. package/scripts/deployments/utils/DeploySpaceProxyInitializer.s.sol +28 -0
  87. package/scripts/deployments/utils/DeployTieredLogPricingV2.s.sol +23 -0
  88. package/scripts/deployments/utils/DeployTieredLogPricingV3.s.sol +23 -0
  89. package/scripts/deployments/utils/DeployTownsBase.s.sol +95 -0
  90. package/scripts/deployments/utils/DeployTownsMainnet.s.sol +66 -0
  91. package/scripts/deployments/utils/DeployTownsMulti.s.sol +53 -0
  92. package/scripts/deployments/utils/DeployWrappedTowns.s.sol +52 -0
  93. package/scripts/deployments/utils/LibLayerZeroValues.sol +34 -0
  94. package/scripts/deployments/utils/pricing/TieredLogPricing.s.sol +45 -0
  95. package/scripts/interactions/InteractAirdrop.s.sol +57 -0
  96. package/scripts/interactions/InteractAlphaPost.s.sol +32 -0
  97. package/scripts/interactions/InteractAlphaSparse.s.sol +173 -0
  98. package/scripts/interactions/InteractBaseAlpha.s.sol +84 -0
  99. package/scripts/interactions/InteractBaseBridge.s.sol +48 -0
  100. package/scripts/interactions/InteractBridgeLayerZero.s.sol +102 -0
  101. package/scripts/interactions/InteractClaimCondition.s.sol +56 -0
  102. package/scripts/interactions/InteractCreateSpace.s.sol +50 -0
  103. package/scripts/interactions/InteractDiamondCut.s.sol +47 -0
  104. package/scripts/interactions/InteractDropFacet.s.sol +32 -0
  105. package/scripts/interactions/InteractEnableNewSnapshotFormat.s.sol +27 -0
  106. package/scripts/interactions/InteractEnableNode2NodeAuth.s.sol +27 -0
  107. package/scripts/interactions/InteractMembership.s.sol +42 -0
  108. package/scripts/interactions/InteractMockERC721A.s.sol +20 -0
  109. package/scripts/interactions/InteractNodeOperators.s.sol +41 -0
  110. package/scripts/interactions/InteractPostDeploy.s.sol +59 -0
  111. package/scripts/interactions/InteractPrepay.s.sol +30 -0
  112. package/scripts/interactions/InteractRegisterApp.s.sol +61 -0
  113. package/scripts/interactions/InteractRiverAlpha.s.sol +30 -0
  114. package/scripts/interactions/InteractRiverAlphaSparse.s.sol +117 -0
  115. package/scripts/interactions/InteractRiverMainnet.s.sol +27 -0
  116. package/scripts/interactions/InteractRiverRegistry.s.sol +36 -0
  117. package/scripts/interactions/InteractRiverRegistrySetBlocklist.s.sol +30 -0
  118. package/scripts/interactions/InteractRiverRegistrySetFreq.s.sol +27 -0
  119. package/scripts/interactions/InteractRiverRegistrySetRepl.s.sol +30 -0
  120. package/scripts/interactions/InteractSetDefaultUri.s.sol +20 -0
  121. package/scripts/interactions/InteractSetDefaultUriLocalhost.s.sol +19 -0
  122. package/scripts/interactions/InteractTransferOwnership.s.sol +21 -0
  123. package/scripts/interactions/InteractUpdateMbRecencyCheck.s.sol +27 -0
  124. package/scripts/interactions/InteractUpdateMediaChunkCount.s.sol +27 -0
  125. package/scripts/interactions/InteractUpdateMediaChunkSize.s.sol +27 -0
  126. package/scripts/interactions/helpers/AlphaHelper.sol +149 -0
  127. package/scripts/interactions/helpers/RiverConfigValues.sol +22 -0
  128. package/scripts/interactions/interfaces/IL1StandardBridge.sol +35 -0
  129. package/scripts/interactions/interfaces/IL2StandardBridge.sol +69 -0
  130. package/src/airdrop/drop/DropBase.sol +210 -0
  131. package/src/airdrop/drop/DropClaim.sol +55 -0
  132. package/src/airdrop/drop/DropFacet.sol +176 -0
  133. package/src/airdrop/drop/DropGroup.sol +111 -0
  134. package/src/airdrop/drop/DropStorage.sol +23 -0
  135. package/src/airdrop/drop/IDropFacet.sol +136 -0
  136. package/src/airdrop/points/CheckIn.sol +71 -0
  137. package/src/airdrop/points/ITownsPoints.sol +64 -0
  138. package/src/airdrop/points/TownsPoints.sol +196 -0
  139. package/src/airdrop/points/TownsPointsStorage.sol +22 -0
  140. package/src/apps/BaseApp.sol +62 -0
  141. package/src/apps/ITownsApp.sol +28 -0
  142. package/src/apps/SchemaResolver.sol +170 -0
  143. package/src/apps/facets/attest/AttestationBase.sol +335 -0
  144. package/src/apps/facets/attest/AttestationLib.sol +64 -0
  145. package/src/apps/facets/attest/AttestationRegistry.sol +39 -0
  146. package/src/apps/facets/attest/AttestationStorage.sol +35 -0
  147. package/src/apps/facets/attest/IAttestationRegistry.sol +43 -0
  148. package/src/apps/facets/registry/AppRegistryBase.sol +403 -0
  149. package/src/apps/facets/registry/AppRegistryFacet.sol +173 -0
  150. package/src/apps/facets/registry/AppRegistryStorage.sol +53 -0
  151. package/src/apps/facets/registry/IAppRegistry.sol +159 -0
  152. package/src/apps/facets/schema/ISchema.sol +14 -0
  153. package/src/apps/facets/schema/SchemaBase.sol +88 -0
  154. package/src/apps/facets/schema/SchemaLib.sol +14 -0
  155. package/src/apps/facets/schema/SchemaRegistry.sol +51 -0
  156. package/src/apps/facets/schema/SchemaStorage.sol +34 -0
  157. package/src/apps/helpers/ISimpleApp.sol +51 -0
  158. package/src/apps/helpers/SimpleApp.sol +97 -0
  159. package/src/apps/helpers/SimpleAppStorage.sol +27 -0
  160. package/src/base/registry/facets/checker/EntitlementChecker.sol +237 -0
  161. package/src/base/registry/facets/checker/EntitlementCheckerStorage.sol +28 -0
  162. package/src/base/registry/facets/checker/IEntitlementChecker.sol +95 -0
  163. package/src/base/registry/facets/delegation/ISpaceDelegation.sol +69 -0
  164. package/src/base/registry/facets/delegation/SpaceDelegationFacet.sol +250 -0
  165. package/src/base/registry/facets/delegation/SpaceDelegationStorage.sol +35 -0
  166. package/src/base/registry/facets/distribution/v1/IRewardsDistribution.sol +51 -0
  167. package/src/base/registry/facets/distribution/v1/RewardsDistribution.sol +439 -0
  168. package/src/base/registry/facets/distribution/v1/RewardsDistributionStorage.sol +32 -0
  169. package/src/base/registry/facets/distribution/v2/DelegationProxy.sol +53 -0
  170. package/src/base/registry/facets/distribution/v2/IRewardsDistribution.sol +372 -0
  171. package/src/base/registry/facets/distribution/v2/RewardsDistributionBase.sol +299 -0
  172. package/src/base/registry/facets/distribution/v2/RewardsDistributionStorage.sol +37 -0
  173. package/src/base/registry/facets/distribution/v2/RewardsDistributionV2.sol +392 -0
  174. package/src/base/registry/facets/distribution/v2/StakingRewards.sol +466 -0
  175. package/src/base/registry/facets/mainnet/ICrossDomainMessenger.sol +58 -0
  176. package/src/base/registry/facets/mainnet/IMainnetDelegation.sol +127 -0
  177. package/src/base/registry/facets/mainnet/MainnetDelegation.sol +119 -0
  178. package/src/base/registry/facets/mainnet/MainnetDelegationBase.sol +274 -0
  179. package/src/base/registry/facets/mainnet/MainnetDelegationStorage.sol +36 -0
  180. package/src/base/registry/facets/operator/INodeOperator.sol +91 -0
  181. package/src/base/registry/facets/operator/NodeOperatorFacet.sol +189 -0
  182. package/src/base/registry/facets/operator/NodeOperatorStorage.sol +39 -0
  183. package/src/base/registry/facets/xchain/IXChain.sol +54 -0
  184. package/src/base/registry/facets/xchain/XChain.sol +158 -0
  185. package/src/base/registry/facets/xchain/XChainCheckLib.sol +105 -0
  186. package/src/base/registry/facets/xchain/XChainLib.sol +46 -0
  187. package/src/diamond/facets/beacon/UpgradeableBeacon.sol +38 -0
  188. package/src/diamond/facets/beacon/UpgradeableBeaconFacet.sol +34 -0
  189. package/src/diamond/facets/governance/votes/Checkpoints.sol +642 -0
  190. package/src/diamond/facets/governance/votes/Votes.sol +63 -0
  191. package/src/diamond/facets/governance/votes/VotesBase.sol +274 -0
  192. package/src/diamond/facets/governance/votes/VotesStorage.sol +21 -0
  193. package/src/diamond/facets/governance/votes/enumerable/IVotesEnumerable.sol +38 -0
  194. package/src/diamond/facets/governance/votes/enumerable/VotesEnumerable.sol +39 -0
  195. package/src/diamond/facets/governance/votes/enumerable/VotesEnumerableLib.sol +102 -0
  196. package/src/diamond/facets/metadata/IMetadata.sol +27 -0
  197. package/src/diamond/facets/metadata/MetadataFacet.sol +71 -0
  198. package/src/diamond/facets/token/ERC5643/ERC5643.sol +51 -0
  199. package/src/diamond/facets/token/ERC5643/ERC5643Base.sol +48 -0
  200. package/src/diamond/facets/token/ERC5643/ERC5643Storage.sol +26 -0
  201. package/src/diamond/facets/token/ERC5643/IERC5643.sol +44 -0
  202. package/src/diamond/facets/token/ERC721A/ERC721A.sol +270 -0
  203. package/src/diamond/facets/token/ERC721A/ERC721ABase.sol +829 -0
  204. package/src/diamond/facets/token/ERC721A/ERC721ANonTransferable.sol +21 -0
  205. package/src/diamond/facets/token/ERC721A/ERC721AStorage.sol +115 -0
  206. package/src/diamond/facets/token/ERC721A/IERC721A.sol +283 -0
  207. package/src/diamond/facets/token/ERC721A/extensions/ERC721AQueryable.sol +134 -0
  208. package/src/diamond/facets/token/ERC721A/extensions/IERC721AQueryable.sol +83 -0
  209. package/src/diamond/utils/Context.sol +19 -0
  210. package/src/factory/SpaceFactoryInit.sol +17 -0
  211. package/src/factory/facets/architect/Architect.sol +98 -0
  212. package/src/factory/facets/architect/ArchitectBase.sol +95 -0
  213. package/src/factory/facets/architect/ArchitectStorage.sol +28 -0
  214. package/src/factory/facets/architect/IArchitect.sol +155 -0
  215. package/src/factory/facets/architect/ImplementationStorage.sol +42 -0
  216. package/src/factory/facets/architect/pricing/IPricingModules.sol +41 -0
  217. package/src/factory/facets/architect/pricing/PricingModulesBase.sol +89 -0
  218. package/src/factory/facets/architect/pricing/PricingModulesFacet.sol +40 -0
  219. package/src/factory/facets/architect/pricing/PricingModulesStorage.sol +30 -0
  220. package/src/factory/facets/create/CreateSpace.sol +107 -0
  221. package/src/factory/facets/create/CreateSpaceLib.sol +335 -0
  222. package/src/factory/facets/create/ICreateSpace.sol +70 -0
  223. package/src/factory/facets/feature/FeatureConditionLib.sol +53 -0
  224. package/src/factory/facets/feature/FeatureManagerFacet.sol +66 -0
  225. package/src/factory/facets/feature/FeatureManagerLib.sol +168 -0
  226. package/src/factory/facets/feature/IFeatureManagerFacet.sol +73 -0
  227. package/src/factory/facets/partner/IPartnerRegistry.sol +56 -0
  228. package/src/factory/facets/partner/PartnerRegistry.sol +57 -0
  229. package/src/factory/facets/partner/PartnerRegistryBase.sol +132 -0
  230. package/src/factory/facets/partner/PartnerRegistryStorage.sol +40 -0
  231. package/src/factory/facets/platform/requirements/IPlatformRequirements.sol +143 -0
  232. package/src/factory/facets/platform/requirements/PlatformRequirementsBase.sol +124 -0
  233. package/src/factory/facets/platform/requirements/PlatformRequirementsFacet.sol +122 -0
  234. package/src/factory/facets/platform/requirements/PlatformRequirementsStorage.sol +41 -0
  235. package/src/factory/facets/registry/IImplementationRegistry.sol +46 -0
  236. package/src/factory/facets/registry/ImplementationRegistry.sol +64 -0
  237. package/src/factory/facets/registry/ImplementationRegistryStorage.sol +28 -0
  238. package/src/factory/facets/wallet-link/IWalletLink.sol +218 -0
  239. package/src/factory/facets/wallet-link/WalletLink.sol +108 -0
  240. package/src/factory/facets/wallet-link/WalletLinkBase.sol +492 -0
  241. package/src/factory/facets/wallet-link/interfaces/IDelegateRegistry.sol +63 -0
  242. package/src/factory/facets/wallet-link/interfaces/IDelegateRegistryV1.sol +35 -0
  243. package/src/factory/facets/wallet-link/interfaces/ISCL_EIP6565.sol +24 -0
  244. package/src/factory/facets/wallet-link/libraries/SolanaUtils.sol +161 -0
  245. package/src/factory/facets/wallet-link/libraries/WalletLib.sol +62 -0
  246. package/src/river/registry/facets/config/IRiverConfig.sol +117 -0
  247. package/src/river/registry/facets/config/RiverConfig.sol +174 -0
  248. package/src/river/registry/facets/node/INodeRegistry.sol +69 -0
  249. package/src/river/registry/facets/node/NodeRegistry.sol +143 -0
  250. package/src/river/registry/facets/operator/IOperatorRegistry.sol +28 -0
  251. package/src/river/registry/facets/operator/OperatorRegistry.sol +86 -0
  252. package/src/river/registry/facets/stream/IStreamRegistry.sol +184 -0
  253. package/src/river/registry/facets/stream/StreamRegistry.sol +396 -0
  254. package/src/river/registry/libraries/RegistryErrors.sol +24 -0
  255. package/src/river/registry/libraries/RegistryStorage.sol +181 -0
  256. package/src/router/ISwapRouter.sol +226 -0
  257. package/src/router/Permit2Hash.sol +92 -0
  258. package/src/router/SwapRouter.sol +463 -0
  259. package/src/router/SwapRouterStorage.sol +21 -0
  260. package/src/spaces/entitlements/ICrossChainEntitlement.sol +22 -0
  261. package/src/spaces/entitlements/IEntitlement.sol +61 -0
  262. package/src/spaces/entitlements/PolymarketEntitlement.sol +79 -0
  263. package/src/spaces/entitlements/poap/IPOAP.sol +26 -0
  264. package/src/spaces/entitlements/poap/PoapEntitlement.sol +56 -0
  265. package/src/spaces/entitlements/rule/IRuleEntitlement.sol +174 -0
  266. package/src/spaces/entitlements/rule/RuleEntitlement.sol +183 -0
  267. package/src/spaces/entitlements/rule/RuleEntitlementV2.sol +219 -0
  268. package/src/spaces/entitlements/user/IUserEntitlement.sol +24 -0
  269. package/src/spaces/entitlements/user/UserEntitlement.sol +273 -0
  270. package/src/spaces/facets/DependencyLib.sol +60 -0
  271. package/src/spaces/facets/Entitled.sol +172 -0
  272. package/src/spaces/facets/Permissions.sol +21 -0
  273. package/src/spaces/facets/account/AppAccount.sol +93 -0
  274. package/src/spaces/facets/account/AppAccountBase.sol +275 -0
  275. package/src/spaces/facets/account/AppAccountStorage.sol +63 -0
  276. package/src/spaces/facets/account/IAppAccount.sol +71 -0
  277. package/src/spaces/facets/account/SignerFacet.sol +26 -0
  278. package/src/spaces/facets/banning/Banning.sol +41 -0
  279. package/src/spaces/facets/banning/BanningBase.sol +33 -0
  280. package/src/spaces/facets/banning/BanningStorage.sol +23 -0
  281. package/src/spaces/facets/banning/IBanning.sol +35 -0
  282. package/src/spaces/facets/channels/ChannelBase.sol +87 -0
  283. package/src/spaces/facets/channels/ChannelService.sol +177 -0
  284. package/src/spaces/facets/channels/ChannelStorage.sol +34 -0
  285. package/src/spaces/facets/channels/Channels.sol +80 -0
  286. package/src/spaces/facets/channels/IChannel.sol +98 -0
  287. package/src/spaces/facets/dispatcher/DispatcherBase.sol +86 -0
  288. package/src/spaces/facets/dispatcher/DispatcherStorage.sol +21 -0
  289. package/src/spaces/facets/dispatcher/IDispatcher.sol +6 -0
  290. package/src/spaces/facets/entitlements/EntitlementsManager.sol +49 -0
  291. package/src/spaces/facets/entitlements/EntitlementsManagerBase.sol +87 -0
  292. package/src/spaces/facets/entitlements/EntitlementsManagerService.sol +142 -0
  293. package/src/spaces/facets/entitlements/EntitlementsManagerStorage.sol +34 -0
  294. package/src/spaces/facets/entitlements/IEntitlementsManager.sol +67 -0
  295. package/src/spaces/facets/entitlements/extensions/EntitlementDataQueryable.sol +153 -0
  296. package/src/spaces/facets/entitlements/extensions/IEntitlementDataQueryable.sol +32 -0
  297. package/src/spaces/facets/executor/ExecutorBase.sol +564 -0
  298. package/src/spaces/facets/executor/ExecutorFacet.sol +178 -0
  299. package/src/spaces/facets/executor/ExecutorStorage.sol +99 -0
  300. package/src/spaces/facets/executor/GroupLib.sol +128 -0
  301. package/src/spaces/facets/executor/IExecutor.sol +287 -0
  302. package/src/spaces/facets/executor/hooks/HookBase.sol +172 -0
  303. package/src/spaces/facets/executor/hooks/HookLib.sol +38 -0
  304. package/src/spaces/facets/executor/hooks/IHookBase.sol +48 -0
  305. package/src/spaces/facets/gated/EntitlementGated.sol +59 -0
  306. package/src/spaces/facets/gated/EntitlementGatedBase.sol +324 -0
  307. package/src/spaces/facets/gated/EntitlementGatedStorage.sol +29 -0
  308. package/src/spaces/facets/gated/IEntitlementGated.sol +55 -0
  309. package/src/spaces/facets/guardian/GuardianBase.sol +80 -0
  310. package/src/spaces/facets/guardian/GuardianFacet.sol +43 -0
  311. package/src/spaces/facets/guardian/GuardianStorage.sol +27 -0
  312. package/src/spaces/facets/guardian/IGuardian.sol +54 -0
  313. package/src/spaces/facets/membership/IMembership.sol +216 -0
  314. package/src/spaces/facets/membership/MembershipBase.sol +272 -0
  315. package/src/spaces/facets/membership/MembershipFacet.sol +191 -0
  316. package/src/spaces/facets/membership/MembershipStorage.sol +40 -0
  317. package/src/spaces/facets/membership/join/MembershipJoin.sol +547 -0
  318. package/src/spaces/facets/membership/metadata/IMembershipMetadata.sol +9 -0
  319. package/src/spaces/facets/membership/metadata/MembershipMetadata.sol +32 -0
  320. package/src/spaces/facets/membership/pricing/IMembershipPricing.sol +18 -0
  321. package/src/spaces/facets/membership/pricing/fixed/FixedPricing.sol +29 -0
  322. package/src/spaces/facets/membership/pricing/fixed/FixedPricingStorage.sol +27 -0
  323. package/src/spaces/facets/membership/pricing/tiered/TieredLogPricingOracleV2.sol +148 -0
  324. package/src/spaces/facets/membership/pricing/tiered/TieredLogPricingOracleV3.sol +137 -0
  325. package/src/spaces/facets/membership/token/MembershipToken.sol +25 -0
  326. package/src/spaces/facets/owner/ISpaceOwner.sol +85 -0
  327. package/src/spaces/facets/owner/SpaceOwner.sol +174 -0
  328. package/src/spaces/facets/owner/SpaceOwnerBase.sol +121 -0
  329. package/src/spaces/facets/owner/SpaceOwnerStorage.sol +41 -0
  330. package/src/spaces/facets/owner/SpaceOwnerUriBase.sol +54 -0
  331. package/src/spaces/facets/points/PointsBase.sol +35 -0
  332. package/src/spaces/facets/prepay/IPrepay.sol +43 -0
  333. package/src/spaces/facets/prepay/PrepayBase.sol +27 -0
  334. package/src/spaces/facets/prepay/PrepayFacet.sol +59 -0
  335. package/src/spaces/facets/prepay/PrepayStorage.sol +26 -0
  336. package/src/spaces/facets/proxy/ISpaceProxyInitializer.sol +21 -0
  337. package/src/spaces/facets/proxy/SpaceProxy.sol +15 -0
  338. package/src/spaces/facets/proxy/SpaceProxyInitializer.sol +55 -0
  339. package/src/spaces/facets/referrals/IReferrals.sol +98 -0
  340. package/src/spaces/facets/referrals/ReferralsBase.sol +81 -0
  341. package/src/spaces/facets/referrals/ReferralsFacet.sol +65 -0
  342. package/src/spaces/facets/referrals/ReferralsStorage.sol +36 -0
  343. package/src/spaces/facets/review/IReview.sol +50 -0
  344. package/src/spaces/facets/review/ReviewFacet.sol +105 -0
  345. package/src/spaces/facets/review/ReviewStorage.sol +29 -0
  346. package/src/spaces/facets/roles/IRoles.sol +197 -0
  347. package/src/spaces/facets/roles/Roles.sol +123 -0
  348. package/src/spaces/facets/roles/RolesBase.sol +420 -0
  349. package/src/spaces/facets/roles/RolesStorage.sol +132 -0
  350. package/src/spaces/facets/swap/ISwapFacet.sol +91 -0
  351. package/src/spaces/facets/swap/SwapFacet.sol +290 -0
  352. package/src/spaces/facets/swap/SwapFacetStorage.sol +24 -0
  353. package/src/spaces/facets/tipping/ITipping.sol +80 -0
  354. package/src/spaces/facets/tipping/TippingBase.sol +73 -0
  355. package/src/spaces/facets/tipping/TippingFacet.sol +123 -0
  356. package/src/spaces/facets/treasury/ITreasury.sol +64 -0
  357. package/src/spaces/facets/treasury/Treasury.sol +82 -0
  358. package/src/spaces/facets/xchain/SpaceEntitlementGated.sol +62 -0
  359. package/src/tokens/Member.sol +246 -0
  360. package/src/tokens/lock/ILock.sol +42 -0
  361. package/src/tokens/lock/LockBase.sol +64 -0
  362. package/src/tokens/lock/LockFacet.sol +44 -0
  363. package/src/tokens/lock/LockStorage.sol +26 -0
  364. package/src/tokens/mainnet/claimer/AuthorizedClaimerStorage.sol +26 -0
  365. package/src/tokens/mainnet/claimer/AuthorizedClaimers.sol +84 -0
  366. package/src/tokens/mainnet/claimer/IAuthorizedClaimers.sol +36 -0
  367. package/src/tokens/mainnet/delegation/ProxyBatchDelegation.sol +86 -0
  368. package/src/tokens/migration/ITokenMigration.sol +35 -0
  369. package/src/tokens/migration/TokenMigrationFacet.sol +86 -0
  370. package/src/tokens/migration/TokenMigrationStorage.sol +27 -0
  371. package/src/tokens/towns/base/IERC7802.sol +30 -0
  372. package/src/tokens/towns/base/IOptimismMintableERC20.sol +31 -0
  373. package/src/tokens/towns/base/ISemver.sol +13 -0
  374. package/src/tokens/towns/base/Towns.sol +283 -0
  375. package/src/tokens/towns/base/TownsDeployer.sol +32 -0
  376. package/src/tokens/towns/base/TownsLib.sol +31 -0
  377. package/src/tokens/towns/base/versions/TownsV2.sol +15 -0
  378. package/src/tokens/towns/mainnet/ITowns.sol +56 -0
  379. package/src/tokens/towns/mainnet/Towns.sol +220 -0
  380. package/src/tokens/towns/mainnet/libs/TokenInflationLib.sol +89 -0
  381. package/src/tokens/towns/multichain/Towns.sol +19 -0
  382. package/src/tokens/towns/multichain/wTowns.sol +18 -0
  383. package/src/utils/Airdrop.sol +156 -0
  384. package/src/utils/airdrop/merkle/IMerkleAirdrop.sol +55 -0
  385. package/src/utils/airdrop/merkle/MerkleAirdrop.sol +118 -0
  386. package/src/utils/airdrop/merkle/MerkleAirdropStorage.sol +29 -0
  387. package/src/utils/interfaces/AggregatorV3Interface.sol +37 -0
  388. package/src/utils/interfaces/IMulticall.sol +10 -0
  389. package/src/utils/interfaces/IWETH.sol +10 -0
  390. package/src/utils/libraries/BasisPoints.sol +24 -0
  391. package/src/utils/libraries/Create2Utils.sol +74 -0
  392. package/src/utils/libraries/CurrencyTransfer.sol +99 -0
  393. package/src/utils/libraries/CustomRevert.sol +49 -0
  394. package/src/utils/libraries/Factory.sol +66 -0
  395. package/src/utils/libraries/StringSet.sol +190 -0
  396. package/src/utils/libraries/Validator.sol +31 -0
@@ -0,0 +1,403 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IERC6900ExecutionModule} from "@erc6900/reference-implementation/interfaces/IERC6900ExecutionModule.sol";
6
+ import {IERC6900Module} from "@erc6900/reference-implementation/interfaces/IERC6900Module.sol";
7
+ import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol";
8
+ import {ITownsApp} from "../../ITownsApp.sol";
9
+ import {IAppRegistryBase} from "./IAppRegistry.sol";
10
+ import {ISchemaResolver} from "@ethereum-attestation-service/eas-contracts/resolver/ISchemaResolver.sol";
11
+ import {ISimpleApp} from "../../helpers/ISimpleApp.sol";
12
+ import {IPlatformRequirements} from "../../../factory/facets/platform/requirements/IPlatformRequirements.sol";
13
+ import {IERC173} from "@towns-protocol/diamond/src/facets/ownable/IERC173.sol";
14
+ import {IAppAccount} from "../../../spaces/facets/account/IAppAccount.sol";
15
+
16
+ // libraries
17
+ import {CustomRevert} from "../../../utils/libraries/CustomRevert.sol";
18
+ import {BasisPoints} from "../../../utils/libraries/BasisPoints.sol";
19
+ import {AppRegistryStorage} from "./AppRegistryStorage.sol";
20
+ import {LibClone} from "solady/utils/LibClone.sol";
21
+ import {FixedPointMathLib} from "solady/utils/FixedPointMathLib.sol";
22
+ import {CurrencyTransfer} from "../../../utils/libraries/CurrencyTransfer.sol";
23
+
24
+ // types
25
+ import {ExecutionManifest} from "@erc6900/reference-implementation/interfaces/IERC6900ExecutionModule.sol";
26
+ import {Attestation, EMPTY_UID} from "@ethereum-attestation-service/eas-contracts/Common.sol";
27
+ import {AttestationRequest, RevocationRequestData} from "@ethereum-attestation-service/eas-contracts/IEAS.sol";
28
+
29
+ // contracts
30
+ import {SchemaBase} from "../schema/SchemaBase.sol";
31
+ import {AttestationBase} from "../attest/AttestationBase.sol";
32
+
33
+ abstract contract AppRegistryBase is IAppRegistryBase, SchemaBase, AttestationBase {
34
+ using CustomRevert for bytes4;
35
+
36
+ uint48 private constant MAX_DURATION = 365 days;
37
+
38
+ function __AppRegistry_init_unchained(
39
+ address spaceFactory,
40
+ string calldata schema,
41
+ ISchemaResolver resolver
42
+ ) internal {
43
+ bytes32 schemaId = _registerSchema(schema, resolver, true);
44
+ _setSchemaId(schemaId);
45
+ _setSpaceFactory(spaceFactory);
46
+ }
47
+
48
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
49
+ /* FUNCTIONS */
50
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
51
+
52
+ function _setSpaceFactory(address spaceFactory) internal {
53
+ if (spaceFactory == address(0)) InvalidAddressInput.selector.revertWith();
54
+ AppRegistryStorage.Layout storage $ = AppRegistryStorage.getLayout();
55
+ $.spaceFactory = spaceFactory;
56
+ }
57
+
58
+ /// @notice Sets the schema ID for the app registry
59
+ /// @param schemaId The schema ID to set
60
+ function _setSchemaId(bytes32 schemaId) internal {
61
+ AppRegistryStorage.Layout storage db = AppRegistryStorage.getLayout();
62
+ db.schemaId = schemaId;
63
+ emit AppSchemaSet(schemaId);
64
+ }
65
+
66
+ /// @notice Retrieves the current schema ID
67
+ /// @return The current schema ID
68
+ function _getSchemaId() internal view returns (bytes32) {
69
+ return AppRegistryStorage.getLayout().schemaId;
70
+ }
71
+
72
+ /// @notice Gets the latest version ID for a app
73
+ /// @param app The address of the app
74
+ /// @return The latest version ID
75
+ function _getLatestAppId(address app) internal view returns (bytes32) {
76
+ AppRegistryStorage.AppInfo storage appInfo = AppRegistryStorage.getLayout().apps[app];
77
+ return appInfo.latestVersion;
78
+ }
79
+
80
+ /// @notice Checks if an app is banned
81
+ /// @param app The address of the app to check
82
+ /// @return True if the app is banned, false otherwise
83
+ function _isBanned(address app) internal view returns (bool) {
84
+ return AppRegistryStorage.getLayout().apps[app].isBanned;
85
+ }
86
+
87
+ function _getAppPrice(address app) internal view returns (uint256 price) {
88
+ try ITownsApp(app).installPrice() returns (uint256 installPrice) {
89
+ (price, ) = _getTotalRequiredPayment(installPrice);
90
+ } catch {
91
+ (price, ) = _getTotalRequiredPayment(0);
92
+ }
93
+ }
94
+
95
+ function _getAppDuration(address app) internal view returns (uint48 duration) {
96
+ try ITownsApp(app).accessDuration() returns (uint48 accessDuration) {
97
+ return _validateDuration(accessDuration);
98
+ } catch {
99
+ return MAX_DURATION;
100
+ }
101
+ }
102
+
103
+ /// @notice Retrieves detailed information about an app by its ID
104
+ /// @param appId The unique identifier of the app
105
+ /// @return appData A struct containing all app information including module, owner, clients, permissions, and manifest
106
+ /// @dev Returns an empty app struct if the appId is not found
107
+ function _getAppById(bytes32 appId) internal view returns (App memory appData) {
108
+ Attestation memory att = _getAttestation(appId);
109
+ if (att.uid == EMPTY_UID) return appData;
110
+ appData = abi.decode(att.data, (App));
111
+ appData.appId = att.uid;
112
+ }
113
+
114
+ /// @notice Retrieves the app address associated with a client
115
+ /// @param client The client address
116
+ /// @return The app address associated with the client
117
+ function _getAppByClient(address client) internal view returns (address) {
118
+ return AppRegistryStorage.getLayout().client[client].app;
119
+ }
120
+
121
+ /// @notice Creates a new app with the specified parameters
122
+ /// @param params The parameters for creating the app
123
+ /// @return app The address of the created app
124
+ /// @return version The version ID of the registered app
125
+ /// @dev Validates inputs, deploys app contract, and registers it
126
+ function _createApp(AppParams calldata params) internal returns (address app, bytes32 version) {
127
+ // Validate basic parameters
128
+ if (bytes(params.name).length == 0) InvalidAppName.selector.revertWith();
129
+ if (params.permissions.length == 0) InvalidArrayInput.selector.revertWith();
130
+ if (params.client == address(0)) InvalidAddressInput.selector.revertWith();
131
+
132
+ uint48 duration = _validateDuration(params.accessDuration);
133
+
134
+ app = LibClone.deployERC1967BeaconProxy(address(this));
135
+ ISimpleApp(app).initialize(
136
+ msg.sender,
137
+ params.name,
138
+ params.permissions,
139
+ params.installPrice,
140
+ duration
141
+ );
142
+
143
+ version = _registerApp(app, params.client);
144
+ emit AppCreated(app, version);
145
+ }
146
+
147
+ /// @notice Registers a new app in the registry
148
+ /// @param app The address of the app to register
149
+ /// @param client The client address that can use the app
150
+ /// @return version The version ID of the registered app
151
+ /// @dev Reverts if app is banned, inputs are invalid, or caller is not the owner
152
+ function _registerApp(address app, address client) internal returns (bytes32 version) {
153
+ _verifyAddAppInputs(app, client);
154
+
155
+ AppRegistryStorage.Layout storage $ = AppRegistryStorage.getLayout();
156
+ AppRegistryStorage.AppInfo storage appInfo = $.apps[app];
157
+ AppRegistryStorage.ClientInfo storage clientInfo = $.client[client];
158
+
159
+ if (clientInfo.app != address(0)) ClientAlreadyRegistered.selector.revertWith();
160
+ if (appInfo.isBanned) BannedApp.selector.revertWith();
161
+
162
+ ITownsApp appContract = ITownsApp(app);
163
+
164
+ uint256 installPrice = appContract.installPrice();
165
+ _validatePricing(installPrice);
166
+
167
+ uint48 accessDuration = appContract.accessDuration();
168
+ uint48 duration = _validateDuration(accessDuration);
169
+
170
+ bytes32[] memory permissions = appContract.requiredPermissions();
171
+ if (permissions.length == 0) InvalidArrayInput.selector.revertWith();
172
+
173
+ address owner = appContract.moduleOwner();
174
+ if (owner == address(0)) InvalidAddressInput.selector.revertWith();
175
+
176
+ ExecutionManifest memory manifest = appContract.executionManifest();
177
+
178
+ App memory appData = App({
179
+ appId: EMPTY_UID,
180
+ module: app,
181
+ owner: owner,
182
+ client: client,
183
+ permissions: permissions,
184
+ manifest: manifest,
185
+ duration: duration
186
+ });
187
+
188
+ AttestationRequest memory request;
189
+ request.schema = _getSchemaId();
190
+ request.data.recipient = app;
191
+ request.data.revocable = true;
192
+ request.data.refUID = appInfo.latestVersion;
193
+ request.data.data = abi.encode(appData);
194
+ version = _attest(msg.sender, msg.value, request).uid;
195
+
196
+ appInfo.latestVersion = version;
197
+ appInfo.app = app;
198
+ clientInfo.app = app;
199
+
200
+ emit AppRegistered(app, version);
201
+ }
202
+
203
+ /// @notice Removes a app from the registry
204
+ /// @param revoker The address revoking the app
205
+ /// @param appId The version ID of the app to remove
206
+ /// @dev Reverts if app is not registered, revoked, or banned
207
+ /// @dev Spaces that install this app will need to uninstall it
208
+ function _removeApp(address revoker, bytes32 appId) internal {
209
+ if (appId == EMPTY_UID) InvalidAppId.selector.revertWith();
210
+
211
+ Attestation memory att = _getAttestation(appId);
212
+
213
+ if (att.uid == EMPTY_UID) AppNotRegistered.selector.revertWith();
214
+ if (att.revocationTime > 0) AppRevoked.selector.revertWith();
215
+
216
+ App memory appData = abi.decode(att.data, (App));
217
+
218
+ AppRegistryStorage.AppInfo storage appInfo = AppRegistryStorage.getLayout().apps[
219
+ appData.module
220
+ ];
221
+
222
+ if (appInfo.isBanned) BannedApp.selector.revertWith();
223
+
224
+ RevocationRequestData memory request;
225
+ request.uid = appId;
226
+ _revoke(att.schema, request, revoker, 0, true);
227
+
228
+ AppRegistryStorage.ClientInfo storage clientInfo = AppRegistryStorage.getLayout().client[
229
+ appData.client
230
+ ];
231
+ clientInfo.app = address(0);
232
+
233
+ emit AppUnregistered(appData.module, appId);
234
+ }
235
+
236
+ /// @notice Installs an app to a specified account
237
+ /// @param app The address of the app to install
238
+ /// @param account The address of the account to install the app to
239
+ /// @param data The data to pass to the app's onInstall function
240
+ /// @dev Handles validation, payment, and installation process
241
+ function _installApp(address app, address account, bytes calldata data) internal {
242
+ bytes32 appId = _getLatestAppId(app);
243
+ if (appId == EMPTY_UID) AppNotRegistered.selector.revertWith();
244
+ if (_isBanned(app)) BannedApp.selector.revertWith();
245
+
246
+ Attestation memory att = _getAttestation(appId);
247
+ if (att.revocationTime > 0) AppRevoked.selector.revertWith();
248
+
249
+ ITownsApp appContract = ITownsApp(app);
250
+ uint256 installPrice = appContract.installPrice();
251
+
252
+ _chargeForInstall(msg.sender, app, installPrice);
253
+
254
+ IAppAccount(account).onInstallApp(appId, data);
255
+
256
+ emit AppInstalled(app, address(account), appId);
257
+ }
258
+
259
+ function _uninstallApp(address app, address account, bytes calldata data) internal {
260
+ bytes32 appId = IAppAccount(account).getAppId(app);
261
+ if (appId == EMPTY_UID) AppNotRegistered.selector.revertWith();
262
+ IAppAccount(account).onUninstallApp(appId, data);
263
+ emit AppUninstalled(app, address(account), appId);
264
+ }
265
+
266
+ function _renewApp(address app, address account, bytes calldata data) internal {
267
+ bytes32 appId = IAppAccount(account).getAppId(app);
268
+ if (appId == EMPTY_UID) AppNotInstalled.selector.revertWith();
269
+ if (_isBanned(app)) BannedApp.selector.revertWith();
270
+
271
+ Attestation memory att = _getAttestation(appId);
272
+ if (att.uid == EMPTY_UID) AppNotRegistered.selector.revertWith();
273
+ if (att.revocationTime > 0) AppRevoked.selector.revertWith();
274
+
275
+ App memory appData = abi.decode(att.data, (App));
276
+
277
+ ITownsApp appContract = ITownsApp(app);
278
+ uint256 installPrice = appContract.installPrice();
279
+
280
+ _chargeForInstall(msg.sender, appData.owner, installPrice);
281
+
282
+ IAppAccount(account).onRenewApp(appId, data);
283
+
284
+ emit AppRenewed(app, account, appId);
285
+ }
286
+
287
+ function _onlyAllowed(address account) internal view {
288
+ if (IERC173(account).owner() != msg.sender) NotAllowed.selector.revertWith();
289
+ }
290
+
291
+ function _getProtocolFee(uint256 installPrice) internal view returns (uint256) {
292
+ IPlatformRequirements platform = _getPlatformRequirements();
293
+ uint256 baseFee = platform.getMembershipFee();
294
+ if (installPrice == 0) return baseFee;
295
+ uint256 bpsFee = BasisPoints.calculate(installPrice, platform.getMembershipBps());
296
+ return FixedPointMathLib.max(bpsFee, baseFee);
297
+ }
298
+
299
+ function _getTotalRequiredPayment(
300
+ uint256 installPrice
301
+ ) internal view returns (uint256 totalRequired, uint256 protocolFee) {
302
+ protocolFee = _getProtocolFee(installPrice);
303
+ if (installPrice == 0) return (protocolFee, protocolFee);
304
+ return (installPrice + protocolFee, protocolFee);
305
+ }
306
+
307
+ /// @notice Charges for app installation including protocol fees and developer payment
308
+ /// @param payer The address paying for the installation
309
+ /// @param recipient The address receiving the developer payment
310
+ /// @param installPrice The base price of the app
311
+ /// @dev Handles protocol fee, developer payment, and excess refund
312
+ function _chargeForInstall(address payer, address recipient, uint256 installPrice) internal {
313
+ (uint256 totalRequired, uint256 protocolFee) = _getTotalRequiredPayment(installPrice);
314
+
315
+ if (msg.value < totalRequired) InsufficientPayment.selector.revertWith();
316
+
317
+ // Cache platform requirements to avoid multiple storage reads
318
+ IPlatformRequirements platform = _getPlatformRequirements();
319
+ address feeRecipient = platform.getFeeRecipient();
320
+
321
+ // Handle protocol fee first - this is always charged
322
+ CurrencyTransfer.transferCurrency(
323
+ CurrencyTransfer.NATIVE_TOKEN,
324
+ payer,
325
+ feeRecipient,
326
+ protocolFee
327
+ );
328
+
329
+ // Transfer developer payment if applicable
330
+ if (totalRequired > protocolFee) {
331
+ uint256 ownerProceeds = totalRequired - protocolFee;
332
+ CurrencyTransfer.transferCurrency(
333
+ CurrencyTransfer.NATIVE_TOKEN,
334
+ payer,
335
+ recipient,
336
+ ownerProceeds
337
+ );
338
+ }
339
+
340
+ // Refund excess payment if any
341
+ uint256 excess = msg.value - totalRequired;
342
+ if (excess > 0) {
343
+ CurrencyTransfer.transferCurrency(
344
+ CurrencyTransfer.NATIVE_TOKEN,
345
+ address(this),
346
+ payer,
347
+ excess
348
+ );
349
+ }
350
+ }
351
+
352
+ /// @notice Bans a app from the registry
353
+ /// @param app The address of the app to ban
354
+ /// @return version The version ID of the banned app
355
+ /// @dev Reverts if app is not registered, already banned, or revoked
356
+ function _banApp(address app) internal returns (bytes32 version) {
357
+ if (app == address(0)) AppNotRegistered.selector.revertWith();
358
+
359
+ AppRegistryStorage.AppInfo storage appInfo = AppRegistryStorage.getLayout().apps[app];
360
+
361
+ if (appInfo.app == address(0)) AppNotRegistered.selector.revertWith();
362
+ if (appInfo.isBanned) BannedApp.selector.revertWith();
363
+
364
+ appInfo.isBanned = true;
365
+
366
+ emit AppBanned(app, appInfo.latestVersion);
367
+
368
+ return appInfo.latestVersion;
369
+ }
370
+
371
+ function _validatePricing(uint256 price) internal view {
372
+ IPlatformRequirements reqs = _getPlatformRequirements();
373
+ uint256 minPlatformFee = reqs.getMembershipFee();
374
+ if (price > 0 && price < minPlatformFee) InvalidPrice.selector.revertWith();
375
+ }
376
+
377
+ function _validateDuration(uint48 duration) internal pure returns (uint48) {
378
+ if (duration > MAX_DURATION) InvalidDuration.selector.revertWith();
379
+ if (duration == 0) duration = MAX_DURATION;
380
+ return duration;
381
+ }
382
+
383
+ /// @notice Verifies inputs for adding a new app
384
+ /// @param app The app address to verify
385
+ /// @param client The client address to verify
386
+ /// @dev Reverts if any input is invalid or app doesn't implement required interfaces
387
+ function _verifyAddAppInputs(address app, address client) internal view {
388
+ if (app == address(0)) InvalidAddressInput.selector.revertWith();
389
+ if (client == address(0)) InvalidAddressInput.selector.revertWith();
390
+
391
+ if (
392
+ !IERC165(app).supportsInterface(type(IERC6900Module).interfaceId) ||
393
+ !IERC165(app).supportsInterface(type(IERC6900ExecutionModule).interfaceId) ||
394
+ !IERC165(app).supportsInterface(type(ITownsApp).interfaceId)
395
+ ) {
396
+ AppDoesNotImplementInterface.selector.revertWith();
397
+ }
398
+ }
399
+
400
+ function _getPlatformRequirements() internal view returns (IPlatformRequirements) {
401
+ return IPlatformRequirements(AppRegistryStorage.getLayout().spaceFactory);
402
+ }
403
+ }
@@ -0,0 +1,173 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IAppRegistry} from "./IAppRegistry.sol";
6
+ import {ISchemaResolver} from "@ethereum-attestation-service/eas-contracts/resolver/ISchemaResolver.sol";
7
+ import {IAppAccount} from "../../../spaces/facets/account/IAppAccount.sol";
8
+ import {ITownsApp} from "../../ITownsApp.sol";
9
+
10
+ // types
11
+ import {Attestation} from "@ethereum-attestation-service/eas-contracts/Common.sol";
12
+
13
+ // contracts
14
+ import {AppRegistryBase} from "./AppRegistryBase.sol";
15
+ import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
16
+ import {ReentrancyGuard} from "solady/utils/ReentrancyGuard.sol";
17
+ import {OwnableBase} from "@towns-protocol/diamond/src/facets/ownable/OwnableBase.sol";
18
+
19
+ contract AppRegistryFacet is IAppRegistry, AppRegistryBase, OwnableBase, ReentrancyGuard, Facet {
20
+ function __AppRegistry_init(
21
+ address spaceFactory,
22
+ string calldata schema,
23
+ ISchemaResolver resolver
24
+ ) external onlyInitializing {
25
+ __AppRegistry_init_unchained(spaceFactory, schema, resolver);
26
+ }
27
+
28
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
29
+ /* DAO functions */
30
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
31
+
32
+ /// @notice Set the schema ID used for app attestations
33
+ /// @param schema The new schema
34
+ function adminRegisterAppSchema(
35
+ string calldata schema,
36
+ ISchemaResolver resolver,
37
+ bool revocable
38
+ ) external onlyOwner returns (bytes32 schemaId) {
39
+ schemaId = _registerSchema(schema, resolver, revocable);
40
+ _setSchemaId(schemaId);
41
+ }
42
+
43
+ /// @notice Ban a app from the registry
44
+ /// @param app The app address to ban
45
+ /// @dev Only the owner can ban a app
46
+ /// @return The attestation UID that was banned
47
+ function adminBanApp(address app) external onlyOwner returns (bytes32) {
48
+ return _banApp(app);
49
+ }
50
+
51
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
52
+ /* App Functions */
53
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
54
+
55
+ /// @notice Register a new app with permissions
56
+ /// @param app The app address to register
57
+ /// @param client The client address that will make calls from this app
58
+ /// @return versionId The version ID of the registered app
59
+ function registerApp(
60
+ ITownsApp app,
61
+ address client
62
+ ) external payable nonReentrant returns (bytes32 versionId) {
63
+ return _registerApp(address(app), client);
64
+ }
65
+
66
+ /// @notice Remove a app from the registry
67
+ /// @param versionId The app ID to remove
68
+ /// @dev Only the owner of the app can remove it
69
+ function removeApp(bytes32 versionId) external nonReentrant {
70
+ _removeApp(msg.sender, versionId);
71
+ }
72
+
73
+ /// @notice Create an upgradeable simple app contract
74
+ /// @param params The parameters of the app
75
+ function createApp(
76
+ AppParams calldata params
77
+ ) external payable nonReentrant returns (address app, bytes32 versionId) {
78
+ return _createApp(params);
79
+ }
80
+
81
+ /// @notice Install an app
82
+ /// @param app The app address to install
83
+ /// @param space The space to install the app to
84
+ /// @param data The data to pass to the app's onInstall function
85
+ function installApp(
86
+ ITownsApp app,
87
+ IAppAccount space,
88
+ bytes calldata data
89
+ ) external payable nonReentrant {
90
+ _onlyAllowed(address(space));
91
+ return _installApp(address(app), address(space), data);
92
+ }
93
+
94
+ /// @notice Uninstall an app
95
+ /// @param app The app address to uninstall
96
+ /// @param account The account to uninstall the app from
97
+ /// @param data The data to pass to the app's onUninstall function
98
+ function uninstallApp(
99
+ ITownsApp app,
100
+ IAppAccount account,
101
+ bytes calldata data
102
+ ) external nonReentrant {
103
+ _onlyAllowed(address(account));
104
+ return _uninstallApp(address(app), address(account), data);
105
+ }
106
+
107
+ /// @notice Renew an app
108
+ /// @param app The app address to renew
109
+ /// @param account The account to renew the app for
110
+ /// @param data The data to pass to the app's onRenewApp function
111
+ function renewApp(
112
+ ITownsApp app,
113
+ IAppAccount account,
114
+ bytes calldata data
115
+ ) external payable nonReentrant {
116
+ _onlyAllowed(address(account));
117
+ _renewApp(address(app), address(account), data);
118
+ }
119
+
120
+ /// @notice Get the schema structure used for registering modules
121
+ /// @return The schema structure
122
+ function getAppSchema() external view returns (string memory) {
123
+ return _getSchema(_getSchemaId()).schema;
124
+ }
125
+
126
+ /// @notice Get the active schema ID used for app attestations
127
+ /// @return The schema ID
128
+ function getAppSchemaId() external view returns (bytes32) {
129
+ return _getSchemaId();
130
+ }
131
+
132
+ /// @notice Get the app by ID
133
+ /// @param appId The app ID
134
+ /// @return app The app
135
+ function getAppById(bytes32 appId) external view returns (App memory app) {
136
+ return _getAppById(appId);
137
+ }
138
+
139
+ /// @notice Get the total price of an app
140
+ /// @param app The app address
141
+ /// @return price The price of the app with protocol fee
142
+ function getAppPrice(address app) external view returns (uint256 price) {
143
+ return _getAppPrice(app);
144
+ }
145
+
146
+ /// @notice Get the duration of an app
147
+ /// @param app The app address
148
+ /// @return duration The duration of the app
149
+ function getAppDuration(address app) external view returns (uint48 duration) {
150
+ return _getAppDuration(app);
151
+ }
152
+
153
+ /// @notice Get the latest version ID for a app
154
+ /// @param app The app address
155
+ /// @return appId The version ID of the registered app
156
+ function getLatestAppId(address app) external view returns (bytes32) {
157
+ return _getLatestAppId(app);
158
+ }
159
+
160
+ /// @notice Get the app address associated with a client
161
+ /// @param client The client address
162
+ /// @return app The app address
163
+ function getAppByClient(address client) external view returns (address app) {
164
+ return _getAppByClient(client);
165
+ }
166
+
167
+ /// @notice Check if a app is banned
168
+ /// @param app The app address
169
+ /// @return isBanned True if the app is banned, false otherwise
170
+ function isAppBanned(address app) external view returns (bool) {
171
+ return _isBanned(app);
172
+ }
173
+ }
@@ -0,0 +1,53 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ // libraries
7
+
8
+ // contracts
9
+
10
+ library AppRegistryStorage {
11
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
12
+ /* STRUCTS */
13
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
14
+
15
+ struct AppInfo {
16
+ address app;
17
+ bytes32 latestVersion;
18
+ bool isBanned;
19
+ }
20
+
21
+ struct ClientInfo {
22
+ address app;
23
+ }
24
+
25
+ struct Layout {
26
+ // Registered schema ID
27
+ bytes32 schemaId;
28
+ // App => AppInfo
29
+ mapping(address => AppInfo) apps;
30
+ // Simple app beacon
31
+ address beacon;
32
+ // Space factory
33
+ address spaceFactory;
34
+ // client => ClientInfo
35
+ mapping(address => ClientInfo) client;
36
+ }
37
+
38
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
39
+ /* STORAGE */
40
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
41
+
42
+ // keccak256(abi.encode(uint256(keccak256("app.registry.storage")) - 1)) & ~bytes32(uint256(0xff))
43
+ bytes32 internal constant STORAGE_SLOT =
44
+ 0xe1abd3beb055e0136b3111c2c34ff6e869f8c0d7540225f8056528d6eb12b500;
45
+
46
+ /// @notice Returns the storage layout for the module registry
47
+ /// @return l The storage layout struct
48
+ function getLayout() internal pure returns (Layout storage l) {
49
+ assembly {
50
+ l.slot := STORAGE_SLOT
51
+ }
52
+ }
53
+ }