@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,82 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
7
+ import {IMembershipBase} from "src/spaces/facets/membership/IMembership.sol";
8
+ import {ITreasury} from "src/spaces/facets/treasury/ITreasury.sol";
9
+
10
+ // libraries
11
+ import {CurrencyTransfer} from "src/utils/libraries/CurrencyTransfer.sol";
12
+
13
+ // contracts
14
+
15
+ import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
16
+ import {TokenOwnableBase} from "@towns-protocol/diamond/src/facets/ownable/token/TokenOwnableBase.sol";
17
+ import {MembershipStorage} from "src/spaces/facets/membership/MembershipStorage.sol";
18
+ import {CustomRevert} from "src/utils/libraries/CustomRevert.sol";
19
+ import {ReentrancyGuard} from "solady/utils/ReentrancyGuard.sol";
20
+
21
+ contract Treasury is TokenOwnableBase, ReentrancyGuard, Facet, ITreasury {
22
+ function __Treasury_init() external onlyInitializing {
23
+ _addInterface(type(IERC1155Receiver).interfaceId);
24
+ }
25
+
26
+ ///@inheritdoc ITreasury
27
+ function withdraw(address account) external onlyOwner nonReentrant {
28
+ if (account == address(0)) {
29
+ CustomRevert.revertWith(IMembershipBase.Membership__InvalidAddress.selector);
30
+ }
31
+
32
+ // get the balance
33
+ uint256 balance = address(this).balance;
34
+
35
+ // verify the balance is not 0
36
+ if (balance == 0) {
37
+ CustomRevert.revertWith(IMembershipBase.Membership__InsufficientPayment.selector);
38
+ }
39
+
40
+ address currency = MembershipStorage.layout().membershipCurrency;
41
+
42
+ CurrencyTransfer.transferCurrency(currency, address(this), account, balance);
43
+
44
+ emit IMembershipBase.MembershipWithdrawal(account, balance);
45
+ }
46
+
47
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
48
+ /* Hooks */
49
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
50
+
51
+ ///@inheritdoc ITreasury
52
+ function onERC721Received(
53
+ address,
54
+ address,
55
+ uint256,
56
+ bytes memory
57
+ ) external pure returns (bytes4) {
58
+ return this.onERC721Received.selector;
59
+ }
60
+
61
+ ///@inheritdoc ITreasury
62
+ function onERC1155Received(
63
+ address,
64
+ address,
65
+ uint256,
66
+ uint256,
67
+ bytes memory
68
+ ) external pure returns (bytes4) {
69
+ return this.onERC1155Received.selector;
70
+ }
71
+
72
+ ///@inheritdoc ITreasury
73
+ function onERC1155BatchReceived(
74
+ address,
75
+ address,
76
+ uint256[] memory,
77
+ uint256[] memory,
78
+ bytes memory
79
+ ) external pure returns (bytes4) {
80
+ return this.onERC1155BatchReceived.selector;
81
+ }
82
+ }
@@ -0,0 +1,62 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IMembership} from "../membership/IMembership.sol";
6
+
7
+ // libraries
8
+
9
+ // contracts
10
+ import {EntitlementGated} from "../gated/EntitlementGated.sol";
11
+ import {MembershipJoin} from "../membership/join/MembershipJoin.sol";
12
+
13
+ /// @title SpaceEntitlementGated
14
+ /// @notice Handles entitlement-gated access to spaces and membership token issuance
15
+ /// @dev Inherits from ISpaceEntitlementGatedBase, MembershipJoin, and EntitlementGated
16
+ contract SpaceEntitlementGated is MembershipJoin, EntitlementGated {
17
+ /// @notice Processes the result of an entitlement check
18
+ /// @dev This function is called when the result of an entitlement check is posted
19
+ /// @param transactionId The unique identifier for the transaction
20
+ /// @param result The result of the entitlement check (PASSED or FAILED)
21
+ function _onEntitlementCheckResultPosted(
22
+ bytes32 transactionId,
23
+ NodeVoteStatus result
24
+ ) internal override {
25
+ bytes storage data = _getCapturedData(transactionId);
26
+
27
+ if (data.length == 0) return;
28
+
29
+ (bytes4 transactionType, , address receiver, ) = abi.decode(
30
+ data,
31
+ (bytes4, address, address, bytes)
32
+ );
33
+
34
+ if (result == NodeVoteStatus.PASSED) {
35
+ PricingDetails memory joinDetails = _getPricingDetails();
36
+
37
+ if (joinDetails.shouldCharge) {
38
+ uint256 payment = _getCapturedValue(transactionId);
39
+
40
+ if (payment < joinDetails.amountDue) {
41
+ _rejectMembership(transactionId, receiver);
42
+ return;
43
+ }
44
+
45
+ if (transactionType == JOIN_SPACE_SELECTOR) {
46
+ _chargeForJoinSpace(transactionId, joinDetails);
47
+ } else if (transactionType == IMembership.joinSpaceWithReferral.selector) {
48
+ _chargeForJoinSpaceWithReferral(transactionId, joinDetails);
49
+ } else {
50
+ _rejectMembership(transactionId, receiver);
51
+ return;
52
+ }
53
+ }
54
+
55
+ _refundBalance(transactionId, receiver);
56
+ _issueToken(receiver);
57
+ return;
58
+ }
59
+
60
+ _rejectMembership(transactionId, receiver);
61
+ }
62
+ }
@@ -0,0 +1,246 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.24;
3
+
4
+ //interfaces
5
+
6
+ //libraries
7
+ import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
8
+
9
+ //contracts
10
+
11
+ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
12
+ import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
13
+
14
+ // @notice TEST CONTRACT, DO NOT USE IN PRODUCTION
15
+ contract Member is ERC721, Ownable {
16
+ /// @notice emitted when an NFT is minted
17
+ /// @param recipient the address that receives the NFT
18
+ event Minted(address indexed recipient, uint256 tokenId, uint256 timestamp);
19
+
20
+ /// @notice emitted when the mint state is changed
21
+ /// @param caller the address that called the function
22
+ /// @param prevState the previous mint state
23
+ /// @param newState the new mint state
24
+ /// @param timestamp the timestamp of the state change
25
+ event MintStateChanged(
26
+ address indexed caller,
27
+ MintState indexed prevState,
28
+ MintState indexed newState,
29
+ uint256 timestamp
30
+ );
31
+
32
+ /// @notice thrown when user tries to mint more than 1 token with same wallet
33
+ error AlreadyMinted();
34
+
35
+ /// @notice thrown when an incorrect amount of ETH is sent to mint
36
+ error MintPriceNotPaid();
37
+
38
+ /// @notice thrown when the max supply is reached
39
+ error MaxSupplyReached();
40
+
41
+ /// @notice thrown when a token is not minted
42
+ error NonExistentTokenURI();
43
+
44
+ /// @notice thrown when the withdraw payment transaction fails
45
+ error WithdrawTransfer();
46
+
47
+ /// @notice thrown when the user is not allowed to perform the action
48
+ error NotAllowed();
49
+
50
+ /// @notice thrown when the mint state is invalid
51
+ error InvalidMintState();
52
+
53
+ /// @notice thrown when the address is invalid
54
+ error InvalidAddress();
55
+
56
+ /// @notice thrown when the proof is invalid
57
+ error InvalidProof();
58
+
59
+ /// @notice the current minting state
60
+ enum MintState {
61
+ Allowlist,
62
+ Waitlist,
63
+ Public
64
+ }
65
+
66
+ // =============================================================
67
+ // CONSTANTS
68
+ // =============================================================
69
+
70
+ /// @notice the total supply of the collection
71
+ uint256 public constant TOTAL_SUPPLY = 2500;
72
+
73
+ /// @notice the mint price for an individual nft
74
+ uint256 public constant MINT_PRICE = 0.08 ether;
75
+
76
+ // =============================================================
77
+ // STORAGE
78
+ // =============================================================
79
+
80
+ /// @notice the base uri
81
+ string public baseURI;
82
+
83
+ /// @notice mapping to track if a wallet has already minted
84
+ mapping(address => bool) public _hasMinted;
85
+
86
+ /// @notice the root of the merkle tree for the allowlist
87
+ bytes32 internal immutable _merkleRoot;
88
+
89
+ /// @notice the current minting state
90
+ MintState internal _mintState;
91
+
92
+ // @notice the counter token id for the next mint
93
+ uint256 public currentTokenId;
94
+
95
+ // =============================================================
96
+ // CONSTRUCTOR
97
+ // =============================================================
98
+
99
+ constructor(
100
+ string memory name_,
101
+ string memory symbol_,
102
+ string memory baseURI_,
103
+ bytes32 merkleRoot_
104
+ ) ERC721(name_, symbol_) Ownable(msg.sender) {
105
+ baseURI = baseURI_;
106
+ _merkleRoot = merkleRoot_;
107
+ _mintState = MintState.Allowlist;
108
+ }
109
+
110
+ // =============================================================
111
+ // MINT OPERATIONS
112
+ // =============================================================
113
+ function privateMint(
114
+ address recipient,
115
+ uint256 allowance,
116
+ bytes32[] calldata proof
117
+ ) external payable returns (uint256) {
118
+ _validateInvalidAddress(recipient);
119
+ _validateMintPrice();
120
+ _validateMaxSupply();
121
+ _validateMinted(recipient);
122
+ _validateAllowlist(allowance);
123
+
124
+ bytes32 payload = keccak256(abi.encodePacked(recipient, allowance));
125
+
126
+ if (!MerkleProof.verify(proof, _merkleRoot, payload)) {
127
+ revert InvalidProof();
128
+ }
129
+
130
+ return _mintTo(recipient);
131
+ }
132
+
133
+ function publicMint(address recipient) external payable returns (uint256) {
134
+ _validateInvalidAddress(recipient);
135
+ _validateMintPrice();
136
+ _validateMaxSupply();
137
+ _validateMinted(recipient);
138
+ _validateState(MintState.Public);
139
+ return _mintTo(recipient);
140
+ }
141
+
142
+ // =============================================================
143
+ // BASE URI OPERATIONS
144
+ // =============================================================
145
+
146
+ function setBaseURI(string memory baseURI_) external onlyOwner {
147
+ baseURI = baseURI_;
148
+ }
149
+
150
+ function _baseURI() internal view override returns (string memory) {
151
+ return baseURI;
152
+ }
153
+
154
+ /// @notice Get the tokenURI for the given tokenId
155
+ /// @param tokenId the id of the token to get the tokenURI for
156
+ /// @return the tokenURI for the given tokenId
157
+ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
158
+ if (ownerOf(tokenId) == address(0)) {
159
+ revert NonExistentTokenURI();
160
+ }
161
+ return
162
+ bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, "councilmetadata")) : "";
163
+ }
164
+
165
+ // =============================================================
166
+ // MINT STATE OPERATIONS
167
+ // =============================================================
168
+
169
+ function startWaitlistMint() external onlyOwner {
170
+ _validateState(MintState.Allowlist);
171
+ _setState(MintState.Waitlist);
172
+ }
173
+
174
+ function startPublicMint() external onlyOwner {
175
+ _validateState(MintState.Waitlist);
176
+ _setState(MintState.Public);
177
+ }
178
+
179
+ // =============================================================
180
+ // ADMIN OPERATIONS
181
+ // =============================================================
182
+
183
+ /// @notice withdraw the balance from the contract
184
+ /// @param payee the address that will receive the withdrawn ether
185
+ function withdrawPayments(address payable payee) external onlyOwner {
186
+ uint256 balance = address(this).balance;
187
+ (bool transferTx, ) = payee.call{value: balance}("");
188
+ if (!transferTx) {
189
+ revert WithdrawTransfer();
190
+ }
191
+ }
192
+
193
+ // =============================================================
194
+ // INTERNAL OPERATIONS
195
+ // =============================================================
196
+ function _mintTo(address recipient) internal returns (uint256) {
197
+ _hasMinted[recipient] = true;
198
+ uint256 tokenId = currentTokenId;
199
+ currentTokenId++;
200
+ _safeMint(recipient, tokenId);
201
+ emit Minted(recipient, tokenId, block.timestamp);
202
+ return tokenId;
203
+ }
204
+
205
+ function _setState(MintState _state) internal {
206
+ MintState prevState = _mintState;
207
+ _mintState = _state;
208
+ emit MintStateChanged(msg.sender, prevState, _state, block.timestamp);
209
+ }
210
+
211
+ function _validateInvalidAddress(address recipient) internal pure {
212
+ if (recipient == address(0)) {
213
+ revert InvalidAddress();
214
+ }
215
+ }
216
+
217
+ function _validateMaxSupply() internal view {
218
+ if (currentTokenId >= TOTAL_SUPPLY) {
219
+ revert MaxSupplyReached();
220
+ }
221
+ }
222
+
223
+ function _validateState(MintState _state) internal view {
224
+ if (_mintState != _state) {
225
+ revert InvalidMintState();
226
+ }
227
+ }
228
+
229
+ function _validateAllowlist(uint256 allowance) internal view {
230
+ if (_mintState == MintState.Allowlist && allowance != 1) {
231
+ revert NotAllowed();
232
+ }
233
+ }
234
+
235
+ function _validateMinted(address recipient) internal view {
236
+ if (_hasMinted[recipient]) {
237
+ revert AlreadyMinted();
238
+ }
239
+ }
240
+
241
+ function _validateMintPrice() internal view {
242
+ if (msg.value != MINT_PRICE) {
243
+ revert MintPriceNotPaid();
244
+ }
245
+ }
246
+ }
@@ -0,0 +1,42 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ // libraries
7
+
8
+ // contracts
9
+
10
+ interface ILockBase {
11
+ error LockNotAuthorized();
12
+
13
+ /// @notice Emitted when the lock is updated.
14
+ /// @param account The account that was updated.
15
+ /// @param enabled Whether the lock is enabled.
16
+ /// @param expiration The expiration of the lock.
17
+ event LockUpdated(address indexed account, bool indexed enabled, uint256 expiration);
18
+ }
19
+
20
+ interface ILock is ILockBase {
21
+ /// @notice Enables the lock for the given account.
22
+ /// @param account The account to enable the lock for.
23
+ function enableLock(address account) external;
24
+
25
+ /// @notice Disables the lock and starts the cooldown for the given account.
26
+ /// @param account The account to disable the lock for.
27
+ function disableLock(address account) external;
28
+
29
+ /// @notice Returns whether the lock is active for the given account.
30
+ /// @param account The account to check the lock for.
31
+ /// @return true if the lock is active
32
+ function isLockActive(address account) external view returns (bool);
33
+
34
+ /// @notice Returns the expiration of the lock for the given account.
35
+ /// @param account The account to check the lock expiration for.
36
+ /// @return The expiration timestamp.
37
+ function lockExpiration(address account) external view returns (uint256);
38
+
39
+ /// @notice Sets the default cooldown for the lock.
40
+ /// @param cooldown The cooldown in seconds.
41
+ function setLockCooldown(uint256 cooldown) external;
42
+ }
@@ -0,0 +1,64 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {ILockBase} from "./ILock.sol";
6
+
7
+ // libraries
8
+
9
+ import {LockStorage} from "./LockStorage.sol";
10
+ import {CustomRevert} from "src/utils/libraries/CustomRevert.sol";
11
+
12
+ abstract contract LockBase is ILockBase {
13
+ function __LockBase_init(uint256 cooldown) internal {
14
+ _setDefaultCooldown(cooldown);
15
+ }
16
+
17
+ modifier onlyAllowed() {
18
+ if (!_canLock()) CustomRevert.revertWith(LockNotAuthorized.selector);
19
+ _;
20
+ }
21
+
22
+ /// @dev Sets the default cooldown for the lock.
23
+ function _setDefaultCooldown(uint256 cooldown) internal {
24
+ LockStorage.layout().defaultCooldown = cooldown;
25
+ }
26
+
27
+ /// @dev Enables the lock for the given account.
28
+ function _enableLock(address account) internal {
29
+ LockStorage.Layout storage ds = LockStorage.layout();
30
+
31
+ ds.enabledByAddress[account] = true;
32
+ ds.expirationByAddress[account] = 0;
33
+
34
+ emit LockUpdated(account, true, 0);
35
+ }
36
+
37
+ /// @dev Disables the lock and starts the cooldown for the given account.
38
+ function _disableLock(address account) internal {
39
+ LockStorage.Layout storage ds = LockStorage.layout();
40
+
41
+ uint256 expiration = block.timestamp + ds.defaultCooldown;
42
+ ds.enabledByAddress[account] = false;
43
+ ds.expirationByAddress[account] = expiration;
44
+
45
+ emit LockUpdated(account, false, expiration);
46
+ }
47
+
48
+ /// @dev Returns the lock expiration for the given account.
49
+ function _lockExpiration(address account) internal view returns (uint256) {
50
+ return LockStorage.layout().expirationByAddress[account];
51
+ }
52
+
53
+ /// @dev Returns whether the lock is active for the given account.
54
+ function _isLockActive(address account) internal view returns (bool) {
55
+ LockStorage.Layout storage ds = LockStorage.layout();
56
+
57
+ if (ds.enabledByAddress[account]) return true;
58
+
59
+ return block.timestamp < ds.expirationByAddress[account];
60
+ }
61
+
62
+ /// @dev Returns whether the caller is authorized to lock.
63
+ function _canLock() internal view virtual returns (bool);
64
+ }
@@ -0,0 +1,44 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {ILock} from "./ILock.sol";
6
+
7
+ // libraries
8
+
9
+ // contracts
10
+
11
+ import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
12
+ import {LockBase} from "src/tokens/lock/LockBase.sol";
13
+
14
+ abstract contract LockFacet is ILock, LockBase, Facet {
15
+ function __LockFacet_init(uint256 cooldown) external onlyInitializing {
16
+ __LockBase_init(cooldown);
17
+ _addInterface(type(ILock).interfaceId);
18
+ }
19
+
20
+ /// @inheritdoc ILock
21
+ function isLockActive(address account) external view virtual returns (bool) {
22
+ return _isLockActive(account);
23
+ }
24
+
25
+ /// @inheritdoc ILock
26
+ function lockExpiration(address account) external view virtual returns (uint256) {
27
+ return _lockExpiration(account);
28
+ }
29
+
30
+ /// @inheritdoc ILock
31
+ function enableLock(address account) external virtual onlyAllowed {
32
+ _enableLock(account);
33
+ }
34
+
35
+ /// @inheritdoc ILock
36
+ function disableLock(address account) external virtual onlyAllowed {
37
+ _disableLock(account);
38
+ }
39
+
40
+ /// @inheritdoc ILock
41
+ function setLockCooldown(uint256 cooldown) external virtual onlyAllowed {
42
+ _setDefaultCooldown(cooldown);
43
+ }
44
+ }
@@ -0,0 +1,26 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ // libraries
7
+
8
+ // contracts
9
+
10
+ library LockStorage {
11
+ // keccak256("river.tokens.lock.storage")
12
+ bytes32 internal constant STORAGE_SLOT =
13
+ 0xfd180fd2eec04a0893e9c9ad4329d2f65f17d7fd0b4133b91663887d04d247c1;
14
+
15
+ struct Layout {
16
+ uint256 defaultCooldown;
17
+ mapping(address => bool) enabledByAddress;
18
+ mapping(address => uint256) expirationByAddress;
19
+ }
20
+
21
+ function layout() internal pure returns (Layout storage l) {
22
+ assembly {
23
+ l.slot := STORAGE_SLOT
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,26 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ // libraries
7
+
8
+ // contracts
9
+
10
+ library AuthorizedClaimerStorage {
11
+ // keccak256(abi.encode(uint256(keccak256("facets.authorized.claimer.storage")) - 1)) &
12
+ // ~bytes32(uint256(0xff))
13
+ bytes32 internal constant STORAGE_SLOT =
14
+ 0x5c7ae9c5b9b0882e9774077e2c97d13a2ab9f337fdc777b0f495e367ced70e00;
15
+
16
+ struct Layout {
17
+ mapping(address => address) authorizedClaimers;
18
+ }
19
+
20
+ function layout() internal pure returns (Layout storage s) {
21
+ bytes32 slot = STORAGE_SLOT;
22
+ assembly {
23
+ s.slot := slot
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,84 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IAuthorizedClaimers} from "./IAuthorizedClaimers.sol";
6
+
7
+ // libraries
8
+ import {AuthorizedClaimerStorage} from "./AuthorizedClaimerStorage.sol";
9
+ import {ECDSA} from "solady/utils/ECDSA.sol";
10
+
11
+ // contracts
12
+ import {EIP712Facet} from "@towns-protocol/diamond/src/utils/cryptography/EIP712Facet.sol";
13
+
14
+ contract AuthorizedClaimers is IAuthorizedClaimers, EIP712Facet {
15
+ // keccak256("Authorize(address owner,address claimer,uint256 nonce,uint256 expiry)")
16
+ bytes32 private constant _AUTHORIZE_TYPEHASH =
17
+ 0x496b440527e20b246a460857dca887b9c1f290387cfc6ac9aa91bb6554be05ac;
18
+
19
+ function authorizeClaimerBySig(
20
+ address owner,
21
+ address claimer,
22
+ uint256 nonce,
23
+ uint256 expiry,
24
+ uint8 v,
25
+ bytes32 r,
26
+ bytes32 s
27
+ ) external {
28
+ if (expiry != 0 && block.timestamp >= expiry) {
29
+ revert AuthorizedClaimers_ExpiredSignature();
30
+ }
31
+
32
+ address signer = ECDSA.recover(
33
+ _hashTypedDataV4(
34
+ keccak256(abi.encode(_AUTHORIZE_TYPEHASH, owner, claimer, nonce, expiry))
35
+ ),
36
+ v,
37
+ r,
38
+ s
39
+ );
40
+
41
+ if (signer != owner) {
42
+ revert AuthorizedClaimers_InvalidSignature();
43
+ }
44
+
45
+ _useCheckedNonce(owner, nonce);
46
+ _authorizeClaimer(owner, claimer);
47
+ }
48
+
49
+ /// @inheritdoc IAuthorizedClaimers
50
+ function authorizeClaimer(address claimer) external {
51
+ _authorizeClaimer(msg.sender, claimer);
52
+ }
53
+
54
+ /// @inheritdoc IAuthorizedClaimers
55
+ function removeAuthorizedClaimer() external {
56
+ _authorizeClaimer(msg.sender, address(0));
57
+ }
58
+
59
+ /// @inheritdoc IAuthorizedClaimers
60
+ function getAuthorizedClaimer(address authorizer) external view returns (address) {
61
+ return AuthorizedClaimerStorage.layout().authorizedClaimers[authorizer];
62
+ }
63
+
64
+ // =============================================================
65
+ // Internal
66
+ // =============================================================
67
+ function _authorizeClaimer(address signer, address claimer) internal {
68
+ AuthorizedClaimerStorage.Layout storage ds = AuthorizedClaimerStorage.layout();
69
+
70
+ if (claimer == address(0)) {
71
+ delete ds.authorizedClaimers[signer];
72
+ emit AuthorizedClaimerRemoved(signer);
73
+ } else {
74
+ address currentClaimer = ds.authorizedClaimers[signer];
75
+ if (currentClaimer == claimer) {
76
+ revert AuthorizedClaimers_ClaimerAlreadyAuthorized();
77
+ }
78
+
79
+ ds.authorizedClaimers[signer] = claimer;
80
+
81
+ emit AuthorizedClaimerChanged(signer, claimer);
82
+ }
83
+ }
84
+ }