@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,69 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.24;
3
+
4
+ interface IL2StandardBridge {
5
+ /// @notice Sends ETH to the sender's address on the other chain.
6
+ /// @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.
7
+ /// @param _extraData Extra data to be sent with the transaction. Note that the recipient will
8
+ /// not be triggered with this data, but it will be emitted and can be used
9
+ /// to identify the transaction.
10
+ function bridgeETH(uint32 _minGasLimit, bytes calldata _extraData) external payable;
11
+
12
+ /// @notice Sends ETH to a receiver's address on the other chain. Note that if ETH is sent to a
13
+ /// smart contract and the call fails, the ETH will be temporarily locked in the
14
+ /// StandardBridge on the other chain until the call is replayed. If the call cannot be
15
+ /// replayed with any amount of gas (call always reverts), then the ETH will be
16
+ /// permanently locked in the StandardBridge on the other chain. ETH will also
17
+ /// be locked if the receiver is the other bridge, because finalizeBridgeETH will revert
18
+ /// in that case.
19
+ /// @param _to Address of the receiver.
20
+ /// @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.
21
+ /// @param _extraData Extra data to be sent with the transaction. Note that the recipient will
22
+ /// not be triggered with this data, but it will be emitted and can be used
23
+ /// to identify the transaction.
24
+ function bridgeETHTo(
25
+ address _to,
26
+ uint32 _minGasLimit,
27
+ bytes calldata _extraData
28
+ ) external payable;
29
+
30
+ /// @notice Sends ERC20 tokens to the sender's address on the other chain. Note that if the
31
+ /// ERC20 token on the other chain does not recognize the local token as the correct
32
+ /// pair token, the ERC20 bridge will fail and the tokens will be returned to sender on
33
+ /// this chain.
34
+ /// @param _localToken Address of the ERC20 on this chain.
35
+ /// @param _remoteToken Address of the corresponding token on the remote chain.
36
+ /// @param _amount Amount of local tokens to deposit.
37
+ /// @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.
38
+ /// @param _extraData Extra data to be sent with the transaction. Note that the recipient will
39
+ /// not be triggered with this data, but it will be emitted and can be used
40
+ /// to identify the transaction.
41
+ function bridgeERC20(
42
+ address _localToken,
43
+ address _remoteToken,
44
+ uint256 _amount,
45
+ uint32 _minGasLimit,
46
+ bytes calldata _extraData
47
+ ) external;
48
+
49
+ /// @notice Sends ERC20 tokens to a receiver's address on the other chain. Note that if the
50
+ /// ERC20 token on the other chain does not recognize the local token as the correct
51
+ /// pair token, the ERC20 bridge will fail and the tokens will be returned to sender on
52
+ /// this chain.
53
+ /// @param _localToken Address of the ERC20 on this chain.
54
+ /// @param _remoteToken Address of the corresponding token on the remote chain.
55
+ /// @param _to Address of the receiver.
56
+ /// @param _amount Amount of local tokens to deposit.
57
+ /// @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.
58
+ /// @param _extraData Extra data to be sent with the transaction. Note that the recipient will
59
+ /// not be triggered with this data, but it will be emitted and can be used
60
+ /// to identify the transaction.
61
+ function bridgeERC20To(
62
+ address _localToken,
63
+ address _remoteToken,
64
+ address _to,
65
+ uint256 _amount,
66
+ uint32 _minGasLimit,
67
+ bytes calldata _extraData
68
+ ) external;
69
+ }
@@ -0,0 +1,210 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IDropFacetBase} from "./IDropFacet.sol";
6
+
7
+ // libraries
8
+ import {BasisPoints} from "../../utils/libraries/BasisPoints.sol";
9
+ import {CustomRevert} from "../../utils/libraries/CustomRevert.sol";
10
+ import {DropGroup} from "./DropGroup.sol";
11
+ import {DropStorage} from "./DropStorage.sol";
12
+ import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol";
13
+
14
+ abstract contract DropBase is IDropFacetBase {
15
+ using DropGroup for DropGroup.Layout;
16
+ using SafeTransferLib for address;
17
+ using CustomRevert for bytes4;
18
+
19
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
20
+ /* SETTERS */
21
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
22
+
23
+ function _setRewardsDistribution(address rewardsDistribution) internal {
24
+ if (rewardsDistribution == address(0)) {
25
+ DropFacet__RewardsDistributionNotSet.selector.revertWith();
26
+ }
27
+
28
+ _getLayout().rewardsDistribution = rewardsDistribution;
29
+ }
30
+
31
+ function _addClaimCondition(DropGroup.ClaimCondition calldata newCondition) internal {
32
+ (uint48 existingStartId, uint48 existingCount) = _getStartIdAndCount();
33
+ uint48 newConditionId = existingStartId + existingCount;
34
+
35
+ // Check timestamp order
36
+ if (existingCount > 0) {
37
+ DropGroup.ClaimCondition storage lastCondition;
38
+ unchecked {
39
+ lastCondition = _getClaimConditionById(newConditionId - 1);
40
+ }
41
+ if (lastCondition.startTimestamp >= newCondition.startTimestamp) {
42
+ DropFacet__ClaimConditionsNotInAscendingOrder.selector.revertWith();
43
+ }
44
+ }
45
+
46
+ // verify enough balance
47
+ _verifyEnoughBalance(newCondition.currency, newCondition.maxClaimableSupply);
48
+
49
+ _getDropGroup(newConditionId).condition = newCondition;
50
+
51
+ // Update condition count
52
+ _getLayout().conditionCount = existingCount + 1;
53
+
54
+ emit DropFacet_ClaimConditionAdded(newConditionId, newCondition);
55
+ }
56
+
57
+ function _setClaimConditions(DropGroup.ClaimCondition[] calldata conditions) internal {
58
+ DropStorage.Layout storage self = _getLayout();
59
+ // get the existing claim condition count and start id
60
+ (uint48 newStartId, uint48 existingConditionCount) = _getStartIdAndCount();
61
+
62
+ if (uint256(newStartId) + conditions.length > type(uint48).max) {
63
+ DropFacet__CannotSetClaimConditions.selector.revertWith();
64
+ }
65
+
66
+ uint48 newConditionCount = uint48(conditions.length);
67
+
68
+ uint48 lastConditionTimestamp;
69
+ uint256 totalClaimableSupply;
70
+
71
+ for (uint256 i; i < newConditionCount; ++i) {
72
+ DropGroup.ClaimCondition calldata newCondition = conditions[i];
73
+ if (lastConditionTimestamp >= newCondition.startTimestamp) {
74
+ DropFacet__ClaimConditionsNotInAscendingOrder.selector.revertWith();
75
+ }
76
+
77
+ // check that amount already claimed is less than or equal to the max claimable supply
78
+ DropGroup.Layout storage drop = self.groupById[newStartId + i];
79
+ uint256 amountAlreadyClaimed = drop.condition.supplyClaimed;
80
+
81
+ if (amountAlreadyClaimed > newCondition.maxClaimableSupply) {
82
+ DropFacet__CannotSetClaimConditions.selector.revertWith();
83
+ }
84
+
85
+ // copy the new condition to the storage except `supplyClaimed`
86
+ drop.updateClaimCondition(newCondition);
87
+
88
+ lastConditionTimestamp = newCondition.startTimestamp;
89
+ totalClaimableSupply += newCondition.maxClaimableSupply;
90
+ _verifyEnoughBalance(newCondition.currency, totalClaimableSupply);
91
+ }
92
+
93
+ self.conditionCount = newConditionCount;
94
+
95
+ if (existingConditionCount > newConditionCount) {
96
+ for (uint256 i = newConditionCount; i < existingConditionCount; ++i) {
97
+ unchecked {
98
+ delete self.groupById[newStartId + i];
99
+ }
100
+ }
101
+ }
102
+
103
+ emit DropFacet_ClaimConditionsUpdated(newStartId, conditions);
104
+ }
105
+
106
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
107
+ /* UTILS */
108
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
109
+
110
+ function _deductPenalty(
111
+ uint256 amount,
112
+ uint16 penaltyBps,
113
+ uint16 expectedPenaltyBps
114
+ ) internal pure returns (uint256) {
115
+ if (penaltyBps != expectedPenaltyBps) {
116
+ DropFacet__UnexpectedPenaltyBps.selector.revertWith();
117
+ }
118
+
119
+ if (penaltyBps > 0) {
120
+ unchecked {
121
+ uint256 penaltyAmount = BasisPoints.calculate(amount, penaltyBps);
122
+ amount -= penaltyAmount;
123
+ }
124
+ }
125
+ return amount;
126
+ }
127
+
128
+ function _verifyEnoughBalance(address token, uint256 amount) internal view {
129
+ if (amount > token.balanceOf(address(this))) {
130
+ DropFacet__InsufficientBalance.selector.revertWith();
131
+ }
132
+ }
133
+
134
+ function _approveClaimToken(address token, uint256 amount) internal {
135
+ token.safeApprove(_getLayout().rewardsDistribution, amount);
136
+ }
137
+
138
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
139
+ /* GETTERS */
140
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
141
+
142
+ function _getLayout() internal pure returns (DropStorage.Layout storage) {
143
+ return DropStorage.getLayout();
144
+ }
145
+
146
+ function _getDropGroup(uint256 conditionId) internal view returns (DropGroup.Layout storage) {
147
+ return _getLayout().groupById[conditionId];
148
+ }
149
+
150
+ function _getClaimConditionById(
151
+ uint256 conditionId
152
+ ) internal view returns (DropGroup.ClaimCondition storage) {
153
+ return _getDropGroup(conditionId).condition;
154
+ }
155
+
156
+ function _getSupplyClaimedByWallet(
157
+ uint256 conditionId,
158
+ address account
159
+ ) internal view returns (DropGroup.Claimed storage) {
160
+ return _getDropGroup(conditionId).supplyClaimedByWallet[account];
161
+ }
162
+
163
+ function _getStartIdAndCount() internal view returns (uint48 startId, uint48 count) {
164
+ DropStorage.Layout storage self = _getLayout();
165
+ (startId, count) = (self.conditionStartId, self.conditionCount);
166
+ }
167
+
168
+ function _getClaimConditions()
169
+ internal
170
+ view
171
+ returns (DropGroup.ClaimCondition[] memory conditions)
172
+ {
173
+ (uint48 conditionStartId, uint48 conditionCount) = _getStartIdAndCount();
174
+ conditions = new DropGroup.ClaimCondition[](conditionCount);
175
+ for (uint256 i; i < conditionCount; ++i) {
176
+ conditions[i] = _getClaimConditionById(conditionStartId + i);
177
+ }
178
+ return conditions;
179
+ }
180
+
181
+ function _getActiveConditionId() internal view returns (uint256) {
182
+ (uint48 conditionStartId, uint48 conditionCount) = _getStartIdAndCount();
183
+
184
+ if (conditionCount == 0) {
185
+ DropFacet__NoActiveClaimCondition.selector.revertWith();
186
+ }
187
+
188
+ uint256 lastConditionId;
189
+ unchecked {
190
+ lastConditionId = conditionStartId + conditionCount - 1;
191
+ }
192
+
193
+ for (uint256 i = lastConditionId + 1; i > conditionStartId; ) {
194
+ unchecked {
195
+ --i;
196
+ }
197
+
198
+ DropGroup.ClaimCondition storage condition = _getClaimConditionById(i);
199
+ uint256 endTimestamp = condition.endTimestamp;
200
+ if (
201
+ block.timestamp >= condition.startTimestamp &&
202
+ (endTimestamp == 0 || block.timestamp < endTimestamp)
203
+ ) {
204
+ return i;
205
+ }
206
+ }
207
+
208
+ DropFacet__NoActiveClaimCondition.selector.revertWith();
209
+ }
210
+ }
@@ -0,0 +1,55 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IDropFacetBase} from "./IDropFacet.sol";
6
+
7
+ // libraries
8
+ import {CustomRevert} from "../../utils/libraries/CustomRevert.sol";
9
+ import {MerkleProofLib} from "solady/utils/MerkleProofLib.sol";
10
+
11
+ // contracts
12
+
13
+ library DropClaim {
14
+ using MerkleProofLib for bytes32[];
15
+ using CustomRevert for bytes4;
16
+
17
+ /// @notice A struct representing a claim
18
+ /// @param conditionId The ID of the claim condition
19
+ /// @param account The address of the account that claimed
20
+ /// @param recipient The address of the recipient of the tokens
21
+ /// @param quantity The quantity of tokens claimed
22
+ /// @param points The points to be burned
23
+ /// @param proof The proof of the claim
24
+ struct Claim {
25
+ uint256 conditionId;
26
+ address account;
27
+ address recipient;
28
+ uint256 quantity;
29
+ uint256 points;
30
+ bytes32[] proof;
31
+ }
32
+
33
+ function verify(Claim calldata claim, bytes32 root) internal pure {
34
+ bytes32 leaf = createLeaf(claim);
35
+ if (!claim.proof.verifyCalldata(root, leaf)) {
36
+ IDropFacetBase.DropFacet__InvalidProof.selector.revertWith();
37
+ }
38
+ }
39
+
40
+ function createLeaf(Claim calldata claim) internal pure returns (bytes32 leaf) {
41
+ address account = claim.account;
42
+ uint256 quantity = claim.quantity;
43
+ uint256 points = claim.points;
44
+ assembly ("memory-safe") {
45
+ let fmp := mload(0x40)
46
+ mstore(0, account)
47
+ mstore(0x20, quantity)
48
+ mstore(0x40, points)
49
+ leaf := keccak256(0, 0x60)
50
+ mstore(0, leaf)
51
+ leaf := keccak256(0, 0x20)
52
+ mstore(0x40, fmp)
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,176 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IRewardsDistribution} from "../../base/registry/facets/distribution/v2/IRewardsDistribution.sol";
6
+ import {IDropFacet} from "./IDropFacet.sol";
7
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
8
+
9
+ // libraries
10
+ import {DropClaim} from "./DropClaim.sol";
11
+ import {DropGroup} from "./DropGroup.sol";
12
+ import {DropStorage} from "./DropStorage.sol";
13
+ import {SafeCastLib} from "solady/utils/SafeCastLib.sol";
14
+ import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol";
15
+ import {CustomRevert} from "../../utils/libraries/CustomRevert.sol";
16
+
17
+ // contracts
18
+ import {TownsPointsStorage} from "../points/TownsPointsStorage.sol";
19
+ import {DropBase} from "./DropBase.sol";
20
+ import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
21
+ import {OwnableBase} from "@towns-protocol/diamond/src/facets/ownable/OwnableBase.sol";
22
+ import {PausableBase} from "@towns-protocol/diamond/src/facets/pausable/PausableBase.sol";
23
+
24
+ contract DropFacet is IDropFacet, DropBase, OwnableBase, PausableBase, Facet {
25
+ using DropClaim for DropClaim.Claim;
26
+ using DropGroup for DropGroup.Layout;
27
+ using SafeTransferLib for address;
28
+ using CustomRevert for bytes4;
29
+
30
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
31
+ /* ADMIN FUNCTIONS */
32
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
33
+
34
+ function __DropFacet_init(address rewardsDistribution) external onlyInitializing {
35
+ _addInterface(type(IDropFacet).interfaceId);
36
+ __DropFacet_init_unchained(rewardsDistribution);
37
+ }
38
+
39
+ function __DropFacet_init_unchained(address rewardsDistribution) internal {
40
+ _setRewardsDistribution(rewardsDistribution);
41
+ }
42
+
43
+ /// @inheritdoc IDropFacet
44
+ function addClaimCondition(DropGroup.ClaimCondition calldata condition) external onlyOwner {
45
+ _addClaimCondition(condition);
46
+ }
47
+
48
+ /// @inheritdoc IDropFacet
49
+ function setClaimConditions(DropGroup.ClaimCondition[] calldata conditions) external onlyOwner {
50
+ _setClaimConditions(conditions);
51
+ }
52
+
53
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
54
+ /* CLAIMING */
55
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
56
+
57
+ /// @inheritdoc IDropFacet
58
+ function claimWithPenalty(
59
+ DropClaim.Claim calldata req,
60
+ uint16 expectedPenaltyBps
61
+ ) external whenNotPaused returns (uint256 amount) {
62
+ if (msg.sender != req.account) DropFacet__NotClaimingAccount.selector.revertWith();
63
+ if (req.recipient == address(0)) DropFacet__InvalidRecipient.selector.revertWith();
64
+
65
+ DropGroup.Layout storage drop = _getDropGroup(req.conditionId);
66
+
67
+ amount = _deductPenalty(req.quantity, drop.condition.penaltyBps, expectedPenaltyBps);
68
+
69
+ drop.verify(amount);
70
+
71
+ // verify the Merkle proof of the claim
72
+ req.verify(drop.condition.merkleRoot);
73
+
74
+ drop.claim(req.account, amount);
75
+
76
+ _burnPoints(req.account, req.points);
77
+
78
+ drop.condition.currency.safeTransfer(req.recipient, amount);
79
+
80
+ emit DropFacet_Claimed_WithPenalty(req.conditionId, msg.sender, req.account, amount);
81
+ }
82
+
83
+ /// @inheritdoc IDropFacet
84
+ function claimAndStake(
85
+ DropClaim.Claim calldata req,
86
+ address delegatee,
87
+ uint256 deadline,
88
+ bytes calldata signature
89
+ ) external whenNotPaused returns (uint256 amount) {
90
+ if (msg.sender != req.account) DropFacet__NotClaimingAccount.selector.revertWith();
91
+ if (req.recipient == address(0)) DropFacet__InvalidRecipient.selector.revertWith();
92
+
93
+ DropGroup.Layout storage drop = _getDropGroup(req.conditionId);
94
+
95
+ amount = req.quantity;
96
+ drop.verify(amount);
97
+
98
+ // verify the Merkle proof of the claim
99
+ req.verify(drop.condition.merkleRoot);
100
+
101
+ drop.claim(req.account, amount);
102
+
103
+ _burnPoints(req.account, req.points);
104
+ _approveClaimToken(drop.condition.currency, amount);
105
+
106
+ uint256 depositId = IRewardsDistribution(DropStorage.getLayout().rewardsDistribution)
107
+ .stakeOnBehalf(
108
+ SafeCastLib.toUint96(amount),
109
+ delegatee,
110
+ req.account,
111
+ req.account,
112
+ deadline,
113
+ signature
114
+ );
115
+
116
+ DropGroup.Claimed storage claimed = drop.supplyClaimedByWallet[req.account];
117
+ claimed.depositId = depositId;
118
+
119
+ emit DropFacet_Claimed_And_Staked(req.conditionId, msg.sender, req.account, amount);
120
+ }
121
+
122
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
123
+ /* GETTERS */
124
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
125
+
126
+ /// @inheritdoc IDropFacet
127
+ function getActiveClaimConditionId() external view returns (uint256) {
128
+ return _getActiveConditionId();
129
+ }
130
+
131
+ /// @inheritdoc IDropFacet
132
+ function getClaimConditions() external view returns (DropGroup.ClaimCondition[] memory) {
133
+ return _getClaimConditions();
134
+ }
135
+
136
+ /// @inheritdoc IDropFacet
137
+ function getClaimConditionById(
138
+ uint256 conditionId
139
+ ) external view returns (DropGroup.ClaimCondition memory condition) {
140
+ assembly ("memory-safe") {
141
+ // By default, memory has been implicitly allocated for `condition`.
142
+ // But we don't need this implicitly allocated memory.
143
+ // So we just set the free memory pointer to what it was before `condition` has been
144
+ // allocated.
145
+ mstore(0x40, condition)
146
+ }
147
+ condition = _getClaimConditionById(conditionId);
148
+ }
149
+
150
+ /// @inheritdoc IDropFacet
151
+ function getSupplyClaimedByWallet(
152
+ address account,
153
+ uint256 conditionId
154
+ ) external view returns (uint256) {
155
+ return _getSupplyClaimedByWallet(conditionId, account).amount;
156
+ }
157
+
158
+ /// @inheritdoc IDropFacet
159
+ function getDepositIdByWallet(
160
+ address account,
161
+ uint256 conditionId
162
+ ) external view returns (uint256) {
163
+ return _getSupplyClaimedByWallet(conditionId, account).depositId;
164
+ }
165
+
166
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
167
+ /* INTERNAL FUNCTIONS */
168
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
169
+
170
+ function _burnPoints(address from, uint256 amount) internal {
171
+ if (amount == 0) return;
172
+ TownsPointsStorage.Layout storage points = TownsPointsStorage.layout();
173
+ points.inner.burn(from, amount);
174
+ emit IERC20.Transfer(from, address(0), amount);
175
+ }
176
+ }
@@ -0,0 +1,111 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IDropFacetBase} from "./IDropFacet.sol";
6
+
7
+ // libraries
8
+ import {CustomRevert} from "../../utils/libraries/CustomRevert.sol";
9
+
10
+ // contracts
11
+
12
+ library DropGroup {
13
+ using CustomRevert for bytes4;
14
+
15
+ /// @notice The layout of the drop group
16
+ /// @param supplyClaimedByWallet A mapping of addresses to their claimed amounts and deposit IDs
17
+ /// @param condition The current claim condition
18
+ struct Layout {
19
+ mapping(address => Claimed) supplyClaimedByWallet;
20
+ ClaimCondition condition;
21
+ }
22
+
23
+ /// @notice A struct representing a claimed drop
24
+ /// @param amount The amount of tokens claimed
25
+ /// @param depositId The deposit ID of the claim
26
+ struct Claimed {
27
+ uint256 amount;
28
+ uint256 depositId;
29
+ }
30
+
31
+ /// @notice A struct representing a claim condition
32
+ /// @param currency The currency to claim in
33
+ /// @param startTimestamp The timestamp at which the claim condition starts
34
+ /// @param endTimestamp The timestamp at which the claim condition ends
35
+ /// @param penaltyBps The penalty in basis points for early withdrawal
36
+ /// @param maxClaimableSupply The maximum claimable supply for the claim condition
37
+ /// @param supplyClaimed The supply already claimed for the claim condition
38
+ /// @param merkleRoot The merkle root for the claim condition
39
+ struct ClaimCondition {
40
+ address currency;
41
+ uint40 startTimestamp;
42
+ uint40 endTimestamp;
43
+ uint16 penaltyBps;
44
+ uint256 maxClaimableSupply;
45
+ uint256 supplyClaimed;
46
+ bytes32 merkleRoot;
47
+ }
48
+
49
+ /// @notice Updates to the claim condition except for `supplyClaimed`
50
+ /// @param self The drop group
51
+ /// @param newCondition The new claim condition
52
+ function updateClaimCondition(
53
+ Layout storage self,
54
+ ClaimCondition calldata newCondition
55
+ ) internal {
56
+ ClaimCondition storage condition = self.condition;
57
+ condition.startTimestamp = newCondition.startTimestamp;
58
+ condition.endTimestamp = newCondition.endTimestamp;
59
+ condition.maxClaimableSupply = newCondition.maxClaimableSupply;
60
+ condition.merkleRoot = newCondition.merkleRoot;
61
+ condition.currency = newCondition.currency;
62
+ condition.penaltyBps = newCondition.penaltyBps;
63
+ }
64
+
65
+ /// @notice Claims the amount of tokens for the claim
66
+ /// @param self The drop group
67
+ /// @param account The claiming account
68
+ /// @param amount The amount of tokens to claim
69
+ function claim(Layout storage self, address account, uint256 amount) internal {
70
+ Claimed storage claimed = self.supplyClaimedByWallet[account];
71
+ // check if already claimed
72
+ if (claimed.amount > 0) {
73
+ IDropFacetBase.DropFacet__AlreadyClaimed.selector.revertWith();
74
+ }
75
+
76
+ self.condition.supplyClaimed += amount;
77
+ claimed.amount = amount;
78
+ }
79
+
80
+ /// @notice Verifies the claim condition
81
+ /// @param self The drop group
82
+ /// @param amount The amount of tokens to claim
83
+ function verify(Layout storage self, uint256 amount) internal view {
84
+ ClaimCondition storage condition = self.condition;
85
+ if (condition.merkleRoot == bytes32(0)) {
86
+ IDropFacetBase.DropFacet__MerkleRootNotSet.selector.revertWith();
87
+ }
88
+
89
+ if (amount == 0) {
90
+ IDropFacetBase.DropFacet__QuantityMustBeGreaterThanZero.selector.revertWith();
91
+ }
92
+
93
+ if (condition.currency == address(0)) {
94
+ IDropFacetBase.DropFacet__CurrencyNotSet.selector.revertWith();
95
+ }
96
+
97
+ // check if the total claimed supply (including the current claim) exceeds the maximum
98
+ // claimable supply
99
+ if (condition.supplyClaimed + amount > condition.maxClaimableSupply) {
100
+ IDropFacetBase.DropFacet__ExceedsMaxClaimableSupply.selector.revertWith();
101
+ }
102
+
103
+ if (block.timestamp < condition.startTimestamp) {
104
+ IDropFacetBase.DropFacet__ClaimHasNotStarted.selector.revertWith();
105
+ }
106
+
107
+ if (condition.endTimestamp > 0 && block.timestamp >= condition.endTimestamp) {
108
+ IDropFacetBase.DropFacet__ClaimHasEnded.selector.revertWith();
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,23 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ import {DropGroup} from "./DropGroup.sol";
5
+
6
+ library DropStorage {
7
+ // keccak256(abi.encode(uint256(keccak256("diamond.facets.drop.storage")) - 1)) & ~bytes32(uint256(0xff))
8
+ bytes32 internal constant STORAGE_SLOT =
9
+ 0xeda6a1e2ce6f1639b6d3066254ca87a2daf51c4f0ad5038d408bbab6cc2cab00;
10
+
11
+ struct Layout {
12
+ address rewardsDistribution;
13
+ uint48 conditionStartId;
14
+ uint48 conditionCount;
15
+ mapping(uint256 groupId => DropGroup.Layout) groupById;
16
+ }
17
+
18
+ function getLayout() internal pure returns (Layout storage l) {
19
+ assembly {
20
+ l.slot := STORAGE_SLOT
21
+ }
22
+ }
23
+ }