// This file is part of Bizinikiwi. // Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, BaseDeliveryFee, CollatorSelection, FeeAssetId, FellowshipAdmin, ForeignAssets, ForeignAssetsInstance, GeneralAdmin, PezkuwiXcm, PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin, TeyrchainInfo, TeyrchainSystem, ToPezkuwichainXcmRouter, TransactionByteFee, Treasurer, TrustBackedAssetsInstance, Uniques, WeightToFee, XcmpQueue, }; use assets_common::{ matching::{FromSiblingTeyrchain, IsForeignConcreteAsset, ParentLocation}, TrustBackedAssetsAsLocation, }; use pezframe_support::{ parameter_types, traits::{ fungible::HoldConsideration, tokens::imbalance::{ResolveAssetTo, ResolveTo}, ConstU32, Contains, Equals, Everything, LinearStoragePrice, PalletInfoAccess, }, }; use pezframe_system::EnsureRoot; use pezpallet_xcm::XcmPassthrough; use pezkuwi_runtime_common::xcm_sender::ExponentialPrice; use pezkuwi_teyrchain_primitives::primitives::Sibling; use pezsp_runtime::traits::{AccountIdConversion, ConvertInto, TryConvertInto}; use teyrchains_common::{ xcm_config::{ AllSiblingSystemTeyrchains, AssetFeeAsExistentialDepositMultiplier, ConcreteAssetFromSystem, RelayOrOtherSystemTeyrchains, }, TREASURY_PALLET_ID, }; use xcm::latest::{prelude::*, PEZKUWICHAIN_GENESIS_HASH, ZAGROS_GENESIS_HASH}; use xcm_builder::{ AccountId32Aliases, AliasChildLocation, AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal, DescribeFamily, EnsureXcmOrigin, FrameTransactionalProcessor, FungibleAdapter, FungiblesAdapter, GlobalConsensusTeyrchainConvertsFor, HashedDescription, IsConcrete, LocalMint, MatchedConvertedConcreteId, NetworkExportTableItem, NoChecking, NonFungiblesAdapter, OriginToPluralityVoice, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SendXcmFeeToAccount, SiblingTeyrchainAsNative, SiblingTeyrchainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SingleAssetExchangeAdapter, SovereignPaidRemoteExporter, SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithLatestLocationConverter, WithUniqueTopic, XcmFeeManagerFromComponents, }; use xcm_executor::XcmExecutor; use zagros_runtime_constants::{ system_teyrchain::COLLECTIVES_ID, xcm::body::FELLOWSHIP_ADMIN_INDEX, }; parameter_types! { pub const RootLocation: Location = Location::here(); pub const ZagrosLocation: Location = Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::ByGenesis(ZAGROS_GENESIS_HASH)); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); pub UniversalLocation: InteriorLocation = [GlobalConsensus(RelayNetwork::get().unwrap()), Teyrchain(TeyrchainInfo::teyrchain_id().into())].into(); pub UniversalLocationNetworkId: NetworkId = UniversalLocation::get().global_consensus().unwrap(); pub TrustBackedAssetsPalletLocation: Location = PalletInstance(TrustBackedAssetsPalletIndex::get()).into(); pub TrustBackedAssetsPalletIndex: u8 = ::index() as u8; pub ForeignAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); pub PoolAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); pub UniquesPalletLocation: Location = PalletInstance(::index() as u8).into(); pub CheckingAccount: AccountId = PezkuwiXcm::check_account(); pub StakingPot: AccountId = CollatorSelection::account_id(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); pub RelayTreasuryLocation: Location = (Parent, PalletInstance(zagros_runtime_constants::TREASURY_PALLET_ID)).into(); } /// Type for specifying how a `Location` can be converted into an `AccountId`. This is used /// when determining ownership of accounts for asset transacting and when attempting to use XCM /// `Transact` in order to determine the dispatch Origin. pub type LocationToAccountId = ( // The parent (Relay-chain) origin converts to the parent `AccountId`. ParentIsPreset, // Sibling teyrchain origins convert to AccountId via the `ParaId::into`. SiblingTeyrchainConvertsVia, // Straight up local `AccountId32` origins just alias directly to `AccountId`. AccountId32Aliases, // Foreign locations alias into accounts according to a hash of their standard description. HashedDescription>, // Different global consensus teyrchain sovereign account. // (Used for over-bridge transfers and reserve processing) GlobalConsensusTeyrchainConvertsFor, ); /// Means for transacting the native currency on this chain. pub type FungibleTransactor = FungibleAdapter< // Use this currency: Balances, // Use this currency when it is a fungible asset matching the given location or name: IsConcrete, // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, // We don't track any teleports of `Balances`. (), >; /// `AssetId`/`Balance` converter for `TrustBackedAssets`. pub type TrustBackedAssetsConvertedConcreteId = assets_common::TrustBackedAssetsConvertedConcreteId; /// Means for transacting assets besides the native currency on this chain. pub type FungiblesTransactor = FungiblesAdapter< // Use this fungibles implementation: Assets, // Use this currency when it is a fungible asset matching the given location or name: TrustBackedAssetsConvertedConcreteId, // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, // We only want to allow teleports of known assets. We use non-zero issuance as an indication // that this asset is known. LocalMint>, // The account to use for tracking teleports. CheckingAccount, >; /// Matcher for converting `ClassId`/`InstanceId` into a uniques asset. pub type UniquesConvertedConcreteId = assets_common::UniquesConvertedConcreteId; /// Means for transacting unique assets. pub type UniquesTransactor = NonFungiblesAdapter< // Use this non-fungibles implementation: Uniques, // This adapter will handle any non-fungible asset from the uniques pallet. UniquesConvertedConcreteId, // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, // Does not check teleports. NoChecking, // The account to use for tracking teleports. CheckingAccount, >; /// `AssetId`/`Balance` converter for `ForeignAssets`. pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConvertedConcreteId< ( // Ignore `TrustBackedAssets` explicitly StartsWith, // Ignore asset which starts explicitly with our `GlobalConsensus(NetworkId)`, means: // - foreign assets from our consensus should be: `Location {parents: 1, X*(Teyrchain(xyz), // ..)} // - foreign assets outside our consensus with the same `GlobalConsensus(NetworkId)` wont // be accepted here StartsWithExplicitGlobalConsensus, ), Balance, xcm::v5::Location, >; /// Means for transacting foreign assets from different global consensus. pub type ForeignFungiblesTransactor = FungiblesAdapter< // Use this fungibles implementation: ForeignAssets, // Use this currency when it is a fungible asset matching the given location or name: ForeignAssetsConvertedConcreteId, // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, // We don't need to check teleports here. NoChecking, // The account to use for tracking teleports. CheckingAccount, >; /// `AssetId`/`Balance` converter for `PoolAssets`. pub type PoolAssetsConvertedConcreteId = assets_common::PoolAssetsConvertedConcreteId; /// Means for transacting asset conversion pool assets on this chain. pub type PoolFungiblesTransactor = FungiblesAdapter< // Use this fungibles implementation: PoolAssets, // Use this currency when it is a fungible asset matching the given location or name: PoolAssetsConvertedConcreteId, // Convert an XCM Location into a local account id: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, // We only want to allow teleports of known assets. We use non-zero issuance as an indication // that this asset is known. LocalMint>, // The account to use for tracking teleports. CheckingAccount, >; /// Means for transacting assets on this chain. pub type AssetTransactors = ( FungibleTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor, UniquesTransactor, ); /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, /// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can /// biases the kind of local `Origin` it will become. pub type XcmOriginToTransactDispatchOrigin = ( // Sovereign account converter; this attempts to derive an `AccountId` from the origin location // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for // foreign chains who want to have a local sovereign account on this chain which they control. SovereignSignedViaLocation, // Native converter for Relay-chain (Parent) location; will convert to a `Relay` origin when // recognised. RelayChainAsNative, // Native converter for sibling Teyrchains; will convert to a `SiblingPara` origin when // recognised. SiblingTeyrchainAsNative, // Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a // transaction from the Root origin. ParentAsSuperuser, // Native signed account converter; this just converts an `AccountId32` origin into a normal // `RuntimeOrigin::Signed` origin of the same 32-byte value. SignedAccountId32AsNative, // Xcm origins can be represented natively under the Xcm pallet's Xcm origin. XcmPassthrough, ); parameter_types! { pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub XcmAssetFeesReceiver: Option = Authorship::author(); } pub struct ParentOrParentsPlurality; impl Contains for ParentOrParentsPlurality { fn contains(location: &Location) -> bool { matches!(location.unpack(), (1, []) | (1, [Plurality { .. }])) } } pub struct FellowshipEntities; impl Contains for FellowshipEntities { fn contains(location: &Location) -> bool { matches!( location.unpack(), (1, [Teyrchain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }]) | (1, [Teyrchain(COLLECTIVES_ID), PalletInstance(64)]) | (1, [Teyrchain(COLLECTIVES_ID), PalletInstance(65)]) ) } } pub struct LocalPlurality; impl Contains for LocalPlurality { fn contains(loc: &Location) -> bool { matches!(loc.unpack(), (0, [Plurality { .. }])) } } pub struct AmbassadorEntities; impl Contains for AmbassadorEntities { fn contains(location: &Location) -> bool { matches!(location.unpack(), (1, [Teyrchain(COLLECTIVES_ID), PalletInstance(74)])) } } pub type Barrier = TrailingSetTopicAsId< DenyThenTry< DenyReserveTransferToRelayChain, ( TakeWeightCredit, // Expected responses are OK. AllowKnownQueryResponses, // Allow XCMs with some computed origins to pass through. WithComputedOrigin< ( // If the message is one that immediately attempts to pay for execution, then // allow it. AllowTopLevelPaidExecutionFrom, // Parent, its pluralities (i.e. governance bodies), relay treasury pallet and // sibling teyrchains get free execution. AllowExplicitUnpaidExecutionFrom<( ParentOrParentsPlurality, Equals, RelayOrOtherSystemTeyrchains, FellowshipEntities, AmbassadorEntities, )>, // Subscriptions for version tracking are OK. AllowSubscriptionsFrom, // HRMP notifications from the relay chain are OK. AllowHrmpNotificationsFromRelayChain, ), UniversalLocation, ConstU32<8>, >, ), >, >; // TODO: This calls into the Assets pallet's default `BalanceToAssetBalance` implementation, which // uses the ratio of minimum balances and requires asset sufficiency. This means that purchasing // weight within XCM programs will still use the old way, and paying fees via asset conversion will // only be possible when transacting locally. We should add an impl of this trait that does asset // conversion. pub type AssetFeeAsExistentialDepositMultiplierFeeCharger = AssetFeeAsExistentialDepositMultiplier< Runtime, WeightToFee, pezpallet_assets::BalanceToAssetBalance, TrustBackedAssetsInstance, >; /// Multiplier used for dedicated `TakeFirstAssetTrader` with `ForeignAssets` instance. pub type ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger = AssetFeeAsExistentialDepositMultiplier< Runtime, WeightToFee, pezpallet_assets::BalanceToAssetBalance, ForeignAssetsInstance, >; /// Locations that will not be charged fees in the executor, /// either execution or delivery. /// We only waive fees for system functions, which these locations represent. pub type WaivedLocations = ( Equals, RelayOrOtherSystemTeyrchains, Equals, FellowshipEntities, AmbassadorEntities, LocalPlurality, ); /// Cases where a remote origin is accepted as trusted Teleporter for a given asset: /// /// - ZGR with the parent Relay Chain and sibling system teyrchains; and /// - Sibling teyrchains' assets from where they originate (as `ForeignCreators`). pub type TrustedTeleporters = ( ConcreteAssetFromSystem, IsForeignConcreteAsset>>, ); /// Asset converter for pool assets. /// Used to convert one asset to another, when there is a pool available between the two. /// This type thus allows paying fees with any asset as long as there is a pool between said /// asset and the asset required for fee payment. pub type PoolAssetsExchanger = SingleAssetExchangeAdapter< crate::AssetConversion, crate::NativeAndNonPoolAssets, ( TrustBackedAssetsAsLocation, ForeignAssetsConvertedConcreteId, // `ForeignAssetsConvertedConcreteId` excludes the relay token, so we add it back here. MatchedConvertedConcreteId< xcm::v5::Location, Balance, Equals, WithLatestLocationConverter, TryConvertInto, >, ), AccountId, >; pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type XcmEventEmitter = PezkuwiXcm; type RuntimeCall = RuntimeCall; type XcmSender = XcmRouter; type AssetTransactor = AssetTransactors; type OriginConverter = XcmOriginToTransactDispatchOrigin; // Asset Hub trusts only particular, pre-configured bridged locations from a different consensus // as reserve locations (we trust the Bridge Hub to relay the message that a reserve is being // held). On Zagros Asset Hub, we allow Pezkuwichain Asset Hub to act as reserve for any asset // native to the Pezkuwichain or Ethereum ecosystems. type IsReserve = ( bridging::to_pezkuwichain::PezkuwichainAssetFromAssetHubPezkuwichain, bridging::to_ethereum::EthereumAssetFromEthereum, ); type IsTeleporter = TrustedTeleporters; type UniversalLocation = UniversalLocation; type Barrier = Barrier; type Weigher = WeightInfoBounds< crate::weights::xcm::AssetHubNextZagrosXcmWeight, RuntimeCall, MaxInstructions, >; type Trader = ( UsingComponents< WeightToFee, ZagrosLocation, AccountId, Balances, ResolveTo, >, cumulus_primitives_utility::SwapFirstAssetTrader< ZagrosLocation, crate::AssetConversion, WeightToFee, crate::NativeAndNonPoolAssets, ( TrustBackedAssetsAsLocation< TrustBackedAssetsPalletLocation, Balance, xcm::v5::Location, >, ForeignAssetsConvertedConcreteId, ), ResolveAssetTo, AccountId, >, // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated // `pezpallet_assets` instance - `Assets`. cumulus_primitives_utility::TakeFirstAssetTrader< AccountId, AssetFeeAsExistentialDepositMultiplierFeeCharger, TrustBackedAssetsConvertedConcreteId, Assets, cumulus_primitives_utility::XcmFeesTo32ByteAccount< FungiblesTransactor, AccountId, XcmAssetFeesReceiver, >, >, // This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated // `pezpallet_assets` instance - `ForeignAssets`. cumulus_primitives_utility::TakeFirstAssetTrader< AccountId, ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, ForeignAssetsConvertedConcreteId, ForeignAssets, cumulus_primitives_utility::XcmFeesTo32ByteAccount< ForeignFungiblesTransactor, AccountId, XcmAssetFeesReceiver, >, >, ); type ResponseHandler = PezkuwiXcm; type AssetTrap = PezkuwiXcm; type AssetClaims = PezkuwiXcm; type SubscriptionService = PezkuwiXcm; type PalletInstancesInfo = AllPalletsWithSystem; type MaxAssetsIntoHolding = MaxAssetsIntoHolding; type AssetLocker = (); type AssetExchanger = PoolAssetsExchanger; type FeeManager = XcmFeeManagerFromComponents< WaivedLocations, SendXcmFeeToAccount, >; type MessageExporter = (); type UniversalAliases = (bridging::to_pezkuwichain::UniversalAliases, bridging::to_ethereum::UniversalAliases); type CallDispatcher = RuntimeCall; type SafeCallFilter = Everything; // We allow any origin to alias into a child sub-location (equivalent to DescendOrigin). type Aliasers = AliasChildLocation; type TransactionalProcessor = FrameTransactionalProcessor; type HrmpNewChannelOpenRequestHandler = (); type HrmpChannelAcceptedHandler = (); type HrmpChannelClosingHandler = (); type XcmRecorder = PezkuwiXcm; } parameter_types! { // `GeneralAdmin` pluralistic body. pub const GeneralAdminBodyId: BodyId = BodyId::Administration; // StakingAdmin pluralistic body. pub const StakingAdminBodyId: BodyId = BodyId::Defense; // FellowshipAdmin pluralistic body. pub const FellowshipAdminBodyId: BodyId = BodyId::Index(FELLOWSHIP_ADMIN_INDEX); // `Treasurer` pluralistic body. pub const TreasurerBodyId: BodyId = BodyId::Treasury; } /// Type to convert the `GeneralAdmin` origin to a Plurality `Location` value. pub type GeneralAdminToPlurality = OriginToPluralityVoice; /// Local origins on this chain are allowed to dispatch XCM sends/executions. pub type LocalOriginToLocation = (GeneralAdminToPlurality, SignedToAccountId32); /// Type to convert the `StakingAdmin` origin to a Plurality `Location` value. pub type StakingAdminToPlurality = OriginToPluralityVoice; /// Type to convert the `FellowshipAdmin` origin to a Plurality `Location` value. pub type FellowshipAdminToPlurality = OriginToPluralityVoice; /// Type to convert the `Treasurer` origin to a Plurality `Location` value. pub type TreasurerToPlurality = OriginToPluralityVoice; /// Type to convert a pallet `Origin` type value into a `Location` value which represents an /// interior location of this chain for a destination chain. pub type LocalPalletOriginToLocation = ( // GeneralAdmin origin to be used in XCM as a corresponding Plurality `Location` value. GeneralAdminToPlurality, // StakingAdmin origin to be used in XCM as a corresponding Plurality `Location` value. StakingAdminToPlurality, // FellowshipAdmin origin to be used in XCM as a corresponding Plurality `Location` value. FellowshipAdminToPlurality, // `Treasurer` origin to be used in XCM as a corresponding Plurality `Location` value. TreasurerToPlurality, ); pub type PriceForParentDelivery = ExponentialPrice; /// For routing XCM messages which do not cross local consensus boundary. type LocalXcmRouter = ( // Two routers - use UMP to communicate with the relay chain: cumulus_primitives_utility::ParentAsUmp, // ..and XCMP to communicate with the sibling chains. XcmpQueue, ); /// The means for routing XCM messages which are not for local execution into the right message /// queues. pub type XcmRouter = WithUniqueTopic<( LocalXcmRouter, // Router which wraps and sends xcm to BridgeHub to be delivered to the Pezkuwichain // GlobalConsensus ToPezkuwichainXcmRouter, // Router which wraps and sends xcm to BridgeHub to be delivered to the Ethereum // GlobalConsensus SovereignPaidRemoteExporter< bridging::to_ethereum::EthereumNetworkExportTable, XcmpQueue, UniversalLocation, >, )>; parameter_types! { pub Collectives: Location = Teyrchain(COLLECTIVES_ID).into_location(); pub const DepositPerItem: Balance = crate::deposit(1, 0); pub const DepositPerByte: Balance = crate::deposit(0, 1); pub const AuthorizeAliasHoldReason: crate::RuntimeHoldReason = crate::RuntimeHoldReason::PezkuwiXcm(pezpallet_xcm::HoldReason::AuthorizeAlias); } impl pezpallet_xcm::Config for Runtime { type RuntimeEvent = RuntimeEvent; type SendXcmOrigin = EnsureXcmOrigin; type XcmRouter = XcmRouter; type ExecuteXcmOrigin = EnsureXcmOrigin; type XcmExecuteFilter = Everything; type XcmExecutor = XcmExecutor; type XcmTeleportFilter = Everything; type XcmReserveTransferFilter = Everything; type Weigher = WeightInfoBounds< crate::weights::xcm::AssetHubNextZagrosXcmWeight, RuntimeCall, MaxInstructions, >; type UniversalLocation = UniversalLocation; type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; type AdvertisedXcmVersion = pezpallet_xcm::CurrentXcmVersion; type Currency = Balances; type CurrencyMatcher = (); type TrustedLockers = (); type SovereignAccountOf = LocationToAccountId; type MaxLockers = ConstU32<8>; type WeightInfo = crate::weights::pezpallet_xcm::WeightInfo; type AdminOrigin = EnsureRoot; type MaxRemoteLockConsumers = ConstU32<0>; type RemoteLockConsumerIdentifier = (); type AuthorizedAliasConsideration = HoldConsideration< AccountId, Balances, AuthorizeAliasHoldReason, LinearStoragePrice, >; } impl cumulus_pallet_xcm::Config for Runtime { type RuntimeEvent = RuntimeEvent; type XcmExecutor = XcmExecutor; } /// All configuration related to bridging pub mod bridging { use super::*; use alloc::collections::btree_set::BTreeSet; use assets_common::matching; parameter_types! { /// Base price of every byte of the Zagros -> Pezkuwichain message. Can be adjusted via /// governance `set_storage` call. /// /// Default value is our estimation of the: /// /// 1) an approximate cost of XCM execution (`ExportMessage` and surroundings) at Zagros bridge hub; /// /// 2) the approximate cost of Zagros -> Pezkuwichain message delivery transaction on Pezkuwichain Bridge Hub, /// converted into ZGRs using 1:1 conversion rate; /// /// 3) the approximate cost of Zagros -> Pezkuwichain message confirmation transaction on Zagros Bridge Hub. pub storage XcmBridgeHubRouterBaseFee: Balance = bp_bridge_hub_zagros::BridgeHubZagrosBaseXcmFeeInWnds::get() .saturating_add(bp_bridge_hub_pezkuwichain::BridgeHubPezkuwichainBaseDeliveryFeeInRocs::get()) .saturating_add(bp_bridge_hub_zagros::BridgeHubZagrosBaseConfirmationFeeInWnds::get()); /// Price of every byte of the Zagros -> Pezkuwichain message. Can be adjusted via /// governance `set_storage` call. pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get(); pub SiblingBridgeHubParaId: u32 = bp_bridge_hub_zagros::BRIDGE_HUB_ZAGROS_TEYRCHAIN_ID; pub SiblingBridgeHub: Location = Location::new(1, [Teyrchain(SiblingBridgeHubParaId::get())]); /// Router expects payment with this `AssetId`. /// (`AssetId` has to be aligned with `BridgeTable`) pub XcmBridgeHubRouterFeeAssetId: AssetId = ZagrosLocation::get().into(); pub BridgeTable: alloc::vec::Vec = alloc::vec::Vec::new().into_iter() .chain(to_pezkuwichain::BridgeTable::get()) .collect(); } pub type NetworkExportTable = xcm_builder::NetworkExportTable; pub mod to_pezkuwichain { use super::*; parameter_types! { pub SiblingBridgeHubWithBridgeHubPezkuwichainInstance: Location = Location::new( 1, [ Teyrchain(SiblingBridgeHubParaId::get()), PalletInstance(bp_bridge_hub_zagros::WITH_BRIDGE_ZAGROS_TO_PEZKUWICHAIN_MESSAGES_PALLET_INDEX) ] ); pub const PezkuwichainNetwork: NetworkId = NetworkId::ByGenesis(PEZKUWICHAIN_GENESIS_HASH); pub PezkuwichainEcosystem: Location = Location::new(2, [GlobalConsensus(PezkuwichainNetwork::get())]); pub RocLocation: Location = Location::new(2, [GlobalConsensus(PezkuwichainNetwork::get())]); pub AssetHubPezkuwichain: Location = Location::new(2, [ GlobalConsensus(PezkuwichainNetwork::get()), Teyrchain(bp_asset_hub_pezkuwichain::ASSET_HUB_PEZKUWICHAIN_TEYRCHAIN_ID) ]); /// Set up exporters configuration. /// `Option` represents static "base fee" which is used for total delivery fee calculation. pub BridgeTable: alloc::vec::Vec = alloc::vec![ NetworkExportTableItem::new( PezkuwichainNetwork::get(), Some(alloc::vec![ AssetHubPezkuwichain::get().interior.split_global().expect("invalid configuration for AssetHubPezkuwichain").1, ]), SiblingBridgeHub::get(), // base delivery fee to local `BridgeHub` Some(( XcmBridgeHubRouterFeeAssetId::get(), XcmBridgeHubRouterBaseFee::get(), ).into()) ) ]; /// Universal aliases pub UniversalAliases: BTreeSet<(Location, Junction)> = BTreeSet::from_iter( alloc::vec![ (SiblingBridgeHubWithBridgeHubPezkuwichainInstance::get(), GlobalConsensus(PezkuwichainNetwork::get())) ] ); } impl Contains<(Location, Junction)> for UniversalAliases { fn contains(alias: &(Location, Junction)) -> bool { UniversalAliases::get().contains(alias) } } /// Allow any asset native to the Pezkuwichain ecosystem if it comes from Pezkuwichain Asset /// Hub. pub type PezkuwichainAssetFromAssetHubPezkuwichain = matching::RemoteAssetFromLocation< StartsWith, AssetHubPezkuwichain, >; } pub mod to_ethereum { use super::*; use assets_common::matching::FromNetwork; use pezsp_std::collections::btree_set::BTreeSet; use testnet_teyrchains_constants::zagros::snowbridge::{ EthereumNetwork, INBOUND_QUEUE_PALLET_INDEX_V1, }; parameter_types! { /// User fee for ERC20 token transfer back to Ethereum. /// (initially was calculated by test `OutboundQueue::calculate_fees` - ETH/ZGR 1/400 and fee_per_gas 20 GWEI = 2200698000000 + *25%) /// Needs to be more than fee calculated from DefaultFeeConfig FeeConfigRecord in snowbridge:teyrchain/pallets/outbound-queue/src/lib.rs /// Pezkuwi uses 10 decimals, Kusama,Pezkuwichain,Zagros 12 decimals. pub const DefaultBridgeHubEthereumBaseFee: Balance = 2_750_872_500_000; pub storage BridgeHubEthereumBaseFee: Balance = DefaultBridgeHubEthereumBaseFee::get(); pub SiblingBridgeHubWithEthereumInboundQueueInstance: Location = Location::new( 1, [ Teyrchain(SiblingBridgeHubParaId::get()), PalletInstance(INBOUND_QUEUE_PALLET_INDEX_V1) ] ); /// Set up exporters configuration. /// `Option` represents static "base fee" which is used for total delivery fee calculation. pub BridgeTable: pezsp_std::vec::Vec = pezsp_std::vec![ NetworkExportTableItem::new( EthereumNetwork::get().into(), Some(pezsp_std::vec![Junctions::Here]), SiblingBridgeHub::get(), Some(( XcmBridgeHubRouterFeeAssetId::get(), BridgeHubEthereumBaseFee::get(), ).into()) ), ]; /// Universal aliases pub UniversalAliases: BTreeSet<(Location, Junction)> = BTreeSet::from_iter( pezsp_std::vec![ (SiblingBridgeHubWithEthereumInboundQueueInstance::get(), GlobalConsensus(EthereumNetwork::get().into())), ] ); pub EthereumBridgeTable: pezsp_std::vec::Vec = pezsp_std::vec::Vec::new().into_iter() .chain(BridgeTable::get()) .collect(); } pub type EthereumNetworkExportTable = xcm_builder::NetworkExportTable; pub type EthereumAssetFromEthereum = IsForeignConcreteAsset>; impl Contains<(Location, Junction)> for UniversalAliases { fn contains(alias: &(Location, Junction)) -> bool { UniversalAliases::get().contains(alias) } } } /// Benchmarks helper for bridging configuration. #[cfg(feature = "runtime-benchmarks")] pub struct BridgingBenchmarksHelper; #[cfg(feature = "runtime-benchmarks")] impl BridgingBenchmarksHelper { pub fn prepare_universal_alias() -> Option<(Location, Junction)> { let alias = to_pezkuwichain::UniversalAliases::get().into_iter().find_map( |(location, junction)| { match to_pezkuwichain::SiblingBridgeHubWithBridgeHubPezkuwichainInstance::get() .eq(&location) { true => Some((location, junction)), false => None, } }, ); Some(alias.expect("we expect here BridgeHubZagros to Pezkuwichain mapping at least")) } } }