pallet-asset-conversion: Decoupling Native Currency Dependancy (#2031)

closes https://github.com/paritytech/polkadot-sdk/issues/1842

Decoupling Pallet from the Concept of Native Currency

Currently, the pallet is intrinsically linked with the concept of native
currency, requiring users to provide implementations of the
`fungible::*` and `fungibles::*` traits to interact with native and non
native assets. This incapsulates some non-related to the pallet
complexity and makes it less adaptable in contexts where the native
currency concept is absent.

With this PR, the dependence on `fungible::*` for liquidity-supplying
assets has been removed. Instead, the native and non-native currencies'
handling is now overseen by a single type that implements the
`fungibles::*` traits. To simplify this integration, types have been
introduced to facilitate the creation of a union between `fungible::*`
and `fungibles::*` implementations, producing a unified `fungibles::*`
type.

One of the reasons driving these changes is the ambition to create a
more user-friendly API for the `SwapCredit` implementation. Given that
it interacts with two distinct credit types from `fungible` and
`fungibles`, a unified type was introduced. Clients now manage potential
conversion failures for those credit types. In certain contexts, it's
vital to guarantee that operations are fail-safe, like in this impl -
[PR](https://github.com/paritytech/polkadot-sdk/pull/1845), place in
[code](https://github.com/paritytech/polkadot-sdk/blob/20b85a5fada8f55c98ba831964f5866ffeadf4da/cumulus/primitives/utility/src/lib.rs#L429).

Additional Updates:
- abstracted the pool ID and its account derivation logic via trait
bounds, along with common implementation offerings;
- removed `inc_providers` on a pool creation for the pool account;
- benchmarks:
-- swap complexity is N, not const;
-- removed `From<u128> + Into<u128>` bound from `T::Balance`;
-- removed swap/liquidity/.. amount constants, resolve them dynamically
based on pallet configuration;
-- migrated to v2 API;
- `OnUnbalanced` handler for the pool creation fee, replacing direct
transfers to a specified account ID;
- renamed `MultiAssetId` to `AssetKind` aligning with naming across
frame crates;

related PRs:
- (depends) https://github.com/paritytech/polkadot-sdk/pull/1677
- (caused) https://github.com/paritytech/polkadot-sdk/pull/2033
- (caused) https://github.com/paritytech/polkadot-sdk/pull/1876

---------

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>
This commit is contained in:
Muharem
2023-12-20 13:57:26 +01:00
committed by GitHub
parent d32f66fb8f
commit 4f832ea865
26 changed files with 1750 additions and 4571 deletions
@@ -29,7 +29,7 @@ pub mod xcm_config;
use assets_common::{
foreign_creators::ForeignCreators,
local_and_foreign_assets::{LocalAndForeignAssets, MultiLocationConverter},
local_and_foreign_assets::{LocalFromLeft, TargetFromLeft},
matching::FromSiblingParachain,
AssetIdForTrustBackedAssetsConvert, MultiLocationForAssetId,
};
@@ -57,8 +57,9 @@ use frame_support::{
genesis_builder_helper::{build_config, create_default_config},
ord_parameter_types, parameter_types,
traits::{
AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse,
Equals, InstanceFilter, TransformOrigin,
fungible, fungibles, tokens::imbalance::ResolveAssetTo, AsEnsureOriginWithArg, ConstBool,
ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, InstanceFilter,
TransformOrigin,
},
weights::{ConstantMultiplier, Weight},
BoundedVec, PalletId,
@@ -82,8 +83,9 @@ use parachains_common::{
use sp_runtime::{Perbill, RuntimeDebug};
use xcm::opaque::v3::MultiLocation;
use xcm_config::{
ForeignAssetsConvertedConcreteId, GovernanceLocation, PoolAssetsConvertedConcreteId,
TokenLocation, TrustBackedAssetsConvertedConcreteId,
ForeignAssetsConvertedConcreteId, ForeignCreatorsSovereignAccountOf, GovernanceLocation,
PoolAssetsConvertedConcreteId, TokenLocation, TrustBackedAssetsConvertedConcreteId,
TrustBackedAssetsPalletLocation,
};
#[cfg(any(feature = "std", test))]
@@ -94,10 +96,6 @@ use pallet_xcm::{EnsureXcm, IsVoiceOfBody};
use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
use xcm::latest::prelude::*;
use crate::xcm_config::{
ForeignCreatorsSovereignAccountOf, LocalAndForeignAssetsMultiLocationMatcher,
TrustBackedAssetsPalletLocation,
};
use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
impl_opaque_keys! {
@@ -279,8 +277,6 @@ impl pallet_assets::Config<TrustBackedAssetsInstance> for Runtime {
parameter_types! {
pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon");
pub const AllowMultiAssetPools: bool = false;
// should be non-zero if AllowMultiAssetPools is true, otherwise can be zero
pub const LiquidityWithdrawalFee: Permill = Permill::from_percent(0);
}
@@ -315,35 +311,50 @@ impl pallet_assets::Config<PoolAssetsInstance> for Runtime {
type BenchmarkHelper = ();
}
/// Union fungibles implementation for `Assets`` and `ForeignAssets`.
pub type LocalAndForeignAssets = fungibles::UnionOf<
Assets,
ForeignAssets,
LocalFromLeft<
AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation>,
AssetIdForTrustBackedAssets,
>,
MultiLocation,
AccountId,
>;
impl pallet_asset_conversion::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Balance = Balance;
type HigherPrecisionBalance = sp_core::U256;
type Currency = Balances;
type AssetId = MultiLocation;
type Assets = LocalAndForeignAssets<
Assets,
AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation>,
ForeignAssets,
type AssetKind = MultiLocation;
type Assets = fungible::UnionOf<
Balances,
LocalAndForeignAssets,
TargetFromLeft<TokenLocation>,
Self::AssetKind,
Self::AccountId,
>;
type PoolAssets = PoolAssets;
type PoolId = (Self::AssetKind, Self::AssetKind);
type PoolLocator =
pallet_asset_conversion::WithFirstAsset<TokenLocation, AccountId, Self::AssetKind>;
type PoolAssetId = u32;
type PoolAssets = PoolAssets;
type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam
type PoolSetupFeeReceiver = AssetConversionOrigin;
// should be non-zero if `AllowMultiAssetPools` is true, otherwise can be zero.
type PoolSetupFeeAsset = TokenLocation;
type PoolSetupFeeTarget = ResolveAssetTo<AssetConversionOrigin, Self::Assets>;
type LiquidityWithdrawalFee = LiquidityWithdrawalFee;
type LPFee = ConstU32<3>;
type PalletId = AssetConversionPalletId;
type AllowMultiAssetPools = AllowMultiAssetPools;
type MaxSwapPathLength = ConstU32<4>;
type MultiAssetId = MultiLocation;
type MultiAssetIdConverter =
MultiLocationConverter<TokenLocation, LocalAndForeignAssetsMultiLocationMatcher>;
type MaxSwapPathLength = ConstU32<3>;
type MintMinLiquidity = ConstU128<100>;
type WeightInfo = weights::pallet_asset_conversion::WeightInfo<Runtime>;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper =
crate::xcm_config::BenchmarkMultiLocationConverter<parachain_info::Pallet<Runtime>>;
type BenchmarkHelper = assets_common::benchmarks::AssetPairFactory<
TokenLocation,
parachain_info::Pallet<Runtime>,
xcm_config::AssetsPalletIndex,
>;
}
parameter_types! {
@@ -733,12 +744,9 @@ impl pallet_collator_selection::Config for Runtime {
impl pallet_asset_conversion_tx_payment::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Fungibles = LocalAndForeignAssets<
Assets,
AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation>,
ForeignAssets,
>;
type OnChargeAssetTransaction = AssetConversionAdapter<Balances, AssetConversion>;
type Fungibles = LocalAndForeignAssets;
type OnChargeAssetTransaction =
AssetConversionAdapter<Balances, AssetConversion, TokenLocation>;
}
parameter_types! {
@@ -1154,7 +1162,7 @@ impl_runtime_apis! {
}
fn get_reserves(asset1: MultiLocation, asset2: MultiLocation) -> Option<(Balance, Balance)> {
AssetConversion::get_reserves(&asset1, &asset2).ok()
AssetConversion::get_reserves(asset1, asset2).ok()
}
}