@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.
- package/LICENSE.txt +21 -0
- package/README.md +206 -0
- package/docs/permitAndStake_integration_guide.md +266 -0
- package/docs/swap_integration_guide.md +591 -0
- package/package.json +57 -0
- package/scripts/common/DeployBase.s.sol +26 -0
- package/scripts/common/DeployFacet.s.sol +7 -0
- package/scripts/common/Deployer.s.sol +33 -0
- package/scripts/common/Interaction.s.sol +51 -0
- package/scripts/deployments/diamonds/DeployAppRegistry.s.sol +168 -0
- package/scripts/deployments/diamonds/DeployBaseRegistry.s.sol +263 -0
- package/scripts/deployments/diamonds/DeployRiverAirdrop.s.sol +203 -0
- package/scripts/deployments/diamonds/DeployRiverMigration.s.sol +129 -0
- package/scripts/deployments/diamonds/DeployRiverRegistry.s.sol +175 -0
- package/scripts/deployments/diamonds/DeploySpace.s.sol +285 -0
- package/scripts/deployments/diamonds/DeploySpaceFactory.s.sol +416 -0
- package/scripts/deployments/diamonds/DeploySpaceOwner.s.sol +183 -0
- package/scripts/deployments/diamonds/DeploySwapRouter.s.sol +176 -0
- package/scripts/deployments/diamonds/IDiamondInitHelper.sol +11 -0
- package/scripts/deployments/facets/DeployAppAccount.s.sol +51 -0
- package/scripts/deployments/facets/DeployAppRegistryFacet.s.sol +69 -0
- package/scripts/deployments/facets/DeployArchitect.s.sol +51 -0
- package/scripts/deployments/facets/DeployAttestationRegistry.s.sol +36 -0
- package/scripts/deployments/facets/DeployBanning.s.sol +30 -0
- package/scripts/deployments/facets/DeployChannels.s.sol +35 -0
- package/scripts/deployments/facets/DeployCreateSpace.s.sol +42 -0
- package/scripts/deployments/facets/DeployDropFacet.s.sol +49 -0
- package/scripts/deployments/facets/DeployERC721A.s.sol +48 -0
- package/scripts/deployments/facets/DeployERC721ANonTransferable.s.sol +49 -0
- package/scripts/deployments/facets/DeployERC721AQueryable.s.sol +30 -0
- package/scripts/deployments/facets/DeployEntitlementChecker.s.sol +49 -0
- package/scripts/deployments/facets/DeployEntitlementDataQueryable.s.sol +29 -0
- package/scripts/deployments/facets/DeployEntitlementsManager.s.sol +33 -0
- package/scripts/deployments/facets/DeployExecutorFacet.s.sol +60 -0
- package/scripts/deployments/facets/DeployFeatureManager.s.sol +38 -0
- package/scripts/deployments/facets/DeployGuardianFacet.s.sol +39 -0
- package/scripts/deployments/facets/DeployImplementationRegistry.s.sol +36 -0
- package/scripts/deployments/facets/DeployMainnetDelegation.s.sol +43 -0
- package/scripts/deployments/facets/DeployMembership.s.sol +77 -0
- package/scripts/deployments/facets/DeployMembershipMetadata.s.sol +30 -0
- package/scripts/deployments/facets/DeployMembershipToken.s.sol +47 -0
- package/scripts/deployments/facets/DeployMerkleAirdrop.s.sol +37 -0
- package/scripts/deployments/facets/DeployMetadata.s.sol +39 -0
- package/scripts/deployments/facets/DeployMockLegacyArchitect.s.sol +33 -0
- package/scripts/deployments/facets/DeployNodeOperator.s.sol +49 -0
- package/scripts/deployments/facets/DeployNodeRegistry.s.sol +37 -0
- package/scripts/deployments/facets/DeployOperatorRegistry.s.sol +36 -0
- package/scripts/deployments/facets/DeployPartnerRegistry.s.sol +41 -0
- package/scripts/deployments/facets/DeployPlatformRequirements.s.sol +75 -0
- package/scripts/deployments/facets/DeployPrepayFacet.s.sol +31 -0
- package/scripts/deployments/facets/DeployPricingModules.s.sol +36 -0
- package/scripts/deployments/facets/DeployReferrals.s.sol +34 -0
- package/scripts/deployments/facets/DeployReviewFacet.s.sol +31 -0
- package/scripts/deployments/facets/DeployRewardsDistributionV2.s.sol +76 -0
- package/scripts/deployments/facets/DeployRiverConfig.s.sol +41 -0
- package/scripts/deployments/facets/DeployRoles.s.sol +48 -0
- package/scripts/deployments/facets/DeploySchemaRegistry.s.sol +35 -0
- package/scripts/deployments/facets/DeploySignerFacet.s.sol +47 -0
- package/scripts/deployments/facets/DeploySimpleApp.s.sol +10 -0
- package/scripts/deployments/facets/DeploySpaceDelegation.s.sol +43 -0
- package/scripts/deployments/facets/DeploySpaceEntitlementGated.s.sol +31 -0
- package/scripts/deployments/facets/DeploySpaceFactoryInit.s.sol +33 -0
- package/scripts/deployments/facets/DeploySpaceOwnerFacet.s.sol +71 -0
- package/scripts/deployments/facets/DeployStreamRegistry.s.sol +50 -0
- package/scripts/deployments/facets/DeploySwapFacet.s.sol +33 -0
- package/scripts/deployments/facets/DeploySwapRouterFacet.s.sol +38 -0
- package/scripts/deployments/facets/DeployTipping.s.sol +31 -0
- package/scripts/deployments/facets/DeployTokenMigration.s.sol +40 -0
- package/scripts/deployments/facets/DeployTownsPoints.s.sol +53 -0
- package/scripts/deployments/facets/DeployTreasury.s.sol +30 -0
- package/scripts/deployments/facets/DeployUpgradeableBeacon.s.sol +34 -0
- package/scripts/deployments/facets/DeployWalletLink.s.sol +56 -0
- package/scripts/deployments/facets/DeployXChain.s.sol +35 -0
- package/scripts/deployments/utils/DeployAccountFactory.s.sol +40 -0
- package/scripts/deployments/utils/DeployEntitlementGatedExample.s.sol +23 -0
- package/scripts/deployments/utils/DeployEntrypoint.s.sol +28 -0
- package/scripts/deployments/utils/DeployMember.s.sol +95 -0
- package/scripts/deployments/utils/DeployMockDiamond.s.sol +7 -0
- package/scripts/deployments/utils/DeployMockERC20.s.sol +24 -0
- package/scripts/deployments/utils/DeployMockERC721A.s.sol +45 -0
- package/scripts/deployments/utils/DeployMockLegacyMembership.s.sol +29 -0
- package/scripts/deployments/utils/DeployMockMessenger.s.sol +42 -0
- package/scripts/deployments/utils/DeployMockNFT.s.sol +86 -0
- package/scripts/deployments/utils/DeployPoapEntitlement.s.sol +16 -0
- package/scripts/deployments/utils/DeployProxyBatchDelegation.s.sol +112 -0
- package/scripts/deployments/utils/DeploySpaceProxyInitializer.s.sol +28 -0
- package/scripts/deployments/utils/DeployTieredLogPricingV2.s.sol +23 -0
- package/scripts/deployments/utils/DeployTieredLogPricingV3.s.sol +23 -0
- package/scripts/deployments/utils/DeployTownsBase.s.sol +95 -0
- package/scripts/deployments/utils/DeployTownsMainnet.s.sol +66 -0
- package/scripts/deployments/utils/DeployTownsMulti.s.sol +53 -0
- package/scripts/deployments/utils/DeployWrappedTowns.s.sol +52 -0
- package/scripts/deployments/utils/LibLayerZeroValues.sol +34 -0
- package/scripts/deployments/utils/pricing/TieredLogPricing.s.sol +45 -0
- package/scripts/interactions/InteractAirdrop.s.sol +57 -0
- package/scripts/interactions/InteractAlphaPost.s.sol +32 -0
- package/scripts/interactions/InteractAlphaSparse.s.sol +173 -0
- package/scripts/interactions/InteractBaseAlpha.s.sol +84 -0
- package/scripts/interactions/InteractBaseBridge.s.sol +48 -0
- package/scripts/interactions/InteractBridgeLayerZero.s.sol +102 -0
- package/scripts/interactions/InteractClaimCondition.s.sol +56 -0
- package/scripts/interactions/InteractCreateSpace.s.sol +50 -0
- package/scripts/interactions/InteractDiamondCut.s.sol +47 -0
- package/scripts/interactions/InteractDropFacet.s.sol +32 -0
- package/scripts/interactions/InteractEnableNewSnapshotFormat.s.sol +27 -0
- package/scripts/interactions/InteractEnableNode2NodeAuth.s.sol +27 -0
- package/scripts/interactions/InteractMembership.s.sol +42 -0
- package/scripts/interactions/InteractMockERC721A.s.sol +20 -0
- package/scripts/interactions/InteractNodeOperators.s.sol +41 -0
- package/scripts/interactions/InteractPostDeploy.s.sol +59 -0
- package/scripts/interactions/InteractPrepay.s.sol +30 -0
- package/scripts/interactions/InteractRegisterApp.s.sol +61 -0
- package/scripts/interactions/InteractRiverAlpha.s.sol +30 -0
- package/scripts/interactions/InteractRiverAlphaSparse.s.sol +117 -0
- package/scripts/interactions/InteractRiverMainnet.s.sol +27 -0
- package/scripts/interactions/InteractRiverRegistry.s.sol +36 -0
- package/scripts/interactions/InteractRiverRegistrySetBlocklist.s.sol +30 -0
- package/scripts/interactions/InteractRiverRegistrySetFreq.s.sol +27 -0
- package/scripts/interactions/InteractRiverRegistrySetRepl.s.sol +30 -0
- package/scripts/interactions/InteractSetDefaultUri.s.sol +20 -0
- package/scripts/interactions/InteractSetDefaultUriLocalhost.s.sol +19 -0
- package/scripts/interactions/InteractTransferOwnership.s.sol +21 -0
- package/scripts/interactions/InteractUpdateMbRecencyCheck.s.sol +27 -0
- package/scripts/interactions/InteractUpdateMediaChunkCount.s.sol +27 -0
- package/scripts/interactions/InteractUpdateMediaChunkSize.s.sol +27 -0
- package/scripts/interactions/helpers/AlphaHelper.sol +149 -0
- package/scripts/interactions/helpers/RiverConfigValues.sol +22 -0
- package/scripts/interactions/interfaces/IL1StandardBridge.sol +35 -0
- package/scripts/interactions/interfaces/IL2StandardBridge.sol +69 -0
- package/src/airdrop/drop/DropBase.sol +210 -0
- package/src/airdrop/drop/DropClaim.sol +55 -0
- package/src/airdrop/drop/DropFacet.sol +176 -0
- package/src/airdrop/drop/DropGroup.sol +111 -0
- package/src/airdrop/drop/DropStorage.sol +23 -0
- package/src/airdrop/drop/IDropFacet.sol +136 -0
- package/src/airdrop/points/CheckIn.sol +71 -0
- package/src/airdrop/points/ITownsPoints.sol +64 -0
- package/src/airdrop/points/TownsPoints.sol +196 -0
- package/src/airdrop/points/TownsPointsStorage.sol +22 -0
- package/src/apps/BaseApp.sol +62 -0
- package/src/apps/ITownsApp.sol +28 -0
- package/src/apps/SchemaResolver.sol +170 -0
- package/src/apps/facets/attest/AttestationBase.sol +335 -0
- package/src/apps/facets/attest/AttestationLib.sol +64 -0
- package/src/apps/facets/attest/AttestationRegistry.sol +39 -0
- package/src/apps/facets/attest/AttestationStorage.sol +35 -0
- package/src/apps/facets/attest/IAttestationRegistry.sol +43 -0
- package/src/apps/facets/registry/AppRegistryBase.sol +403 -0
- package/src/apps/facets/registry/AppRegistryFacet.sol +173 -0
- package/src/apps/facets/registry/AppRegistryStorage.sol +53 -0
- package/src/apps/facets/registry/IAppRegistry.sol +159 -0
- package/src/apps/facets/schema/ISchema.sol +14 -0
- package/src/apps/facets/schema/SchemaBase.sol +88 -0
- package/src/apps/facets/schema/SchemaLib.sol +14 -0
- package/src/apps/facets/schema/SchemaRegistry.sol +51 -0
- package/src/apps/facets/schema/SchemaStorage.sol +34 -0
- package/src/apps/helpers/ISimpleApp.sol +51 -0
- package/src/apps/helpers/SimpleApp.sol +97 -0
- package/src/apps/helpers/SimpleAppStorage.sol +27 -0
- package/src/base/registry/facets/checker/EntitlementChecker.sol +237 -0
- package/src/base/registry/facets/checker/EntitlementCheckerStorage.sol +28 -0
- package/src/base/registry/facets/checker/IEntitlementChecker.sol +95 -0
- package/src/base/registry/facets/delegation/ISpaceDelegation.sol +69 -0
- package/src/base/registry/facets/delegation/SpaceDelegationFacet.sol +250 -0
- package/src/base/registry/facets/delegation/SpaceDelegationStorage.sol +35 -0
- package/src/base/registry/facets/distribution/v1/IRewardsDistribution.sol +51 -0
- package/src/base/registry/facets/distribution/v1/RewardsDistribution.sol +439 -0
- package/src/base/registry/facets/distribution/v1/RewardsDistributionStorage.sol +32 -0
- package/src/base/registry/facets/distribution/v2/DelegationProxy.sol +53 -0
- package/src/base/registry/facets/distribution/v2/IRewardsDistribution.sol +372 -0
- package/src/base/registry/facets/distribution/v2/RewardsDistributionBase.sol +299 -0
- package/src/base/registry/facets/distribution/v2/RewardsDistributionStorage.sol +37 -0
- package/src/base/registry/facets/distribution/v2/RewardsDistributionV2.sol +392 -0
- package/src/base/registry/facets/distribution/v2/StakingRewards.sol +466 -0
- package/src/base/registry/facets/mainnet/ICrossDomainMessenger.sol +58 -0
- package/src/base/registry/facets/mainnet/IMainnetDelegation.sol +127 -0
- package/src/base/registry/facets/mainnet/MainnetDelegation.sol +119 -0
- package/src/base/registry/facets/mainnet/MainnetDelegationBase.sol +274 -0
- package/src/base/registry/facets/mainnet/MainnetDelegationStorage.sol +36 -0
- package/src/base/registry/facets/operator/INodeOperator.sol +91 -0
- package/src/base/registry/facets/operator/NodeOperatorFacet.sol +189 -0
- package/src/base/registry/facets/operator/NodeOperatorStorage.sol +39 -0
- package/src/base/registry/facets/xchain/IXChain.sol +54 -0
- package/src/base/registry/facets/xchain/XChain.sol +158 -0
- package/src/base/registry/facets/xchain/XChainCheckLib.sol +105 -0
- package/src/base/registry/facets/xchain/XChainLib.sol +46 -0
- package/src/diamond/facets/beacon/UpgradeableBeacon.sol +38 -0
- package/src/diamond/facets/beacon/UpgradeableBeaconFacet.sol +34 -0
- package/src/diamond/facets/governance/votes/Checkpoints.sol +642 -0
- package/src/diamond/facets/governance/votes/Votes.sol +63 -0
- package/src/diamond/facets/governance/votes/VotesBase.sol +274 -0
- package/src/diamond/facets/governance/votes/VotesStorage.sol +21 -0
- package/src/diamond/facets/governance/votes/enumerable/IVotesEnumerable.sol +38 -0
- package/src/diamond/facets/governance/votes/enumerable/VotesEnumerable.sol +39 -0
- package/src/diamond/facets/governance/votes/enumerable/VotesEnumerableLib.sol +102 -0
- package/src/diamond/facets/metadata/IMetadata.sol +27 -0
- package/src/diamond/facets/metadata/MetadataFacet.sol +71 -0
- package/src/diamond/facets/token/ERC5643/ERC5643.sol +51 -0
- package/src/diamond/facets/token/ERC5643/ERC5643Base.sol +48 -0
- package/src/diamond/facets/token/ERC5643/ERC5643Storage.sol +26 -0
- package/src/diamond/facets/token/ERC5643/IERC5643.sol +44 -0
- package/src/diamond/facets/token/ERC721A/ERC721A.sol +270 -0
- package/src/diamond/facets/token/ERC721A/ERC721ABase.sol +829 -0
- package/src/diamond/facets/token/ERC721A/ERC721ANonTransferable.sol +21 -0
- package/src/diamond/facets/token/ERC721A/ERC721AStorage.sol +115 -0
- package/src/diamond/facets/token/ERC721A/IERC721A.sol +283 -0
- package/src/diamond/facets/token/ERC721A/extensions/ERC721AQueryable.sol +134 -0
- package/src/diamond/facets/token/ERC721A/extensions/IERC721AQueryable.sol +83 -0
- package/src/diamond/utils/Context.sol +19 -0
- package/src/factory/SpaceFactoryInit.sol +17 -0
- package/src/factory/facets/architect/Architect.sol +98 -0
- package/src/factory/facets/architect/ArchitectBase.sol +95 -0
- package/src/factory/facets/architect/ArchitectStorage.sol +28 -0
- package/src/factory/facets/architect/IArchitect.sol +155 -0
- package/src/factory/facets/architect/ImplementationStorage.sol +42 -0
- package/src/factory/facets/architect/pricing/IPricingModules.sol +41 -0
- package/src/factory/facets/architect/pricing/PricingModulesBase.sol +89 -0
- package/src/factory/facets/architect/pricing/PricingModulesFacet.sol +40 -0
- package/src/factory/facets/architect/pricing/PricingModulesStorage.sol +30 -0
- package/src/factory/facets/create/CreateSpace.sol +107 -0
- package/src/factory/facets/create/CreateSpaceLib.sol +335 -0
- package/src/factory/facets/create/ICreateSpace.sol +70 -0
- package/src/factory/facets/feature/FeatureConditionLib.sol +53 -0
- package/src/factory/facets/feature/FeatureManagerFacet.sol +66 -0
- package/src/factory/facets/feature/FeatureManagerLib.sol +168 -0
- package/src/factory/facets/feature/IFeatureManagerFacet.sol +73 -0
- package/src/factory/facets/partner/IPartnerRegistry.sol +56 -0
- package/src/factory/facets/partner/PartnerRegistry.sol +57 -0
- package/src/factory/facets/partner/PartnerRegistryBase.sol +132 -0
- package/src/factory/facets/partner/PartnerRegistryStorage.sol +40 -0
- package/src/factory/facets/platform/requirements/IPlatformRequirements.sol +143 -0
- package/src/factory/facets/platform/requirements/PlatformRequirementsBase.sol +124 -0
- package/src/factory/facets/platform/requirements/PlatformRequirementsFacet.sol +122 -0
- package/src/factory/facets/platform/requirements/PlatformRequirementsStorage.sol +41 -0
- package/src/factory/facets/registry/IImplementationRegistry.sol +46 -0
- package/src/factory/facets/registry/ImplementationRegistry.sol +64 -0
- package/src/factory/facets/registry/ImplementationRegistryStorage.sol +28 -0
- package/src/factory/facets/wallet-link/IWalletLink.sol +218 -0
- package/src/factory/facets/wallet-link/WalletLink.sol +108 -0
- package/src/factory/facets/wallet-link/WalletLinkBase.sol +492 -0
- package/src/factory/facets/wallet-link/interfaces/IDelegateRegistry.sol +63 -0
- package/src/factory/facets/wallet-link/interfaces/IDelegateRegistryV1.sol +35 -0
- package/src/factory/facets/wallet-link/interfaces/ISCL_EIP6565.sol +24 -0
- package/src/factory/facets/wallet-link/libraries/SolanaUtils.sol +161 -0
- package/src/factory/facets/wallet-link/libraries/WalletLib.sol +62 -0
- package/src/river/registry/facets/config/IRiverConfig.sol +117 -0
- package/src/river/registry/facets/config/RiverConfig.sol +174 -0
- package/src/river/registry/facets/node/INodeRegistry.sol +69 -0
- package/src/river/registry/facets/node/NodeRegistry.sol +143 -0
- package/src/river/registry/facets/operator/IOperatorRegistry.sol +28 -0
- package/src/river/registry/facets/operator/OperatorRegistry.sol +86 -0
- package/src/river/registry/facets/stream/IStreamRegistry.sol +184 -0
- package/src/river/registry/facets/stream/StreamRegistry.sol +396 -0
- package/src/river/registry/libraries/RegistryErrors.sol +24 -0
- package/src/river/registry/libraries/RegistryStorage.sol +181 -0
- package/src/router/ISwapRouter.sol +226 -0
- package/src/router/Permit2Hash.sol +92 -0
- package/src/router/SwapRouter.sol +463 -0
- package/src/router/SwapRouterStorage.sol +21 -0
- package/src/spaces/entitlements/ICrossChainEntitlement.sol +22 -0
- package/src/spaces/entitlements/IEntitlement.sol +61 -0
- package/src/spaces/entitlements/PolymarketEntitlement.sol +79 -0
- package/src/spaces/entitlements/poap/IPOAP.sol +26 -0
- package/src/spaces/entitlements/poap/PoapEntitlement.sol +56 -0
- package/src/spaces/entitlements/rule/IRuleEntitlement.sol +174 -0
- package/src/spaces/entitlements/rule/RuleEntitlement.sol +183 -0
- package/src/spaces/entitlements/rule/RuleEntitlementV2.sol +219 -0
- package/src/spaces/entitlements/user/IUserEntitlement.sol +24 -0
- package/src/spaces/entitlements/user/UserEntitlement.sol +273 -0
- package/src/spaces/facets/DependencyLib.sol +60 -0
- package/src/spaces/facets/Entitled.sol +172 -0
- package/src/spaces/facets/Permissions.sol +21 -0
- package/src/spaces/facets/account/AppAccount.sol +93 -0
- package/src/spaces/facets/account/AppAccountBase.sol +275 -0
- package/src/spaces/facets/account/AppAccountStorage.sol +63 -0
- package/src/spaces/facets/account/IAppAccount.sol +71 -0
- package/src/spaces/facets/account/SignerFacet.sol +26 -0
- package/src/spaces/facets/banning/Banning.sol +41 -0
- package/src/spaces/facets/banning/BanningBase.sol +33 -0
- package/src/spaces/facets/banning/BanningStorage.sol +23 -0
- package/src/spaces/facets/banning/IBanning.sol +35 -0
- package/src/spaces/facets/channels/ChannelBase.sol +87 -0
- package/src/spaces/facets/channels/ChannelService.sol +177 -0
- package/src/spaces/facets/channels/ChannelStorage.sol +34 -0
- package/src/spaces/facets/channels/Channels.sol +80 -0
- package/src/spaces/facets/channels/IChannel.sol +98 -0
- package/src/spaces/facets/dispatcher/DispatcherBase.sol +86 -0
- package/src/spaces/facets/dispatcher/DispatcherStorage.sol +21 -0
- package/src/spaces/facets/dispatcher/IDispatcher.sol +6 -0
- package/src/spaces/facets/entitlements/EntitlementsManager.sol +49 -0
- package/src/spaces/facets/entitlements/EntitlementsManagerBase.sol +87 -0
- package/src/spaces/facets/entitlements/EntitlementsManagerService.sol +142 -0
- package/src/spaces/facets/entitlements/EntitlementsManagerStorage.sol +34 -0
- package/src/spaces/facets/entitlements/IEntitlementsManager.sol +67 -0
- package/src/spaces/facets/entitlements/extensions/EntitlementDataQueryable.sol +153 -0
- package/src/spaces/facets/entitlements/extensions/IEntitlementDataQueryable.sol +32 -0
- package/src/spaces/facets/executor/ExecutorBase.sol +564 -0
- package/src/spaces/facets/executor/ExecutorFacet.sol +178 -0
- package/src/spaces/facets/executor/ExecutorStorage.sol +99 -0
- package/src/spaces/facets/executor/GroupLib.sol +128 -0
- package/src/spaces/facets/executor/IExecutor.sol +287 -0
- package/src/spaces/facets/executor/hooks/HookBase.sol +172 -0
- package/src/spaces/facets/executor/hooks/HookLib.sol +38 -0
- package/src/spaces/facets/executor/hooks/IHookBase.sol +48 -0
- package/src/spaces/facets/gated/EntitlementGated.sol +59 -0
- package/src/spaces/facets/gated/EntitlementGatedBase.sol +324 -0
- package/src/spaces/facets/gated/EntitlementGatedStorage.sol +29 -0
- package/src/spaces/facets/gated/IEntitlementGated.sol +55 -0
- package/src/spaces/facets/guardian/GuardianBase.sol +80 -0
- package/src/spaces/facets/guardian/GuardianFacet.sol +43 -0
- package/src/spaces/facets/guardian/GuardianStorage.sol +27 -0
- package/src/spaces/facets/guardian/IGuardian.sol +54 -0
- package/src/spaces/facets/membership/IMembership.sol +216 -0
- package/src/spaces/facets/membership/MembershipBase.sol +272 -0
- package/src/spaces/facets/membership/MembershipFacet.sol +191 -0
- package/src/spaces/facets/membership/MembershipStorage.sol +40 -0
- package/src/spaces/facets/membership/join/MembershipJoin.sol +547 -0
- package/src/spaces/facets/membership/metadata/IMembershipMetadata.sol +9 -0
- package/src/spaces/facets/membership/metadata/MembershipMetadata.sol +32 -0
- package/src/spaces/facets/membership/pricing/IMembershipPricing.sol +18 -0
- package/src/spaces/facets/membership/pricing/fixed/FixedPricing.sol +29 -0
- package/src/spaces/facets/membership/pricing/fixed/FixedPricingStorage.sol +27 -0
- package/src/spaces/facets/membership/pricing/tiered/TieredLogPricingOracleV2.sol +148 -0
- package/src/spaces/facets/membership/pricing/tiered/TieredLogPricingOracleV3.sol +137 -0
- package/src/spaces/facets/membership/token/MembershipToken.sol +25 -0
- package/src/spaces/facets/owner/ISpaceOwner.sol +85 -0
- package/src/spaces/facets/owner/SpaceOwner.sol +174 -0
- package/src/spaces/facets/owner/SpaceOwnerBase.sol +121 -0
- package/src/spaces/facets/owner/SpaceOwnerStorage.sol +41 -0
- package/src/spaces/facets/owner/SpaceOwnerUriBase.sol +54 -0
- package/src/spaces/facets/points/PointsBase.sol +35 -0
- package/src/spaces/facets/prepay/IPrepay.sol +43 -0
- package/src/spaces/facets/prepay/PrepayBase.sol +27 -0
- package/src/spaces/facets/prepay/PrepayFacet.sol +59 -0
- package/src/spaces/facets/prepay/PrepayStorage.sol +26 -0
- package/src/spaces/facets/proxy/ISpaceProxyInitializer.sol +21 -0
- package/src/spaces/facets/proxy/SpaceProxy.sol +15 -0
- package/src/spaces/facets/proxy/SpaceProxyInitializer.sol +55 -0
- package/src/spaces/facets/referrals/IReferrals.sol +98 -0
- package/src/spaces/facets/referrals/ReferralsBase.sol +81 -0
- package/src/spaces/facets/referrals/ReferralsFacet.sol +65 -0
- package/src/spaces/facets/referrals/ReferralsStorage.sol +36 -0
- package/src/spaces/facets/review/IReview.sol +50 -0
- package/src/spaces/facets/review/ReviewFacet.sol +105 -0
- package/src/spaces/facets/review/ReviewStorage.sol +29 -0
- package/src/spaces/facets/roles/IRoles.sol +197 -0
- package/src/spaces/facets/roles/Roles.sol +123 -0
- package/src/spaces/facets/roles/RolesBase.sol +420 -0
- package/src/spaces/facets/roles/RolesStorage.sol +132 -0
- package/src/spaces/facets/swap/ISwapFacet.sol +91 -0
- package/src/spaces/facets/swap/SwapFacet.sol +290 -0
- package/src/spaces/facets/swap/SwapFacetStorage.sol +24 -0
- package/src/spaces/facets/tipping/ITipping.sol +80 -0
- package/src/spaces/facets/tipping/TippingBase.sol +73 -0
- package/src/spaces/facets/tipping/TippingFacet.sol +123 -0
- package/src/spaces/facets/treasury/ITreasury.sol +64 -0
- package/src/spaces/facets/treasury/Treasury.sol +82 -0
- package/src/spaces/facets/xchain/SpaceEntitlementGated.sol +62 -0
- package/src/tokens/Member.sol +246 -0
- package/src/tokens/lock/ILock.sol +42 -0
- package/src/tokens/lock/LockBase.sol +64 -0
- package/src/tokens/lock/LockFacet.sol +44 -0
- package/src/tokens/lock/LockStorage.sol +26 -0
- package/src/tokens/mainnet/claimer/AuthorizedClaimerStorage.sol +26 -0
- package/src/tokens/mainnet/claimer/AuthorizedClaimers.sol +84 -0
- package/src/tokens/mainnet/claimer/IAuthorizedClaimers.sol +36 -0
- package/src/tokens/mainnet/delegation/ProxyBatchDelegation.sol +86 -0
- package/src/tokens/migration/ITokenMigration.sol +35 -0
- package/src/tokens/migration/TokenMigrationFacet.sol +86 -0
- package/src/tokens/migration/TokenMigrationStorage.sol +27 -0
- package/src/tokens/towns/base/IERC7802.sol +30 -0
- package/src/tokens/towns/base/IOptimismMintableERC20.sol +31 -0
- package/src/tokens/towns/base/ISemver.sol +13 -0
- package/src/tokens/towns/base/Towns.sol +283 -0
- package/src/tokens/towns/base/TownsDeployer.sol +32 -0
- package/src/tokens/towns/base/TownsLib.sol +31 -0
- package/src/tokens/towns/base/versions/TownsV2.sol +15 -0
- package/src/tokens/towns/mainnet/ITowns.sol +56 -0
- package/src/tokens/towns/mainnet/Towns.sol +220 -0
- package/src/tokens/towns/mainnet/libs/TokenInflationLib.sol +89 -0
- package/src/tokens/towns/multichain/Towns.sol +19 -0
- package/src/tokens/towns/multichain/wTowns.sol +18 -0
- package/src/utils/Airdrop.sol +156 -0
- package/src/utils/airdrop/merkle/IMerkleAirdrop.sol +55 -0
- package/src/utils/airdrop/merkle/MerkleAirdrop.sol +118 -0
- package/src/utils/airdrop/merkle/MerkleAirdropStorage.sol +29 -0
- package/src/utils/interfaces/AggregatorV3Interface.sol +37 -0
- package/src/utils/interfaces/IMulticall.sol +10 -0
- package/src/utils/interfaces/IWETH.sol +10 -0
- package/src/utils/libraries/BasisPoints.sol +24 -0
- package/src/utils/libraries/Create2Utils.sol +74 -0
- package/src/utils/libraries/CurrencyTransfer.sol +99 -0
- package/src/utils/libraries/CustomRevert.sol +49 -0
- package/src/utils/libraries/Factory.sol +66 -0
- package/src/utils/libraries/StringSet.sol +190 -0
- 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
|
+
}
|