@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,273 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.24;
|
|
3
|
+
|
|
4
|
+
// interfaces
|
|
5
|
+
import {IEntitlement} from "../IEntitlement.sol";
|
|
6
|
+
|
|
7
|
+
import {IChannel} from "src/spaces/facets/channels/IChannel.sol";
|
|
8
|
+
import {IRoles} from "src/spaces/facets/roles/IRoles.sol";
|
|
9
|
+
|
|
10
|
+
// libraries
|
|
11
|
+
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
|
12
|
+
|
|
13
|
+
// contracts
|
|
14
|
+
|
|
15
|
+
import {IUserEntitlement} from "./IUserEntitlement.sol";
|
|
16
|
+
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
17
|
+
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
18
|
+
import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
|
|
19
|
+
import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
|
|
20
|
+
|
|
21
|
+
contract UserEntitlement is
|
|
22
|
+
Initializable,
|
|
23
|
+
ERC165Upgradeable,
|
|
24
|
+
ContextUpgradeable,
|
|
25
|
+
UUPSUpgradeable,
|
|
26
|
+
IUserEntitlement
|
|
27
|
+
{
|
|
28
|
+
using EnumerableSet for EnumerableSet.UintSet;
|
|
29
|
+
|
|
30
|
+
address constant EVERYONE_ADDRESS = address(1);
|
|
31
|
+
address public SPACE_ADDRESS;
|
|
32
|
+
|
|
33
|
+
struct Entitlement {
|
|
34
|
+
address grantedBy;
|
|
35
|
+
uint256 grantedTime;
|
|
36
|
+
address[] users;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// @notice mapping holding all the entitlements by RoleId added to Entitlement
|
|
40
|
+
mapping(uint256 => Entitlement) internal entitlementsByRoleId;
|
|
41
|
+
mapping(address => uint256[]) internal roleIdsByUser;
|
|
42
|
+
EnumerableSet.UintSet allEntitlementRoleIds;
|
|
43
|
+
|
|
44
|
+
string public constant name = "User Entitlement";
|
|
45
|
+
string public constant description = "Entitlement for users";
|
|
46
|
+
string public constant moduleType = "UserEntitlement";
|
|
47
|
+
|
|
48
|
+
modifier onlySpace() {
|
|
49
|
+
if (_msgSender() != SPACE_ADDRESS) {
|
|
50
|
+
revert Entitlement__NotAllowed();
|
|
51
|
+
}
|
|
52
|
+
_;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
56
|
+
constructor() {
|
|
57
|
+
_disableInitializers();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function initialize(address _space) public initializer {
|
|
61
|
+
__UUPSUpgradeable_init();
|
|
62
|
+
__ERC165_init();
|
|
63
|
+
__Context_init();
|
|
64
|
+
|
|
65
|
+
SPACE_ADDRESS = _space;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/// @notice allow the contract to be upgraded while retaining state
|
|
69
|
+
/// @param newImplementation address of the new implementation
|
|
70
|
+
function _authorizeUpgrade(address newImplementation) internal override onlySpace {}
|
|
71
|
+
|
|
72
|
+
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
|
|
73
|
+
return
|
|
74
|
+
interfaceId == type(IEntitlement).interfaceId || super.supportsInterface(interfaceId);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// @inheritdoc IEntitlement
|
|
78
|
+
function isCrosschain() external pure override returns (bool) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// @inheritdoc IEntitlement
|
|
83
|
+
function isEntitled(
|
|
84
|
+
bytes32 channelId,
|
|
85
|
+
address[] memory wallets,
|
|
86
|
+
bytes32 permission
|
|
87
|
+
) external view returns (bool) {
|
|
88
|
+
// Check if channelId is not equal to the zero value for bytes32
|
|
89
|
+
if (channelId != bytes32(0)) {
|
|
90
|
+
return _isEntitledToChannel(channelId, wallets, permission);
|
|
91
|
+
} else {
|
|
92
|
+
return _isEntitledToSpace(wallets, permission);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// @inheritdoc IEntitlement
|
|
97
|
+
function setEntitlement(uint256 roleId, bytes calldata entitlementData) external onlySpace {
|
|
98
|
+
address[] memory users = abi.decode(entitlementData, (address[]));
|
|
99
|
+
|
|
100
|
+
for (uint256 i = 0; i < users.length; i++) {
|
|
101
|
+
address user = users[i];
|
|
102
|
+
if (user == address(0)) {
|
|
103
|
+
revert Entitlement__InvalidValue();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// First remove any prior values
|
|
108
|
+
while (entitlementsByRoleId[roleId].users.length > 0) {
|
|
109
|
+
address user = entitlementsByRoleId[roleId].users[
|
|
110
|
+
entitlementsByRoleId[roleId].users.length - 1
|
|
111
|
+
];
|
|
112
|
+
_removeRoleIdFromUser(user, roleId);
|
|
113
|
+
entitlementsByRoleId[roleId].users.pop();
|
|
114
|
+
}
|
|
115
|
+
delete entitlementsByRoleId[roleId];
|
|
116
|
+
|
|
117
|
+
entitlementsByRoleId[roleId] = Entitlement({
|
|
118
|
+
grantedBy: _msgSender(),
|
|
119
|
+
grantedTime: block.timestamp,
|
|
120
|
+
users: users
|
|
121
|
+
});
|
|
122
|
+
for (uint256 i = 0; i < users.length; i++) {
|
|
123
|
+
roleIdsByUser[users[i]].push(roleId);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// @inheritdoc IEntitlement
|
|
128
|
+
function removeEntitlement(uint256 roleId) external onlySpace {
|
|
129
|
+
if (entitlementsByRoleId[roleId].grantedBy == address(0)) {
|
|
130
|
+
revert Entitlement__InvalidValue();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// First remove any prior values
|
|
134
|
+
while (entitlementsByRoleId[roleId].users.length > 0) {
|
|
135
|
+
address user = entitlementsByRoleId[roleId].users[
|
|
136
|
+
entitlementsByRoleId[roleId].users.length - 1
|
|
137
|
+
];
|
|
138
|
+
_removeRoleIdFromUser(user, roleId);
|
|
139
|
+
entitlementsByRoleId[roleId].users.pop();
|
|
140
|
+
}
|
|
141
|
+
delete entitlementsByRoleId[roleId];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// @inheritdoc IEntitlement
|
|
145
|
+
function getEntitlementDataByRoleId(uint256 roleId) external view returns (bytes memory) {
|
|
146
|
+
return abi.encode(entitlementsByRoleId[roleId].users);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/// @notice checks is a user is entitled to a specific channel
|
|
150
|
+
/// @param channelId the channel id
|
|
151
|
+
/// @param wallets the user address who we are checking for
|
|
152
|
+
/// @param permission the permission we are checking for
|
|
153
|
+
/// @return _entitled true if the user is entitled to the channel
|
|
154
|
+
function _isEntitledToChannel(
|
|
155
|
+
bytes32 channelId,
|
|
156
|
+
address[] memory wallets,
|
|
157
|
+
bytes32 permission
|
|
158
|
+
) internal view returns (bool _entitled) {
|
|
159
|
+
IChannel.Channel memory channel = IChannel(SPACE_ADDRESS).getChannel(channelId);
|
|
160
|
+
|
|
161
|
+
// get all the roleids for the user
|
|
162
|
+
uint256[] memory rolesIds = _getRoleIdsByUser(wallets);
|
|
163
|
+
|
|
164
|
+
// loop over all role ids in a channel
|
|
165
|
+
for (uint256 i = 0; i < channel.roleIds.length; i++) {
|
|
166
|
+
// get each role id
|
|
167
|
+
uint256 roleId = channel.roleIds[i];
|
|
168
|
+
|
|
169
|
+
// loop over all the valid entitlements
|
|
170
|
+
for (uint256 j = 0; j < rolesIds.length; j++) {
|
|
171
|
+
// check if the role id for that channel matches the entitlement role id
|
|
172
|
+
// and if the permission matches the role permission
|
|
173
|
+
if (rolesIds[j] == roleId && _validateRolePermission(rolesIds[j], permission)) {
|
|
174
|
+
_entitled = true;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/// @notice gets all the roles given to specific users
|
|
181
|
+
/// @param wallets the array of user addresses
|
|
182
|
+
/// @return roles the array of roles these users have, may include duplicates
|
|
183
|
+
function _getRoleIdsByUser(address[] memory wallets) internal view returns (uint256[] memory) {
|
|
184
|
+
uint256 totalLength = 0;
|
|
185
|
+
|
|
186
|
+
// Calculate total length
|
|
187
|
+
for (uint256 i = 0; i < wallets.length; i++) {
|
|
188
|
+
totalLength += roleIdsByUser[wallets[i]].length;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
totalLength += roleIdsByUser[EVERYONE_ADDRESS].length;
|
|
192
|
+
|
|
193
|
+
// Create an array to hold all roles
|
|
194
|
+
uint256[] memory roles = new uint256[](totalLength);
|
|
195
|
+
uint256 currentIndex = 0;
|
|
196
|
+
|
|
197
|
+
// Populate the roles array
|
|
198
|
+
for (uint256 i = 0; i < wallets.length; i++) {
|
|
199
|
+
uint256[] memory rolesForWallet = roleIdsByUser[wallets[i]];
|
|
200
|
+
for (uint256 j = 0; j < rolesForWallet.length; j++) {
|
|
201
|
+
roles[currentIndex++] = rolesForWallet[j];
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
uint256[] memory rolesForEveryone = roleIdsByUser[EVERYONE_ADDRESS];
|
|
206
|
+
for (uint256 j = 0; j < rolesForEveryone.length; j++) {
|
|
207
|
+
roles[currentIndex++] = rolesForEveryone[j];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return roles;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/// @notice checks if a user is entitled to a specific space
|
|
214
|
+
/// @param wallets the user address
|
|
215
|
+
/// @param permission the permission we are checking for
|
|
216
|
+
/// @return _entitled true if the user is entitled to the space
|
|
217
|
+
function _isEntitledToSpace(
|
|
218
|
+
address[] memory wallets,
|
|
219
|
+
bytes32 permission
|
|
220
|
+
) internal view returns (bool) {
|
|
221
|
+
// get all the roleids for the user
|
|
222
|
+
uint256[] memory rolesIds = _getRoleIdsByUser(wallets);
|
|
223
|
+
|
|
224
|
+
for (uint256 i = 0; i < rolesIds.length; i++) {
|
|
225
|
+
if (_validateRolePermission(rolesIds[i], permission)) {
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/// @notice checks if a role has a specific permission
|
|
234
|
+
/// @param roleId the role id
|
|
235
|
+
/// @param permission the permission we are checking for
|
|
236
|
+
/// @return _hasPermission true if the role has the permission
|
|
237
|
+
function _validateRolePermission(
|
|
238
|
+
uint256 roleId,
|
|
239
|
+
bytes32 permission
|
|
240
|
+
) internal view returns (bool) {
|
|
241
|
+
string[] memory permissions = IRoles(SPACE_ADDRESS).getPermissionsByRoleId(roleId);
|
|
242
|
+
uint256 permissionLen = permissions.length;
|
|
243
|
+
|
|
244
|
+
for (uint256 i = 0; i < permissionLen; i++) {
|
|
245
|
+
bytes32 permissionBytes = bytes32(abi.encodePacked(permissions[i]));
|
|
246
|
+
if (permissionBytes == permission) {
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function _removeRoleIdFromUser(address user, uint256 roleId) internal {
|
|
255
|
+
uint256[] storage roles = roleIdsByUser[user];
|
|
256
|
+
for (uint256 i = 0; i < roles.length; i++) {
|
|
257
|
+
if (roles[i] == roleId) {
|
|
258
|
+
roles[i] = roles[roles.length - 1];
|
|
259
|
+
roles.pop();
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Optional: Revert if the roleId is not found
|
|
265
|
+
revert("Role ID not found for the user");
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* @dev Added to allow future versions to add new variables in case this contract becomes
|
|
270
|
+
* inherited. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
|
|
271
|
+
*/
|
|
272
|
+
uint256[49] private __gap;
|
|
273
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
// interfaces
|
|
5
|
+
import {IAppRegistry} from "../../apps/facets/registry/IAppRegistry.sol";
|
|
6
|
+
import {IImplementationRegistry} from "../../factory/facets/registry/IImplementationRegistry.sol";
|
|
7
|
+
|
|
8
|
+
// libraries
|
|
9
|
+
import {MembershipStorage} from "./membership/MembershipStorage.sol";
|
|
10
|
+
|
|
11
|
+
// contracts
|
|
12
|
+
|
|
13
|
+
/// @title DependencyLib
|
|
14
|
+
/// @dev Library for resolving contract dependencies via the Implementation Registry. Used for
|
|
15
|
+
/// retrieving the latest implementation addresses for named dependencies within a space.
|
|
16
|
+
library DependencyLib {
|
|
17
|
+
// Constants for dependency names
|
|
18
|
+
bytes32 internal constant RIVER_AIRDROP = bytes32("RiverAirdrop");
|
|
19
|
+
bytes32 internal constant SPACE_OPERATOR = bytes32("SpaceOperator"); // BaseRegistry
|
|
20
|
+
bytes32 internal constant SPACE_OWNER = bytes32("Space Owner");
|
|
21
|
+
bytes32 internal constant APP_REGISTRY = bytes32("AppRegistry");
|
|
22
|
+
bytes32 internal constant SWAP_ROUTER = bytes32("SwapRouter");
|
|
23
|
+
|
|
24
|
+
/// @notice Retrieves the latest implementation address for a given dependency name.
|
|
25
|
+
/// @dev Looks up the dependency in the Implementation Registry associated with the space factory.
|
|
26
|
+
/// @param ms The MembershipStorage layout containing the spaceFactory address.
|
|
27
|
+
/// @param dependencyName The keccak256 hash of the dependency name to resolve.
|
|
28
|
+
/// @return The address of the latest implementation for the specified dependency.
|
|
29
|
+
function getDependency(
|
|
30
|
+
MembershipStorage.Layout storage ms,
|
|
31
|
+
bytes32 dependencyName
|
|
32
|
+
) internal view returns (address) {
|
|
33
|
+
IImplementationRegistry registry = IImplementationRegistry(ms.spaceFactory);
|
|
34
|
+
return registry.getLatestImplementation(dependencyName);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/// @notice Retrieves the latest implementation addresses for multiple dependency names.
|
|
38
|
+
/// @dev Batch resolves dependencies using the Implementation Registry associated with the space factory.
|
|
39
|
+
/// @param ms The MembershipStorage layout containing the spaceFactory address.
|
|
40
|
+
/// @param deps An array of keccak256 hashes of dependency names to resolve.
|
|
41
|
+
/// @return dependencies An array of addresses corresponding to the latest implementations for each dependency.
|
|
42
|
+
function getDependencies(
|
|
43
|
+
MembershipStorage.Layout storage ms,
|
|
44
|
+
bytes32[] memory deps
|
|
45
|
+
) internal view returns (address[] memory dependencies) {
|
|
46
|
+
uint256 length = deps.length;
|
|
47
|
+
dependencies = new address[](length);
|
|
48
|
+
IImplementationRegistry registry = IImplementationRegistry(ms.spaceFactory);
|
|
49
|
+
for (uint256 i; i < length; ++i) {
|
|
50
|
+
dependencies[i] = registry.getLatestImplementation(deps[i]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/// @notice Retrieves the latest implementation address for the App Registry dependency.
|
|
55
|
+
/// @dev Convenience method to get the App Registry implementation from the registry.
|
|
56
|
+
/// @return The address of the latest App Registry implementation.
|
|
57
|
+
function getAppRegistry() internal view returns (IAppRegistry) {
|
|
58
|
+
return IAppRegistry(getDependency(MembershipStorage.layout(), APP_REGISTRY));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
// interfaces
|
|
5
|
+
import {IWalletLink} from "../../factory/facets/wallet-link/IWalletLink.sol";
|
|
6
|
+
import {IEntitlement, IEntitlementBase} from "../entitlements/IEntitlement.sol";
|
|
7
|
+
|
|
8
|
+
// libraries
|
|
9
|
+
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
|
10
|
+
import {PausableStorage} from "@towns-protocol/diamond/src/facets/pausable/PausableStorage.sol";
|
|
11
|
+
import {LibSort} from "solady/utils/LibSort.sol";
|
|
12
|
+
import {ERC721AStorage} from "../../diamond/facets/token/ERC721A/ERC721AStorage.sol";
|
|
13
|
+
import {CustomRevert} from "../../utils/libraries/CustomRevert.sol";
|
|
14
|
+
import {EntitlementsManagerStorage} from "./entitlements/EntitlementsManagerStorage.sol";
|
|
15
|
+
import {MembershipStorage} from "./membership/MembershipStorage.sol";
|
|
16
|
+
import {BanningStorage} from "./banning/BanningStorage.sol";
|
|
17
|
+
import {AppAccountStorage} from "./account/AppAccountStorage.sol";
|
|
18
|
+
import {DependencyLib} from "./DependencyLib.sol";
|
|
19
|
+
|
|
20
|
+
// contracts
|
|
21
|
+
import {TokenOwnableBase} from "@towns-protocol/diamond/src/facets/ownable/token/TokenOwnableBase.sol";
|
|
22
|
+
|
|
23
|
+
abstract contract Entitled is IEntitlementBase, TokenOwnableBase {
|
|
24
|
+
using EnumerableSet for EnumerableSet.AddressSet;
|
|
25
|
+
using EnumerableSet for EnumerableSet.UintSet;
|
|
26
|
+
using CustomRevert for bytes4;
|
|
27
|
+
|
|
28
|
+
bytes32 internal constant IN_TOWN = 0x0;
|
|
29
|
+
uint256 internal constant MEMBERSHIP_START_TOKEN_ID = 0;
|
|
30
|
+
|
|
31
|
+
function _isEntitledToSpace(
|
|
32
|
+
address user,
|
|
33
|
+
string memory permission
|
|
34
|
+
) internal view returns (bool) {
|
|
35
|
+
return _isEntitledToChannel(IN_TOWN, user, bytes32(bytes(permission)));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function _isEntitledToChannel(
|
|
39
|
+
bytes32 channelId,
|
|
40
|
+
address user,
|
|
41
|
+
bytes32 permission
|
|
42
|
+
) internal view returns (bool) {
|
|
43
|
+
address[] memory wallets = _getLinkedWalletsWithUser(user);
|
|
44
|
+
if (wallets.length == 0) return false;
|
|
45
|
+
|
|
46
|
+
// Check owner first (cheapest check)
|
|
47
|
+
address owner = _owner();
|
|
48
|
+
for (uint256 i; i < wallets.length; ++i) if (wallets[i] == owner) return true;
|
|
49
|
+
|
|
50
|
+
// Check if any wallet is banned using optimized O(n log n + m) approach
|
|
51
|
+
if (_hasAnyBannedWallet(wallets)) return false;
|
|
52
|
+
|
|
53
|
+
// Entitlement checks for members
|
|
54
|
+
EntitlementsManagerStorage.Layout storage ds = EntitlementsManagerStorage.layout();
|
|
55
|
+
address[] memory entitlements = ds.entitlements.values();
|
|
56
|
+
uint256 entitlementsLength = entitlements.length;
|
|
57
|
+
|
|
58
|
+
for (uint256 i; i < entitlementsLength; ++i) {
|
|
59
|
+
IEntitlement entitlement = ds.entitlementByAddress[entitlements[i]].entitlement;
|
|
60
|
+
if (
|
|
61
|
+
!entitlement.isCrosschain() &&
|
|
62
|
+
entitlement.isEntitled(channelId, wallets, permission)
|
|
63
|
+
) return true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function _validatePermission(string memory permission) internal view {
|
|
70
|
+
// Owner always has permission
|
|
71
|
+
if (_owner() == msg.sender) return;
|
|
72
|
+
|
|
73
|
+
// Check if not paused and user has permission
|
|
74
|
+
if (!PausableStorage.layout().paused) {
|
|
75
|
+
bytes32 permissionHash = bytes32(bytes(permission));
|
|
76
|
+
|
|
77
|
+
// Check space entitlements
|
|
78
|
+
if (_isEntitledToSpace(msg.sender, permission)) return;
|
|
79
|
+
|
|
80
|
+
// Check bot entitlements
|
|
81
|
+
if (_isBotEntitled(msg.sender, permissionHash)) return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
Entitlement__NotAllowed.selector.revertWith();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function _isMember(address user) internal view returns (bool member) {
|
|
88
|
+
member = ERC721AStorage.balanceOf(user) > 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function _validateMembership(address user) internal view {
|
|
92
|
+
// return if the user is a member or the owner
|
|
93
|
+
if (_isMember(user)) return;
|
|
94
|
+
address owner = _owner();
|
|
95
|
+
if (user == owner) return;
|
|
96
|
+
|
|
97
|
+
// otherwise, check if the user is a linked wallet
|
|
98
|
+
address[] memory wallets = _getLinkedWalletsWithUser(user);
|
|
99
|
+
uint256 length = wallets.length;
|
|
100
|
+
for (uint256 i; i < length; ++i) {
|
|
101
|
+
if (_isMember(wallets[i]) || wallets[i] == owner) return;
|
|
102
|
+
}
|
|
103
|
+
Entitlement__NotMember.selector.revertWith();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function _getLinkedWalletsWithUser(
|
|
107
|
+
address rootKey
|
|
108
|
+
) internal view returns (address[] memory wallets) {
|
|
109
|
+
IWalletLink wl = IWalletLink(MembershipStorage.layout().spaceFactory);
|
|
110
|
+
address[] memory linkedWallets = wl.getWalletsByRootKey(rootKey);
|
|
111
|
+
|
|
112
|
+
// Allow for the possibility that the user is not a root key, but a linked wallet.
|
|
113
|
+
if (linkedWallets.length == 0) {
|
|
114
|
+
address alternateRootKey = wl.getRootKeyForWallet(rootKey);
|
|
115
|
+
if (alternateRootKey != address(0)) {
|
|
116
|
+
rootKey = alternateRootKey;
|
|
117
|
+
linkedWallets = wl.getWalletsByRootKey(rootKey);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
wallets = LibSort.copy(linkedWallets);
|
|
122
|
+
assembly ("memory-safe") {
|
|
123
|
+
// Increment the size of the array by 1 and add the root key
|
|
124
|
+
mstore(wallets, add(mload(wallets), 1))
|
|
125
|
+
// LibSort.copy assigns the free memory pointer to the end of the array
|
|
126
|
+
mstore(mload(0x40), rootKey)
|
|
127
|
+
mstore(0x40, add(mload(0x40), 0x20))
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function _isBotEntitled(address client, bytes32 permission) internal view returns (bool) {
|
|
132
|
+
// Early return if client is zero address
|
|
133
|
+
if (client == address(0)) return false;
|
|
134
|
+
|
|
135
|
+
address app = DependencyLib.getAppRegistry().getAppByClient(client);
|
|
136
|
+
if (app == address(0)) return false;
|
|
137
|
+
|
|
138
|
+
return AppAccountStorage.isAppEntitled(app, client, permission);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function _hasAnyBannedWallet(address[] memory wallets) internal view returns (bool) {
|
|
142
|
+
BanningStorage.Layout storage ds = BanningStorage.layout();
|
|
143
|
+
uint256[] memory bannedTokens = ds.bannedIds.values();
|
|
144
|
+
|
|
145
|
+
if (bannedTokens.length == 0) return false;
|
|
146
|
+
|
|
147
|
+
// Step 1: Collect banned token owners - O(n)
|
|
148
|
+
address[] memory bannedOwners = new address[](bannedTokens.length);
|
|
149
|
+
for (uint256 i; i < bannedTokens.length; ++i) {
|
|
150
|
+
bannedOwners[i] = ERC721AStorage.ownerAt(MEMBERSHIP_START_TOKEN_ID, bannedTokens[i]);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Step 2: Sort and deduplicate banned owners - O(n log n)
|
|
154
|
+
LibSort.sort(bannedOwners);
|
|
155
|
+
LibSort.uniquifySorted(bannedOwners);
|
|
156
|
+
|
|
157
|
+
unchecked {
|
|
158
|
+
// Step 3: Combine wallets with unique banned owners - O(m + n)
|
|
159
|
+
address[] memory combined = new address[](wallets.length + bannedOwners.length);
|
|
160
|
+
for (uint256 i; i < wallets.length; ++i) {
|
|
161
|
+
combined[i] = wallets[i];
|
|
162
|
+
}
|
|
163
|
+
for (uint256 i; i < bannedOwners.length; ++i) {
|
|
164
|
+
combined[wallets.length + i] = bannedOwners[i];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Step 4: Check for duplicates - O(m + n)
|
|
168
|
+
// any duplicate found is an intersection between wallets and banned owners
|
|
169
|
+
return LibSort.hasDuplicate(combined);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
// interfaces
|
|
5
|
+
|
|
6
|
+
// libraries
|
|
7
|
+
|
|
8
|
+
// contracts
|
|
9
|
+
|
|
10
|
+
library Permissions {
|
|
11
|
+
string public constant ModifyChannel = "ModifyChannel";
|
|
12
|
+
string public constant AddRemoveChannels = "AddRemoveChannels";
|
|
13
|
+
string public constant ModifySpaceSettings = "ModifySpaceSettings";
|
|
14
|
+
string public constant ModifyRoles = "ModifyRoles";
|
|
15
|
+
string public constant JoinSpace = "JoinSpace";
|
|
16
|
+
string public constant ModifyBanning = "ModifyBanning";
|
|
17
|
+
string public constant Read = "Read";
|
|
18
|
+
string public constant Write = "Write";
|
|
19
|
+
string public constant React = "React";
|
|
20
|
+
string public constant Ping = "Ping";
|
|
21
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
// interfaces
|
|
5
|
+
import {IAppAccount} from "./IAppAccount.sol";
|
|
6
|
+
|
|
7
|
+
// libraries
|
|
8
|
+
import {AppAccountBase} from "./AppAccountBase.sol";
|
|
9
|
+
|
|
10
|
+
// contracts
|
|
11
|
+
|
|
12
|
+
import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
|
|
13
|
+
import {ReentrancyGuard} from "solady/utils/ReentrancyGuard.sol";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @title AppAccount
|
|
17
|
+
* @notice A lightweight modular erc6900 semi-compatible account
|
|
18
|
+
* @dev This account is used to execute transactions on behalf of a Space
|
|
19
|
+
*/
|
|
20
|
+
contract AppAccount is IAppAccount, AppAccountBase, ReentrancyGuard, Facet {
|
|
21
|
+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
|
|
22
|
+
/* Execution */
|
|
23
|
+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
|
|
24
|
+
|
|
25
|
+
function execute(
|
|
26
|
+
address target,
|
|
27
|
+
uint256 value,
|
|
28
|
+
bytes calldata data
|
|
29
|
+
) external payable nonReentrant returns (bytes memory result) {
|
|
30
|
+
result = _onExecute(target, value, data);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
|
|
34
|
+
/* App Management */
|
|
35
|
+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
|
|
36
|
+
|
|
37
|
+
/// @inheritdoc IAppAccount
|
|
38
|
+
function onInstallApp(bytes32 appId, bytes calldata data) external nonReentrant {
|
|
39
|
+
_onlyRegistry();
|
|
40
|
+
_installApp(appId, data);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/// @inheritdoc IAppAccount
|
|
44
|
+
function onUninstallApp(bytes32 appId, bytes calldata data) external {
|
|
45
|
+
_onlyRegistry();
|
|
46
|
+
_uninstallApp(appId, data);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// @inheritdoc IAppAccount
|
|
50
|
+
function onRenewApp(bytes32 appId, bytes calldata data) external nonReentrant {
|
|
51
|
+
_onlyRegistry();
|
|
52
|
+
_onRenewApp(appId, data);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// @inheritdoc IAppAccount
|
|
56
|
+
function enableApp(address app) external onlyOwner {
|
|
57
|
+
_enableApp(app);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/// @inheritdoc IAppAccount
|
|
61
|
+
function disableApp(address app) external onlyOwner {
|
|
62
|
+
_disableApp(app);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/// @inheritdoc IAppAccount
|
|
66
|
+
function getInstalledApps() external view returns (address[] memory) {
|
|
67
|
+
return _getApps();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/// @inheritdoc IAppAccount
|
|
71
|
+
function isAppInstalled(address app) external view returns (bool) {
|
|
72
|
+
return _isAppInstalled(app);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/// @inheritdoc IAppAccount
|
|
76
|
+
function getAppId(address app) external view returns (bytes32) {
|
|
77
|
+
return _getInstalledAppId(app);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/// @inheritdoc IAppAccount
|
|
81
|
+
function getAppExpiration(address app) external view returns (uint48) {
|
|
82
|
+
return _getGroupExpiration(_getInstalledAppId(app));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/// @inheritdoc IAppAccount
|
|
86
|
+
function isAppEntitled(
|
|
87
|
+
address app,
|
|
88
|
+
address publicKey,
|
|
89
|
+
bytes32 permission
|
|
90
|
+
) external view returns (bool) {
|
|
91
|
+
return _isAppEntitled(app, publicKey, permission);
|
|
92
|
+
}
|
|
93
|
+
}
|