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