@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
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 River Association
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Towns Contracts
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This project is a blockchain-based space/channel management system with role-based access control and entitlements. It implements a complex permission system using smart contracts that allows for cross-chain rule validation and user management.
|
|
6
|
+
|
|
7
|
+
The system also supports cross-chain delegation between Ethereum L1 and Base L2, allowing users to stake tokens on L1 and have delegation benefits on L2. Node operators can receive delegations directly or via spaces, with rewards distributed based on stake amounts and time.
|
|
8
|
+
|
|
9
|
+
### The system allows for:
|
|
10
|
+
|
|
11
|
+
- Creation and management of spaces and channels
|
|
12
|
+
- Role-based access control with granular permissions
|
|
13
|
+
- Cross-chain entitlement validation
|
|
14
|
+
- User membership management
|
|
15
|
+
- Rule-based entitlements with logical operations
|
|
16
|
+
- Staking and rewards distribution for DAO participants and node operators
|
|
17
|
+
- Cross-chain delegation and governance mechanisms
|
|
18
|
+
|
|
19
|
+
## Tech Stack
|
|
20
|
+
|
|
21
|
+
- Solidity ^0.8.23
|
|
22
|
+
- OpenZeppelin Contracts
|
|
23
|
+
- Solady Contracts
|
|
24
|
+
- Diamond Pattern (EIP-2535) for upgradeable contracts
|
|
25
|
+
- Foundry for development and testing
|
|
26
|
+
- TypeScript for contract type generation
|
|
27
|
+
|
|
28
|
+
## Project Structure
|
|
29
|
+
|
|
30
|
+
- `src/airdrop/` - Token distribution mechanisms (drops, points, streaks, rules)
|
|
31
|
+
- `src/base/registry/` - Core registry, delegation, rewards, entitlement checking
|
|
32
|
+
- `/facets/distribution/` - Staking and rewards distribution for DAO participants and node operators
|
|
33
|
+
- `/facets/mainnet/` - Cross-chain delegation handling and message relaying
|
|
34
|
+
- `/facets/delegation/` - Space-to-operator delegation management
|
|
35
|
+
- `/facets/operator/` - Node operator registration and management
|
|
36
|
+
- `src/spaces/` - Space management, entitlements, permissions, cross-chain rules
|
|
37
|
+
- `src/factory/` - Factory contracts for space creation, deployment, wallet linking
|
|
38
|
+
- `src/utils/` - Utility libraries (currency, math, reverts, patterns)
|
|
39
|
+
- `src/diamond/` - Diamond pattern implementation, facets, upgradeability
|
|
40
|
+
- `src/tokens/` - Token management, membership NFTs, locks, bridging, inflation
|
|
41
|
+
- `scripts/diamonds` - Diamond deployment scripts
|
|
42
|
+
|
|
43
|
+
### Key Contracts
|
|
44
|
+
|
|
45
|
+
- `RuleEntitlement.sol` - Rule-based entitlements, cross-chain permission validation
|
|
46
|
+
- `EntitlementsManager.sol` - Entitlement validation and access control
|
|
47
|
+
- `Architect.sol` - Factory for space creation/initialization
|
|
48
|
+
- `CreateSpace.sol` - Space instance creation/initialization
|
|
49
|
+
- `Roles.sol` - Role-based permissions and hierarchies
|
|
50
|
+
- `Towns.sol` - Main ERC20 token (inflation, governance)
|
|
51
|
+
- `DropFacet.sol` - Token airdrops, claiming conditions
|
|
52
|
+
- `TownsPoints.sol` - Points-based rewards, check-ins, streaks
|
|
53
|
+
- `RewardsDistribution.sol` - Manages token staking, delegation proxies, and reward calculations
|
|
54
|
+
- `MainnetDelegation.sol` - Handles cross-chain delegation via cross-domain messengers
|
|
55
|
+
- `SpaceDelegationFacet.sol` - Manages delegation of spaces to node operators
|
|
56
|
+
- `EntitlementChecker.sol` - Cross-chain entitlement validation
|
|
57
|
+
- `DiamondCutFacet.sol` - Diamond upgradeability
|
|
58
|
+
|
|
59
|
+
## Requirements
|
|
60
|
+
|
|
61
|
+
Install [yarn](https://yarnpkg.com/getting-started/install) via corepack:
|
|
62
|
+
|
|
63
|
+
```shell
|
|
64
|
+
npm install -g corepack
|
|
65
|
+
corepack enable
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Install [Foundry](https://github.com/foundry-rs/foundry):
|
|
69
|
+
|
|
70
|
+
```shell
|
|
71
|
+
curl -L https://foundry.paradigm.xyz | bash
|
|
72
|
+
foundryup
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Project Setup
|
|
76
|
+
|
|
77
|
+
Clone the repo, then:
|
|
78
|
+
|
|
79
|
+
```shell
|
|
80
|
+
yarn
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**To compile the smart contracts:**
|
|
84
|
+
|
|
85
|
+
```shell
|
|
86
|
+
forge build
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**To run the solidity unit tests:**
|
|
90
|
+
|
|
91
|
+
```shell
|
|
92
|
+
forge test
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
You can add verbosity to the tests by adding `-vvvv` (1-4 levels) to the command.
|
|
96
|
+
|
|
97
|
+
## Local Development
|
|
98
|
+
|
|
99
|
+
**To start a local Ethereum blockchain:**
|
|
100
|
+
|
|
101
|
+
```shell
|
|
102
|
+
anvil
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
It will generate a set of 10 public/private keys with 10k ether each. Save one of these private keys for deployment.
|
|
106
|
+
It starts listening on `http://127.0.0.1:8545`.
|
|
107
|
+
If you want to interact with anvil via a front end, you will need to add the local network to Metamask with `ChainID=1337`.
|
|
108
|
+
|
|
109
|
+
**To start a local base blockchain and river blockchain:**
|
|
110
|
+
|
|
111
|
+
```shell
|
|
112
|
+
./scripts/bc-all-start.sh
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Deployment
|
|
116
|
+
|
|
117
|
+
### Local Deployment
|
|
118
|
+
|
|
119
|
+
**To deploy our contracts to your local base and river instances:**
|
|
120
|
+
|
|
121
|
+
1. Duplicate `.env.localhost` file in the [contracts](.) folder of the project and rename it to `.env` (this is excluded from git via .gitignore)
|
|
122
|
+
2. Run `export RIVER_ENV="local_multi"` from your terminal
|
|
123
|
+
3. Execute `./scripts/deploy-contracts.sh` to deploy the entire suite of contracts to your local base-anvil and river-anvil chains
|
|
124
|
+
|
|
125
|
+
### Diamond Contract Deployment
|
|
126
|
+
|
|
127
|
+
**To deploy a single diamond base contract to your local anvil instance:**
|
|
128
|
+
|
|
129
|
+
From within the `contracts/` folder you can run:
|
|
130
|
+
|
|
131
|
+
```shell
|
|
132
|
+
make deploy-base-anvil contract=Deploy[Contract] type=diamonds
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Replace `[Contract]` with the contract you want to deploy. You can see all the contracts available for deployment in the [diamonds deployments directory](./scripts/deployments/diamonds).
|
|
136
|
+
|
|
137
|
+
### Facet Deployment
|
|
138
|
+
|
|
139
|
+
The project supports two methods for deploying facets:
|
|
140
|
+
|
|
141
|
+
1. **Using custom deployment scripts:**
|
|
142
|
+
|
|
143
|
+
```shell
|
|
144
|
+
make deploy-base-anvil contract=Deploy[Facet] type=facets
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- Replace `[Facet]` with the name of your facet deployment script found in [./scripts/deployments/facets](./scripts/deployments/facets)
|
|
148
|
+
- This approach uses scripts that inherit from `Deployer` and implement `versionName()` and `__deploy()` functions
|
|
149
|
+
|
|
150
|
+
2. **Using the standardized `DeployFacet` script:**
|
|
151
|
+
|
|
152
|
+
```shell
|
|
153
|
+
make deploy-facet-local rpc=base_anvil contract=[FacetName]
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
- Replace `[FacetName]` with the actual facet contract name (without "Deploy" prefix)
|
|
157
|
+
- This approach uses the common `DeployFacet.s.sol` script with the `CONTRACT_NAME` environment variable
|
|
158
|
+
- It leverages deterministic CREATE2 addresses and supports batch deployments
|
|
159
|
+
- For more details, see the [DeployFacet documentation](https://github.com/towns-protocol/diamond/blob/main/scripts/README.md)
|
|
160
|
+
|
|
161
|
+
### Live Network Deployment
|
|
162
|
+
|
|
163
|
+
**To deploy facets to a live network:**
|
|
164
|
+
|
|
165
|
+
From within the `contracts/` folder you can run:
|
|
166
|
+
|
|
167
|
+
```shell
|
|
168
|
+
# For custom deployment scripts:
|
|
169
|
+
make deploy-base-sepolia contract=Deploy[Contract] type=facets context=[context]
|
|
170
|
+
|
|
171
|
+
# For standardized DeployFacet script:
|
|
172
|
+
make deploy-facet rpc=base_sepolia contract=[FacetName] context=[context]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
For example, to deploy the WalletLink facet to Base Sepolia with a deployment context of "gamma":
|
|
176
|
+
|
|
177
|
+
```shell
|
|
178
|
+
# Using custom deployment script:
|
|
179
|
+
make deploy-base-sepolia contract=DeployWalletLink type=facets context=gamma
|
|
180
|
+
|
|
181
|
+
# Using standardized DeployFacet script:
|
|
182
|
+
make deploy-facet rpc=base_sepolia contract=WalletLink context=gamma
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Hardware Wallet Deployments
|
|
186
|
+
|
|
187
|
+
For hardware wallet deployments, use the corresponding ledger commands:
|
|
188
|
+
|
|
189
|
+
```shell
|
|
190
|
+
# Using custom deployment script:
|
|
191
|
+
make deploy-ledger-base-sepolia contract=DeployWalletLink type=facets context=gamma
|
|
192
|
+
|
|
193
|
+
# Using standardized DeployFacet script:
|
|
194
|
+
make deploy-facet-ledger rpc=base_sepolia contract=WalletLink context=gamma
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
You can see all the contracts available for deployment in the [deployments](./scripts/deployments) directory.
|
|
198
|
+
|
|
199
|
+
## Contributing
|
|
200
|
+
|
|
201
|
+
For detailed information on contributing to this project, please see our [CONTRIBUTING.md](CONTRIBUTING.md) file. It includes:
|
|
202
|
+
|
|
203
|
+
- Guidelines for opening issues and pull requests
|
|
204
|
+
- Coding standards and best practices
|
|
205
|
+
- Diamond Pattern implementation details
|
|
206
|
+
- Facet development guidelines
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# PermitAndStake Integration Guide
|
|
2
|
+
|
|
3
|
+
This guide explains how to integrate with the new `permitAndStake` function in the Towns Protocol RewardsDistribution contract, which uses Permit2 for gasless token approvals and enhanced smart contract wallet support.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `permitAndStake` function allows users to approve and stake tokens in a single transaction using Uniswap's Permit2 protocol. This provides several advantages over traditional EIP-2612 permits:
|
|
8
|
+
|
|
9
|
+
- **Smart Contract Wallet Support**: Works with smart contracts via ERC-1271 signature verification
|
|
10
|
+
- **Universal Token Approval**: Uses Permit2 as a universal approval router
|
|
11
|
+
- **Enhanced Security**: Cryptographically binds signatures to specific spenders and amounts
|
|
12
|
+
- **Gasless Approval**: No separate approval transaction required
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
Before using `permitAndStake`, ensure:
|
|
17
|
+
|
|
18
|
+
1. **Towns Token Approval**: No pre-approval needed. The Towns token gives Permit2 infinite allowance by default, so users can directly call `permitAndStake` without any prior approval transactions.
|
|
19
|
+
|
|
20
|
+
2. **Permit2 Deployment**: Permit2 is deployed at the deterministic address `0x000000000022D473030F116dDEE9F6B43aC78BA3` on all networks.
|
|
21
|
+
|
|
22
|
+
## Function Signature
|
|
23
|
+
|
|
24
|
+
```solidity
|
|
25
|
+
function permitAndStake(
|
|
26
|
+
uint96 amount, // Amount of Towns tokens to stake
|
|
27
|
+
address delegatee, // Operator or space to delegate to
|
|
28
|
+
address beneficiary, // Address that receives staking rewards
|
|
29
|
+
uint256 nonce, // Unique nonce for replay protection
|
|
30
|
+
uint256 deadline, // Expiration timestamp for the permit
|
|
31
|
+
bytes calldata signature // Permit2 signature
|
|
32
|
+
) external returns (uint256 depositId);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Integration Guide
|
|
36
|
+
|
|
37
|
+
### TypeScript/JavaScript Integration
|
|
38
|
+
|
|
39
|
+
#### Dependencies
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
yarn add @uniswap/permit2-sdk viem
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
#### Complete Integration Example
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import {
|
|
49
|
+
PERMIT2_ADDRESS,
|
|
50
|
+
SignatureTransfer,
|
|
51
|
+
PermitTransferFrom,
|
|
52
|
+
} from "@uniswap/permit2-sdk";
|
|
53
|
+
import { createWalletClient, http, parseUnits } from "viem";
|
|
54
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
55
|
+
import { base } from "viem/chains";
|
|
56
|
+
|
|
57
|
+
// Contract addresses
|
|
58
|
+
const REWARDS_DISTRIBUTION_ADDRESS = "0x..."; // Your deployed contract
|
|
59
|
+
const TOWNS_TOKEN_ADDRESS = "0x..."; // Towns token address
|
|
60
|
+
|
|
61
|
+
// Create wallet client
|
|
62
|
+
const account = privateKeyToAccount("0x...");
|
|
63
|
+
const walletClient = createWalletClient({
|
|
64
|
+
account,
|
|
65
|
+
chain: base,
|
|
66
|
+
transport: http(),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
async function permitAndStake({
|
|
70
|
+
amount, // Amount to stake (in token units, e.g., "100")
|
|
71
|
+
delegatee, // Operator or space address
|
|
72
|
+
beneficiary, // Beneficiary address
|
|
73
|
+
}) {
|
|
74
|
+
// 1. Convert amount to proper units
|
|
75
|
+
const amountWei = parseUnits(amount, 18); // Towns token has 18 decimals
|
|
76
|
+
|
|
77
|
+
// 2. Generate unique nonce (you can use timestamp + random)
|
|
78
|
+
const nonce =
|
|
79
|
+
BigInt(Math.floor(Date.now() / 1000)) * 1000000n +
|
|
80
|
+
BigInt(Math.floor(Math.random() * 1000000));
|
|
81
|
+
|
|
82
|
+
// 3. Set deadline (e.g., 10 minutes from now)
|
|
83
|
+
const deadline = BigInt(Math.floor(Date.now() / 1000) + 600);
|
|
84
|
+
|
|
85
|
+
// 4. Create permit data structure
|
|
86
|
+
const permit: PermitTransferFrom = {
|
|
87
|
+
permitted: {
|
|
88
|
+
token: TOWNS_TOKEN_ADDRESS,
|
|
89
|
+
amount: amountWei,
|
|
90
|
+
},
|
|
91
|
+
spender: REWARDS_DISTRIBUTION_ADDRESS,
|
|
92
|
+
nonce: nonce,
|
|
93
|
+
deadline: deadline,
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// 5. Create domain for signing
|
|
97
|
+
const domain = {
|
|
98
|
+
name: "Permit2",
|
|
99
|
+
version: "1",
|
|
100
|
+
chainId: base.id,
|
|
101
|
+
verifyingContract: PERMIT2_ADDRESS as `0x${string}`,
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// 6. Sign the permit
|
|
105
|
+
const signature = await walletClient.signTypedData({
|
|
106
|
+
account,
|
|
107
|
+
domain,
|
|
108
|
+
types: SignatureTransfer.getPermitData(permit, PERMIT2_ADDRESS, base.id)
|
|
109
|
+
.types,
|
|
110
|
+
primaryType: "PermitTransferFrom",
|
|
111
|
+
message: SignatureTransfer.getPermitData(permit, PERMIT2_ADDRESS, base.id)
|
|
112
|
+
.values,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// 7. Call permitAndStake
|
|
116
|
+
const txHash = await walletClient.writeContract({
|
|
117
|
+
address: REWARDS_DISTRIBUTION_ADDRESS,
|
|
118
|
+
abi: [
|
|
119
|
+
{
|
|
120
|
+
name: "permitAndStake",
|
|
121
|
+
type: "function",
|
|
122
|
+
inputs: [
|
|
123
|
+
{ name: "amount", type: "uint96" },
|
|
124
|
+
{ name: "delegatee", type: "address" },
|
|
125
|
+
{ name: "beneficiary", type: "address" },
|
|
126
|
+
{ name: "nonce", type: "uint256" },
|
|
127
|
+
{ name: "deadline", type: "uint256" },
|
|
128
|
+
{ name: "signature", type: "bytes" },
|
|
129
|
+
],
|
|
130
|
+
outputs: [{ name: "depositId", type: "uint256" }],
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
functionName: "permitAndStake",
|
|
134
|
+
args: [amountWei, delegatee, beneficiary, nonce, deadline, signature],
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
return txHash;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Usage example
|
|
141
|
+
async function main() {
|
|
142
|
+
const txHash = await permitAndStake({
|
|
143
|
+
amount: "100", // Stake 100 Towns tokens
|
|
144
|
+
delegatee: "0x123...", // Operator address
|
|
145
|
+
beneficiary: "0x456...", // Beneficiary address
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
console.log("Transaction hash:", txHash);
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### Wallet Integration (MetaMask/WalletConnect)
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { useAccount, useSignTypedData, useWriteContract } from 'wagmi';
|
|
156
|
+
|
|
157
|
+
function StakeWithPermit() {
|
|
158
|
+
const { address } = useAccount();
|
|
159
|
+
const { signTypedDataAsync } = useSignTypedData();
|
|
160
|
+
const { writeContractAsync } = useWriteContract();
|
|
161
|
+
|
|
162
|
+
const handleStakeWithPermit = async (amount: string, delegatee: string) => {
|
|
163
|
+
try {
|
|
164
|
+
// Prepare permit data
|
|
165
|
+
const amountWei = parseUnits(amount, 18);
|
|
166
|
+
const nonce = BigInt(Date.now());
|
|
167
|
+
const deadline = BigInt(Math.floor(Date.now() / 1000) + 600);
|
|
168
|
+
|
|
169
|
+
const permit = {
|
|
170
|
+
permitted: {
|
|
171
|
+
token: TOWNS_TOKEN_ADDRESS,
|
|
172
|
+
amount: amountWei,
|
|
173
|
+
},
|
|
174
|
+
spender: REWARDS_DISTRIBUTION_ADDRESS,
|
|
175
|
+
nonce,
|
|
176
|
+
deadline,
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// Sign permit
|
|
180
|
+
const signature = await signTypedDataAsync({
|
|
181
|
+
domain: {
|
|
182
|
+
name: 'Permit2',
|
|
183
|
+
version: '1',
|
|
184
|
+
chainId: base.id,
|
|
185
|
+
verifyingContract: PERMIT2_ADDRESS,
|
|
186
|
+
},
|
|
187
|
+
types: SignatureTransfer.getPermitData(permit, PERMIT2_ADDRESS, base.id).types,
|
|
188
|
+
primaryType: 'PermitTransferFrom',
|
|
189
|
+
message: SignatureTransfer.getPermitData(permit, PERMIT2_ADDRESS, base.id).values,
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Execute stake
|
|
193
|
+
const txHash = await writeContractAsync({
|
|
194
|
+
address: REWARDS_DISTRIBUTION_ADDRESS,
|
|
195
|
+
abi: rewardsDistributionAbi,
|
|
196
|
+
functionName: 'permitAndStake',
|
|
197
|
+
args: [amountWei, delegatee, address, nonce, deadline, signature]
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
console.log('Staking successful:', txHash);
|
|
201
|
+
} catch (error) {
|
|
202
|
+
console.error('Staking failed:', error);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
return (
|
|
207
|
+
<button onClick={() => handleStakeWithPermit("100", "0x...")}>
|
|
208
|
+
Stake with Permit
|
|
209
|
+
</button>
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Security Considerations
|
|
215
|
+
|
|
216
|
+
### 1. Nonce Management
|
|
217
|
+
|
|
218
|
+
- **Uniqueness**: Each permit must use a unique nonce
|
|
219
|
+
- **Collision Prevention**: Use timestamp-based or incrementing nonces
|
|
220
|
+
- **Replay Protection**: Never reuse nonces
|
|
221
|
+
|
|
222
|
+
### 2. Deadline Validation
|
|
223
|
+
|
|
224
|
+
- **Short Expiry**: Use reasonable deadlines (5-30 minutes)
|
|
225
|
+
- **Clock Skew**: Account for minor time differences between client and blockchain
|
|
226
|
+
|
|
227
|
+
### 3. Signature Security
|
|
228
|
+
|
|
229
|
+
- **Private Key Protection**: Never expose private keys in frontend code
|
|
230
|
+
- **Secure Signing**: Use hardware wallets or secure key management for production
|
|
231
|
+
- **Verification**: Always verify signature validity before submission
|
|
232
|
+
|
|
233
|
+
### 4. Front-running Protection
|
|
234
|
+
|
|
235
|
+
The permit signature cryptographically binds to `msg.sender`, preventing front-running attacks. An attacker cannot use someone else's signature because verification will fail.
|
|
236
|
+
|
|
237
|
+
## Error Handling
|
|
238
|
+
|
|
239
|
+
Common errors and solutions:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
try {
|
|
243
|
+
const txHash = await permitAndStake(...);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
if (error.message.includes('InvalidSignature')) {
|
|
246
|
+
// Signature verification failed - check signing process
|
|
247
|
+
console.error('Invalid permit signature');
|
|
248
|
+
} else if (error.message.includes('ExpiredDeadline')) {
|
|
249
|
+
// Deadline passed - generate new permit
|
|
250
|
+
console.error('Permit expired, please try again');
|
|
251
|
+
} else if (error.message.includes('InvalidNonce')) {
|
|
252
|
+
// Nonce already used or invalid
|
|
253
|
+
console.error('Invalid nonce, generate a new one');
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Best Practices
|
|
259
|
+
|
|
260
|
+
1. **Gas Optimization**: Batch multiple operations when possible
|
|
261
|
+
2. **User Experience**: Show clear signing prompts explaining what users are approving
|
|
262
|
+
3. **Error Messages**: Provide user-friendly error messages
|
|
263
|
+
4. **Fallback**: Offer traditional `approve` + `stake` flow as backup
|
|
264
|
+
5. **Testing**: Test with different wallet types (EOA, smart contract wallets)
|
|
265
|
+
|
|
266
|
+
This integration enables gasless token approvals and enhanced compatibility with smart contract wallets, providing a superior user experience for staking in the Towns Protocol.
|