Skip to content
4 changes: 0 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// 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 crate::{
create_pool_with_wnd_on,
imports::{
asset_hub_westend_runtime::{ExistentialDeposit, Runtime},
*,
},
};
use asset_hub_westend_runtime::{
xcm_config::WestendLocation, Balances, ForeignAssets, PolkadotXcm, RuntimeOrigin,
};
use emulated_integration_tests_common::{accounts::ALICE, xcm_emulator::TestExt};
use frame_support::{
assert_err_ignore_postinfo, assert_ok,
traits::fungible::{Inspect, Mutate},
};
use parachains_common::{AccountId, Balance};
use std::convert::Into;
use xcm::latest::{Assets, Location, Xcm};

const UNITS: Balance = 1_000_000_000;

#[test]
fn exchange_asset_success() {
test_exchange_asset(true, 500 * UNITS, 665 * UNITS, true);
}

#[test]
fn exchange_asset_insufficient_liquidity() {
test_exchange_asset(true, 1_000 * UNITS, 2_000 * UNITS, false);
}

#[test]
fn exchange_asset_insufficient_balance() {
test_exchange_asset(true, 5_000 * UNITS, 1_665 * UNITS, false);
}

#[test]
fn exchange_asset_pool_not_created() {
test_exchange_asset(false, 500 * UNITS, 665 * UNITS, false);
}

fn test_exchange_asset(
create_pool: bool,
give_amount: Balance,
want_amount: Balance,
should_succeed: bool,
) {
let alice: AccountId = Westend::account_id_of(ALICE);
let native_asset_location = WestendLocation::get();
let native_asset_id = AssetId(native_asset_location.clone());
let origin = RuntimeOrigin::signed(alice.clone());
let asset_location = Location::new(1, [Parachain(2001)]);
let asset_id = AssetId(asset_location.clone());

// Setup initial state
AssetHubWestend::execute_with(|| {
assert_ok!(<Balances as Mutate<_>>::mint_into(
&alice,
ExistentialDeposit::get() + (1_000 * UNITS)
));

assert_ok!(ForeignAssets::force_create(
RuntimeOrigin::root(),
asset_location.clone().into(),
alice.clone().into(),
true,
1
));
});

if create_pool {
create_pool_with_wnd_on!(AssetHubWestend, asset_location.clone(), true, alice.clone());
}

// Execute and verify swap
AssetHubWestend::execute_with(|| {
let foreign_balance_before = ForeignAssets::balance(asset_location.clone(), &alice);
let wnd_balance_before = Balances::total_balance(&alice);

let give: Assets = (native_asset_id, give_amount).into();
let want: Assets = (asset_id, want_amount).into();
let xcm = Xcm(vec![
WithdrawAsset(give.clone().into()),
ExchangeAsset { give: give.into(), want: want.into(), maximal: true },
DepositAsset { assets: Wild(All), beneficiary: alice.clone().into() },
]);

let result = PolkadotXcm::execute(origin, bx!(xcm::VersionedXcm::from(xcm)), Weight::MAX);

let foreign_balance_after = ForeignAssets::balance(asset_location, &alice);
let wnd_balance_after = Balances::total_balance(&alice);

if should_succeed {
assert_ok!(result);
assert!(
foreign_balance_after >= foreign_balance_before + want_amount,
"Expected foreign balance to increase by at least {want_amount} units, got {foreign_balance_after} from {foreign_balance_before}"
);
assert_eq!(
wnd_balance_after, wnd_balance_before - give_amount,
"Expected WND balance to decrease by {give_amount} units, got {wnd_balance_after} from {wnd_balance_before}"
);
} else {
assert_err_ignore_postinfo!(
result,
pallet_xcm::Error::<Runtime>::LocalExecutionIncomplete
);
assert_eq!(
foreign_balance_after, foreign_balance_before,
"Foreign balance changed unexpectedly: got {foreign_balance_after}, expected {foreign_balance_before}"
);
assert_eq!(
wnd_balance_after, wnd_balance_before,
"WND balance changed unexpectedly: got {wnd_balance_after}, expected {wnd_balance_before}"
);
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// limitations under the License.

mod claim_assets;
mod exchange_asset;
mod fellowship_treasury;
mod hybrid_transfers;
mod reserve_transfer;
Expand Down
49 changes: 48 additions & 1 deletion cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1938,7 +1938,54 @@ impl_runtime_apis! {
}

fn worst_case_asset_exchange() -> Result<(XcmAssets, XcmAssets), BenchmarkError> {
Err(BenchmarkError::Skip)
let native_asset_location = WestendLocation::get();
let native_asset_id = AssetId(native_asset_location.clone());
let (account, _) = pallet_xcm_benchmarks::account_and_location::<Runtime>(1);
let origin = RuntimeOrigin::signed(account.clone());
let asset_location = Location::new(1, [Parachain(2001)]);
let asset_id = AssetId(asset_location.clone());

assert_ok!(<Balances as fungible::Mutate<_>>::mint_into(
&account,
ExistentialDeposit::get() + (1_000 * UNITS)
));

assert_ok!(ForeignAssets::force_create(
RuntimeOrigin::root(),
asset_location.clone().into(),
account.clone().into(),
true,
1,
));

assert_ok!(ForeignAssets::mint(
origin.clone(),
asset_location.clone().into(),
account.clone().into(),
3_000 * UNITS,
));

assert_ok!(AssetConversion::create_pool(
origin.clone(),
native_asset_location.clone().into(),
asset_location.clone().into(),
));

assert_ok!(AssetConversion::add_liquidity(
origin,
native_asset_location.into(),
asset_location.into(),
1_000 * UNITS,
2_000 * UNITS,
1,
1,
account.into(),
));

let give_assets: XcmAssets = (native_asset_id, 500 * UNITS).into();
let receive_assets: XcmAssets = (asset_id, 660 * UNITS).into();

Ok((give_assets, receive_assets))
}

fn universal_alias() -> Result<(Location, Junction), BenchmarkError> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,11 @@ impl<Call> XcmWeightInfo<Call> for AssetHubWestendXcmWeight<Call> {
fn deposit_reserve_asset(assets: &AssetFilter, _dest: &Location, _xcm: &Xcm<()>) -> Weight {
assets.weigh_assets(XcmFungibleWeight::<Runtime>::deposit_reserve_asset())
}
fn exchange_asset(_give: &AssetFilter, _receive: &Assets, _maximal: &bool) -> Weight {
Weight::MAX
fn exchange_asset(give: &AssetFilter, receive: &Assets, _maximal: &bool) -> Weight {
let base_weight = XcmGeneric::<Runtime>::exchange_asset();
let give_weight = give.weigh_assets(base_weight);
let receive_weight = receive.weigh_assets(base_weight);
give_weight.max(receive_weight)
}
fn initiate_reserve_withdraw(
assets: &AssetFilter,
Expand Down
Loading
Loading