@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,148 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IMembershipPricing} from "src/spaces/facets/membership/pricing/IMembershipPricing.sol";
6
+ import {AggregatorV3Interface} from "src/utils/interfaces/AggregatorV3Interface.sol";
7
+
8
+ // libraries
9
+ import {Casting, UD60x18, log10} from "@prb/math/UD60x18.sol";
10
+
11
+ // contracts
12
+ import {IntrospectionFacet} from "@towns-protocol/diamond/src/facets/introspection/IntrospectionFacet.sol";
13
+
14
+ /**
15
+ * @title TieredLogPricingOracle
16
+ * @notice Network: Base (Sepolia)
17
+ */
18
+ contract TieredLogPricingOracleV2 is IMembershipPricing, IntrospectionFacet {
19
+ AggregatorV3Interface internal dataFeed;
20
+
21
+ uint256 internal constant SCALE = 1e18; // 1 ether
22
+ uint256 internal constant CENT_SCALE = 100;
23
+ uint256 internal constant LOG_BASE = 10 ** 16;
24
+ uint256 internal constant FEED_TIMEOUT = 24 hours;
25
+
26
+ // Cached values for optimization
27
+ uint256 private immutable exchangeRateDecimals;
28
+ uint256 private immutable exchangeRateScale;
29
+
30
+ // Error messages
31
+ error TieredLogPricingOracle__InvalidAnswer();
32
+ error TieredLogPricingOracle__InvalidRound();
33
+ error TieredLogPricingOracle__InvalidTimestamp();
34
+ error TieredLogPricingOracle__StaleData();
35
+
36
+ constructor(address priceFeed) {
37
+ __IntrospectionBase_init();
38
+ _addInterface(type(IMembershipPricing).interfaceId);
39
+ dataFeed = AggregatorV3Interface(priceFeed);
40
+ exchangeRateDecimals = 10 ** dataFeed.decimals();
41
+ exchangeRateScale = exchangeRateDecimals * CENT_SCALE;
42
+ }
43
+
44
+ function name() public pure override returns (string memory) {
45
+ return "TieredLogPricingOracleV2";
46
+ }
47
+
48
+ function description() public pure override returns (string memory) {
49
+ return "Free for the first 100 members, then logarithmically increasing price";
50
+ }
51
+
52
+ function setPrice(uint256) external pure {
53
+ revert("TieredLogPricingOracle: price is calculated");
54
+ }
55
+
56
+ function getPrice(uint256 freeAllocation, uint256 totalMinted) public view returns (uint256) {
57
+ uint256 stablePriceCents = _calculateStablePrice(freeAllocation, totalMinted);
58
+
59
+ return _getWeiFromCents(stablePriceCents);
60
+ }
61
+
62
+ // =============================================================
63
+ // Internal
64
+ // =============================================================
65
+
66
+ function getChainlinkDataFeedLatestAnswer() public view returns (uint256) {
67
+ // prettier-ignore
68
+ (
69
+ uint80 roundId,
70
+ int256 answer,
71
+ /*uint startedAt*/
72
+ ,
73
+ uint256 updatedAt,
74
+ /*uint80 answeredInRound*/
75
+ ) = dataFeed.latestRoundData();
76
+
77
+ if (answer <= 0) revert TieredLogPricingOracle__InvalidAnswer();
78
+ if (roundId == 0) revert TieredLogPricingOracle__InvalidRound();
79
+ if (updatedAt == 0) revert TieredLogPricingOracle__InvalidTimestamp();
80
+ if (updatedAt > block.timestamp) {
81
+ revert TieredLogPricingOracle__InvalidTimestamp();
82
+ }
83
+ if (block.timestamp - updatedAt > FEED_TIMEOUT) {
84
+ revert TieredLogPricingOracle__StaleData();
85
+ }
86
+
87
+ return uint256(answer);
88
+ }
89
+
90
+ /// @notice Converts a price in cents to wei
91
+ /// @param cents The price in cents to convert
92
+ /// @return The price in wei
93
+ function _getWeiFromCents(uint256 cents) internal view returns (uint256) {
94
+ uint256 exchangeRate = getChainlinkDataFeedLatestAnswer(); // chainlink oracle returns this
95
+ // value
96
+
97
+ // oracle or governance
98
+ // multiple before divide to avoid truncation which ends up in precision loss
99
+ uint256 ethToUsdExchangeRateCents = (exchangeRate * 100) / exchangeRateDecimals;
100
+ uint256 oneCentInWei = SCALE / ethToUsdExchangeRateCents;
101
+
102
+ return oneCentInWei * cents;
103
+ }
104
+
105
+ function _calculateStablePrice(
106
+ uint256 freeAllocation,
107
+ uint256 totalMinted
108
+ ) internal pure returns (uint256) {
109
+ // Free allocation handling
110
+ if (freeAllocation > 0 && totalMinted < freeAllocation) {
111
+ return 0;
112
+ }
113
+
114
+ // Define minted tiers
115
+ uint256 tier1 = 100;
116
+ uint256 tier2 = 1000;
117
+ uint256 tier3 = 10_000;
118
+
119
+ // Define base prices in cents
120
+ uint256 basePriceTier1 = 100; // $1.00
121
+ uint256 basePriceTier2 = 1000; // $10.00
122
+ uint256 basePriceTier3 = 10_000; // $100.00
123
+
124
+ if (totalMinted > tier3) {
125
+ return basePriceTier3;
126
+ } else if (totalMinted > tier2) {
127
+ // Logarithmic scaling for tier 2
128
+ uint256 logScale = _calculateLogScale(totalMinted);
129
+ return logScale * 22 + basePriceTier2;
130
+ } else if (totalMinted > tier1) {
131
+ // Logarithmic scaling for tier 1
132
+ uint256 logScale = _calculateLogScale(totalMinted);
133
+ return logScale * 3 + basePriceTier1;
134
+ } else {
135
+ // Below tier 1
136
+ if (freeAllocation > totalMinted) return 0;
137
+
138
+ // Logarithmic scaling for tier 0
139
+ uint256 logScale = _calculateLogScale(totalMinted == 0 ? 1 : totalMinted);
140
+ return logScale / 2 + basePriceTier1; // // Dividing by 2 is an arbitrary scaling factor
141
+ }
142
+ }
143
+
144
+ function _calculateLogScale(uint256 value) private pure returns (uint256) {
145
+ UD60x18 logResult = log10(Casting.ud(value * SCALE));
146
+ return Casting.intoUint256(logResult) / LOG_BASE;
147
+ }
148
+ }
@@ -0,0 +1,137 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IMembershipPricing} from "src/spaces/facets/membership/pricing/IMembershipPricing.sol";
6
+ import {AggregatorV3Interface} from "src/utils/interfaces/AggregatorV3Interface.sol";
7
+
8
+ // libraries
9
+ import {Casting, UD60x18, log10} from "@prb/math/UD60x18.sol";
10
+
11
+ // contracts
12
+ import {IntrospectionFacet} from "@towns-protocol/diamond/src/facets/introspection/IntrospectionFacet.sol";
13
+
14
+ /**
15
+ * @title TieredLogPricingOracle
16
+ * @notice Network: Base (Sepolia)
17
+ */
18
+ contract TieredLogPricingOracleV3 is IMembershipPricing, IntrospectionFacet {
19
+ AggregatorV3Interface internal dataFeed;
20
+
21
+ uint256 internal constant SCALE = 1e18; // 1 ether
22
+ uint256 internal constant CENT_SCALE = 100;
23
+ uint256 internal constant LOG_BASE = 10 ** 16;
24
+ uint256 internal constant FEED_TIMEOUT = 24 hours;
25
+
26
+ // Cached values for optimization
27
+ uint256 private immutable exchangeRateDecimals;
28
+ uint256 private immutable exchangeRateScale;
29
+
30
+ // Error messages
31
+ error TieredLogPricingOracle__InvalidAnswer();
32
+ error TieredLogPricingOracle__InvalidRound();
33
+ error TieredLogPricingOracle__InvalidTimestamp();
34
+ error TieredLogPricingOracle__StaleData();
35
+
36
+ constructor(address priceFeed) {
37
+ __IntrospectionBase_init();
38
+ _addInterface(type(IMembershipPricing).interfaceId);
39
+ dataFeed = AggregatorV3Interface(priceFeed);
40
+ exchangeRateDecimals = 10 ** dataFeed.decimals();
41
+ exchangeRateScale = exchangeRateDecimals * CENT_SCALE;
42
+ }
43
+
44
+ function name() public pure override returns (string memory) {
45
+ return "TieredLogPricingOracleV3";
46
+ }
47
+
48
+ function description() public pure override returns (string memory) {
49
+ return "Logarithmically increasing price";
50
+ }
51
+
52
+ function setPrice(uint256) external pure {
53
+ revert("TieredLogPricingOracle: price is calculated logarithmically");
54
+ }
55
+
56
+ function getPrice(uint256 freeAllocation, uint256 totalMinted) public view returns (uint256) {
57
+ uint256 stablePriceCents = _calculateStablePrice(freeAllocation, totalMinted);
58
+
59
+ return _getWeiFromCents(stablePriceCents);
60
+ }
61
+
62
+ // =============================================================
63
+ // Internal
64
+ // =============================================================
65
+
66
+ function getChainlinkDataFeedLatestAnswer() public view returns (uint256) {
67
+ // prettier-ignore
68
+ (
69
+ uint80 roundId,
70
+ int256 answer,
71
+ /*uint startedAt*/
72
+ ,
73
+ uint256 updatedAt,
74
+ /*uint80 answeredInRound*/
75
+ ) = dataFeed.latestRoundData();
76
+
77
+ if (answer <= 0) revert TieredLogPricingOracle__InvalidAnswer();
78
+ if (roundId == 0) revert TieredLogPricingOracle__InvalidRound();
79
+ if (updatedAt == 0) revert TieredLogPricingOracle__InvalidTimestamp();
80
+ if (updatedAt > block.timestamp) {
81
+ revert TieredLogPricingOracle__InvalidTimestamp();
82
+ }
83
+ if (block.timestamp - updatedAt > FEED_TIMEOUT) {
84
+ revert TieredLogPricingOracle__StaleData();
85
+ }
86
+
87
+ return uint256(answer);
88
+ }
89
+
90
+ /// @notice Converts a price in cents to wei
91
+ /// @param cents The price in cents to convert
92
+ /// @return The price in wei
93
+ function _getWeiFromCents(uint256 cents) internal view returns (uint256) {
94
+ uint256 exchangeRate = getChainlinkDataFeedLatestAnswer(); // chainlink oracle returns this
95
+ // value
96
+
97
+ // oracle or governance
98
+ // multiple before divide to avoid truncation which ends up in precision loss
99
+ uint256 ethToUsdExchangeRateCents = (exchangeRate * 100) / exchangeRateDecimals;
100
+ uint256 oneCentInWei = SCALE / ethToUsdExchangeRateCents;
101
+
102
+ return oneCentInWei * cents;
103
+ }
104
+
105
+ function _calculateStablePrice(uint256, uint256 totalMinted) internal pure returns (uint256) {
106
+ // Define minted tiers
107
+ uint256 tier1 = 100;
108
+ uint256 tier2 = 1000;
109
+ uint256 tier3 = 10_000;
110
+
111
+ // Define base prices in cents
112
+ uint256 basePriceTier1 = 100; // $1.00
113
+ uint256 basePriceTier2 = 1000; // $10.00
114
+ uint256 basePriceTier3 = 10_000; // $100.00
115
+
116
+ if (totalMinted <= tier1) {
117
+ // Logarithmic scaling for tier 1
118
+ uint256 logScale = _calculateLogScale(totalMinted == 0 ? 1 : totalMinted);
119
+ return logScale / 2 + basePriceTier1; // Dividing by 2 is an arbitrary scaling factor
120
+ } else if (totalMinted <= tier2) {
121
+ // Logarithmic scaling for tier 2
122
+ uint256 logScale = _calculateLogScale(totalMinted);
123
+ return logScale * 3 + basePriceTier1;
124
+ } else if (totalMinted <= tier3) {
125
+ // Logarithmic scaling for tier 3
126
+ uint256 logScale = _calculateLogScale(totalMinted);
127
+ return logScale * 22 + basePriceTier2;
128
+ } else {
129
+ return basePriceTier3;
130
+ }
131
+ }
132
+
133
+ function _calculateLogScale(uint256 value) private pure returns (uint256) {
134
+ UD60x18 logResult = log10(Casting.ud(value * SCALE));
135
+ return Casting.intoUint256(logResult) / LOG_BASE;
136
+ }
137
+ }
@@ -0,0 +1,25 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IMembershipBase} from "src/spaces/facets/membership/IMembership.sol";
6
+
7
+ // libraries
8
+
9
+ // contracts
10
+ import {ERC721A} from "src/diamond/facets/token/ERC721A/ERC721A.sol";
11
+ import {BanningBase} from "src/spaces/facets/banning/BanningBase.sol";
12
+
13
+ contract MembershipToken is ERC721A, BanningBase, IMembershipBase {
14
+ function _beforeTokenTransfers(
15
+ address from,
16
+ address to,
17
+ uint256 tokenId,
18
+ uint256 quantity
19
+ ) internal override {
20
+ if (from != address(0) && _isBanned(tokenId)) {
21
+ revert Membership__Banned();
22
+ }
23
+ super._beforeTokenTransfers(from, to, tokenId, quantity);
24
+ }
25
+ }
@@ -0,0 +1,85 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ // libraries
7
+
8
+ // contracts
9
+ interface ISpaceOwnerBase {
10
+ struct Space {
11
+ string name;
12
+ string uri;
13
+ uint256 tokenId;
14
+ uint256 createdAt;
15
+ string shortDescription;
16
+ string longDescription;
17
+ }
18
+
19
+ error SpaceOwner__OnlyFactoryAllowed();
20
+ error SpaceOwner__OnlySpaceOwnerAllowed();
21
+ error SpaceOwner__SpaceNotFound();
22
+ error SpaceOwner__DefaultUriNotSet();
23
+
24
+ event SpaceOwner__UpdateSpace(address indexed space);
25
+ event SpaceOwner__SetFactory(address factory);
26
+ event SpaceOwner__SetDefaultUri(string uri);
27
+ }
28
+
29
+ interface ISpaceOwner is ISpaceOwnerBase {
30
+ /// @notice Set the factory address that is allowed to mint spaces
31
+ function setFactory(address factory) external;
32
+
33
+ /// @notice Get the factory address
34
+ function getFactory() external view returns (address);
35
+
36
+ /// @notice Set the default URI
37
+ function setDefaultUri(string memory uri) external;
38
+
39
+ /// @notice Get the default URI
40
+ function getDefaultUri() external view returns (string memory);
41
+
42
+ /// @notice Get the next token id that will be used to mint a space
43
+ function nextTokenId() external view returns (uint256);
44
+
45
+ /// @notice Mint a space
46
+ /// @dev Only the factory is allowed to mint spaces
47
+ /// @param name The name of the space
48
+ /// @param uri The URI of the space
49
+ /// @param space The address of the space
50
+ /// @param shortDescription The short description of the space
51
+ /// @param longDescription The long description of the space
52
+ /// @return tokenId The token id of the minted space
53
+ function mintSpace(
54
+ string memory name,
55
+ string memory uri,
56
+ address space,
57
+ string memory shortDescription,
58
+ string memory longDescription
59
+ ) external returns (uint256 tokenId);
60
+
61
+ /// @notice Get the space info
62
+ /// @param space The address of the space
63
+ /// @return space The space info
64
+ function getSpaceInfo(address space) external view returns (Space memory);
65
+
66
+ /// @notice Get the space address by token id
67
+ /// @param tokenId The token id of the space
68
+ /// @return space The address of the space
69
+ function getSpaceByTokenId(uint256 tokenId) external view returns (address);
70
+
71
+ /// @notice Update the space info
72
+ /// @dev Only the space owner is allowed to update the space info
73
+ /// @param space The address of the space
74
+ /// @param name The name of the space
75
+ /// @param uri The URI of the space
76
+ /// @param shortDescription The short description of the space
77
+ /// @param longDescription The long description of the space
78
+ function updateSpaceInfo(
79
+ address space,
80
+ string memory name,
81
+ string memory uri,
82
+ string memory shortDescription,
83
+ string memory longDescription
84
+ ) external;
85
+ }
@@ -0,0 +1,174 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ import {ISpaceOwner} from "./ISpaceOwner.sol";
7
+ import {IERC4906} from "@openzeppelin/contracts/interfaces/IERC4906.sol";
8
+ import {IMembershipMetadata} from "src/spaces/facets/membership/metadata/IMembershipMetadata.sol";
9
+
10
+ // libraries
11
+
12
+ // contracts
13
+
14
+ import {SpaceOwnerBase} from "./SpaceOwnerBase.sol";
15
+
16
+ import {SpaceOwnerUriBase} from "./SpaceOwnerUriBase.sol";
17
+ import {OwnableBase} from "@towns-protocol/diamond/src/facets/ownable/OwnableBase.sol";
18
+ import {Votes} from "src/diamond/facets/governance/votes/Votes.sol";
19
+ import {ERC721A} from "src/diamond/facets/token/ERC721A/ERC721A.sol";
20
+ import {GuardianBase} from "src/spaces/facets/guardian/GuardianBase.sol";
21
+
22
+ contract SpaceOwner is
23
+ ISpaceOwner,
24
+ SpaceOwnerBase,
25
+ SpaceOwnerUriBase,
26
+ OwnableBase,
27
+ GuardianBase,
28
+ Votes,
29
+ ERC721A
30
+ {
31
+ function __SpaceOwner_init(string memory name, string memory symbol) external initializer {
32
+ __ERC721A_init_unchained(name, symbol);
33
+ }
34
+
35
+ // =============================================================
36
+ // Factory
37
+ // =============================================================
38
+
39
+ /// @inheritdoc ISpaceOwner
40
+ function setFactory(address factory) external onlyOwner {
41
+ _setFactory(factory);
42
+ }
43
+
44
+ /// @inheritdoc ISpaceOwner
45
+ function getFactory() external view returns (address) {
46
+ return _getFactory();
47
+ }
48
+
49
+ // =============================================================
50
+ // Space
51
+ // =============================================================
52
+
53
+ /// @inheritdoc ISpaceOwner
54
+ function nextTokenId() external view returns (uint256) {
55
+ return _nextTokenId();
56
+ }
57
+
58
+ /// @inheritdoc ISpaceOwner
59
+ function mintSpace(
60
+ string memory name,
61
+ string memory uri,
62
+ address space,
63
+ string memory shortDescription,
64
+ string memory longDescription
65
+ ) external onlyFactory returns (uint256 tokenId) {
66
+ tokenId = _nextTokenId();
67
+ _mintSpace(name, uri, tokenId, space, shortDescription, longDescription);
68
+ _mint(msg.sender, 1);
69
+ }
70
+
71
+ /// @inheritdoc ISpaceOwner
72
+ function getSpaceInfo(address space) external view returns (Space memory) {
73
+ return _getSpace(space);
74
+ }
75
+
76
+ /// @inheritdoc ISpaceOwner
77
+ function getSpaceByTokenId(uint256 tokenId) external view returns (address) {
78
+ return _getSpaceByTokenId(tokenId);
79
+ }
80
+
81
+ /// @inheritdoc ISpaceOwner
82
+ function updateSpaceInfo(
83
+ address space,
84
+ string memory name,
85
+ string memory uri,
86
+ string memory shortDescription,
87
+ string memory longDescription
88
+ ) external {
89
+ _onlySpaceOwner(space);
90
+ _updateSpace(space, name, uri, shortDescription, longDescription);
91
+
92
+ IMembershipMetadata(space).refreshMetadata();
93
+
94
+ emit IERC4906.MetadataUpdate(_getTokenId(space));
95
+ }
96
+
97
+ // =============================================================
98
+ // Uri
99
+ // =============================================================
100
+
101
+ /// @inheritdoc ISpaceOwner
102
+ function setDefaultUri(string memory uri) external onlyOwner {
103
+ _setDefaultUri(uri);
104
+ }
105
+
106
+ /// @inheritdoc ISpaceOwner
107
+ function getDefaultUri() external view returns (string memory) {
108
+ return _getDefaultUri();
109
+ }
110
+
111
+ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
112
+ if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
113
+
114
+ return _render(tokenId);
115
+ }
116
+
117
+ // =============================================================
118
+ // Overrides
119
+ // =============================================================
120
+ function approve(address to, uint256 tokenId) public payable override {
121
+ // allow removing approvals even if guardian is enabled
122
+ if (to != address(0) && _guardianEnabled(msg.sender)) {
123
+ revert Guardian_Enabled();
124
+ }
125
+
126
+ super.approve(to, tokenId);
127
+ }
128
+
129
+ function setApprovalForAll(address operator, bool approved) public override {
130
+ // allow removing approvals even if guardian is enabled
131
+ if (approved && _guardianEnabled(msg.sender)) {
132
+ revert Guardian_Enabled();
133
+ }
134
+
135
+ super.setApprovalForAll(operator, approved);
136
+ }
137
+
138
+ function _beforeTokenTransfers(
139
+ address from,
140
+ address to,
141
+ uint256 startTokenId,
142
+ uint256 quantity
143
+ ) internal override {
144
+ if (from != address(0) && _guardianEnabled(from)) {
145
+ // allow transferring handle at minting time
146
+ revert Guardian_Enabled();
147
+ }
148
+
149
+ super._beforeTokenTransfers(from, to, startTokenId, quantity);
150
+ }
151
+
152
+ function _afterTokenTransfers(
153
+ address from,
154
+ address to,
155
+ uint256 firstTokenId,
156
+ uint256 batchSize
157
+ ) internal virtual override {
158
+ _transferVotingUnits(from, to, batchSize);
159
+ super._afterTokenTransfers(from, to, firstTokenId, batchSize);
160
+ }
161
+
162
+ function _getVotingUnits(address account) internal view virtual override returns (uint256) {
163
+ return balanceOf(account);
164
+ }
165
+
166
+ // =============================================================
167
+ // Internal
168
+ // =============================================================
169
+ function _onlySpaceOwner(address space) internal view {
170
+ if (_ownerOf(_getTokenId(space)) != msg.sender) {
171
+ revert SpaceOwner__OnlySpaceOwnerAllowed();
172
+ }
173
+ }
174
+ }
@@ -0,0 +1,121 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {ISpaceOwnerBase} from "./ISpaceOwner.sol";
6
+
7
+ // libraries
8
+ import {SpaceOwnerStorage} from "./SpaceOwnerStorage.sol";
9
+ import {Validator} from "../../../utils/libraries/Validator.sol";
10
+
11
+ // contracts
12
+
13
+ abstract contract SpaceOwnerBase is ISpaceOwnerBase {
14
+ // =============================================================
15
+ // Factory
16
+ // =============================================================
17
+ modifier onlyFactory() {
18
+ SpaceOwnerStorage.Layout storage ds = SpaceOwnerStorage.layout();
19
+ if (msg.sender != ds.factory) {
20
+ revert SpaceOwner__OnlyFactoryAllowed();
21
+ }
22
+ _;
23
+ }
24
+
25
+ function _setFactory(address factory) internal {
26
+ Validator.checkAddress(factory);
27
+
28
+ SpaceOwnerStorage.Layout storage ds = SpaceOwnerStorage.layout();
29
+ ds.factory = factory;
30
+ emit SpaceOwner__SetFactory(factory);
31
+ }
32
+
33
+ function _getFactory() internal view returns (address) {
34
+ SpaceOwnerStorage.Layout storage ds = SpaceOwnerStorage.layout();
35
+ return ds.factory;
36
+ }
37
+
38
+ // =============================================================
39
+ // Space
40
+ // =============================================================
41
+
42
+ function _mintSpace(
43
+ string memory name,
44
+ string memory uri,
45
+ uint256 tokenId,
46
+ address space,
47
+ string memory shortDescription,
48
+ string memory longDescription
49
+ ) internal {
50
+ Validator.checkLength(name, 2);
51
+ // if the space uri is empty, it will default to `${defaultUri}/${spaceAddress}`
52
+ Validator.checkLength(uri, 0);
53
+ Validator.checkAddress(space);
54
+
55
+ SpaceOwnerStorage.Layout storage ds = SpaceOwnerStorage.layout();
56
+
57
+ ds.spaceByTokenId[tokenId] = space;
58
+ ds.spaceByAddress[space] = SpaceOwnerStorage.Space({
59
+ name: name,
60
+ uri: uri,
61
+ tokenId: tokenId,
62
+ createdAt: block.timestamp
63
+ });
64
+ ds.spaceMetadata[space] = SpaceOwnerStorage.SpaceMetadata({
65
+ shortDescription: shortDescription,
66
+ longDescription: longDescription
67
+ });
68
+ }
69
+
70
+ function _updateSpace(
71
+ address space,
72
+ string memory name,
73
+ string memory uri,
74
+ string memory shortDescription,
75
+ string memory longDescription
76
+ ) internal {
77
+ Validator.checkLength(name, 2);
78
+ // if the space uri is empty, it will default to `${defaultUri}/${spaceAddress}`
79
+ Validator.checkLength(uri, 0);
80
+
81
+ SpaceOwnerStorage.Layout storage ds = SpaceOwnerStorage.layout();
82
+
83
+ SpaceOwnerStorage.Space storage spaceInfo = ds.spaceByAddress[space];
84
+ spaceInfo.name = name;
85
+ spaceInfo.uri = uri;
86
+
87
+ SpaceOwnerStorage.SpaceMetadata storage metadata = ds.spaceMetadata[space];
88
+ metadata.shortDescription = shortDescription;
89
+ metadata.longDescription = longDescription;
90
+
91
+ emit SpaceOwner__UpdateSpace(space);
92
+ }
93
+
94
+ function _getSpace(address space) internal view returns (Space memory) {
95
+ SpaceOwnerStorage.Space storage spaceInfo = SpaceOwnerStorage.layout().spaceByAddress[
96
+ space
97
+ ];
98
+
99
+ SpaceOwnerStorage.SpaceMetadata storage metadata = SpaceOwnerStorage.layout().spaceMetadata[
100
+ space
101
+ ];
102
+
103
+ return
104
+ Space({
105
+ name: spaceInfo.name,
106
+ uri: spaceInfo.uri,
107
+ tokenId: spaceInfo.tokenId,
108
+ createdAt: spaceInfo.createdAt,
109
+ shortDescription: metadata.shortDescription,
110
+ longDescription: metadata.longDescription
111
+ });
112
+ }
113
+
114
+ function _getTokenId(address space) internal view returns (uint256) {
115
+ return SpaceOwnerStorage.layout().spaceByAddress[space].tokenId;
116
+ }
117
+
118
+ function _getSpaceByTokenId(uint256 tokenId) internal view returns (address) {
119
+ return SpaceOwnerStorage.layout().spaceByTokenId[tokenId];
120
+ }
121
+ }