@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,189 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {INodeOperator} from "./INodeOperator.sol";
6
+
7
+ // libraries
8
+ import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
9
+ import {NodeOperatorStatus, NodeOperatorStorage} from "src/base/registry/facets/operator/NodeOperatorStorage.sol";
10
+
11
+ // contracts
12
+ import {OwnableBase} from "@towns-protocol/diamond/src/facets/ownable/OwnableBase.sol";
13
+ import {ERC721ABase} from "src/diamond/facets/token/ERC721A/ERC721ABase.sol";
14
+
15
+ import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
16
+
17
+ contract NodeOperatorFacet is INodeOperator, OwnableBase, ERC721ABase, Facet {
18
+ using EnumerableSet for EnumerableSet.AddressSet;
19
+
20
+ function __NodeOperator_init() external onlyInitializing {
21
+ _addInterface(type(INodeOperator).interfaceId);
22
+ }
23
+
24
+ // =============================================================
25
+ // Registration
26
+ // =============================================================
27
+
28
+ /// @inheritdoc INodeOperator
29
+ function registerOperator(address claimer) external {
30
+ if (claimer == address(0)) revert NodeOperator__InvalidAddress();
31
+
32
+ NodeOperatorStorage.Layout storage ds = NodeOperatorStorage.layout();
33
+
34
+ if (ds.operators.contains(msg.sender)) {
35
+ revert NodeOperator__AlreadyRegistered();
36
+ }
37
+
38
+ _mint(msg.sender, 1);
39
+
40
+ ds.operators.add(msg.sender);
41
+ ds.statusByOperator[msg.sender] = NodeOperatorStatus.Standby;
42
+ ds.claimerByOperator[msg.sender] = claimer;
43
+ ds.operatorsByClaimer[claimer].add(msg.sender);
44
+
45
+ emit OperatorRegistered(msg.sender);
46
+ }
47
+
48
+ // =============================================================
49
+ // Operator Status
50
+ // =============================================================
51
+
52
+ /// @inheritdoc INodeOperator
53
+ function isOperator(address operator) external view returns (bool) {
54
+ NodeOperatorStorage.Layout storage ds = NodeOperatorStorage.layout();
55
+ return ds.operators.contains(operator);
56
+ }
57
+
58
+ /// @inheritdoc INodeOperator
59
+ function setOperatorStatus(address operator, NodeOperatorStatus newStatus) external onlyOwner {
60
+ if (operator == address(0)) revert NodeOperator__InvalidAddress();
61
+
62
+ NodeOperatorStorage.Layout storage ds = NodeOperatorStorage.layout();
63
+
64
+ if (!ds.operators.contains(operator)) revert NodeOperator__NotRegistered();
65
+
66
+ NodeOperatorStatus currentStatus = ds.statusByOperator[operator];
67
+
68
+ if (currentStatus == newStatus) revert NodeOperator__StatusNotChanged();
69
+
70
+ // Check for valid newStatus transitions
71
+ // Exiting -> Standby
72
+ // Standby -> Approved
73
+ // Approved -> Exiting || Active
74
+ // Active -> Exiting || Approved
75
+ if (
76
+ currentStatus == NodeOperatorStatus.Exiting && newStatus != NodeOperatorStatus.Standby
77
+ ) {
78
+ revert NodeOperator__InvalidStatusTransition();
79
+ } else if (
80
+ currentStatus == NodeOperatorStatus.Standby && newStatus != NodeOperatorStatus.Approved
81
+ ) {
82
+ revert NodeOperator__InvalidStatusTransition();
83
+ } else if (
84
+ currentStatus == NodeOperatorStatus.Approved &&
85
+ (newStatus != NodeOperatorStatus.Exiting && newStatus != NodeOperatorStatus.Active)
86
+ ) {
87
+ revert NodeOperator__InvalidStatusTransition();
88
+ } else if (
89
+ currentStatus == NodeOperatorStatus.Active &&
90
+ (newStatus != NodeOperatorStatus.Exiting && newStatus != NodeOperatorStatus.Approved)
91
+ ) {
92
+ revert NodeOperator__InvalidStatusTransition();
93
+ }
94
+ if (newStatus == NodeOperatorStatus.Active) {
95
+ ds.approvalTimeByOperator[operator] = block.timestamp;
96
+ } else {
97
+ ds.approvalTimeByOperator[operator] = 0;
98
+ }
99
+ ds.statusByOperator[operator] = newStatus;
100
+
101
+ emit OperatorStatusChanged(operator, newStatus);
102
+ }
103
+
104
+ /// @inheritdoc INodeOperator
105
+ function getOperatorStatus(address operator) external view returns (NodeOperatorStatus) {
106
+ NodeOperatorStorage.Layout storage ds = NodeOperatorStorage.layout();
107
+ return ds.statusByOperator[operator];
108
+ }
109
+
110
+ // =============================================================
111
+ // Operator Info
112
+ // =============================================================
113
+
114
+ /// @inheritdoc INodeOperator
115
+ function setClaimAddressForOperator(
116
+ address claimer,
117
+ address operator
118
+ ) external onlyClaimer(msg.sender, operator) {
119
+ NodeOperatorStorage.Layout storage ds = NodeOperatorStorage.layout();
120
+
121
+ if (!ds.operators.contains(operator)) revert NodeOperator__NotRegistered();
122
+
123
+ address currentClaimer = ds.claimerByOperator[operator];
124
+
125
+ if (currentClaimer == claimer) {
126
+ revert NodeOperator__ClaimAddressNotChanged();
127
+ }
128
+
129
+ if (ds.operatorsByClaimer[currentClaimer].contains(operator)) {
130
+ ds.operatorsByClaimer[currentClaimer].remove(operator);
131
+ }
132
+
133
+ ds.claimerByOperator[operator] = claimer;
134
+ ds.operatorsByClaimer[claimer].add(operator);
135
+
136
+ emit OperatorClaimAddressChanged(operator, claimer);
137
+ }
138
+
139
+ /// @inheritdoc INodeOperator
140
+ function getClaimAddressForOperator(address operator) external view returns (address) {
141
+ return NodeOperatorStorage.layout().claimerByOperator[operator];
142
+ }
143
+
144
+ function getOperators() external view returns (address[] memory) {
145
+ NodeOperatorStorage.Layout storage ds = NodeOperatorStorage.layout();
146
+ return ds.operators.values();
147
+ }
148
+
149
+ // =============================================================
150
+ // Commission
151
+ // =============================================================
152
+ function setCommissionRate(uint256 rateBps) external {
153
+ NodeOperatorStorage.Layout storage ds = NodeOperatorStorage.layout();
154
+ if (!ds.operators.contains(msg.sender)) {
155
+ revert NodeOperator__NotRegistered();
156
+ }
157
+ if (rateBps > 10_000) revert NodeOperator__InvalidCommissionRate();
158
+
159
+ //only allow raising the commission if operator is in standby status
160
+ if (
161
+ rateBps > ds.commissionByOperator[msg.sender] &&
162
+ ds.statusByOperator[msg.sender] != NodeOperatorStatus.Standby
163
+ ) {
164
+ revert NodeOperator__InvalidCommissionRate();
165
+ }
166
+
167
+ ds.commissionByOperator[msg.sender] = rateBps;
168
+ emit OperatorCommissionChanged(msg.sender, rateBps);
169
+ }
170
+
171
+ function getCommissionRate(address operator) external view returns (uint256) {
172
+ NodeOperatorStorage.Layout storage ds = NodeOperatorStorage.layout();
173
+ return ds.commissionByOperator[operator];
174
+ }
175
+
176
+ // =============================================================
177
+ // Modifiers
178
+ // =============================================================
179
+
180
+ // only an existing claimer for that operator can call this function
181
+ modifier onlyClaimer(address claimer, address operator) {
182
+ NodeOperatorStorage.Layout storage ds = NodeOperatorStorage.layout();
183
+
184
+ if (!ds.operatorsByClaimer[claimer].contains(operator)) {
185
+ revert NodeOperator__NotClaimer();
186
+ }
187
+ _;
188
+ }
189
+ }
@@ -0,0 +1,39 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ // libraries
7
+ import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
8
+
9
+ // contracts
10
+
11
+ enum NodeOperatorStatus {
12
+ Exiting,
13
+ Standby,
14
+ Approved,
15
+ Active
16
+ }
17
+
18
+ library NodeOperatorStorage {
19
+ // keccak256(abi.encode(uint256(keccak256("factory.facets.operator.storage")) - 1)) &
20
+ // ~bytes32(uint256(0xff))
21
+ bytes32 internal constant STORAGE_SLOT =
22
+ 0x988e8266be98e92aff755bdd688f8f4a2421e26daa6089c7e2668053a3bf5500;
23
+
24
+ struct Layout {
25
+ EnumerableSet.AddressSet operators;
26
+ mapping(address => NodeOperatorStatus) statusByOperator;
27
+ mapping(address => uint256) commissionByOperator;
28
+ mapping(address => address) claimerByOperator;
29
+ mapping(address => EnumerableSet.AddressSet) operatorsByClaimer;
30
+ mapping(address operator => uint256 approvalTime) approvalTimeByOperator;
31
+ }
32
+
33
+ function layout() internal pure returns (Layout storage l) {
34
+ bytes32 slot = STORAGE_SLOT;
35
+ assembly {
36
+ l.slot := slot
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,54 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ import {IEntitlementCheckerBase} from "src/base/registry/facets/checker/IEntitlementChecker.sol";
7
+ import {IEntitlementGatedBase} from "src/spaces/facets/gated/IEntitlementGated.sol";
8
+
9
+ // libraries
10
+
11
+ // contracts
12
+
13
+ /// @dev Struct to hold voting context and avoid stack too deep
14
+ struct VotingContext {
15
+ bytes32 transactionId;
16
+ address caller;
17
+ uint256 value;
18
+ bool completed;
19
+ }
20
+
21
+ /// @dev Struct to hold vote counting results
22
+ struct VoteResults {
23
+ uint256 passed;
24
+ uint256 failed;
25
+ uint256 totalNodes;
26
+ IEntitlementGatedBase.NodeVoteStatus finalStatus;
27
+ }
28
+
29
+ interface IXChain is IEntitlementGatedBase, IEntitlementCheckerBase {
30
+ /// @notice Checks if a specific entitlement check request has been completed
31
+ /// @param transactionId The unique identifier of the transaction
32
+ /// @param requestId The ID of the specific check request
33
+ /// @return bool True if the check is completed, false otherwise
34
+ function isCheckCompleted(
35
+ bytes32 transactionId,
36
+ uint256 requestId
37
+ ) external view returns (bool);
38
+
39
+ /// @notice Allows protocol to provide a refund for a timed-out entitlement check
40
+ /// @dev Will revert if the contract has insufficient funds
41
+ /// @param senderAddress The address to receive the refund
42
+ /// @param transactionId The unique identifier of the transaction being checked
43
+ function provideXChainRefund(address senderAddress, bytes32 transactionId) external;
44
+
45
+ /// @notice Posts the result of an entitlement check from a node
46
+ /// @param transactionId The unique identifier of the transaction being checked
47
+ /// @param roleId The ID of the role being checked
48
+ /// @param result The vote result from the node (PASSED, FAILED, or NOT_VOTED)
49
+ function postEntitlementCheckResult(
50
+ bytes32 transactionId,
51
+ uint256 roleId,
52
+ NodeVoteStatus result
53
+ ) external;
54
+ }
@@ -0,0 +1,158 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IXChain, VotingContext, VoteResults} from "./IXChain.sol";
6
+ import {IEntitlementGated} from "src/spaces/facets/gated/IEntitlementGated.sol";
7
+
8
+ // libraries
9
+ import {XChainLib} from "./XChainLib.sol";
10
+ import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
11
+ import {CurrencyTransfer} from "src/utils/libraries/CurrencyTransfer.sol";
12
+ import {CustomRevert} from "src/utils/libraries/CustomRevert.sol";
13
+ import {XChainCheckLib} from "./XChainCheckLib.sol";
14
+
15
+ // contracts
16
+ import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
17
+ import {EntitlementGated} from "src/spaces/facets/gated/EntitlementGated.sol";
18
+ import {ReentrancyGuard} from "solady/utils/ReentrancyGuard.sol";
19
+ import {OwnableBase} from "@towns-protocol/diamond/src/facets/ownable/OwnableBase.sol";
20
+
21
+ contract XChain is IXChain, ReentrancyGuard, OwnableBase, Facet {
22
+ using EnumerableSet for EnumerableSet.AddressSet;
23
+ using EnumerableSet for EnumerableSet.UintSet;
24
+ using EnumerableSet for EnumerableSet.Bytes32Set;
25
+ using CustomRevert for bytes4;
26
+ using XChainCheckLib for XChainLib.Check;
27
+
28
+ function __XChain_init() external onlyInitializing {
29
+ _addInterface(type(IEntitlementGated).interfaceId);
30
+ }
31
+
32
+ /// @inheritdoc IXChain
33
+ function isCheckCompleted(
34
+ bytes32 transactionId,
35
+ uint256 requestId
36
+ ) external view returns (bool) {
37
+ return XChainLib.layout().checks[transactionId].voteCompleted[requestId];
38
+ }
39
+
40
+ /// @inheritdoc IXChain
41
+ function provideXChainRefund(address senderAddress, bytes32 transactionId) external onlyOwner {
42
+ if (!XChainLib.layout().requestsBySender[senderAddress].remove(transactionId)) {
43
+ EntitlementGated_TransactionCheckAlreadyCompleted.selector.revertWith();
44
+ }
45
+
46
+ XChainLib.Request storage request = XChainLib.layout().requests[transactionId];
47
+
48
+ if (request.completed) {
49
+ EntitlementGated_TransactionCheckAlreadyCompleted.selector.revertWith();
50
+ }
51
+
52
+ if (request.value == 0) {
53
+ EntitlementGated_InvalidValue.selector.revertWith();
54
+ }
55
+
56
+ request.completed = true;
57
+
58
+ XChainLib.Check storage check = XChainLib.layout().checks[transactionId];
59
+
60
+ // clean up checks if any
61
+ uint256 requestIdsLength = check.requestIds.length();
62
+ if (requestIdsLength > 0) {
63
+ for (uint256 i; i < requestIdsLength; ++i) {
64
+ uint256 requestId = check.requestIds.at(i);
65
+ check.voteCompleted[requestId] = true;
66
+ }
67
+ }
68
+
69
+ CurrencyTransfer.transferCurrency(
70
+ CurrencyTransfer.NATIVE_TOKEN,
71
+ address(this),
72
+ senderAddress,
73
+ request.value
74
+ );
75
+ }
76
+
77
+ /// @inheritdoc IXChain
78
+ function postEntitlementCheckResult(
79
+ bytes32 transactionId,
80
+ uint256 requestId,
81
+ NodeVoteStatus result
82
+ ) external nonReentrant {
83
+ XChainLib.Request storage request = XChainLib.layout().requests[transactionId];
84
+ XChainLib.Check storage check = XChainLib.layout().checks[transactionId];
85
+
86
+ VotingContext memory context = check.validateVotingEligibility(
87
+ request,
88
+ transactionId,
89
+ requestId
90
+ );
91
+
92
+ check.processNodeVote(requestId, result);
93
+ VoteResults memory voteResults = check.calculateVoteResults(requestId);
94
+
95
+ if (_hasReachedQuorum(voteResults)) {
96
+ _completeVotingForRequest(context, requestId, voteResults.finalStatus);
97
+ }
98
+ }
99
+
100
+ /// @notice Checks if quorum has been reached (more than half voted the same way)
101
+ /// @param results The vote counting results
102
+ /// @return hasQuorum True if quorum is reached
103
+ function _hasReachedQuorum(VoteResults memory results) internal pure returns (bool hasQuorum) {
104
+ uint256 quorumThreshold = results.totalNodes / 2;
105
+ return results.passed > quorumThreshold || results.failed > quorumThreshold;
106
+ }
107
+
108
+ /// @notice Completes the voting for a specific request and finalizes the transaction
109
+ /// @param context The voting context
110
+ /// @param requestId The request identifier
111
+ /// @param finalStatus The final voting status for this request
112
+ function _completeVotingForRequest(
113
+ VotingContext memory context,
114
+ uint256 requestId,
115
+ NodeVoteStatus finalStatus
116
+ ) internal {
117
+ // Mark this specific request as completed
118
+ XChainLib.layout().checks[context.transactionId].voteCompleted[requestId] = true;
119
+
120
+ // In V2, each entitlement check is independent - finalize immediately when voting completes
121
+ _finalizeTransaction(context, finalStatus);
122
+ }
123
+
124
+ /// @notice Finalizes the transaction and calls back to the original caller
125
+ /// @param context The voting context
126
+ /// @param finalStatus The final status to report
127
+ function _finalizeTransaction(
128
+ VotingContext memory context,
129
+ NodeVoteStatus finalStatus
130
+ ) internal {
131
+ // Mark transaction as completed and clean up
132
+ XChainLib.layout().requests[context.transactionId].completed = true;
133
+ XChainLib.layout().requestsBySender[context.caller].remove(context.transactionId);
134
+
135
+ // Call back to the original caller with the result
136
+ EntitlementGated(context.caller).postEntitlementCheckResultV2{value: context.value}(
137
+ context.transactionId,
138
+ 0,
139
+ finalStatus
140
+ );
141
+ }
142
+
143
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
144
+ /* Internal */
145
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
146
+
147
+ function _checkAllRequestsCompleted(bytes32 transactionId) internal view returns (bool) {
148
+ XChainLib.Check storage check = XChainLib.layout().checks[transactionId];
149
+
150
+ uint256 requestIdsLength = check.requestIds.length();
151
+ for (uint256 i; i < requestIdsLength; ++i) {
152
+ if (!check.voteCompleted[check.requestIds.at(i)]) {
153
+ return false;
154
+ }
155
+ }
156
+ return true;
157
+ }
158
+ }
@@ -0,0 +1,105 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ // libraries
7
+
8
+ // contracts
9
+ import {XChainLib} from "./XChainLib.sol";
10
+ import {IEntitlementGatedBase} from "src/spaces/facets/gated/IEntitlementGated.sol";
11
+ import {CustomRevert} from "src/utils/libraries/CustomRevert.sol";
12
+ import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
13
+ import {VoteResults, VotingContext} from "./IXChain.sol";
14
+
15
+ library XChainCheckLib {
16
+ using CustomRevert for bytes4;
17
+ using EnumerableSet for EnumerableSet.AddressSet;
18
+ using EnumerableSet for EnumerableSet.UintSet;
19
+
20
+ function validateVotingEligibility(
21
+ XChainLib.Check storage self,
22
+ XChainLib.Request storage request,
23
+ bytes32 transactionId,
24
+ uint256 requestId
25
+ ) internal view returns (VotingContext memory context) {
26
+ if (request.completed) {
27
+ IEntitlementGatedBase
28
+ .EntitlementGated_TransactionCheckAlreadyCompleted
29
+ .selector
30
+ .revertWith();
31
+ }
32
+
33
+ if (!self.requestIds.contains(requestId)) {
34
+ IEntitlementGatedBase.EntitlementGated_RequestIdNotFound.selector.revertWith();
35
+ }
36
+
37
+ if (!self.nodes[requestId].contains(msg.sender)) {
38
+ IEntitlementGatedBase.EntitlementGated_NodeNotFound.selector.revertWith();
39
+ }
40
+
41
+ if (self.voteCompleted[requestId]) {
42
+ IEntitlementGatedBase
43
+ .EntitlementGated_TransactionCheckAlreadyCompleted
44
+ .selector
45
+ .revertWith();
46
+ }
47
+
48
+ // Populate context with needed data
49
+ context.transactionId = transactionId;
50
+ context.caller = request.caller;
51
+ context.value = request.value;
52
+ context.completed = request.completed;
53
+ }
54
+
55
+ function processNodeVote(
56
+ XChainLib.Check storage self,
57
+ uint256 requestId,
58
+ IEntitlementGatedBase.NodeVoteStatus result
59
+ ) internal {
60
+ uint256 nodeCount = self.nodes[requestId].length();
61
+ bool voteRecorded = false;
62
+
63
+ for (uint256 i; i < nodeCount; ++i) {
64
+ IEntitlementGatedBase.NodeVote storage currentVote = self.votes[requestId][i];
65
+
66
+ if (currentVote.node == msg.sender) {
67
+ if (currentVote.vote != IEntitlementGatedBase.NodeVoteStatus.NOT_VOTED) {
68
+ IEntitlementGatedBase.EntitlementGated_NodeAlreadyVoted.selector.revertWith();
69
+ }
70
+ currentVote.vote = result;
71
+ voteRecorded = true;
72
+ break; // Exit early once vote is recorded
73
+ }
74
+ }
75
+
76
+ if (!voteRecorded) {
77
+ IEntitlementGatedBase.EntitlementGated_NodeNotFound.selector.revertWith();
78
+ }
79
+ }
80
+
81
+ function calculateVoteResults(
82
+ XChainLib.Check storage self,
83
+ uint256 requestId
84
+ ) internal view returns (VoteResults memory results) {
85
+ results.totalNodes = self.nodes[requestId].length();
86
+
87
+ for (uint256 i; i < results.totalNodes; ++i) {
88
+ IEntitlementGatedBase.NodeVote storage vote = self.votes[requestId][i];
89
+
90
+ if (vote.vote == IEntitlementGatedBase.NodeVoteStatus.PASSED) {
91
+ unchecked {
92
+ ++results.passed;
93
+ }
94
+ } else if (vote.vote == IEntitlementGatedBase.NodeVoteStatus.FAILED) {
95
+ unchecked {
96
+ ++results.failed;
97
+ }
98
+ }
99
+ }
100
+
101
+ results.finalStatus = results.passed > results.failed
102
+ ? IEntitlementGatedBase.NodeVoteStatus.PASSED
103
+ : IEntitlementGatedBase.NodeVoteStatus.FAILED;
104
+ }
105
+ }
@@ -0,0 +1,46 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IEntitlementChecker} from "src/base/registry/facets/checker/IEntitlementChecker.sol";
6
+ import {IEntitlementGatedBase} from "src/spaces/facets/gated/IEntitlementGated.sol";
7
+ // libraries
8
+ import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
9
+
10
+ // contracts
11
+
12
+ library XChainLib {
13
+ // keccak256(abi.encode(uint256(keccak256("xchain.entitlement.transactions.storage")) - 1)) &
14
+ // ~bytes32(uint256(0xff))
15
+ bytes32 internal constant STORAGE_SLOT =
16
+ 0xf501c51c066c21fd640901535874a71171bb35113f6dc2832fce1b1f9da0cc00;
17
+
18
+ struct Check {
19
+ EnumerableSet.UintSet requestIds;
20
+ mapping(uint256 requestId => EnumerableSet.AddressSet) nodes;
21
+ mapping(uint256 requestId => IEntitlementGatedBase.NodeVote[]) votes;
22
+ mapping(uint256 requestId => bool voteCompleted) voteCompleted;
23
+ }
24
+
25
+ struct Request {
26
+ uint256 value;
27
+ uint256 blockNumber;
28
+ address caller;
29
+ bool completed;
30
+ address receiver;
31
+ }
32
+
33
+ struct Layout {
34
+ IEntitlementChecker entitlementChecker;
35
+ mapping(address => EnumerableSet.Bytes32Set) requestsBySender;
36
+ mapping(bytes32 => Request) requests;
37
+ mapping(bytes32 => Check) checks;
38
+ }
39
+
40
+ function layout() internal pure returns (Layout storage l) {
41
+ bytes32 slot = STORAGE_SLOT;
42
+ assembly {
43
+ l.slot := slot
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,38 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ abstract contract UpgradeableBeaconBase {
5
+ /// @dev The new implementation is not a deployed contract.
6
+ error NewImplementationHasNoCode();
7
+
8
+ /// @dev Emitted when the proxy's implementation is upgraded.
9
+ event Upgraded(address indexed implementation);
10
+
11
+ /// @dev `keccak256(bytes("Upgraded(address)"))`.
12
+ uint256 private constant _UPGRADED_EVENT_SIGNATURE =
13
+ 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b;
14
+
15
+ /// @dev The storage slot for the implementation address.
16
+ /// `uint72(bytes9(keccak256("_UPGRADEABLE_BEACON_IMPLEMENTATION_SLOT")))`.
17
+ uint256 internal constant _UPGRADEABLE_BEACON_IMPLEMENTATION_SLOT = 0x911c5a209f08d5ec5e;
18
+
19
+ function __UpgradeableBeacon_init_unchained(address initialImplementation) internal {
20
+ _setImplementation(initialImplementation);
21
+ }
22
+
23
+ /// @dev Sets the implementation directly without authorization guard.
24
+ function _setImplementation(address newImplementation) internal virtual {
25
+ /// @solidity memory-safe-assembly
26
+ assembly {
27
+ newImplementation := shr(96, shl(96, newImplementation)) // Clean the upper 96 bits.
28
+ if iszero(extcodesize(newImplementation)) {
29
+ mstore(0x00, 0x6d3e283b) // `NewImplementationHasNoCode()`.
30
+ revert(0x1c, 0x04)
31
+ }
32
+ sstore(_UPGRADEABLE_BEACON_IMPLEMENTATION_SLOT, newImplementation) // Store the
33
+ // implementation.
34
+ // Emit the {Upgraded} event.
35
+ log2(codesize(), 0x00, _UPGRADED_EVENT_SIGNATURE, newImplementation)
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,34 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+
6
+ // libraries
7
+
8
+ // contracts
9
+ import {UpgradeableBeaconBase} from "src/diamond/facets/beacon/UpgradeableBeacon.sol";
10
+ import {OwnableBase} from "@towns-protocol/diamond/src/facets/ownable/OwnableBase.sol";
11
+ import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
12
+
13
+ /// @notice Upgradeable beacon for ERC1967 beacon proxies.
14
+ /// @author Modified from Solady
15
+ /// (https://github.com/vectorized/solady/blob/main/src/utils/UpgradeableBeacon.sol)
16
+ contract UpgradeableBeaconFacet is UpgradeableBeaconBase, OwnableBase, Facet {
17
+ function __UpgradeableBeacon_init(address initialImplementation) external onlyInitializing {
18
+ __UpgradeableBeacon_init_unchained(initialImplementation);
19
+ }
20
+
21
+ /// @dev Allows the owner to upgrade the implementation.
22
+ function upgradeTo(address newImplementation) public virtual onlyOwner {
23
+ _setImplementation(newImplementation);
24
+ }
25
+
26
+ /// @dev Returns the implementation stored in the beacon.
27
+ /// See: https://eips.ethereum.org/EIPS/eip-1967#beacon-contract-address
28
+ function implementation() public view returns (address result) {
29
+ /// @solidity memory-safe-assembly
30
+ assembly {
31
+ result := sload(_UPGRADEABLE_BEACON_IMPLEMENTATION_SLOT)
32
+ }
33
+ }
34
+ }