mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 10:31:03 +00:00
Asset Conversion release to westmint (#2148)
* Dex and payment by dex in westmint * Wrap U256 type for now (to support required traits.) * cargo fmt * We can now use U256 * Rename PromotedBalance * name change * Updating the code to master. TODO: handle dust! * cargo fmt * Minimising changes and step towards getting benchmarks compiling (still a From<u32> bound in the pallet) * minimise diff * Update parachains/runtimes/assets/westmint/src/lib.rs Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com> * Update parachains/runtimes/assets/westmint/src/lib.rs Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com> * Update parachains/common/src/impls.rs Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com> * Fix benchmark build * Add in AssetConversionAPI * Handle dust * cargo fmt * Don't need to be explicit that it's AccountId32 * remove pool setup fee (Asset deposit fees are a sufficient anti-spam measure) * More natural way to specify native * cargo fmt * Update parachains/runtimes/assets/westmint/src/lib.rs * Additional required impls * either form of multilocation should be acceptable. * add call filter exclusion * Fix typo & try_convert now fails if native is converted * merge master fixup * Fix: HoldReason should be there. * Box MultiAssetId Otherwise it blows out the Call enum memory size. * cargo fmt * update lock file * add std feature, update lock file * need to turn on std on common * adding in westmint tests * WeightToFee must be from the destination chain. * cargo fmt * account for higher ED on westmint * type removed as not used * cargo fmt * remove unused import * minimising diff * import needed only with feature enabled * use multilocation contains * move the impls to separate file * simplify on conversion * simplify on reverse conversion also. * rename var * clippy * removed dead code * cargo fmt * Use pay by swap * review suggestions * cargo fmt * Update parachains/runtimes/assets/asset-hub-westend/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * add benchmarks for new assets pallet * revert common/src changes * need a concrete id * more fixes * lock --------- Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com> Co-authored-by: joepetrowski <joe@parity.io> Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
This commit is contained in:
@@ -16,6 +16,7 @@ sp-core = { default-features = false, git = "https://github.com/paritytech/subst
|
||||
sp-weights = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
pallet-assets = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
pallet-asset-conversion = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
# Polkadot
|
||||
polkadot-core-primitives = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" }
|
||||
|
||||
@@ -26,7 +26,8 @@ pub use integration_tests_common::{
|
||||
},
|
||||
AccountId, AssetHubWestend, AssetHubWestendPallet, AssetHubWestendReceiver,
|
||||
AssetHubWestendSender, Collectives, CollectivesPallet, CollectivesReceiver, CollectivesSender,
|
||||
PenpalWestend, Westend, WestendPallet, WestendReceiver, WestendSender,
|
||||
PenpalWestend, PenpalWestendPallet, PenpalWestendReceiver, PenpalWestendSender, Westend,
|
||||
WestendPallet, WestendReceiver, WestendSender,
|
||||
};
|
||||
pub use polkadot_core_primitives::InboundDownwardMessage;
|
||||
pub use xcm::{
|
||||
|
||||
+1
@@ -15,5 +15,6 @@
|
||||
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
mod reserve_transfer;
|
||||
mod swap;
|
||||
mod teleport;
|
||||
mod transact;
|
||||
|
||||
+307
@@ -0,0 +1,307 @@
|
||||
use crate::*;
|
||||
use frame_support::{instances::Instance2, BoundedVec};
|
||||
use xcm_emulator::Parachain;
|
||||
|
||||
#[test]
|
||||
fn swap_locally_on_chain_using_local_assets() {
|
||||
const ASSET_ID: u32 = 1;
|
||||
|
||||
let asset_native = Box::new(MultiLocation { parents: 0, interior: Here });
|
||||
let asset_one = Box::new(MultiLocation {
|
||||
parents: 0,
|
||||
interior: X2(PalletInstance(50), GeneralIndex(ASSET_ID.into())),
|
||||
});
|
||||
|
||||
AssetHubWestend::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubWestend as Parachain>::RuntimeEvent;
|
||||
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::Assets::create(
|
||||
<AssetHubWestend as Parachain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
|
||||
ASSET_ID.into(),
|
||||
AssetHubWestendSender::get().into(),
|
||||
1000,
|
||||
));
|
||||
assert!(<AssetHubWestend as AssetHubWestendPallet>::Assets::asset_exists(ASSET_ID));
|
||||
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::Assets::mint(
|
||||
<AssetHubWestend as Parachain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
|
||||
ASSET_ID.into(),
|
||||
AssetHubWestendSender::get().into(),
|
||||
3_000_000_000_000,
|
||||
));
|
||||
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::create_pool(
|
||||
<AssetHubWestend as Parachain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
|
||||
asset_native.clone(),
|
||||
asset_one.clone(),
|
||||
));
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {},
|
||||
]
|
||||
);
|
||||
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::add_liquidity(
|
||||
<AssetHubWestend as Parachain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
|
||||
asset_native.clone(),
|
||||
asset_one.clone(),
|
||||
1_000_000_000_000,
|
||||
2_000_000_000_000,
|
||||
0,
|
||||
0,
|
||||
AssetHubWestendSender::get().into()
|
||||
));
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => { lp_token_minted: *lp_token_minted == 1414213562273, },
|
||||
]
|
||||
);
|
||||
|
||||
let path = BoundedVec::<_, _>::truncate_from(vec![asset_native.clone(), asset_one.clone()]);
|
||||
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::swap_exact_tokens_for_tokens(
|
||||
<AssetHubWestend as Parachain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
|
||||
path,
|
||||
100,
|
||||
1,
|
||||
AssetHubWestendSender::get().into(),
|
||||
true
|
||||
));
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapExecuted { amount_in, amount_out, .. }) => {
|
||||
amount_in: *amount_in == 100,
|
||||
amount_out: *amount_out == 199,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::remove_liquidity(
|
||||
<AssetHubWestend as Parachain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
|
||||
asset_native,
|
||||
asset_one,
|
||||
1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved.
|
||||
0,
|
||||
0,
|
||||
AssetHubWestendSender::get().into(),
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn swap_locally_on_chain_using_foreign_assets() {
|
||||
use frame_support::weights::WeightToFee;
|
||||
|
||||
const ASSET_ID: u32 = 1;
|
||||
let asset_native = Box::new(MultiLocation { parents: 0, interior: Here });
|
||||
|
||||
let foreign_asset1_at_asset_hub_westend = Box::new(MultiLocation {
|
||||
parents: 1,
|
||||
interior: X3(
|
||||
Parachain(PenpalWestend::para_id().into()),
|
||||
PalletInstance(50),
|
||||
GeneralIndex(ASSET_ID.into()),
|
||||
),
|
||||
});
|
||||
|
||||
let assets_para_destination: VersionedMultiLocation =
|
||||
MultiLocation { parents: 1, interior: X1(Parachain(AssetHubWestend::para_id().into())) }
|
||||
.into();
|
||||
|
||||
let penpal_location =
|
||||
MultiLocation { parents: 1, interior: X1(Parachain(PenpalWestend::para_id().into())) };
|
||||
|
||||
// 1. Create asset on penpal:
|
||||
PenpalWestend::execute_with(|| {
|
||||
assert_ok!(<PenpalWestend as PenpalWestendPallet>::Assets::create(
|
||||
<PenpalWestend as Parachain>::RuntimeOrigin::signed(PenpalWestendSender::get()),
|
||||
ASSET_ID.into(),
|
||||
PenpalWestendSender::get().into(),
|
||||
1000,
|
||||
));
|
||||
|
||||
assert!(<PenpalWestend as PenpalWestendPallet>::Assets::asset_exists(ASSET_ID));
|
||||
});
|
||||
|
||||
// 2. Create foreign asset on asset_hub_westend:
|
||||
|
||||
let require_weight_at_most = Weight::from_parts(1_100_000_000_000, 30_000);
|
||||
let origin_kind = OriginKind::Xcm;
|
||||
let sov_penpal_on_asset_hub_westend = AssetHubWestend::sovereign_account_id_of(penpal_location);
|
||||
|
||||
AssetHubWestend::fund_accounts(vec![
|
||||
(AssetHubWestendSender::get(), 5_000_000), // An account to swap dot for something else.
|
||||
(sov_penpal_on_asset_hub_westend.clone(), 1000_000_000_000_000_000),
|
||||
]);
|
||||
|
||||
let sov_penpal_on_asset_hub_westend_as_location: MultiLocation = MultiLocation {
|
||||
parents: 0,
|
||||
interior: X1(AccountId32 {
|
||||
network: None,
|
||||
id: sov_penpal_on_asset_hub_westend.clone().into(),
|
||||
}),
|
||||
};
|
||||
|
||||
let call_foreign_assets_create =
|
||||
<AssetHubWestend as Para>::RuntimeCall::ForeignAssets(pallet_assets::Call::<
|
||||
<AssetHubWestend as Para>::Runtime,
|
||||
Instance2,
|
||||
>::create {
|
||||
id: *foreign_asset1_at_asset_hub_westend,
|
||||
min_balance: 1000,
|
||||
admin: sov_penpal_on_asset_hub_westend.clone().into(),
|
||||
})
|
||||
.encode()
|
||||
.into();
|
||||
|
||||
let buy_execution_fee_amount =
|
||||
asset_hub_westend_runtime::constants::fee::WeightToFee::weight_to_fee(&Weight::from_parts(
|
||||
10_100_000_000_000,
|
||||
300_000,
|
||||
));
|
||||
let buy_execution_fee = MultiAsset {
|
||||
id: Concrete(MultiLocation { parents: 1, interior: Here }),
|
||||
fun: Fungible(buy_execution_fee_amount),
|
||||
};
|
||||
|
||||
let xcm = VersionedXcm::from(Xcm(vec![
|
||||
WithdrawAsset { 0: vec![buy_execution_fee.clone()].into() },
|
||||
BuyExecution { fees: buy_execution_fee.clone(), weight_limit: Unlimited },
|
||||
Transact { require_weight_at_most, origin_kind, call: call_foreign_assets_create },
|
||||
RefundSurplus,
|
||||
DepositAsset {
|
||||
assets: All.into(),
|
||||
beneficiary: sov_penpal_on_asset_hub_westend_as_location,
|
||||
},
|
||||
]));
|
||||
|
||||
// Send XCM message from penpal => asset_hub_westend
|
||||
let sudo_penpal_origin = <PenpalWestend as Parachain>::RuntimeOrigin::root();
|
||||
PenpalWestend::execute_with(|| {
|
||||
assert_ok!(<PenpalWestend as PenpalWestendPallet>::PolkadotXcm::send(
|
||||
sudo_penpal_origin.clone(),
|
||||
bx!(assets_para_destination.clone()),
|
||||
bx!(xcm),
|
||||
));
|
||||
|
||||
type RuntimeEvent = <PenpalWestend as Parachain>::RuntimeEvent;
|
||||
|
||||
assert_expected_events!(
|
||||
PenpalWestend,
|
||||
vec![
|
||||
RuntimeEvent::PolkadotXcm(pallet_xcm::Event::Sent { .. }) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
// Receive XCM message in Assets Parachain
|
||||
AssetHubWestend::execute_with(|| {
|
||||
assert!(<AssetHubWestend as AssetHubWestendPallet>::ForeignAssets::asset_exists(
|
||||
*foreign_asset1_at_asset_hub_westend
|
||||
));
|
||||
|
||||
// 3: Mint foreign asset on asset_hub_westend:
|
||||
//
|
||||
// (While it might be nice to use batch,
|
||||
// currently that's disabled due to safe call filters.)
|
||||
|
||||
type RuntimeEvent = <AssetHubWestend as Parachain>::RuntimeEvent;
|
||||
// 3. Mint foreign asset (in reality this should be a teleport or some such)
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::ForeignAssets::mint(
|
||||
<AssetHubWestend as Parachain>::RuntimeOrigin::signed(
|
||||
sov_penpal_on_asset_hub_westend.clone().into()
|
||||
),
|
||||
*foreign_asset1_at_asset_hub_westend,
|
||||
sov_penpal_on_asset_hub_westend.clone().into(),
|
||||
3_000_000_000_000,
|
||||
));
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {},
|
||||
]
|
||||
);
|
||||
|
||||
// 4. Create pool:
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::create_pool(
|
||||
<AssetHubWestend as Parachain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
|
||||
asset_native.clone(),
|
||||
foreign_asset1_at_asset_hub_westend.clone(),
|
||||
));
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {},
|
||||
]
|
||||
);
|
||||
|
||||
// 5. Add liquidity:
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::add_liquidity(
|
||||
<AssetHubWestend as Parachain>::RuntimeOrigin::signed(
|
||||
sov_penpal_on_asset_hub_westend.clone()
|
||||
),
|
||||
asset_native.clone(),
|
||||
foreign_asset1_at_asset_hub_westend.clone(),
|
||||
1_000_000_000_000,
|
||||
2_000_000_000_000,
|
||||
0,
|
||||
0,
|
||||
sov_penpal_on_asset_hub_westend.clone().into()
|
||||
));
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => {
|
||||
lp_token_minted: *lp_token_minted == 1414213562273,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
// 6. Swap!
|
||||
let path = BoundedVec::<_, _>::truncate_from(vec![
|
||||
asset_native.clone(),
|
||||
foreign_asset1_at_asset_hub_westend.clone(),
|
||||
]);
|
||||
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::swap_exact_tokens_for_tokens(
|
||||
<AssetHubWestend as Parachain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
|
||||
path,
|
||||
100000,
|
||||
1000,
|
||||
AssetHubWestendSender::get().into(),
|
||||
true
|
||||
));
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapExecuted { amount_in, amount_out, .. },) => {
|
||||
amount_in: *amount_in == 100000,
|
||||
amount_out: *amount_out == 199399,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
// 7. Remove liquidity
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::remove_liquidity(
|
||||
<AssetHubWestend as Parachain>::RuntimeOrigin::signed(
|
||||
sov_penpal_on_asset_hub_westend.clone()
|
||||
),
|
||||
asset_native,
|
||||
foreign_asset1_at_asset_hub_westend,
|
||||
1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved.
|
||||
0,
|
||||
0,
|
||||
sov_penpal_on_asset_hub_westend.clone().into(),
|
||||
));
|
||||
});
|
||||
}
|
||||
@@ -98,6 +98,7 @@ decl_test_parachains! {
|
||||
PolkadotXcm: asset_hub_westend_runtime::PolkadotXcm,
|
||||
Assets: asset_hub_westend_runtime::Assets,
|
||||
ForeignAssets: asset_hub_westend_runtime::ForeignAssets,
|
||||
AssetConversion: asset_hub_westend_runtime::AssetConversion,
|
||||
}
|
||||
},
|
||||
// Polkadot
|
||||
|
||||
Reference in New Issue
Block a user