diff --git a/Cargo.lock b/Cargo.lock index e6df1b1bbe..83b64d4015 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -212,6 +212,7 @@ dependencies = [ "orml-currencies", "orml-tokens 0.4.1-dev (git+https://github.com/open-web3-stack/open-runtime-module-library?rev=8d5432c3458702a7df14b374bddde43a2a20aa43)", "orml-traits 0.4.1-dev (git+https://github.com/open-web3-stack/open-runtime-module-library?rev=8d5432c3458702a7df14b374bddde43a2a20aa43)", + "orml-unknown-tokens", "orml-xcm-support", "orml-xtokens", "pallet-aura", @@ -805,6 +806,7 @@ dependencies = [ "orml-currencies", "orml-tokens 0.4.1-dev (git+https://github.com/open-web3-stack/open-runtime-module-library?rev=8d5432c3458702a7df14b374bddde43a2a20aa43)", "orml-traits 0.4.1-dev (git+https://github.com/open-web3-stack/open-runtime-module-library?rev=8d5432c3458702a7df14b374bddde43a2a20aa43)", + "orml-unknown-tokens", "orml-xcm-support", "orml-xtokens", "pallet-aura", @@ -2266,6 +2268,7 @@ dependencies = [ "orml-currencies", "orml-tokens 0.4.1-dev (git+https://github.com/open-web3-stack/open-runtime-module-library?rev=8d5432c3458702a7df14b374bddde43a2a20aa43)", "orml-traits 0.4.1-dev (git+https://github.com/open-web3-stack/open-runtime-module-library?rev=8d5432c3458702a7df14b374bddde43a2a20aa43)", + "orml-unknown-tokens", "orml-xcm-support", "orml-xtokens", "pallet-aura", @@ -5476,6 +5479,20 @@ dependencies = [ "xcm", ] +[[package]] +name = "orml-unknown-tokens" +version = "0.4.1-dev" +source = "git+https://github.com/open-web3-stack/open-runtime-module-library?rev=8d5432c3458702a7df14b374bddde43a2a20aa43#8d5432c3458702a7df14b374bddde43a2a20aa43" +dependencies = [ + "frame-support", + "frame-system", + "orml-xcm-support", + "parity-scale-codec", + "serde", + "sp-std", + "xcm", +] + [[package]] name = "orml-utilities" version = "0.4.1-dev" diff --git a/Cargo.toml b/Cargo.toml index 09f41019a7..fb426d284e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -197,4 +197,5 @@ orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-li orml-currencies = {git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "8d5432c3458702a7df14b374bddde43a2a20aa43" } orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "8d5432c3458702a7df14b374bddde43a2a20aa43" } orml-xtokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "8d5432c3458702a7df14b374bddde43a2a20aa43" } +orml-unknown-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "8d5432c3458702a7df14b374bddde43a2a20aa43" } orml-xcm-support = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "8d5432c3458702a7df14b374bddde43a2a20aa43" } \ No newline at end of file diff --git a/runtime/asgard/Cargo.toml b/runtime/asgard/Cargo.toml index 8226bc9ff6..e133534bb6 100644 --- a/runtime/asgard/Cargo.toml +++ b/runtime/asgard/Cargo.toml @@ -100,6 +100,7 @@ orml-currencies = { version = "0.4.1-dev", default-features = false } orml-tokens = { version = "0.4.1-dev", default-features = false } orml-traits = { version = "0.4.1-dev", default-features = false } orml-xtokens = { version = "0.4.1-dev", default-features = false } +orml-unknown-tokens = { version = "0.4.1-dev", default-features = false } orml-xcm-support = { version = "0.4.1-dev", default-features = false } zenlink-protocol = { version = "*", default-features = false } @@ -182,6 +183,7 @@ std = [ "orml-traits/std", "orml-tokens/std", "orml-xtokens/std", + "orml-unknown-tokens/std", "orml-xcm-support/std", "zenlink-protocol/std", "zenlink-protocol-runtime-api/std", diff --git a/runtime/asgard/src/lib.rs b/runtime/asgard/src/lib.rs index 9c69dd4623..d36fb997a4 100644 --- a/runtime/asgard/src/lib.rs +++ b/runtime/asgard/src/lib.rs @@ -94,6 +94,7 @@ use node_primitives::{ // orml imports use orml_currencies::BasicCurrencyAdapter; use orml_traits::MultiCurrency; +use orml_xcm_support::MultiCurrencyAdapter; use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use sp_runtime::traits::ConvertInto; @@ -106,10 +107,10 @@ use xcm_builder::{ EnsureXcmOrigin, FixedRateOfConcreteFungible, FixedWeightBounds, IsConcrete, LocationInverter, ParentAsSuperuser, ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, - SovereignSignedViaLocation, TakeRevenue, TakeWeightCredit, UsingComponents, + SovereignSignedViaLocation, TakeRevenue, TakeWeightCredit, }; use xcm_executor::{Config, XcmExecutor}; -use xcm_support::{BifrostCurrencyAdapter, BifrostXcmAdaptor}; +use xcm_support::BifrostXcmAdaptor; // zenlink imports use zenlink_protocol::{ make_x2_location, AssetBalance, AssetId, LocalAssetHandler, MultiAssetsHandler, PairInfo, @@ -758,8 +759,9 @@ pub type Barrier = ( BifrostXcmTransactFilter, ); -pub type BifrostAssetTransactor = BifrostCurrencyAdapter< - Tokens, +pub type BifrostAssetTransactor = MultiCurrencyAdapter< + Currencies, + UnknownTokens, BifrostAssetMatcher>, AccountId, LocationToAccountId, @@ -1265,6 +1267,10 @@ impl orml_xtokens::Config for Runtime { type BaseXcmWeight = XcmWeight; } +impl orml_unknown_tokens::Config for Runtime { + type Event = Event; +} + // orml runtime end construct_runtime! { @@ -1324,6 +1330,7 @@ construct_runtime! { XTokens: orml_xtokens::{Pallet, Call, Event} = 70, Tokens: orml_tokens::{Pallet, Call, Storage, Event, Config} = 71, Currencies: orml_currencies::{Pallet, Call, Event} = 72, + UnknownTokens: orml_unknown_tokens::{Pallet, Storage, Event} = 73, // Bifrost modules VtokenMint: bifrost_vtoken_mint::{Pallet, Call, Storage, Event, Config} = 101, diff --git a/runtime/bifrost/Cargo.toml b/runtime/bifrost/Cargo.toml index a9c9fd489d..29bfcf4afd 100644 --- a/runtime/bifrost/Cargo.toml +++ b/runtime/bifrost/Cargo.toml @@ -94,8 +94,9 @@ xcm-support = { path = "../../xcm-support", default-features = false } orml-currencies = { version = "0.4.1-dev", default-features = false } orml-tokens = { version = "0.4.1-dev", default-features = false } orml-traits = { version = "0.4.1-dev", default-features = false } -orml-xcm-support = { version = "0.4.1-dev", default-features = false } orml-xtokens = { version = "0.4.1-dev", default-features = false } +orml-unknown-tokens = { version = "0.4.1-dev", default-features = false } +orml-xcm-support = { version = "0.4.1-dev", default-features = false } [build-dependencies] substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9" } @@ -155,6 +156,7 @@ std = [ "orml-traits/std", "orml-tokens/std", "orml-xtokens/std", + "orml-unknown-tokens/std", "orml-xcm-support/std", "bifrost-runtime-common/std", "bifrost-flexible-fee/std", diff --git a/runtime/bifrost/src/lib.rs b/runtime/bifrost/src/lib.rs index f517a26287..836c662a61 100644 --- a/runtime/bifrost/src/lib.rs +++ b/runtime/bifrost/src/lib.rs @@ -79,13 +79,14 @@ use frame_support::{ use frame_system::{EnsureOneOf, EnsureRoot, RawOrigin}; use hex_literal::hex; use node_primitives::{ - Amount, CurrencyId, Moment, Nonce, ParaId, ParachainDerivedProxyAccountType, + Amount, CurrencyId, Moment, Nonce, ParachainDerivedProxyAccountType, ParachainTransactProxyType, ParachainTransactType, TokenSymbol, TransferOriginType, XcmBaseWeight, }; // orml imports use orml_currencies::BasicCurrencyAdapter; use orml_traits::MultiCurrency; +use orml_xcm_support::MultiCurrencyAdapter; use pallet_xcm::XcmPassthrough; // XCM imports use polkadot_parachain::primitives::Sibling; @@ -99,10 +100,10 @@ use xcm_builder::{ EnsureXcmOrigin, FixedRateOfConcreteFungible, FixedWeightBounds, IsConcrete, LocationInverter, ParentAsSuperuser, ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, - SovereignSignedViaLocation, TakeRevenue, TakeWeightCredit, UsingComponents, + SovereignSignedViaLocation, TakeRevenue, TakeWeightCredit, }; use xcm_executor::{Config, XcmExecutor}; -use xcm_support::{BifrostCurrencyAdapter, BifrostXcmAdaptor, Get}; +use xcm_support::{BifrostXcmAdaptor, Get}; // Weights used in the runtime. mod weights; @@ -670,8 +671,9 @@ pub type Barrier = ( BifrostXcmTransactFilter, ); -pub type BifrostAssetTransactor = BifrostCurrencyAdapter< - Tokens, +pub type BifrostAssetTransactor = MultiCurrencyAdapter< + Currencies, + UnknownTokens, BifrostAssetMatcher>, AccountId, LocationToAccountId, @@ -884,6 +886,10 @@ impl orml_xtokens::Config for Runtime { type BaseXcmWeight = XcmWeight; } +impl orml_unknown_tokens::Config for Runtime { + type Event = Event; +} + // orml runtime end // Bifrost modules start @@ -1062,9 +1068,10 @@ construct_runtime! { Bounties: pallet_bounties::{Pallet, Call, Storage, Event} = 62, Tips: pallet_tips::{Pallet, Call, Storage, Event} = 63, - XTokens: orml_xtokens::{Pallet, Storage, Call, Event} = 70, + XTokens: orml_xtokens::{Pallet, Call, Event} = 70, Tokens: orml_tokens::{Pallet, Call, Storage, Event} = 71, Currencies: orml_currencies::{Pallet, Call, Event} = 72, + UnknownTokens: orml_unknown_tokens::{Pallet, Storage, Event} = 73, // Bifrost modules FlexibleFee: bifrost_flexible_fee::{Pallet, Call, Storage, Event} = 100, diff --git a/runtime/common/src/xcm_impl.rs b/runtime/common/src/xcm_impl.rs index 74222f96a5..33c1569434 100644 --- a/runtime/common/src/xcm_impl.rs +++ b/runtime/common/src/xcm_impl.rs @@ -114,44 +114,48 @@ fn native_currency_location(id: CurrencyId, para_id: ParaId) -> MultiLocation { pub struct BifrostCurrencyIdConvert(sp_std::marker::PhantomData); impl> Convert> for BifrostCurrencyIdConvert { fn convert(id: CurrencyId) -> Option { - use CurrencyId::{Native, Stable, Token}; + use CurrencyId::{Native, Token}; match id { Token(TokenSymbol::KSM) => Some(X1(Parent)), Native(TokenSymbol::ASG) | Native(TokenSymbol::BNC) => Some(native_currency_location(id, T::get())), // Karura currencyId types - Token(TokenSymbol::KAR) | Stable(TokenSymbol::KUSD) => - Some(X3(Parent, Parachain(2000), GeneralKey(id.encode()))), + Token(TokenSymbol::KAR) => + Some(X3(Parent, Parachain(2000), GeneralKey([0, 128].to_vec()))), + Token(TokenSymbol::KUSD) => + Some(X3(Parent, Parachain(2000), GeneralKey([0, 129].to_vec()))), _ => None, } } } impl> Convert> for BifrostCurrencyIdConvert { fn convert(location: MultiLocation) -> Option { - use CurrencyId::{Native, Stable, Token}; + use CurrencyId::{Native, Token}; use TokenSymbol::*; match location { X1(Parent) => Some(Token(KSM)), X3(Parent, Junction::Parachain(id), GeneralKey(key)) => { - // decode the general key - if let Ok(currency_id) = CurrencyId::decode(&mut &key[..]) { - // check `currency_id` is cross-chain asset - if ParaId::from(id) == T::get() { + // check `currency_id` is cross-chain asset + if ParaId::from(id) == T::get() { + // decode the general key + if let Ok(currency_id) = CurrencyId::decode(&mut &key[..]) { match currency_id { - Native(TokenSymbol::ASG) | Native(TokenSymbol::BNC) => - Some(currency_id), - _ => None, - } - // Kurara CurrencyId types - } else if id == 2000 { - match currency_id { - Token(TokenSymbol::KAR) | Stable(TokenSymbol::KUSD) => - Some(currency_id), + Native(TokenSymbol::ASG) => Some(Native(TokenSymbol::ASG)), + Native(TokenSymbol::BNC) => Some(Native(TokenSymbol::BNC)), _ => None, } } else { None } + // Kurara CurrencyId types + } else if id == 2000 { + if key == [0, 128].to_vec() { + Some(Token(TokenSymbol::KAR)) + } else if key == [0, 129].to_vec() { + Some(Token(TokenSymbol::KUSD)) + } else { + None + } } else { None } diff --git a/runtime/dev/Cargo.toml b/runtime/dev/Cargo.toml index 0c6d644e56..0b4ef325fc 100644 --- a/runtime/dev/Cargo.toml +++ b/runtime/dev/Cargo.toml @@ -98,6 +98,7 @@ orml-currencies = { version = "0.4.1-dev", default-features = false } orml-tokens = { version = "0.4.1-dev", default-features = false } orml-traits = { version = "0.4.1-dev", default-features = false } orml-xtokens = { version = "0.4.1-dev", default-features = false } +orml-unknown-tokens = { version = "0.4.1-dev", default-features = false } orml-xcm-support = { version = "0.4.1-dev", default-features = false } zenlink-protocol = { version = "*", default-features = false } diff --git a/runtime/dev/src/lib.rs b/runtime/dev/src/lib.rs index b73df56f59..35e0d61718 100644 --- a/runtime/dev/src/lib.rs +++ b/runtime/dev/src/lib.rs @@ -99,6 +99,7 @@ use node_primitives::{ // orml imports use orml_currencies::BasicCurrencyAdapter; use orml_traits::MultiCurrency; +use orml_xcm_support::MultiCurrencyAdapter; use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use sp_runtime::traits::ConvertInto; @@ -112,7 +113,7 @@ use xcm_builder::{ UsingComponents, }; use xcm_executor::{Config, XcmExecutor}; -use xcm_support::{BifrostCurrencyAdapter, BifrostXcmAdaptor}; +use xcm_support::BifrostXcmAdaptor; // zenlink imports use zenlink_protocol::{ make_x2_location, AssetBalance, AssetId, LocalAssetHandler, MultiAssetsHandler, PairInfo, @@ -757,8 +758,9 @@ pub type Barrier = ( BifrostXcmTransactFilter, ); -pub type BifrostAssetTransactor = BifrostCurrencyAdapter< - Tokens, +pub type BifrostAssetTransactor = MultiCurrencyAdapter< + Currencies, + UnknownTokens, BifrostAssetMatcher>, AccountId, LocationToAccountId, @@ -1199,6 +1201,10 @@ impl orml_xtokens::Config for Runtime { type BaseXcmWeight = XcmWeight; } +impl orml_unknown_tokens::Config for Runtime { + type Event = Event; +} + // orml runtime end construct_runtime! { @@ -1254,6 +1260,7 @@ construct_runtime! { XTokens: orml_xtokens::{Pallet, Call, Event} = 70, Tokens: orml_tokens::{Pallet, Call, Storage, Event, Config} = 71, Currencies: orml_currencies::{Pallet, Call, Event} = 72, + UnknownTokens: orml_unknown_tokens::{Pallet, Storage, Event} = 73, // Bifrost modules VtokenMint: bifrost_vtoken_mint::{Pallet, Call, Storage, Event, Config} = 101, diff --git a/xcm-support/src/lib.rs b/xcm-support/src/lib.rs index 60bbd2a59d..9971a3f292 100644 --- a/xcm-support/src/lib.rs +++ b/xcm-support/src/lib.rs @@ -26,27 +26,17 @@ #![cfg_attr(not(feature = "std"), no_std)] -use codec::{Encode, FullCodec}; +use codec::Encode; pub use cumulus_primitives_core::{self, ParaId}; pub use frame_support::{traits::Get, weights::Weight}; pub use paste; -use sp_runtime::traits::{Convert, MaybeSerializeDeserialize, SaturatedConversion}; pub use sp_std::{cell::RefCell, marker::PhantomData}; -use sp_std::{ - cmp::{Eq, PartialEq}, - fmt::Debug, - prelude::*, - vec, -}; +use sp_std::{prelude::*, vec}; pub use xcm::VersionedXcm; use xcm::{ - v0::{ - Error as XcmError, Junction, MultiAsset, MultiLocation, OriginKind, Result as XcmResult, - SendXcm, Xcm, - }, + v0::{Error as XcmError, Junction, MultiAsset, MultiLocation, OriginKind, SendXcm, Xcm}, DoubleEncoded, }; -use xcm_executor::traits::{Convert as xcmConvert, MatchesFungible, TransactAsset}; pub use xcm_executor::XcmExecutor; mod calls; mod traits; @@ -56,6 +46,8 @@ use node_primitives::MessageId; pub use node_primitives::XcmBaseWeight; pub use traits::{BifrostXcmExecutor, HandleDmpMessage, HandleUmpMessage, HandleXcmpMessage}; #[allow(unused_imports)] +use xcm::opaque::v0::prelude::XcmResult; +#[allow(unused_imports)] use xcm::v0::{ prelude::{Parachain, Parent, X1, X2}, Order, @@ -68,6 +60,7 @@ mod mock; mod tests; /// Asset transaction errors. +#[allow(dead_code)] enum Error { /// Failed to match fungible. FailedToMatchFungible, @@ -90,76 +83,6 @@ impl From for XcmError { } } -/// The `TransactAsset` implementation, to handle `MultiAsset` deposit/withdraw. -/// -/// If the asset is known, deposit/withdraw will be handled by `MultiCurrency`, -/// else by `UnknownAsset` if unknown. -pub struct BifrostCurrencyAdapter< - MultiCurrency, - Matcher, - AccountId, - AccountIdConvert, - CurrencyId, - CurrencyIdConvert, ->( - PhantomData<( - MultiCurrency, - Matcher, - AccountId, - AccountIdConvert, - CurrencyId, - CurrencyIdConvert, - )>, -); - -impl< - MultiCurrency: orml_traits::MultiCurrency, - Matcher: MatchesFungible, - AccountId: sp_std::fmt::Debug + sp_std::clone::Clone, - AccountIdConvert: xcmConvert, - CurrencyId: FullCodec + Eq + PartialEq + Copy + MaybeSerializeDeserialize + Debug, - CurrencyIdConvert: Convert>, - > TransactAsset - for BifrostCurrencyAdapter< - MultiCurrency, - Matcher, - AccountId, - AccountIdConvert, - CurrencyId, - CurrencyIdConvert, - > -{ - fn deposit_asset(asset: &MultiAsset, location: &MultiLocation) -> XcmResult { - match ( - AccountIdConvert::convert_ref(location.clone()), - CurrencyIdConvert::convert(asset.clone()), - Matcher::matches_fungible(&asset), - ) { - // known asset - (Ok(who), Some(currency_id), Some(amount)) => - MultiCurrency::deposit(currency_id, &who, amount) - .map_err(|e| XcmError::FailedToTransactAsset(e.into())), - _ => Err(XcmError::AssetNotFound), - } - } - - fn withdraw_asset( - asset: &MultiAsset, - location: &MultiLocation, - ) -> Result { - let who = AccountIdConvert::convert_ref(location) - .map_err(|_| XcmError::from(Error::AccountIdConversionFailed))?; - let currency_id = CurrencyIdConvert::convert(asset.clone()) - .ok_or_else(|| XcmError::from(Error::CurrencyIdConversionFailed))?; - let amount: MultiCurrency::Balance = Matcher::matches_fungible(&asset) - .ok_or_else(|| XcmError::from(Error::FailedToMatchFungible))? - .saturated_into(); - MultiCurrency::withdraw(currency_id, &who, amount) - .map_err(|e| XcmError::FailedToTransactAsset(e.into()))?; - Ok(asset.clone().into()) - } -} - pub struct BifrostXcmAdaptor( PhantomData<(XcmSender, BaseXcmWeight, WeightToFee)>, );