@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,237 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
// interfaces
|
|
5
|
+
import {IEntitlementChecker} from "./IEntitlementChecker.sol";
|
|
6
|
+
import {IEntitlementGatedBase} from "src/spaces/facets/gated/IEntitlementGated.sol";
|
|
7
|
+
|
|
8
|
+
// libraries
|
|
9
|
+
|
|
10
|
+
import {EntitlementCheckerStorage} from "./EntitlementCheckerStorage.sol";
|
|
11
|
+
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
|
12
|
+
import {NodeOperatorStatus, NodeOperatorStorage} from "src/base/registry/facets/operator/NodeOperatorStorage.sol";
|
|
13
|
+
import {XChainLib} from "src/base/registry/facets/xchain/XChainLib.sol";
|
|
14
|
+
import {CustomRevert} from "src/utils/libraries/CustomRevert.sol";
|
|
15
|
+
|
|
16
|
+
// contracts
|
|
17
|
+
import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
|
|
18
|
+
|
|
19
|
+
contract EntitlementChecker is IEntitlementChecker, Facet {
|
|
20
|
+
using EnumerableSet for EnumerableSet.AddressSet;
|
|
21
|
+
using EnumerableSet for EnumerableSet.UintSet;
|
|
22
|
+
using EnumerableSet for EnumerableSet.Bytes32Set;
|
|
23
|
+
using CustomRevert for bytes4;
|
|
24
|
+
|
|
25
|
+
// =============================================================
|
|
26
|
+
// Initializer
|
|
27
|
+
// =============================================================
|
|
28
|
+
|
|
29
|
+
function __EntitlementChecker_init() external onlyInitializing {
|
|
30
|
+
_addInterface(type(IEntitlementChecker).interfaceId);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// =============================================================
|
|
34
|
+
// Modifiers
|
|
35
|
+
// =============================================================
|
|
36
|
+
modifier onlyNodeOperator(address node, address operator) {
|
|
37
|
+
EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
|
|
38
|
+
|
|
39
|
+
if (layout.operatorByNode[node] != operator) {
|
|
40
|
+
EntitlementChecker_InvalidNodeOperator.selector.revertWith();
|
|
41
|
+
}
|
|
42
|
+
_;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
modifier onlyRegisteredApprovedOperator() {
|
|
46
|
+
NodeOperatorStorage.Layout storage nodeOperatorLayout = NodeOperatorStorage.layout();
|
|
47
|
+
|
|
48
|
+
if (!nodeOperatorLayout.operators.contains(msg.sender)) {
|
|
49
|
+
EntitlementChecker_InvalidOperator.selector.revertWith();
|
|
50
|
+
}
|
|
51
|
+
_;
|
|
52
|
+
|
|
53
|
+
if (nodeOperatorLayout.statusByOperator[msg.sender] != NodeOperatorStatus.Approved) {
|
|
54
|
+
EntitlementChecker_OperatorNotActive.selector.revertWith();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// =============================================================
|
|
59
|
+
// External
|
|
60
|
+
// =============================================================
|
|
61
|
+
|
|
62
|
+
/// @inheritdoc IEntitlementChecker
|
|
63
|
+
function registerNode(address node) external onlyRegisteredApprovedOperator {
|
|
64
|
+
EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
|
|
65
|
+
|
|
66
|
+
if (layout.nodes.contains(node)) {
|
|
67
|
+
EntitlementChecker_NodeAlreadyRegistered.selector.revertWith();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
layout.nodes.add(node);
|
|
71
|
+
layout.operatorByNode[node] = msg.sender;
|
|
72
|
+
|
|
73
|
+
emit NodeRegistered(node);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// @inheritdoc IEntitlementChecker
|
|
77
|
+
function unregisterNode(address node) external onlyNodeOperator(node, msg.sender) {
|
|
78
|
+
EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
|
|
79
|
+
|
|
80
|
+
if (!layout.nodes.contains(node)) {
|
|
81
|
+
EntitlementChecker_NodeNotRegistered.selector.revertWith();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
layout.nodes.remove(node);
|
|
85
|
+
delete layout.operatorByNode[node];
|
|
86
|
+
|
|
87
|
+
emit NodeUnregistered(node);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/// @inheritdoc IEntitlementChecker
|
|
91
|
+
function isValidNode(address node) external view returns (bool) {
|
|
92
|
+
EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
|
|
93
|
+
return layout.nodes.contains(node);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/// @inheritdoc IEntitlementChecker
|
|
97
|
+
function getNodeCount() external view returns (uint256) {
|
|
98
|
+
EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
|
|
99
|
+
return layout.nodes.length();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/// @inheritdoc IEntitlementChecker
|
|
103
|
+
function getNodeAtIndex(uint256 index) external view returns (address) {
|
|
104
|
+
EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
|
|
105
|
+
|
|
106
|
+
require(index < layout.nodes.length(), "Index out of bounds");
|
|
107
|
+
return layout.nodes.at(index);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/// @inheritdoc IEntitlementChecker
|
|
111
|
+
function getRandomNodes(uint256 count) external view returns (address[] memory) {
|
|
112
|
+
return _getRandomNodes(count);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/// @inheritdoc IEntitlementChecker
|
|
116
|
+
function requestEntitlementCheck(
|
|
117
|
+
address walletAddress,
|
|
118
|
+
bytes32 transactionId,
|
|
119
|
+
uint256 roleId,
|
|
120
|
+
address[] memory nodes
|
|
121
|
+
) external {
|
|
122
|
+
emit EntitlementCheckRequested(walletAddress, msg.sender, transactionId, roleId, nodes);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/// @inheritdoc IEntitlementChecker
|
|
126
|
+
function requestEntitlementCheckV2(
|
|
127
|
+
address walletAddress,
|
|
128
|
+
bytes32 transactionId,
|
|
129
|
+
uint256 requestId,
|
|
130
|
+
bytes memory extraData
|
|
131
|
+
) external payable {
|
|
132
|
+
address space = msg.sender;
|
|
133
|
+
address senderAddress = abi.decode(extraData, (address));
|
|
134
|
+
|
|
135
|
+
XChainLib.Layout storage layout = XChainLib.layout();
|
|
136
|
+
|
|
137
|
+
layout.requestsBySender[senderAddress].add(transactionId);
|
|
138
|
+
|
|
139
|
+
// Only create the request if it doesn't exist yet
|
|
140
|
+
XChainLib.Request storage request = layout.requests[transactionId];
|
|
141
|
+
if (request.caller == address(0)) {
|
|
142
|
+
// First time creating this request
|
|
143
|
+
layout.requests[transactionId] = XChainLib.Request({
|
|
144
|
+
caller: space,
|
|
145
|
+
blockNumber: block.number,
|
|
146
|
+
value: msg.value,
|
|
147
|
+
completed: false,
|
|
148
|
+
receiver: walletAddress
|
|
149
|
+
});
|
|
150
|
+
} else {
|
|
151
|
+
if (msg.value != 0) {
|
|
152
|
+
EntitlementChecker_InvalidValue.selector.revertWith();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
address[] memory randomNodes = _getRandomNodes(5);
|
|
157
|
+
|
|
158
|
+
XChainLib.Check storage check = XChainLib.layout().checks[transactionId];
|
|
159
|
+
|
|
160
|
+
check.requestIds.add(requestId);
|
|
161
|
+
|
|
162
|
+
for (uint256 i; i < randomNodes.length; ++i) {
|
|
163
|
+
check.nodes[requestId].add(randomNodes[i]);
|
|
164
|
+
check.votes[requestId].push(
|
|
165
|
+
IEntitlementGatedBase.NodeVote({
|
|
166
|
+
node: randomNodes[i],
|
|
167
|
+
vote: IEntitlementGatedBase.NodeVoteStatus.NOT_VOTED
|
|
168
|
+
})
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
emit EntitlementCheckRequestedV2(
|
|
173
|
+
walletAddress,
|
|
174
|
+
space,
|
|
175
|
+
address(this),
|
|
176
|
+
transactionId,
|
|
177
|
+
requestId,
|
|
178
|
+
randomNodes
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/// @inheritdoc IEntitlementChecker
|
|
183
|
+
function getNodesByOperator(address operator) external view returns (address[] memory nodes) {
|
|
184
|
+
EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
|
|
185
|
+
uint256 totalNodeCount = layout.nodes.length();
|
|
186
|
+
nodes = new address[](totalNodeCount);
|
|
187
|
+
uint256 nodeCount;
|
|
188
|
+
for (uint256 i; i < totalNodeCount; ++i) {
|
|
189
|
+
address node = layout.nodes.at(i);
|
|
190
|
+
if (layout.operatorByNode[node] == operator) {
|
|
191
|
+
unchecked {
|
|
192
|
+
nodes[nodeCount++] = node;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
assembly ("memory-safe") {
|
|
197
|
+
mstore(nodes, nodeCount) // Update the length of the array
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// =============================================================
|
|
202
|
+
// Internal
|
|
203
|
+
// =============================================================
|
|
204
|
+
function _getRandomNodes(uint256 count) internal view returns (address[] memory randomNodes) {
|
|
205
|
+
EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
|
|
206
|
+
|
|
207
|
+
uint256 nodeCount = layout.nodes.length();
|
|
208
|
+
|
|
209
|
+
if (count > nodeCount) {
|
|
210
|
+
EntitlementChecker_InsufficientNumberOfNodes.selector.revertWith();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
randomNodes = new address[](count);
|
|
214
|
+
uint256[] memory indices = new uint256[](nodeCount);
|
|
215
|
+
|
|
216
|
+
for (uint256 i; i < nodeCount; ++i) {
|
|
217
|
+
indices[i] = i;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
unchecked {
|
|
221
|
+
for (uint256 i; i < count; ++i) {
|
|
222
|
+
// Adjust random function to generate within range 0 to n-1
|
|
223
|
+
uint256 rand = _pseudoRandom(i, nodeCount);
|
|
224
|
+
randomNodes[i] = layout.nodes.at(indices[rand]);
|
|
225
|
+
// Move the last element to the used slot and reduce the pool size
|
|
226
|
+
indices[rand] = indices[--nodeCount];
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Generate a pseudo-random index based on a seed and the node count
|
|
232
|
+
function _pseudoRandom(uint256 seed, uint256 nodeCount) internal view returns (uint256) {
|
|
233
|
+
return
|
|
234
|
+
uint256(keccak256(abi.encode(block.prevrandao, block.timestamp, seed, msg.sender))) %
|
|
235
|
+
nodeCount;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
// interfaces
|
|
5
|
+
|
|
6
|
+
// libraries
|
|
7
|
+
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
|
8
|
+
|
|
9
|
+
// contracts
|
|
10
|
+
|
|
11
|
+
library EntitlementCheckerStorage {
|
|
12
|
+
// keccak256(abi.encode(uint256(keccak256("facets.entitlement.checker.storage")) - 1)) &
|
|
13
|
+
// ~bytes32(uint256(0xff))
|
|
14
|
+
bytes32 internal constant STORAGE_SLOT =
|
|
15
|
+
0x180c1d0b9e5eeea9f2f078bc2712cd77acc6afea03b37705abe96dda6f602600;
|
|
16
|
+
|
|
17
|
+
struct Layout {
|
|
18
|
+
EnumerableSet.AddressSet nodes;
|
|
19
|
+
mapping(address node => address operator) operatorByNode;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function layout() internal pure returns (Layout storage l) {
|
|
23
|
+
bytes32 slot = STORAGE_SLOT;
|
|
24
|
+
assembly {
|
|
25
|
+
l.slot := slot
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
interface IEntitlementCheckerBase {
|
|
5
|
+
error EntitlementChecker_NodeAlreadyRegistered();
|
|
6
|
+
error EntitlementChecker_NodeNotRegistered();
|
|
7
|
+
error EntitlementChecker_InsufficientNumberOfNodes();
|
|
8
|
+
error EntitlementChecker_InvalidNodeOperator();
|
|
9
|
+
error EntitlementChecker_InvalidOperator();
|
|
10
|
+
error EntitlementChecker_OperatorNotActive();
|
|
11
|
+
error EntitlementChecker_NoPendingRequests();
|
|
12
|
+
error EntitlementChecker_InsufficientFunds();
|
|
13
|
+
error EntitlementChecker_NoRefundsAvailable();
|
|
14
|
+
error EntitlementChecker_InvalidValue();
|
|
15
|
+
|
|
16
|
+
// Events
|
|
17
|
+
event NodeRegistered(address indexed nodeAddress);
|
|
18
|
+
event NodeUnregistered(address indexed nodeAddress);
|
|
19
|
+
|
|
20
|
+
/// @notice Event emitted when an entitlement check is requested
|
|
21
|
+
event EntitlementCheckRequested(
|
|
22
|
+
address callerAddress,
|
|
23
|
+
address contractAddress,
|
|
24
|
+
bytes32 transactionId,
|
|
25
|
+
uint256 roleId,
|
|
26
|
+
address[] selectedNodes
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
event EntitlementCheckRequestedV2(
|
|
30
|
+
address walletAddress,
|
|
31
|
+
address spaceAddress,
|
|
32
|
+
address resolverAddress,
|
|
33
|
+
bytes32 transactionId,
|
|
34
|
+
uint256 roleId,
|
|
35
|
+
address[] selectedNodes
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface IEntitlementChecker is IEntitlementCheckerBase {
|
|
40
|
+
/// @notice Register a new node in the system
|
|
41
|
+
/// @param node The address of the node to register
|
|
42
|
+
function registerNode(address node) external;
|
|
43
|
+
|
|
44
|
+
/// @notice Unregister an existing node from the system
|
|
45
|
+
/// @param node The address of the node to unregister
|
|
46
|
+
function unregisterNode(address node) external;
|
|
47
|
+
|
|
48
|
+
/// @notice Check if a node address is registered and valid
|
|
49
|
+
/// @param node The address of the node to check
|
|
50
|
+
/// @return bool True if the node is valid, false otherwise
|
|
51
|
+
function isValidNode(address node) external view returns (bool);
|
|
52
|
+
|
|
53
|
+
/// @notice Get the total number of registered nodes
|
|
54
|
+
/// @return uint256 The count of registered nodes
|
|
55
|
+
function getNodeCount() external view returns (uint256);
|
|
56
|
+
|
|
57
|
+
/// @notice Get the node address at a specific index
|
|
58
|
+
/// @param index The index of the node to retrieve
|
|
59
|
+
/// @return address The address of the node at the given index
|
|
60
|
+
function getNodeAtIndex(uint256 index) external view returns (address);
|
|
61
|
+
|
|
62
|
+
/// @notice Get a random selection of registered nodes
|
|
63
|
+
/// @param count The number of random nodes to return
|
|
64
|
+
/// @return address[] Array of randomly selected node addresses
|
|
65
|
+
function getRandomNodes(uint256 count) external view returns (address[] memory);
|
|
66
|
+
|
|
67
|
+
/// @notice Request an entitlement check for a transaction
|
|
68
|
+
/// @param callerAddress The address initiating the check
|
|
69
|
+
/// @param transactionId The unique identifier of the transaction
|
|
70
|
+
/// @param roleId The role ID to check entitlements against
|
|
71
|
+
/// @param nodes Array of node addresses that will perform the check
|
|
72
|
+
function requestEntitlementCheck(
|
|
73
|
+
address callerAddress,
|
|
74
|
+
bytes32 transactionId,
|
|
75
|
+
uint256 roleId,
|
|
76
|
+
address[] memory nodes
|
|
77
|
+
) external;
|
|
78
|
+
|
|
79
|
+
/// @notice Request an entitlement check with additional data (V2)
|
|
80
|
+
/// @param walletAddress The wallet address to check entitlements for
|
|
81
|
+
/// @param transactionId The unique identifier of the transaction
|
|
82
|
+
/// @param requestId The unique identifier for this specific request
|
|
83
|
+
/// @param extraData Additional data required for the check
|
|
84
|
+
function requestEntitlementCheckV2(
|
|
85
|
+
address walletAddress,
|
|
86
|
+
bytes32 transactionId,
|
|
87
|
+
uint256 requestId,
|
|
88
|
+
bytes memory extraData
|
|
89
|
+
) external payable;
|
|
90
|
+
|
|
91
|
+
/// @notice Get all nodes registered to a specific operator
|
|
92
|
+
/// @param operator The address of the operator
|
|
93
|
+
/// @return address[] Array of node addresses registered to the operator
|
|
94
|
+
function getNodesByOperator(address operator) external view returns (address[] memory);
|
|
95
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
interface ISpaceDelegationBase {
|
|
5
|
+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
|
|
6
|
+
/* ERRORS */
|
|
7
|
+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
|
|
8
|
+
|
|
9
|
+
error SpaceDelegation__InvalidAddress();
|
|
10
|
+
error SpaceDelegation__InvalidOperator();
|
|
11
|
+
error SpaceDelegation__InvalidSpace();
|
|
12
|
+
error SpaceDelegation__NotSpaceOwner();
|
|
13
|
+
error SpaceDelegation__NotSpaceMember();
|
|
14
|
+
error SpaceDelegation__AlreadyDelegated(address operator);
|
|
15
|
+
error SpaceDelegation__NotDelegated();
|
|
16
|
+
error SpaceDelegation__InvalidStakeRequirement();
|
|
17
|
+
|
|
18
|
+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
|
|
19
|
+
/* EVENTS */
|
|
20
|
+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
|
|
21
|
+
|
|
22
|
+
event SpaceDelegatedToOperator(address indexed space, address indexed operator);
|
|
23
|
+
event RiverTokenChanged(address indexed riverToken);
|
|
24
|
+
event SpaceFactoryChanged(address indexed spaceFactory);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface ISpaceDelegation is ISpaceDelegationBase {
|
|
28
|
+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
|
|
29
|
+
/* DELEGATION */
|
|
30
|
+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
|
|
31
|
+
|
|
32
|
+
/// @notice Adds a space delegation to an operator
|
|
33
|
+
/// @param space The address of the space
|
|
34
|
+
/// @param operator The address of the operator
|
|
35
|
+
function addSpaceDelegation(address space, address operator) external;
|
|
36
|
+
|
|
37
|
+
/// @notice Removes a space delegation from an operator
|
|
38
|
+
/// @param space The address of the space
|
|
39
|
+
function removeSpaceDelegation(address space) external;
|
|
40
|
+
|
|
41
|
+
/// @notice Gets the operator address for a given space
|
|
42
|
+
/// @param space The address of the space
|
|
43
|
+
/// @return The address of the operator delegated to the space
|
|
44
|
+
function getSpaceDelegation(address space) external view returns (address);
|
|
45
|
+
|
|
46
|
+
/// @notice Gets all spaces delegated to a specific operator
|
|
47
|
+
/// @param operator The address of the operator
|
|
48
|
+
/// @return An array of space addresses delegated to the operator
|
|
49
|
+
function getSpaceDelegationsByOperator(
|
|
50
|
+
address operator
|
|
51
|
+
) external view returns (address[] memory);
|
|
52
|
+
|
|
53
|
+
/// @notice Gets the total delegation for a specific operator
|
|
54
|
+
/// @param operator The address of the operator
|
|
55
|
+
/// @return The total amount delegated to the operator
|
|
56
|
+
function getTotalDelegation(address operator) external view returns (uint256);
|
|
57
|
+
|
|
58
|
+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
|
|
59
|
+
/* FACTORY */
|
|
60
|
+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
|
|
61
|
+
|
|
62
|
+
/// @notice Sets the address of the space factory
|
|
63
|
+
/// @param spaceFactory The address of the space factory
|
|
64
|
+
function setSpaceFactory(address spaceFactory) external;
|
|
65
|
+
|
|
66
|
+
/// @notice Gets the address of the space factory
|
|
67
|
+
/// @return The address of the space factory
|
|
68
|
+
function getSpaceFactory() external view returns (address);
|
|
69
|
+
}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
// interfaces
|
|
5
|
+
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
6
|
+
import {IERC173} from "@towns-protocol/diamond/src/facets/ownable/IERC173.sol";
|
|
7
|
+
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
|
|
8
|
+
import {IArchitect} from "../../../../factory/facets/architect/IArchitect.sol";
|
|
9
|
+
import {IVotesEnumerable} from "../../../../diamond/facets/governance/votes/enumerable/IVotesEnumerable.sol";
|
|
10
|
+
import {IMainnetDelegation} from "../mainnet/IMainnetDelegation.sol";
|
|
11
|
+
import {IRewardsDistributionBase} from "../distribution/v2/IRewardsDistribution.sol";
|
|
12
|
+
import {ISpaceDelegation} from "./ISpaceDelegation.sol";
|
|
13
|
+
|
|
14
|
+
// libraries
|
|
15
|
+
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
|
16
|
+
import {CustomRevert} from "../../../../utils/libraries/CustomRevert.sol";
|
|
17
|
+
import {NodeOperatorStatus, NodeOperatorStorage} from "../operator/NodeOperatorStorage.sol";
|
|
18
|
+
import {RewardsDistributionStorage} from "../distribution/v2/RewardsDistributionStorage.sol";
|
|
19
|
+
import {StakingRewards} from "../distribution/v2/StakingRewards.sol";
|
|
20
|
+
import {SpaceDelegationStorage} from "./SpaceDelegationStorage.sol";
|
|
21
|
+
|
|
22
|
+
// contracts
|
|
23
|
+
import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
|
|
24
|
+
import {OwnableBase} from "@towns-protocol/diamond/src/facets/ownable/OwnableBase.sol";
|
|
25
|
+
|
|
26
|
+
contract SpaceDelegationFacet is ISpaceDelegation, OwnableBase, Facet {
|
|
27
|
+
using EnumerableSet for EnumerableSet.AddressSet;
|
|
28
|
+
using StakingRewards for StakingRewards.Layout;
|
|
29
|
+
using CustomRevert for bytes4;
|
|
30
|
+
|
|
31
|
+
modifier onlySpaceOwner(address space) {
|
|
32
|
+
if (!_isValidSpace(space)) SpaceDelegation__InvalidSpace.selector.revertWith();
|
|
33
|
+
if (!_isValidSpaceOwner(space)) SpaceDelegation__NotSpaceOwner.selector.revertWith();
|
|
34
|
+
_;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
|
|
38
|
+
/* DELEGATION */
|
|
39
|
+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @inheritdoc ISpaceDelegation
|
|
43
|
+
* @dev Delegates a space to a node operator for reward distribution.
|
|
44
|
+
* Authorization logic:
|
|
45
|
+
* - Only space members can delegate a space that has never been delegated
|
|
46
|
+
* - Only the space owner can delegate/redelegate once the space has been delegated before
|
|
47
|
+
*
|
|
48
|
+
* Process:
|
|
49
|
+
* 1. Validates operator address and space existence
|
|
50
|
+
* 2. Checks operator is registered and not exiting
|
|
51
|
+
* 3. Validates caller is member (for never delegated) or owner (for previously delegated)
|
|
52
|
+
* 4. Sweeps any pending rewards from previous delegation
|
|
53
|
+
* 5. Updates storage mappings and delegation timestamp
|
|
54
|
+
* 6. Emits SpaceDelegatedToOperator event
|
|
55
|
+
*/
|
|
56
|
+
function addSpaceDelegation(address space, address operator) external {
|
|
57
|
+
if (operator == address(0)) SpaceDelegation__InvalidAddress.selector.revertWith();
|
|
58
|
+
|
|
59
|
+
// validate that the space exists
|
|
60
|
+
if (!_isValidSpace(space)) SpaceDelegation__InvalidSpace.selector.revertWith();
|
|
61
|
+
|
|
62
|
+
SpaceDelegationStorage.Layout storage ds = SpaceDelegationStorage.layout();
|
|
63
|
+
|
|
64
|
+
address currentOperator = ds.operatorBySpace[space];
|
|
65
|
+
|
|
66
|
+
if (currentOperator == operator) SpaceDelegation__AlreadyDelegated.selector.revertWith();
|
|
67
|
+
|
|
68
|
+
// Authorization logic: only members can delegate if space has never been delegated,
|
|
69
|
+
// only owner can delegate/redelegate if space has been delegated before (even if removed)
|
|
70
|
+
if (ds.spaceDelegationTime[space] != 0) {
|
|
71
|
+
// space has been delegated before (even if currently removed), only owner can delegate
|
|
72
|
+
if (!_isValidSpaceOwner(space)) SpaceDelegation__NotSpaceOwner.selector.revertWith();
|
|
73
|
+
} else {
|
|
74
|
+
// Space has never been delegated, only members can delegate
|
|
75
|
+
if (!_isValidSpaceMember(space)) SpaceDelegation__NotSpaceMember.selector.revertWith();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
NodeOperatorStorage.Layout storage nodeOperatorDs = NodeOperatorStorage.layout();
|
|
79
|
+
|
|
80
|
+
// check if the operator is valid
|
|
81
|
+
if (!nodeOperatorDs.operators.contains(operator))
|
|
82
|
+
SpaceDelegation__InvalidOperator.selector.revertWith();
|
|
83
|
+
|
|
84
|
+
// check if operator is not exiting
|
|
85
|
+
if (nodeOperatorDs.statusByOperator[operator] == NodeOperatorStatus.Exiting)
|
|
86
|
+
SpaceDelegation__InvalidOperator.selector.revertWith();
|
|
87
|
+
|
|
88
|
+
_sweepSpaceRewardsIfNecessary(space, currentOperator);
|
|
89
|
+
|
|
90
|
+
// remove the space from the current operator
|
|
91
|
+
ds.spacesByOperator[currentOperator].remove(space);
|
|
92
|
+
|
|
93
|
+
// overwrite the operator for this space
|
|
94
|
+
ds.operatorBySpace[space] = operator;
|
|
95
|
+
|
|
96
|
+
// add the space to this new operator array
|
|
97
|
+
ds.spacesByOperator[operator].add(space);
|
|
98
|
+
ds.spaceDelegationTime[space] = block.timestamp;
|
|
99
|
+
|
|
100
|
+
emit SpaceDelegatedToOperator(space, operator);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @inheritdoc ISpaceDelegation
|
|
105
|
+
* @dev Removes delegation from a space, returning it to an undelegated state.
|
|
106
|
+
* Only the space owner can call this function.
|
|
107
|
+
* Note: The delegation timestamp is preserved to maintain history that the space
|
|
108
|
+
* was delegated before, ensuring only the owner can redelegate.
|
|
109
|
+
*
|
|
110
|
+
* Process:
|
|
111
|
+
* 1. Validates space address and delegation existence
|
|
112
|
+
* 2. Sweeps any pending rewards to the current operator
|
|
113
|
+
* 3. Clears operator mappings but preserves delegation timestamp
|
|
114
|
+
* 4. Emits SpaceDelegatedToOperator event with address(0)
|
|
115
|
+
*/
|
|
116
|
+
function removeSpaceDelegation(address space) external onlySpaceOwner(space) {
|
|
117
|
+
if (space == address(0)) SpaceDelegation__InvalidAddress.selector.revertWith();
|
|
118
|
+
|
|
119
|
+
SpaceDelegationStorage.Layout storage ds = SpaceDelegationStorage.layout();
|
|
120
|
+
|
|
121
|
+
address operator = ds.operatorBySpace[space];
|
|
122
|
+
|
|
123
|
+
if (operator == address(0)) SpaceDelegation__NotDelegated.selector.revertWith();
|
|
124
|
+
|
|
125
|
+
_sweepSpaceRewardsIfNecessary(space, operator);
|
|
126
|
+
|
|
127
|
+
ds.operatorBySpace[space] = address(0);
|
|
128
|
+
ds.spacesByOperator[operator].remove(space);
|
|
129
|
+
// don't reset spaceDelegationTime to preserve delegation history
|
|
130
|
+
|
|
131
|
+
emit SpaceDelegatedToOperator(space, address(0));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/// @inheritdoc ISpaceDelegation
|
|
135
|
+
function getSpaceDelegation(address space) external view returns (address) {
|
|
136
|
+
return SpaceDelegationStorage.layout().operatorBySpace[space];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/// @inheritdoc ISpaceDelegation
|
|
140
|
+
function getSpaceDelegationsByOperator(
|
|
141
|
+
address operator
|
|
142
|
+
) external view returns (address[] memory) {
|
|
143
|
+
return SpaceDelegationStorage.layout().spacesByOperator[operator].values();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/// @inheritdoc ISpaceDelegation
|
|
147
|
+
function getTotalDelegation(address operator) external view returns (uint256) {
|
|
148
|
+
return _getTotalDelegation(operator);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
|
|
152
|
+
/* FACTORY */
|
|
153
|
+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
|
|
154
|
+
|
|
155
|
+
/// @inheritdoc ISpaceDelegation
|
|
156
|
+
function setSpaceFactory(address spaceFactory) external onlyOwner {
|
|
157
|
+
if (spaceFactory == address(0)) SpaceDelegation__InvalidAddress.selector.revertWith();
|
|
158
|
+
|
|
159
|
+
SpaceDelegationStorage.layout().spaceFactory = spaceFactory;
|
|
160
|
+
emit SpaceFactoryChanged(spaceFactory);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/// @inheritdoc ISpaceDelegation
|
|
164
|
+
function getSpaceFactory() public view returns (address) {
|
|
165
|
+
return SpaceDelegationStorage.layout().spaceFactory;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
|
|
169
|
+
/* INTERNAL */
|
|
170
|
+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
|
|
171
|
+
|
|
172
|
+
/// @dev Sweeps the rewards in the space delegation to the operator if necessary
|
|
173
|
+
/// @dev Handles two scenarios:
|
|
174
|
+
/// 1. If currentOperator exists: transfers accumulated rewards to the current operator
|
|
175
|
+
/// (rewards earned while the space was delegated to them)
|
|
176
|
+
/// 2. If no currentOperator: forfeits accumulated rewards (clears unallocated rewards from
|
|
177
|
+
/// existing stakes after undelegation that shouldn't go to a new operator)
|
|
178
|
+
/// @param space The space address to sweep rewards from
|
|
179
|
+
/// @param currentOperator The current operator (address(0) if undelegated)
|
|
180
|
+
function _sweepSpaceRewardsIfNecessary(address space, address currentOperator) internal {
|
|
181
|
+
StakingRewards.Layout storage staking = RewardsDistributionStorage.layout().staking;
|
|
182
|
+
|
|
183
|
+
uint256 reward;
|
|
184
|
+
if (currentOperator != address(0)) {
|
|
185
|
+
// transfer rewards from space to current operator
|
|
186
|
+
reward = staking.transferReward(space, currentOperator);
|
|
187
|
+
} else {
|
|
188
|
+
// forfeit rewards (clear without transfer)
|
|
189
|
+
reward = staking.sweepReward(space);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (reward != 0) {
|
|
193
|
+
emit IRewardsDistributionBase.SpaceRewardsSwept(space, currentOperator, reward);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function _getTotalDelegation(address operator) internal view returns (uint256) {
|
|
198
|
+
SpaceDelegationStorage.Layout storage ds = SpaceDelegationStorage.layout();
|
|
199
|
+
(address riverToken_, address mainnetDelegation_) = (ds.riverToken, ds.mainnetDelegation);
|
|
200
|
+
if (riverToken_ == address(0) || mainnetDelegation_ == address(0)) return 0;
|
|
201
|
+
|
|
202
|
+
// get the delegation from the mainnet delegation
|
|
203
|
+
uint256 delegation = IMainnetDelegation(mainnetDelegation_).getDelegatedStakeByOperator(
|
|
204
|
+
operator
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
// get the delegation from the base delegation
|
|
208
|
+
address[] memory baseDelegators = IVotesEnumerable(riverToken_).getDelegatorsByDelegatee(
|
|
209
|
+
operator
|
|
210
|
+
);
|
|
211
|
+
for (uint256 i; i < baseDelegators.length; ++i) {
|
|
212
|
+
delegation += IERC20(riverToken_).balanceOf(baseDelegators[i]);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
address[] memory spaces = ds.spacesByOperator[operator].values();
|
|
216
|
+
|
|
217
|
+
for (uint256 i; i < spaces.length; ++i) {
|
|
218
|
+
address[] memory usersDelegatingToSpace = IVotesEnumerable(riverToken_)
|
|
219
|
+
.getDelegatorsByDelegatee(spaces[i]);
|
|
220
|
+
|
|
221
|
+
for (uint256 j; j < usersDelegatingToSpace.length; ++j) {
|
|
222
|
+
delegation += IERC20(riverToken_).balanceOf(usersDelegatingToSpace[j]);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return delegation;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/// @dev Checks if the space is valid by verifying if it has a nonzero token ID in the factory
|
|
230
|
+
function _isValidSpace(address space) internal view returns (bool) {
|
|
231
|
+
return IArchitect(getSpaceFactory()).getTokenIdBySpace(space) != 0;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/// @dev Checks if the caller is the owner of the space
|
|
235
|
+
/// @dev Assumes that the space is valid
|
|
236
|
+
function _isValidSpaceOwner(address space) internal view returns (bool) {
|
|
237
|
+
return IERC173(space).owner() == msg.sender;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/// @dev Checks if the caller is a member of the space (has at least one membership token)
|
|
241
|
+
/// @dev Also considers the space owner as a member
|
|
242
|
+
/// @dev Assumes that the space is valid
|
|
243
|
+
function _isValidSpaceMember(address space) internal view returns (bool) {
|
|
244
|
+
// Check if caller is the space owner
|
|
245
|
+
if (IERC173(space).owner() == msg.sender) return true;
|
|
246
|
+
|
|
247
|
+
// Check if caller has at least one membership token
|
|
248
|
+
return IERC721(space).balanceOf(msg.sender) != 0;
|
|
249
|
+
}
|
|
250
|
+
}
|