From 2af174105cff77504ae2e3f96e051ee9eed4879a Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Mon, 3 Feb 2025 22:24:39 +1300 Subject: [PATCH] Support DOT reseve on AH and Snowfork bridged assets --- runtime/acala/src/xcm_config.rs | 23 ++++++++++++++++++++--- runtime/common/src/xcm_config.rs | 4 ++++ runtime/common/src/xcm_impl.rs | 25 ++++++++++++++++++++++++- runtime/karura/src/xcm_config.rs | 23 ++++++++++++++++++++--- 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/runtime/acala/src/xcm_config.rs b/runtime/acala/src/xcm_config.rs index 8c9ed51897..73d483e573 100644 --- a/runtime/acala/src/xcm_config.rs +++ b/runtime/acala/src/xcm_config.rs @@ -40,13 +40,14 @@ use parity_scale_codec::{Decode, Encode}; use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; use primitives::evm::is_system_contract; use runtime_common::{ - local_currency_location, native_currency_location, AcalaDropAssets, EnsureRootOrHalfGeneralCouncil, + local_currency_location, native_currency_location, xcm_config::RelayLocationFilter, + xcm_impl::IsBridgedConcreteAssetFrom, AcalaDropAssets, EnsureRootOrHalfGeneralCouncil, EnsureRootOrThreeFourthsGeneralCouncil, FixedRateOfAsset, RuntimeBlockWeights, }; use sp_runtime::Perbill; use xcm::{prelude::*, v3::Weight as XcmWeight}; use xcm_builder::{ - EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, FrameTransactionalProcessor, SignedToAccountId32, + Case, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, FrameTransactionalProcessor, SignedToAccountId32, }; parameter_types! { @@ -94,8 +95,24 @@ parameter_types! { 0 ); pub BaseRate: u128 = aca_per_second(); + + /// Location of Asset Hub + pub AssetHubLocation: Location = Location::new(1, [Parachain(1000)]); + pub RelayChainNativeAssetFromAssetHub: (AssetFilter, Location) = ( + RelayLocationFilter::get(), + AssetHubLocation::get() + ); } +type Reserves = ( + // Assets bridged from different consensus systems held in reserve on Asset Hub. + IsBridgedConcreteAssetFrom, + // Relaychain (DOT) from Asset Hub + Case, + // Assets which the reserve is the same as the origin. + MultiNativeAsset, +); + pub type Trader = ( FixedRateOfAsset>, FixedRateOfFungible, @@ -115,7 +132,7 @@ impl xcm_executor::Config for XcmConfig { // How to withdraw and deposit an asset. type AssetTransactor = LocalAssetTransactor; type OriginConverter = XcmOriginToCallOrigin; - type IsReserve = MultiNativeAsset; + type IsReserve = Reserves; type IsTeleporter = runtime_common::xcm_config::TrustedTeleporters; type UniversalLocation = UniversalLocation; type Barrier = Barrier; diff --git a/runtime/common/src/xcm_config.rs b/runtime/common/src/xcm_config.rs index 373b2c2c66..c737095138 100644 --- a/runtime/common/src/xcm_config.rs +++ b/runtime/common/src/xcm_config.rs @@ -127,6 +127,10 @@ impl Convert for AccountIdToLocation { parameter_types! { pub const RelayLocation: Location = Location::parent(); + pub RelayLocationFilter: AssetFilter = Wild(AllOf { + fun: WildFungible, + id: xcm::prelude::AssetId(RelayLocation::get()), + }); } // define assets that can be trusted to teleport by remotes diff --git a/runtime/common/src/xcm_impl.rs b/runtime/common/src/xcm_impl.rs index 52a198eece..5515615773 100644 --- a/runtime/common/src/xcm_impl.rs +++ b/runtime/common/src/xcm_impl.rs @@ -18,7 +18,10 @@ //! Common xcm implementation -use frame_support::{traits::Get, weights::constants::WEIGHT_REF_TIME_PER_SECOND}; +use frame_support::{ + traits::{ContainsPair, Get}, + weights::constants::WEIGHT_REF_TIME_PER_SECOND, +}; use module_support::BuyWeightRate; use orml_traits::GetByKey; use parity_scale_codec::Encode; @@ -295,6 +298,26 @@ where } } +/// Matches foreign assets from a given origin. +/// Foreign assets are assets bridged from other consensus systems. i.e parents > 1. +pub struct IsBridgedConcreteAssetFrom(PhantomData); +impl ContainsPair for IsBridgedConcreteAssetFrom +where + Origin: Get, +{ + fn contains(asset: &Asset, origin: &Location) -> bool { + let loc = Origin::get(); + &loc == origin + && matches!( + asset, + Asset { + id: AssetId(Location { parents: 2, .. }), + fun: Fungibility::Fungible(_) + }, + ) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/runtime/karura/src/xcm_config.rs b/runtime/karura/src/xcm_config.rs index 061a59780f..b65cdc8d2c 100644 --- a/runtime/karura/src/xcm_config.rs +++ b/runtime/karura/src/xcm_config.rs @@ -38,13 +38,14 @@ use parity_scale_codec::{Decode, Encode}; use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; use primitives::evm::is_system_contract; use runtime_common::{ - local_currency_location, native_currency_location, AcalaDropAssets, EnsureRootOrHalfGeneralCouncil, + local_currency_location, native_currency_location, xcm_config::RelayLocationFilter, + xcm_impl::IsBridgedConcreteAssetFrom, AcalaDropAssets, EnsureRootOrHalfGeneralCouncil, EnsureRootOrThreeFourthsGeneralCouncil, FixedRateOfAsset, RuntimeBlockWeights, }; use sp_runtime::Perbill; use xcm::{prelude::*, v3::Weight as XcmWeight}; use xcm_builder::{ - EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, FrameTransactionalProcessor, SignedToAccountId32, + Case, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, FrameTransactionalProcessor, SignedToAccountId32, }; parameter_types! { @@ -136,8 +137,24 @@ parameter_types! { ); pub BaseRate: u128 = kar_per_second(); + + /// Location of Asset Hub + pub AssetHubLocation: Location = Location::new(1, [Parachain(1000)]); + pub RelayChainNativeAssetFromAssetHub: (AssetFilter, Location) = ( + RelayLocationFilter::get(), + AssetHubLocation::get() + ); } +type Reserves = ( + // Assets bridged from different consensus systems held in reserve on Asset Hub. + IsBridgedConcreteAssetFrom, + // Relaychain (DOT) from Asset Hub + Case, + // Assets which the reserve is the same as the origin. + MultiNativeAsset, +); + pub type Trader = ( FixedRateOfAsset>, FixedRateOfFungible, @@ -162,7 +179,7 @@ impl xcm_executor::Config for XcmConfig { // How to withdraw and deposit an asset. type AssetTransactor = LocalAssetTransactor; type OriginConverter = XcmOriginToCallOrigin; - type IsReserve = MultiNativeAsset; + type IsReserve = Reserves; type IsTeleporter = runtime_common::xcm_config::TrustedTeleporters; type UniversalLocation = UniversalLocation; type Barrier = Barrier;