@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,108 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IWalletLink} from "./IWalletLink.sol";
6
+
7
+ // libraries
8
+ import {WalletLib} from "./libraries/WalletLib.sol";
9
+ // contracts
10
+ import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
11
+ import {WalletLinkBase} from "./WalletLinkBase.sol";
12
+ import {OwnableBase} from "@towns-protocol/diamond/src/facets/ownable/OwnableBase.sol";
13
+
14
+ contract WalletLink is IWalletLink, WalletLinkBase, OwnableBase, Facet {
15
+ function __WalletLink_init(address sclEip6565) external onlyInitializing {
16
+ _addInterface(type(IWalletLink).interfaceId);
17
+ _setDependency(SCL_EIP6565, sclEip6565);
18
+ }
19
+
20
+ /// @inheritdoc IWalletLink
21
+ function linkCallerToRootKey(LinkedWallet calldata rootWallet, uint256 nonce) external {
22
+ _linkCallerToRootWallet(rootWallet, nonce);
23
+ }
24
+
25
+ /// @inheritdoc IWalletLink
26
+ function linkWalletToRootKey(
27
+ LinkedWallet calldata wallet,
28
+ LinkedWallet calldata rootWallet,
29
+ uint256 nonce
30
+ ) external {
31
+ _linkWalletToRootWallet(wallet, rootWallet, nonce);
32
+ }
33
+
34
+ /// @inheritdoc IWalletLink
35
+ function linkNonEVMWalletToRootKey(NonEVMLinkedWallet calldata wallet, uint256 nonce) external {
36
+ _linkNonEVMWalletToRootWalletViaCaller(wallet, nonce);
37
+ }
38
+
39
+ /// @inheritdoc IWalletLink
40
+ function removeNonEVMWalletLink(WalletLib.Wallet calldata wallet, uint256 nonce) external {
41
+ _removeNonEVMWalletLink(wallet, nonce);
42
+ }
43
+
44
+ /// @inheritdoc IWalletLink
45
+ function removeLink(address wallet, LinkedWallet calldata rootWallet, uint256 nonce) external {
46
+ _removeLink(wallet, rootWallet, nonce);
47
+ }
48
+
49
+ /// @inheritdoc IWalletLink
50
+ function removeCallerLink() external {
51
+ _removeCallerLink();
52
+ }
53
+
54
+ /// @inheritdoc IWalletLink
55
+ function setDefaultWallet(address defaultWallet) external {
56
+ _setDefaultWallet(msg.sender, defaultWallet);
57
+ }
58
+
59
+ /// @inheritdoc IWalletLink
60
+ function getDefaultWallet(address rootWallet) external view returns (address) {
61
+ return _getDefaultWallet(rootWallet);
62
+ }
63
+
64
+ /// @inheritdoc IWalletLink
65
+ function getWalletsByRootKey(address rootKey) external view returns (address[] memory wallets) {
66
+ return _getWalletsByRootKey(rootKey);
67
+ }
68
+
69
+ /// @inheritdoc IWalletLink
70
+ function getAllWalletsByRootKey(
71
+ address rootKey
72
+ ) external view returns (WalletLib.Wallet[] memory wallets) {
73
+ return _getAllWalletsByRootKey(rootKey);
74
+ }
75
+
76
+ /// @inheritdoc IWalletLink
77
+ function getRootKeyForWallet(address wallet) external view returns (address rootKey) {
78
+ return _getRootKeyByWallet(wallet);
79
+ }
80
+
81
+ /// @inheritdoc IWalletLink
82
+ function checkIfLinked(address rootKey, address wallet) external view returns (bool) {
83
+ return _checkIfLinked(rootKey, wallet);
84
+ }
85
+
86
+ /// @inheritdoc IWalletLink
87
+ function checkIfNonEVMWalletLinked(
88
+ address rootKey,
89
+ bytes32 walletHash
90
+ ) external view returns (bool) {
91
+ return _checkIfNonEVMWalletLinked(rootKey, walletHash);
92
+ }
93
+
94
+ /// @inheritdoc IWalletLink
95
+ function getLatestNonceForRootKey(address rootKey) external view returns (uint256) {
96
+ return _latestNonce(rootKey);
97
+ }
98
+
99
+ /// @inheritdoc IWalletLink
100
+ function getDependency(bytes32 dependency) external view returns (address) {
101
+ return _getDependency(dependency);
102
+ }
103
+
104
+ /// @inheritdoc IWalletLink
105
+ function setDependency(bytes32 dependency, address dependencyAddress) external onlyOwner {
106
+ _setDependency(dependency, dependencyAddress);
107
+ }
108
+ }
@@ -0,0 +1,492 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.23;
3
+
4
+ // interfaces
5
+ import {IWalletLinkBase} from "./IWalletLink.sol";
6
+
7
+ // libraries
8
+ import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
9
+ import {ECDSA} from "solady/utils/ECDSA.sol";
10
+ import {ISCL_EIP6565} from "./interfaces/ISCL_EIP6565.sol";
11
+ import {LibString} from "solady/utils/LibString.sol";
12
+ import {WalletLib} from "./libraries/WalletLib.sol";
13
+ import {CustomRevert} from "src/utils/libraries/CustomRevert.sol";
14
+ import {SolanaUtils} from "./libraries/SolanaUtils.sol";
15
+
16
+ // contracts
17
+ import {Nonces} from "@towns-protocol/diamond/src/utils/Nonces.sol";
18
+ import {EIP712Base} from "@towns-protocol/diamond/src/utils/cryptography/EIP712Base.sol";
19
+
20
+ abstract contract WalletLinkBase is IWalletLinkBase, EIP712Base, Nonces {
21
+ using EnumerableSet for EnumerableSet.AddressSet;
22
+ using EnumerableSet for EnumerableSet.Bytes32Set;
23
+
24
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
25
+ /* Constants
26
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
27
+ /// @dev `keccak256("LinkedWallet(string message,address userID,uint256 nonce)")`.
28
+ // https://eips.ethereum.org/EIPS/eip-712
29
+ bytes32 private constant _LINKED_WALLET_TYPEHASH =
30
+ 0x6bb89d031fcd292ecd4c0e6855878b7165cebc3a2f35bc6bbac48c088dd8325c;
31
+
32
+ /// @dev Maximum number of linked wallets per root key
33
+ uint256 internal constant MAX_LINKED_WALLETS = 10;
34
+
35
+ /// @dev Dependency name of SCL_EIP6565 verifier library
36
+ bytes32 internal constant SCL_EIP6565 = bytes32("SCL_EIP6565");
37
+
38
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
39
+ /* External - Write
40
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
41
+
42
+ /// @dev Links a caller address to a root wallet
43
+ /// @param rootWallet the root wallet that the caller is linking to
44
+ /// @param nonce a nonce used to prevent replay attacks, nonce must always be higher than previous nonce
45
+ function _linkCallerToRootWallet(LinkedWallet calldata rootWallet, uint256 nonce) internal {
46
+ WalletLib.Layout storage ds = WalletLib.layout();
47
+
48
+ // The caller is the wallet that is being linked to the root wallet
49
+ address newWallet = msg.sender;
50
+
51
+ _verifyWallets(ds, newWallet, rootWallet.addr);
52
+
53
+ bytes32 structHash = _getLinkedWalletTypedDataHash(rootWallet.message, newWallet, nonce);
54
+
55
+ //Verify that the root wallet signature contains the correct nonce and the correct caller wallet
56
+ bytes32 rootKeyMessageHash = _hashTypedDataV4(structHash);
57
+
58
+ // Verify the signature of the root wallet is correct for the nonce and wallet address
59
+ if (ECDSA.recover(rootKeyMessageHash, rootWallet.signature) != rootWallet.addr) {
60
+ revert WalletLink__InvalidSignature();
61
+ }
62
+
63
+ //Check that the nonce being used is higher than the last nonce used
64
+ _useCheckedNonce(rootWallet.addr, nonce);
65
+
66
+ //set link in mapping
67
+ ds.walletsByRootKey[rootWallet.addr].add(newWallet);
68
+ ds.rootKeyByWallet[newWallet] = rootWallet.addr;
69
+
70
+ emit LinkWalletToRootKey(newWallet, rootWallet.addr);
71
+ }
72
+
73
+ /// @dev Links a wallet to a root wallet
74
+ /// @param wallet the wallet that is being linked to the root wallet
75
+ /// @param rootWallet the root wallet that the wallet is linking to
76
+ /// @param nonce The root wallet's nonce used to prevent replay attacks, nonce must always be higher than previous nonce
77
+ /// @dev Links a wallet to a root wallet by verifying both the wallet's signature and root wallet's signature.
78
+ /// The wallet signs a message containing the root wallet's address and nonce, while the root wallet signs a message
79
+ /// containing the wallet's address and nonce. Both signatures must be valid for the link to be created.
80
+ function _linkWalletToRootWallet(
81
+ LinkedWallet calldata wallet,
82
+ LinkedWallet calldata rootWallet,
83
+ uint256 nonce
84
+ ) internal {
85
+ WalletLib.Layout storage ds = WalletLib.layout();
86
+
87
+ _verifyWallets(ds, wallet.addr, rootWallet.addr);
88
+
89
+ bytes32 structHash = _getLinkedWalletTypedDataHash(wallet.message, wallet.addr, nonce);
90
+
91
+ //Verify that the root wallet signature contains the correct nonce and the correct wallet
92
+ bytes32 rootKeyMessageHash = _hashTypedDataV4(structHash);
93
+
94
+ // Verify the signature of the root wallet is correct for the nonce and wallet address
95
+ if (ECDSA.recover(rootKeyMessageHash, rootWallet.signature) != rootWallet.addr) {
96
+ revert WalletLink__InvalidSignature();
97
+ }
98
+
99
+ structHash = _getLinkedWalletTypedDataHash(rootWallet.message, rootWallet.addr, nonce);
100
+ bytes32 walletMessageHash = _hashTypedDataV4(structHash);
101
+
102
+ // Verify the signature of the wallet is correct for the nonce and root wallet address
103
+ if (ECDSA.recover(walletMessageHash, wallet.signature) != wallet.addr) {
104
+ revert WalletLink__InvalidSignature();
105
+ }
106
+
107
+ //Check that the nonce being used is higher than the last nonce used
108
+ _useCheckedNonce(rootWallet.addr, nonce);
109
+
110
+ //set link in mapping
111
+ ds.walletsByRootKey[rootWallet.addr].add(wallet.addr);
112
+ ds.rootKeyByWallet[wallet.addr] = rootWallet.addr;
113
+
114
+ emit LinkWalletToRootKey(wallet.addr, rootWallet.addr);
115
+ }
116
+
117
+ function _linkNonEVMWalletToRootWalletViaCaller(
118
+ NonEVMLinkedWallet calldata nonEVMWallet,
119
+ uint256 nonce
120
+ ) internal {
121
+ WalletLib.Layout storage ds = WalletLib.layout();
122
+ address linkedWallet = msg.sender;
123
+ bytes32 walletHash = keccak256(abi.encode(nonEVMWallet.wallet));
124
+
125
+ _validateNonEVMWalletInputs(ds, nonEVMWallet, walletHash);
126
+
127
+ address rootKey = ds.rootKeyByWallet[linkedWallet];
128
+
129
+ EnumerableSet.Bytes32Set storage walletHashes = ds
130
+ .rootWalletByRootKey[rootKey]
131
+ .walletHashes;
132
+
133
+ if (walletHashes.contains(walletHash)) {
134
+ revert WalletLink__NonEVMWalletAlreadyLinked(nonEVMWallet.wallet.addr, rootKey);
135
+ }
136
+
137
+ // Check that we haven't reached the maximum number of linked wallets
138
+ if (walletHashes.length() >= MAX_LINKED_WALLETS) {
139
+ revert WalletLink__MaxLinkedWalletsReached();
140
+ }
141
+
142
+ if (nonEVMWallet.wallet.vmType == WalletLib.VirtualMachineType.SVM) {
143
+ _validateAddressFormatByVMType(nonEVMWallet.wallet);
144
+ _verifySolanaWallet(nonEVMWallet);
145
+ } else {
146
+ CustomRevert.revertWith(IWalletLinkBase.WalletLink__UnsupportedVMType.selector);
147
+ }
148
+
149
+ ds.rootKeyByHash[walletHash] = rootKey;
150
+ walletHashes.add(walletHash);
151
+ ds.rootWalletByRootKey[rootKey].walletByHash[walletHash] = nonEVMWallet.wallet;
152
+
153
+ _useCheckedNonce(rootKey, nonce);
154
+
155
+ emit LinkNonEVMWalletToRootWallet(walletHash, rootKey);
156
+ }
157
+
158
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
159
+ /* Remove
160
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
161
+
162
+ function _removeNonEVMWalletLink(WalletLib.Wallet calldata wallet, uint256 nonce) internal {
163
+ WalletLib.Layout storage ds = WalletLib.layout();
164
+ address linkedWallet = msg.sender;
165
+ bytes32 walletHash = keccak256(abi.encode(wallet));
166
+ address rootKey = ds.rootKeyByWallet[linkedWallet];
167
+
168
+ if (rootKey == address(0)) {
169
+ revert WalletLink__NotLinked(linkedWallet, rootKey);
170
+ }
171
+
172
+ EnumerableSet.Bytes32Set storage walletHashes = ds
173
+ .rootWalletByRootKey[rootKey]
174
+ .walletHashes;
175
+
176
+ if (!walletHashes.contains(walletHash)) {
177
+ revert WalletLink__NonEVMWalletNotLinked(wallet.addr, rootKey);
178
+ }
179
+
180
+ // Check that the nonce is higher than the last nonce used
181
+ _useCheckedNonce(rootKey, nonce);
182
+
183
+ // Remove the wallet from the root wallet
184
+ walletHashes.remove(walletHash);
185
+ delete ds.rootWalletByRootKey[rootKey].walletByHash[walletHash];
186
+
187
+ emit RemoveNonEVMWalletLink(walletHash, rootKey);
188
+ }
189
+
190
+ function _removeLink(
191
+ address walletToRemove,
192
+ LinkedWallet calldata rootWallet,
193
+ uint256 nonce
194
+ ) internal {
195
+ WalletLib.Layout storage ds = WalletLib.layout();
196
+
197
+ // Check walletToRemove or rootWallet.addr are not address(0)
198
+ if (walletToRemove == address(0) || rootWallet.addr == address(0)) {
199
+ revert WalletLink__InvalidAddress();
200
+ }
201
+
202
+ // Check walletToRemove is not the root wallet
203
+ if (walletToRemove == rootWallet.addr) {
204
+ revert WalletLink__CannotRemoveRootWallet();
205
+ }
206
+
207
+ // Check that the wallet is linked to the root wallet
208
+ if (ds.rootKeyByWallet[walletToRemove] != rootWallet.addr) {
209
+ revert WalletLink__NotLinked(walletToRemove, rootWallet.addr);
210
+ }
211
+
212
+ // Check that the wallet is not the default wallet
213
+ if (ds.rootWalletByRootKey[rootWallet.addr].defaultWallet == walletToRemove) {
214
+ revert WalletLink__CannotRemoveDefaultWallet();
215
+ }
216
+
217
+ // Verify that the root wallet signature contains the correct nonce and the correct wallet
218
+ bytes32 structHash = _getLinkedWalletTypedDataHash(
219
+ rootWallet.message,
220
+ walletToRemove,
221
+ nonce
222
+ );
223
+ bytes32 rootKeyMessageHash = _hashTypedDataV4(structHash);
224
+
225
+ // Verify the signature of the root wallet is correct for the nonce and wallet address
226
+ if (ECDSA.recover(rootKeyMessageHash, rootWallet.signature) != rootWallet.addr) {
227
+ revert WalletLink__InvalidSignature();
228
+ }
229
+
230
+ //Check that the nonce being used is higher than the last nonce used
231
+ _useCheckedNonce(rootWallet.addr, nonce);
232
+
233
+ // Remove the link in the walletToRemove to root keys map
234
+ ds.rootKeyByWallet[walletToRemove] = address(0);
235
+ ds.walletsByRootKey[rootWallet.addr].remove(walletToRemove);
236
+
237
+ emit RemoveLink(walletToRemove, msg.sender);
238
+ }
239
+
240
+ function _removeCallerLink() internal {
241
+ WalletLib.Layout storage ds = WalletLib.layout();
242
+ address walletToRemove = msg.sender;
243
+ address rootWallet = ds.rootKeyByWallet[walletToRemove];
244
+
245
+ if (rootWallet == address(0)) {
246
+ revert WalletLink__NotLinked(walletToRemove, rootWallet);
247
+ }
248
+
249
+ // check that the default wallet is not the wallet to remove
250
+ if (ds.rootWalletByRootKey[rootWallet].defaultWallet == walletToRemove) {
251
+ revert WalletLink__CannotRemoveDefaultWallet();
252
+ }
253
+
254
+ // Remove the link in the walletToRemove to root keys map
255
+ ds.rootKeyByWallet[walletToRemove] = address(0);
256
+ ds.walletsByRootKey[rootWallet].remove(walletToRemove);
257
+
258
+ emit RemoveLink(walletToRemove, rootWallet);
259
+ }
260
+
261
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
262
+ /* Read
263
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
264
+ function _getWalletsByRootKey(
265
+ address rootKey
266
+ ) internal view returns (address[] memory wallets) {
267
+ return WalletLib.layout().walletsByRootKey[rootKey].values();
268
+ }
269
+
270
+ function _getAllWalletsByRootKey(
271
+ address rootKey
272
+ ) internal view returns (WalletLib.Wallet[] memory wallets) {
273
+ WalletLib.Layout storage ds = WalletLib.layout();
274
+ WalletLib.RootWallet storage rootWallet = ds.rootWalletByRootKey[rootKey];
275
+
276
+ // Get all EVM linked wallets
277
+ address[] memory linkedWallets = ds.walletsByRootKey[rootKey].values();
278
+
279
+ // Get all non-EVM linked wallets
280
+ bytes32[] memory nonEVMLinkedWallets = rootWallet.walletHashes.values();
281
+
282
+ // Calculate total length for combined array
283
+ uint256 evmLength = linkedWallets.length;
284
+ uint256 nonEVMLength = nonEVMLinkedWallets.length;
285
+ uint256 totalLength = evmLength + nonEVMLength;
286
+
287
+ wallets = new WalletLib.Wallet[](totalLength);
288
+
289
+ for (uint256 i; i < evmLength; ++i) {
290
+ wallets[i] = WalletLib.Wallet({
291
+ addr: LibString.toHexString(linkedWallets[i]),
292
+ vmType: WalletLib.VirtualMachineType.EVM
293
+ });
294
+ }
295
+
296
+ for (uint256 i; i < nonEVMLength; ++i) {
297
+ WalletLib.Wallet memory wallet = rootWallet.walletByHash[nonEVMLinkedWallets[i]];
298
+ uint256 index = evmLength + i;
299
+ wallets[index] = wallet;
300
+ }
301
+ }
302
+
303
+ function _getRootKeyByWallet(address wallet) internal view returns (address rootKey) {
304
+ return WalletLib.layout().rootKeyByWallet[wallet];
305
+ }
306
+
307
+ function _checkIfLinked(address rootKey, address wallet) internal view returns (bool) {
308
+ WalletLib.Layout storage ds = WalletLib.layout();
309
+ return ds.rootKeyByWallet[wallet] == rootKey;
310
+ }
311
+
312
+ function _checkIfNonEVMWalletLinked(
313
+ address rootKey,
314
+ bytes32 walletHash
315
+ ) internal view returns (bool) {
316
+ return WalletLib.layout().rootKeyByHash[walletHash] == rootKey;
317
+ }
318
+
319
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
320
+ /* Default Wallet Functions */
321
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
322
+
323
+ function _setDefaultWallet(address caller, address defaultWallet) internal {
324
+ // check that the default wallet is not address(0)
325
+ if (defaultWallet == address(0)) {
326
+ revert WalletLink__InvalidAddress();
327
+ }
328
+
329
+ address rootKey = _getRootKeyByWallet(defaultWallet);
330
+
331
+ // check that the default wallet is linked to a root wallet
332
+ if (rootKey == address(0)) {
333
+ revert WalletLink__NotLinked(defaultWallet, rootKey);
334
+ }
335
+
336
+ // check that the caller can only be a linked wallet or the root wallet
337
+ if (!_checkIfLinked(rootKey, caller) && caller != rootKey) {
338
+ revert WalletLink__NotLinked(caller, rootKey);
339
+ }
340
+
341
+ WalletLib.Layout storage ds = WalletLib.layout();
342
+ WalletLib.RootWallet storage rootWallet = ds.rootWalletByRootKey[rootKey];
343
+
344
+ // check that the default isn't already the default wallet
345
+ if (rootWallet.defaultWallet == defaultWallet) {
346
+ revert WalletLink__DefaultWalletAlreadySet();
347
+ }
348
+
349
+ rootWallet.defaultWallet = defaultWallet;
350
+
351
+ emit SetDefaultWallet(rootKey, defaultWallet);
352
+ }
353
+
354
+ function _getDefaultWallet(address rootKey) internal view returns (address defaultWallet) {
355
+ return WalletLib.layout().rootWalletByRootKey[rootKey].defaultWallet;
356
+ }
357
+
358
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
359
+ /* Dependencies Functions */
360
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
361
+ function _getDependency(bytes32 dependency) internal view returns (address) {
362
+ return WalletLib.layout().dependencies[dependency];
363
+ }
364
+
365
+ function _setDependency(bytes32 dependency, address dependencyAddress) internal {
366
+ WalletLib.layout().dependencies[dependency] = dependencyAddress;
367
+ }
368
+
369
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
370
+ /* Helpers
371
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
372
+ function _validateNonEVMWalletInputs(
373
+ WalletLib.Layout storage ds,
374
+ NonEVMLinkedWallet calldata nonEVMWallet,
375
+ bytes32 walletHash
376
+ ) internal view {
377
+ address caller = msg.sender;
378
+
379
+ // Check that the wallet address string is not empty
380
+ if (bytes(nonEVMWallet.wallet.addr).length == 0) {
381
+ revert WalletLink__InvalidNonEVMAddress();
382
+ }
383
+
384
+ // Limit wallet address length
385
+ if (bytes(nonEVMWallet.wallet.addr).length > 100) {
386
+ revert WalletLink__InvalidNonEVMAddress();
387
+ }
388
+
389
+ address callerRootKey = ds.rootKeyByWallet[msg.sender];
390
+
391
+ // Check that the caller wallet is linked to a root wallet
392
+ if (callerRootKey == address(0)) {
393
+ revert WalletLink__NotLinked(caller, address(0));
394
+ }
395
+
396
+ address rootKey = ds.rootKeyByHash[walletHash];
397
+
398
+ // Ensure the caller's root key is consistent with intended operations
399
+ if (rootKey != address(0) && rootKey != callerRootKey) {
400
+ revert WalletLink__RootKeyMismatch(callerRootKey, rootKey);
401
+ }
402
+ }
403
+
404
+ function _verifyWallets(
405
+ WalletLib.Layout storage db,
406
+ address wallet,
407
+ address rootWallet
408
+ ) internal view {
409
+ // Check wallet or rootWallet.addr are not address(0)
410
+ if (wallet == address(0) || rootWallet == address(0)) {
411
+ revert WalletLink__InvalidAddress();
412
+ }
413
+
414
+ // Check not linking wallet to itself
415
+ if (wallet == rootWallet) {
416
+ revert WalletLink__CannotLinkToSelf();
417
+ }
418
+
419
+ // Check that the wallet is not already linked to the root wallet
420
+ if (db.rootKeyByWallet[wallet] != address(0)) {
421
+ revert WalletLink__LinkAlreadyExists(wallet, rootWallet);
422
+ }
423
+
424
+ // Check that the root wallet is not already linked to another root wallet
425
+ if (db.rootKeyByWallet[rootWallet] != address(0)) {
426
+ revert WalletLink__LinkedToAnotherRootKey(wallet, db.rootKeyByWallet[rootWallet]);
427
+ }
428
+
429
+ // Check that the wallet is not itself a root wallet
430
+ if (db.walletsByRootKey[wallet].length() > 0) {
431
+ revert WalletLink__CannotLinkToRootWallet(wallet, rootWallet);
432
+ }
433
+
434
+ // Check that we haven't reached the maximum number of linked wallets
435
+ if (db.walletsByRootKey[rootWallet].length() >= MAX_LINKED_WALLETS) {
436
+ revert WalletLink__MaxLinkedWalletsReached();
437
+ }
438
+ }
439
+
440
+ function _verifySolanaWallet(NonEVMLinkedWallet calldata nonEVMWallet) internal {
441
+ SolanaSpecificData memory solanaSpecificData = abi.decode(
442
+ nonEVMWallet.extraData[0].value,
443
+ (SolanaSpecificData)
444
+ );
445
+
446
+ // Check that the extPubKey and the wallet address match
447
+ if (
448
+ !SolanaUtils.isValidSolanaAddress(
449
+ nonEVMWallet.wallet.addr,
450
+ solanaSpecificData.extPubKey
451
+ )
452
+ ) {
453
+ revert WalletLink__AddressMismatch();
454
+ }
455
+
456
+ ISCL_EIP6565 sclEIP6565 = ISCL_EIP6565(_getDependency(SCL_EIP6565));
457
+
458
+ (uint256 r, uint256 s) = abi.decode(nonEVMWallet.signature, (uint256, uint256));
459
+
460
+ bool isValidSignature = sclEIP6565.Verify_LE(
461
+ nonEVMWallet.message,
462
+ r,
463
+ s,
464
+ solanaSpecificData.extPubKey
465
+ );
466
+
467
+ if (!isValidSignature) {
468
+ revert WalletLink__InvalidSignature();
469
+ }
470
+ }
471
+
472
+ function _validateAddressFormatByVMType(WalletLib.Wallet calldata wallet) internal pure {
473
+ if (wallet.vmType == WalletLib.VirtualMachineType.SVM) {
474
+ // Validate Solana address format (base58, 32-44 chars)
475
+ if (bytes(wallet.addr).length < 32 || bytes(wallet.addr).length > 44) {
476
+ CustomRevert.revertWith(WalletLink__InvalidNonEVMAddress.selector);
477
+ }
478
+ }
479
+ }
480
+
481
+ function _getLinkedWalletTypedDataHash(
482
+ string memory message,
483
+ address addr,
484
+ uint256 nonce
485
+ ) internal pure returns (bytes32) {
486
+ // https://eips.ethereum.org/EIPS/eip-712
487
+ // ATTENTION: "The dynamic values bytes and string are encoded as a keccak256 hash of their contents."
488
+ // in this case, the message is a string, so it is keccak256 hashed
489
+ return
490
+ keccak256(abi.encode(_LINKED_WALLET_TYPEHASH, keccak256(bytes(message)), addr, nonce));
491
+ }
492
+ }
@@ -0,0 +1,63 @@
1
+ // SPDX-License-Identifier: CC0-1.0
2
+ pragma solidity >=0.8.13;
3
+
4
+ /**
5
+ * @title IDelegateRegistry
6
+ * @custom:version 2.0
7
+ * @custom:author foobar (0xfoobar)
8
+ * @notice A standalone immutable registry storing delegated permissions from one address to another
9
+ * @dev This is a copy from the delegate.xyz v2 registry
10
+ */
11
+ interface IDelegateRegistry {
12
+ /// @notice Delegation type, NONE is used when a delegation does not exist or is revoked
13
+ enum DelegationType {
14
+ NONE,
15
+ ALL,
16
+ CONTRACT,
17
+ ERC721,
18
+ ERC20,
19
+ ERC1155
20
+ }
21
+
22
+ /// @notice Struct for returning delegations
23
+ struct Delegation {
24
+ DelegationType type_;
25
+ address to;
26
+ address from;
27
+ bytes32 rights;
28
+ address contract_;
29
+ uint256 tokenId;
30
+ uint256 amount;
31
+ }
32
+
33
+ /**
34
+ * ----------- CHECKS -----------
35
+ */
36
+
37
+ /**
38
+ * @notice Check if `to` is a delegate of `from` for the entire wallet
39
+ * @param to The potential delegate address
40
+ * @param from The potential address who delegated rights
41
+ * @param rights Specific rights to check for, pass the zero value to ignore subdelegations and
42
+ * check full delegations only
43
+ * @return valid Whether delegate is granted to act on the from's behalf
44
+ */
45
+ function checkDelegateForAll(
46
+ address to,
47
+ address from,
48
+ bytes32 rights
49
+ ) external view returns (bool);
50
+
51
+ /**
52
+ * ----------- ENUMERATIONS -----------
53
+ */
54
+
55
+ /**
56
+ * @notice Returns all enabled delegations a given delegate has received
57
+ * @param to The address to retrieve delegations for
58
+ * @return delegations Array of Delegation structs
59
+ */
60
+ function getIncomingDelegations(
61
+ address to
62
+ ) external view returns (Delegation[] memory delegations);
63
+ }
@@ -0,0 +1,35 @@
1
+ // SPDX-License-Identifier: CC0-1.0
2
+ pragma solidity ^0.8.17;
3
+
4
+ /**
5
+ * @title An immutable registry contract to be deployed as a standalone primitive
6
+ * @dev See EIP-5639, new project launches can read previous cold wallet -> hot wallet delegations
7
+ * from here and integrate those permissions into their flow
8
+ */
9
+ interface IDelegateRegistryV1 {
10
+ /// @notice Delegation type
11
+ enum DelegationType {
12
+ NONE,
13
+ ALL,
14
+ CONTRACT,
15
+ TOKEN
16
+ }
17
+
18
+ /// @notice Info about a single delegation, used for onchain enumeration
19
+ struct DelegationInfo {
20
+ DelegationType type_;
21
+ address vault;
22
+ address delegate;
23
+ address contract_;
24
+ uint256 tokenId;
25
+ }
26
+
27
+ /**
28
+ * @notice Returns all active delegations a given delegate is able to claim on behalf of
29
+ * @param delegate The delegate that you would like to retrieve delegations for
30
+ * @return info Array of DelegationInfo structs
31
+ */
32
+ function getDelegationsByDelegate(
33
+ address delegate
34
+ ) external view returns (DelegationInfo[] memory);
35
+ }