@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,172 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IHookBase, HookConfig, Hook} from "./IHookBase.sol";
6
+
7
+ // libraries
8
+ import {ExecutorStorage} from "../ExecutorStorage.sol";
9
+ import {CustomRevert} from "../../../../utils/libraries/CustomRevert.sol";
10
+ import {EnumerableSetLib} from "solady/utils/EnumerableSetLib.sol";
11
+ import {LibCall} from "solady/utils/LibCall.sol";
12
+ import {HookLib} from "./HookLib.sol";
13
+
14
+ // contracts
15
+
16
+ abstract contract HookBase is IHookBase {
17
+ using EnumerableSetLib for EnumerableSetLib.Bytes32Set;
18
+ using CustomRevert for bytes4;
19
+ using HookLib for HookConfig;
20
+
21
+ uint256 internal constant MAX_HOOKS = 10;
22
+
23
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
24
+ /* HOOKS */
25
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
26
+ function _addHook(
27
+ address module,
28
+ bytes4 selector,
29
+ uint32 entityId,
30
+ bool isPre,
31
+ bool isPost
32
+ ) internal {
33
+ HookConfig storage config = _getConfig(module, selector);
34
+ bytes32 hookId = _entityId(module, entityId);
35
+
36
+ if (config.isHookActive(hookId)) HookAlreadyExists.selector.revertWith();
37
+
38
+ config.createHook(hookId, module, entityId);
39
+
40
+ if (isPre) {
41
+ if (config.preHooks.length() >= MAX_HOOKS) TooManyHooks.selector.revertWith();
42
+ config.preHooks.add(hookId);
43
+ }
44
+
45
+ if (isPost) {
46
+ if (config.postHooks.length() >= MAX_HOOKS) TooManyHooks.selector.revertWith();
47
+ config.postHooks.add(hookId);
48
+ }
49
+
50
+ emit HookAdded(module, selector, entityId, isPre, isPost);
51
+ }
52
+
53
+ function _removeHook(address module, bytes4 selector, uint32 entityId) internal {
54
+ HookConfig storage config = _getConfig(module, selector);
55
+ bytes32 hookId = _entityId(module, entityId);
56
+
57
+ if (!config.isHookActive(hookId)) HookDoesNotExist.selector.revertWith();
58
+
59
+ config.removeHook(hookId, selector);
60
+
61
+ emit HookRemoved(module, selector, entityId);
62
+ }
63
+
64
+ function _callPreHooks(
65
+ address module,
66
+ bytes4 selector,
67
+ uint256 value,
68
+ bytes calldata data
69
+ ) internal {
70
+ HookConfig storage config = _getConfig(module, selector);
71
+
72
+ uint256 preHookCount = config.preHooks.length();
73
+ for (uint256 i; i < preHookCount; ++i) {
74
+ bytes32 hookId = config.preHooks.at(i);
75
+ Hook storage hook = config.hookData[hookId];
76
+
77
+ if (!hook.isActive) continue;
78
+
79
+ // Execute pre-hook and capture its return data
80
+ bytes memory preHookData = LibCall.callContract(
81
+ hook.module,
82
+ abi.encodeWithSignature(
83
+ "preExecutionHook(uint32,address,uint256,bytes)",
84
+ hook.entityId,
85
+ msg.sender,
86
+ value,
87
+ data
88
+ )
89
+ );
90
+
91
+ // Store with selector context
92
+ if (preHookData.length > 0) {
93
+ config.preHookData[selector][hookId] = preHookData;
94
+ }
95
+ }
96
+ }
97
+
98
+ function _callPostHooks(address module, bytes4 selector) internal {
99
+ HookConfig storage config = _getConfig(module, selector);
100
+
101
+ uint256 postHookCount = config.postHooks.length();
102
+
103
+ for (uint256 i; i < postHookCount; ++i) {
104
+ bytes32 hookId = config.postHooks.at(i);
105
+ Hook storage hook = config.hookData[hookId];
106
+
107
+ if (!hook.isActive) continue;
108
+
109
+ // Get stored pre-hook data with selector context
110
+ bytes memory preHookData = config.preHookData[selector][hookId];
111
+
112
+ LibCall.callContract(
113
+ hook.module,
114
+ abi.encodeWithSignature(
115
+ "postExecutionHook(uint32,bytes)",
116
+ hook.entityId,
117
+ preHookData
118
+ )
119
+ );
120
+
121
+ // Clean up storage with selector context
122
+ delete config.preHookData[selector][hookId];
123
+ }
124
+ }
125
+
126
+ function _getHooks(
127
+ address module,
128
+ bytes4 selector,
129
+ bool isPre
130
+ ) internal view returns (Hook[] memory hooks) {
131
+ HookConfig storage config = _getConfig(module, selector);
132
+ EnumerableSetLib.Bytes32Set storage hookSet = isPre ? config.preHooks : config.postHooks;
133
+
134
+ uint256 length = hookSet.length();
135
+ hooks = new Hook[](length);
136
+
137
+ for (uint256 i; i < length; ++i) {
138
+ bytes32 hookId = hookSet.at(i);
139
+ hooks[i] = config.hookData[hookId];
140
+ }
141
+ }
142
+
143
+ function _hasHook(
144
+ address module,
145
+ bytes4 selector,
146
+ uint32 entityId,
147
+ bool isPre
148
+ ) internal view returns (bool) {
149
+ HookConfig storage config = _getConfig(module, selector);
150
+ bytes32 hookId = _entityId(module, entityId);
151
+
152
+ EnumerableSetLib.Bytes32Set storage hooks = isPre ? config.preHooks : config.postHooks;
153
+
154
+ return hooks.contains(hookId);
155
+ }
156
+
157
+ function _configId(address target, bytes4 selector) internal pure returns (bytes32) {
158
+ return keccak256(abi.encode(target, selector));
159
+ }
160
+
161
+ function _entityId(address module, uint32 entity) internal pure returns (bytes32) {
162
+ return keccak256(abi.encode(module, entity));
163
+ }
164
+
165
+ function _getConfig(
166
+ address module,
167
+ bytes4 selector
168
+ ) internal view virtual returns (HookConfig storage config) {
169
+ bytes32 id = _configId(module, selector);
170
+ config = ExecutorStorage.getLayout().hooks[id];
171
+ }
172
+ }
@@ -0,0 +1,38 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ // libraries
7
+ import {CustomRevert} from "src/utils/libraries/CustomRevert.sol";
8
+ import {EnumerableSetLib} from "solady/utils/EnumerableSetLib.sol";
9
+ import {LibCall} from "solady/utils/LibCall.sol";
10
+
11
+ // types
12
+ import {HookConfig, Hook} from "./IHookBase.sol";
13
+
14
+ // contracts
15
+
16
+ library HookLib {
17
+ using EnumerableSetLib for EnumerableSetLib.Bytes32Set;
18
+
19
+ function isHookActive(HookConfig storage self, bytes32 hookId) internal view returns (bool) {
20
+ return self.hookData[hookId].isActive;
21
+ }
22
+
23
+ function createHook(
24
+ HookConfig storage self,
25
+ bytes32 hookId,
26
+ address module,
27
+ uint32 entityId
28
+ ) internal {
29
+ self.hookData[hookId] = Hook({module: module, entityId: entityId, isActive: true});
30
+ }
31
+
32
+ function removeHook(HookConfig storage self, bytes32 hookId, bytes4 selector) internal {
33
+ delete self.hookData[hookId];
34
+ delete self.preHookData[selector][hookId];
35
+ self.preHooks.remove(hookId);
36
+ self.postHooks.remove(hookId);
37
+ }
38
+ }
@@ -0,0 +1,48 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ // libraries
7
+ import {EnumerableSetLib} from "solady/utils/EnumerableSetLib.sol";
8
+
9
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
10
+ /* STRUCTS */
11
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
12
+ struct Hook {
13
+ address module;
14
+ uint32 entityId;
15
+ bool isActive;
16
+ }
17
+
18
+ struct HookConfig {
19
+ EnumerableSetLib.Bytes32Set preHooks;
20
+ EnumerableSetLib.Bytes32Set postHooks;
21
+ mapping(bytes4 selector => mapping(bytes32 entityId => bytes)) preHookData;
22
+ mapping(bytes32 entityId => Hook) hookData;
23
+ }
24
+
25
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
26
+ /* BASE INTERFACE */
27
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
28
+
29
+ interface IHookBase {
30
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
31
+ /* ERRORS */
32
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
33
+ error HookAlreadyExists();
34
+ error HookDoesNotExist();
35
+ error TooManyHooks();
36
+
37
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
38
+ /* EVENTS */
39
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
40
+ event HookAdded(
41
+ address indexed module,
42
+ bytes4 indexed selector,
43
+ uint32 indexed entityId,
44
+ bool isPre,
45
+ bool isPostHook
46
+ );
47
+ event HookRemoved(address indexed module, bytes4 indexed selector, uint32 indexed entityId);
48
+ }
@@ -0,0 +1,59 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IEntitlementGated} from "./IEntitlementGated.sol";
6
+
7
+ import {IEntitlementChecker} from "src/base/registry/facets/checker/IEntitlementChecker.sol";
8
+ import {IRuleEntitlement} from "src/spaces/entitlements/rule/IRuleEntitlement.sol";
9
+
10
+ // libraries
11
+
12
+ // contracts
13
+ import {EntitlementGatedBase} from "./EntitlementGatedBase.sol";
14
+ import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
15
+ import {ReentrancyGuard} from "solady/utils/ReentrancyGuard.sol";
16
+
17
+ contract EntitlementGated is IEntitlementGated, EntitlementGatedBase, ReentrancyGuard, Facet {
18
+ function __EntitlementGated_init(
19
+ IEntitlementChecker entitlementChecker
20
+ ) external onlyInitializing {
21
+ __EntitlementGated_init_unchained(entitlementChecker);
22
+ }
23
+
24
+ function __EntitlementGated_init_unchained(IEntitlementChecker entitlementChecker) internal {
25
+ _addInterface(type(IEntitlementGated).interfaceId);
26
+ _setEntitlementChecker(entitlementChecker);
27
+ }
28
+
29
+ // Called by the xchain node to post the result of the entitlement check
30
+ // the internal function validates the transactionId and the result
31
+ function postEntitlementCheckResult(
32
+ bytes32 transactionId,
33
+ uint256 roleId,
34
+ NodeVoteStatus result
35
+ ) external nonReentrant {
36
+ _postEntitlementCheckResult(transactionId, roleId, result);
37
+ }
38
+
39
+ /// @notice Post the result of the entitlement check for a specific role
40
+ /// @dev Only the entitlement checker can call this function
41
+ /// @param transactionId The unique identifier for the transaction
42
+ /// @param roleId The role ID for the entitlement check
43
+ /// @param result The result of the entitlement check (PASSED or FAILED)
44
+ function postEntitlementCheckResultV2(
45
+ bytes32 transactionId,
46
+ uint256 roleId,
47
+ NodeVoteStatus result
48
+ ) external payable onlyEntitlementChecker nonReentrant {
49
+ _postEntitlementCheckResultV2(transactionId, roleId, result);
50
+ }
51
+
52
+ /// deprecated Use EntitlementDataQueryable.getCrossChainEntitlementData instead
53
+ function getRuleData(
54
+ bytes32 transactionId,
55
+ uint256 roleId
56
+ ) external view returns (IRuleEntitlement.RuleData memory) {
57
+ return _getRuleData(transactionId, roleId);
58
+ }
59
+ }
@@ -0,0 +1,324 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IEntitlementGatedBase} from "./IEntitlementGated.sol";
6
+
7
+ import {IEntitlementChecker} from "src/base/registry/facets/checker/IEntitlementChecker.sol";
8
+ import {IImplementationRegistry} from "src/factory/facets/registry/IImplementationRegistry.sol";
9
+ import {IRuleEntitlement} from "src/spaces/entitlements/rule/IRuleEntitlement.sol";
10
+
11
+ // libraries
12
+ import {EntitlementGatedStorage} from "./EntitlementGatedStorage.sol";
13
+ import {MembershipStorage} from "src/spaces/facets/membership/MembershipStorage.sol";
14
+ import {CustomRevert} from "src/utils/libraries/CustomRevert.sol";
15
+
16
+ abstract contract EntitlementGatedBase is IEntitlementGatedBase {
17
+ using CustomRevert for bytes4;
18
+
19
+ modifier onlyEntitlementChecker() {
20
+ if (msg.sender != address(EntitlementGatedStorage.layout().entitlementChecker)) {
21
+ CustomRevert.revertWith(EntitlementGated_OnlyEntitlementChecker.selector);
22
+ }
23
+ _;
24
+ }
25
+
26
+ function _setEntitlementChecker(IEntitlementChecker entitlementChecker) internal {
27
+ EntitlementGatedStorage.layout().entitlementChecker = entitlementChecker;
28
+ }
29
+
30
+ function _requestEntitlementCheck(
31
+ address callerAddress,
32
+ bytes32 transactionId,
33
+ IRuleEntitlement entitlement,
34
+ uint256 roleId
35
+ ) internal {
36
+ if (callerAddress == address(0)) {
37
+ CustomRevert.revertWith(EntitlementGated_InvalidAddress.selector);
38
+ }
39
+
40
+ EntitlementGatedStorage.Layout storage ds = EntitlementGatedStorage.layout();
41
+ Transaction storage transaction = ds.transactions[transactionId];
42
+ if (transaction.finalized) {
43
+ uint256 _length = transaction.roleIds.length;
44
+ for (uint256 i; i < _length; ++i) {
45
+ if (transaction.roleIds[i] == roleId) {
46
+ revert EntitlementGated_TransactionCheckAlreadyRegistered();
47
+ }
48
+ }
49
+ }
50
+
51
+ // if the entitlement checker has not been set, set it
52
+ if (address(ds.entitlementChecker) == address(0)) {
53
+ _setFallbackEntitlementChecker();
54
+ }
55
+
56
+ address[] memory selectedNodes = ds.entitlementChecker.getRandomNodes(5);
57
+
58
+ if (!transaction.finalized) {
59
+ transaction.finalized = true;
60
+ transaction.entitlement = entitlement;
61
+ transaction.clientAddress = callerAddress;
62
+ }
63
+
64
+ transaction.roleIds.push(roleId);
65
+
66
+ uint256 length = selectedNodes.length;
67
+ NodeVote[] storage nodeVotesForRole = transaction.nodeVotesArray[roleId];
68
+ for (uint256 i; i < length; ++i) {
69
+ nodeVotesForRole.push(
70
+ NodeVote({node: selectedNodes[i], vote: NodeVoteStatus.NOT_VOTED})
71
+ );
72
+ }
73
+
74
+ ds.entitlementChecker.requestEntitlementCheck(
75
+ callerAddress,
76
+ transactionId,
77
+ roleId,
78
+ selectedNodes
79
+ );
80
+ }
81
+
82
+ function _postEntitlementCheckResult(
83
+ bytes32 transactionId,
84
+ uint256 roleId,
85
+ NodeVoteStatus result
86
+ ) internal {
87
+ EntitlementGatedStorage.Layout storage ds = EntitlementGatedStorage.layout();
88
+ Transaction storage transaction = ds.transactions[transactionId];
89
+
90
+ if (transaction.clientAddress == address(0) || transaction.finalized == false) {
91
+ revert EntitlementGated_TransactionNotRegistered();
92
+ }
93
+
94
+ if (transaction.isCompleted[roleId]) {
95
+ revert EntitlementGated_TransactionCheckAlreadyCompleted();
96
+ }
97
+
98
+ // Find node in the array and update the vote, revert if node was not found.
99
+ bool found;
100
+
101
+ // count the votes
102
+ uint256 passed = 0;
103
+ uint256 failed = 0;
104
+
105
+ NodeVote[] storage nodeVotesForRole = transaction.nodeVotesArray[roleId];
106
+ uint256 transactionNodesLength = nodeVotesForRole.length;
107
+
108
+ for (uint256 i; i < transactionNodesLength; ++i) {
109
+ NodeVote storage currentVote = nodeVotesForRole[i];
110
+
111
+ // Update vote if not yet voted
112
+ if (currentVote.node == msg.sender) {
113
+ if (currentVote.vote != NodeVoteStatus.NOT_VOTED) {
114
+ revert EntitlementGated_NodeAlreadyVoted();
115
+ }
116
+ currentVote.vote = result;
117
+ found = true;
118
+ }
119
+
120
+ unchecked {
121
+ NodeVoteStatus currentStatus = currentVote.vote;
122
+ // Count votes
123
+ if (currentStatus == NodeVoteStatus.PASSED) {
124
+ ++passed;
125
+ } else if (currentStatus == NodeVoteStatus.FAILED) {
126
+ ++failed;
127
+ }
128
+ }
129
+ }
130
+
131
+ if (!found) {
132
+ revert EntitlementGated_NodeNotFound();
133
+ }
134
+
135
+ if (passed > transactionNodesLength / 2 || failed > transactionNodesLength / 2) {
136
+ transaction.isCompleted[roleId] = true;
137
+ NodeVoteStatus finalStatusForRole = passed > failed
138
+ ? NodeVoteStatus.PASSED
139
+ : NodeVoteStatus.FAILED;
140
+
141
+ bool allRoleIdsCompleted = _checkAllRoleIdsCompleted(transactionId);
142
+
143
+ if (finalStatusForRole == NodeVoteStatus.PASSED || allRoleIdsCompleted) {
144
+ _onEntitlementCheckResultPosted(transactionId, finalStatusForRole);
145
+ emit EntitlementCheckResultPosted(transactionId, finalStatusForRole);
146
+ }
147
+
148
+ if (allRoleIdsCompleted) {
149
+ _removeTransaction(transactionId);
150
+ }
151
+ }
152
+ }
153
+
154
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
155
+ /* V2 */
156
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
157
+
158
+ /// @notice Requests a V2 entitlement check with optimized validation and execution
159
+ /// @param walletAddress The wallet address to check entitlements for
160
+ /// @param senderAddress The original sender address (encoded in extraData)
161
+ /// @param transactionId The unique transaction identifier
162
+ /// @param entitlement The entitlement contract to use for checking
163
+ /// @param requestId The specific request identifier
164
+ /// @param value The amount of ETH to send with the request (if any)
165
+ function _requestEntitlementCheckV2(
166
+ address walletAddress,
167
+ address senderAddress,
168
+ bytes32 transactionId,
169
+ IRuleEntitlement entitlement,
170
+ uint256 requestId,
171
+ uint256 value
172
+ ) internal {
173
+ // Validate all inputs upfront
174
+ _validateEntitlementCheckInputs(walletAddress, entitlement, value);
175
+
176
+ // Setup transaction state
177
+ EntitlementGatedStorage.Layout storage $ = EntitlementGatedStorage.layout();
178
+ _setupTransaction($.transactions[transactionId], entitlement);
179
+
180
+ // Execute the entitlement check request
181
+ _executeEntitlementCheckRequest(
182
+ $.entitlementChecker,
183
+ walletAddress,
184
+ transactionId,
185
+ requestId,
186
+ value,
187
+ abi.encode(senderAddress)
188
+ );
189
+ }
190
+
191
+ /// @notice Validates inputs for entitlement check request
192
+ /// @param walletAddress The wallet address being checked
193
+ /// @param entitlement The entitlement contract
194
+ /// @param value The ETH value being sent
195
+ function _validateEntitlementCheckInputs(
196
+ address walletAddress,
197
+ IRuleEntitlement entitlement,
198
+ uint256 value
199
+ ) private view {
200
+ if (value > msg.value) {
201
+ EntitlementGated_InvalidValue.selector.revertWith();
202
+ }
203
+ if (walletAddress == address(0)) {
204
+ EntitlementGated_InvalidAddress.selector.revertWith();
205
+ }
206
+ if (address(entitlement) == address(0)) {
207
+ EntitlementGated_InvalidEntitlement.selector.revertWith();
208
+ }
209
+ }
210
+
211
+ /// @notice Sets up transaction state for entitlement checking
212
+ /// @param transaction Storage reference to the transaction
213
+ /// @param entitlement The entitlement contract to associate
214
+ function _setupTransaction(
215
+ Transaction storage transaction,
216
+ IRuleEntitlement entitlement
217
+ ) private {
218
+ transaction.finalized = true;
219
+ transaction.entitlement = entitlement;
220
+ }
221
+
222
+ /// @notice Executes the entitlement check request with optimized call pattern
223
+ /// @param checker The entitlement checker contract
224
+ /// @param walletAddress The wallet address to check
225
+ /// @param transactionId The transaction identifier
226
+ /// @param requestId The request identifier
227
+ /// @param value The ETH value to send
228
+ /// @param extraData Encoded additional data
229
+ function _executeEntitlementCheckRequest(
230
+ IEntitlementChecker checker,
231
+ address walletAddress,
232
+ bytes32 transactionId,
233
+ uint256 requestId,
234
+ uint256 value,
235
+ bytes memory extraData
236
+ ) private {
237
+ if (value > 0) {
238
+ checker.requestEntitlementCheckV2{value: value}(
239
+ walletAddress,
240
+ transactionId,
241
+ requestId,
242
+ extraData
243
+ );
244
+ } else {
245
+ checker.requestEntitlementCheckV2(walletAddress, transactionId, requestId, extraData);
246
+ }
247
+ }
248
+
249
+ function _postEntitlementCheckResultV2(
250
+ bytes32 transactionId,
251
+ uint256,
252
+ NodeVoteStatus result
253
+ ) internal {
254
+ EntitlementGatedStorage.Layout storage $ = EntitlementGatedStorage.layout();
255
+ Transaction storage transaction = $.transactions[transactionId];
256
+
257
+ if (!transaction.finalized) {
258
+ EntitlementGated_TransactionNotRegistered.selector.revertWith();
259
+ }
260
+
261
+ emit EntitlementCheckResultPosted(transactionId, result);
262
+ _onEntitlementCheckResultPosted(transactionId, result);
263
+ _removeTransaction(transactionId);
264
+ }
265
+
266
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
267
+ /* Helpers */
268
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
269
+
270
+ function _checkAllRoleIdsCompleted(bytes32 transactionId) internal view returns (bool) {
271
+ EntitlementGatedStorage.Layout storage ds = EntitlementGatedStorage.layout();
272
+
273
+ Transaction storage transaction = ds.transactions[transactionId];
274
+ uint256 roleIdsLength = transaction.roleIds.length;
275
+ for (uint256 i; i < roleIdsLength; ++i) {
276
+ if (!transaction.isCompleted[transaction.roleIds[i]]) {
277
+ return false;
278
+ }
279
+ }
280
+ return true;
281
+ }
282
+
283
+ function _removeTransaction(bytes32 transactionId) internal {
284
+ EntitlementGatedStorage.Layout storage ds = EntitlementGatedStorage.layout();
285
+
286
+ Transaction storage transaction = ds.transactions[transactionId];
287
+ uint256 length = transaction.roleIds.length;
288
+ for (uint256 i; i < length; ++i) {
289
+ delete transaction.nodeVotesArray[transaction.roleIds[i]];
290
+ }
291
+ delete transaction.roleIds;
292
+ delete ds.transactions[transactionId];
293
+ }
294
+
295
+ function _getRuleData(
296
+ bytes32 transactionId,
297
+ uint256 roleId
298
+ ) internal view returns (IRuleEntitlement.RuleData memory) {
299
+ EntitlementGatedStorage.Layout storage ds = EntitlementGatedStorage.layout();
300
+
301
+ Transaction storage transaction = ds.transactions[transactionId];
302
+
303
+ if (!transaction.finalized) {
304
+ revert EntitlementGated_TransactionNotRegistered();
305
+ }
306
+
307
+ IRuleEntitlement re = IRuleEntitlement(address(transaction.entitlement));
308
+ return re.getRuleData(roleId);
309
+ }
310
+
311
+ function _onEntitlementCheckResultPosted(
312
+ bytes32 transactionId,
313
+ NodeVoteStatus result
314
+ ) internal virtual {}
315
+
316
+ // TODO: This should be removed in the future when we wipe data
317
+ function _setFallbackEntitlementChecker() internal {
318
+ EntitlementGatedStorage.Layout storage ds = EntitlementGatedStorage.layout();
319
+ address entitlementChecker = IImplementationRegistry(
320
+ MembershipStorage.layout().spaceFactory
321
+ ).getLatestImplementation("SpaceOperator");
322
+ ds.entitlementChecker = IEntitlementChecker(entitlementChecker);
323
+ }
324
+ }
@@ -0,0 +1,29 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IEntitlementGatedBase} from "./IEntitlementGated.sol";
6
+ import {IEntitlementChecker} from "src/base/registry/facets/checker/IEntitlementChecker.sol";
7
+
8
+ // libraries
9
+
10
+ // contracts
11
+
12
+ library EntitlementGatedStorage {
13
+ // keccak256(abi.encode(uint256(keccak256("facets.entitlement.gated.storage")) - 1)) &
14
+ // ~bytes32(uint256(0xff))
15
+ bytes32 internal constant STORAGE_SLOT =
16
+ 0x9075c515a635ba70c9696f31149324218d75cf00afe836c482e6473f38b19e00;
17
+
18
+ struct Layout {
19
+ IEntitlementChecker entitlementChecker;
20
+ mapping(bytes32 => IEntitlementGatedBase.Transaction) transactions;
21
+ }
22
+
23
+ function layout() internal pure returns (Layout storage l) {
24
+ bytes32 slot = STORAGE_SLOT;
25
+ assembly {
26
+ l.slot := slot
27
+ }
28
+ }
29
+ }