Skip to content

Commit 0217ab5

Browse files
authored
Reanchor recipient in to-non-reserve transfer (#787)
* Reanchor recipient in to-non-reserve transfer due to the case where it is overriden by SelfLocation, that could be in relative view Signed-off-by: Georgi Zlatarev <[email protected]> * Handle error Signed-off-by: Georgi Zlatarev <[email protected]> * Clippy Signed-off-by: Georgi Zlatarev <[email protected]> * Add test case Signed-off-by: Georgi Zlatarev <[email protected]> * Use relative para chain for test Signed-off-by: Georgi Zlatarev <[email protected]> * Remove println Signed-off-by: Georgi Zlatarev <[email protected]> * Reanchor before execute_and_send_reserve_kind_xcm instead of in transfer_to_non_reserve Signed-off-by: Georgi Zlatarev <[email protected]> * Edit readme Signed-off-by: Georgi Zlatarev <[email protected]>
1 parent b57f88b commit 0217ab5

File tree

4 files changed

+75
-2
lines changed

4 files changed

+75
-2
lines changed

xtokens/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,6 @@ parameter_type_with_key! {
7171
}
7272
```
7373

74-
Notice the implementation for now also rely on `SelfLocation` which already in `xtokens` config. The `SelfLocation` current is `(1, Parachain(id))` refer to sender parachain. If parachain set `SelfLocation` to (0, Here), it'll be error in this case.
74+
Notice the implementation for now also relies on `SelfLocation` which is already in `xtokens` config. The `SelfLocation` is currently set to absolute view `(1, Parachain(id))` and refers to the sender parachain. However `SelfLocation` set to relative view `(0, Here)` will also work.
7575

7676
We use `SelfLocation` to fund fee to sender's parachain sovereign account on destination parachain, which asset is originated from sender account on sender parachain. This means if user setup too much fee, the fee will not returned to user, instead deposit to sibling parachain sovereign account on destination parachain.

xtokens/src/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,15 @@ pub mod module {
561561
let asset_to_fee_reserve = subtract_fee(&fee, min_xcm_fee);
562562
assets_to_fee_reserve.push(asset_to_fee_reserve.clone());
563563

564+
let mut override_recipient = T::SelfLocation::get();
565+
if override_recipient == MultiLocation::here() {
566+
let dest_chain_part = dest.chain_part().ok_or(Error::<T>::InvalidDest)?;
567+
let ancestry = T::LocationInverter::ancestry();
568+
let _ = override_recipient
569+
.reanchor(&dest_chain_part, &ancestry)
570+
.map_err(|_| Error::<T>::CannotReanchor);
571+
}
572+
564573
// First xcm sent to fee reserve chain and routed to dest chain.
565574
// We can use `MinXcmFee` configuration to decide which target parachain use
566575
// teleport. But as current there's only one case which is Parachain send back
@@ -571,7 +580,7 @@ pub mod module {
571580
asset_to_fee_reserve,
572581
fee_reserve,
573582
&dest,
574-
Some(T::SelfLocation::get()),
583+
Some(override_recipient),
575584
dest_weight,
576585
true,
577586
)?;

xtokens/src/mock/para_relative_view.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ parameter_type_with_key! {
307307
#[allow(clippy::match_ref_pats)] // false positive
308308
match (location.parents, location.first_interior()) {
309309
(1, Some(Parachain(2))) => Some(40),
310+
(1, Some(Parachain(3))) => Some(40),
310311
_ => None,
311312
}
312313
};

xtokens/src/tests.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,69 @@ fn sending_sibling_asset_to_reserve_sibling_with_relay_fee_works() {
705705
});
706706
}
707707

708+
#[test]
709+
fn sending_sibling_asset_to_reserve_sibling_with_relay_fee_works_with_relative_self_location() {
710+
TestNet::reset();
711+
712+
ParaD::execute_with(|| {
713+
assert_ok!(ParaTokens::deposit(CurrencyId::C, &ALICE, 1_000));
714+
});
715+
716+
ParaC::execute_with(|| {
717+
assert_ok!(ParaTeleportTokens::deposit(CurrencyId::C, &sibling_d_account(), 1_000));
718+
});
719+
720+
Relay::execute_with(|| {
721+
let _ = RelayBalances::deposit_creating(&para_d_account(), 1_000);
722+
});
723+
724+
let fee_amount: u128 = 200;
725+
let weight: u128 = 50;
726+
let dest_weight: u128 = 40;
727+
728+
ParaD::execute_with(|| {
729+
assert_ok!(ParaRelativeXTokens::transfer_multicurrencies(
730+
Some(ALICE).into(),
731+
vec![(CurrencyId::C, 450), (CurrencyId::R, fee_amount)],
732+
1,
733+
Box::new(
734+
(
735+
Parent,
736+
Parachain(3),
737+
Junction::AccountId32 {
738+
network: NetworkId::Any,
739+
id: BOB.into(),
740+
},
741+
)
742+
.into()
743+
),
744+
weight as u64,
745+
));
746+
assert_eq!(550, ParaRelativeTokens::free_balance(CurrencyId::C, &ALICE));
747+
assert_eq!(
748+
1000 - fee_amount,
749+
ParaRelativeTokens::free_balance(CurrencyId::R, &ALICE)
750+
);
751+
});
752+
753+
Relay::execute_with(|| {
754+
assert_eq!(
755+
1000 - (fee_amount - dest_weight),
756+
RelayBalances::free_balance(&para_d_account())
757+
);
758+
});
759+
760+
ParaC::execute_with(|| {
761+
assert_eq!(
762+
fee_amount - dest_weight * 4,
763+
ParaTeleportTokens::free_balance(CurrencyId::R, &sibling_d_account())
764+
);
765+
766+
assert_eq!(450, ParaTeleportTokens::free_balance(CurrencyId::C, &BOB));
767+
assert_eq!(0, ParaTeleportTokens::free_balance(CurrencyId::R, &BOB));
768+
});
769+
}
770+
708771
#[test]
709772
fn sending_sibling_asset_to_reserve_sibling_with_relay_fee_not_enough() {
710773
TestNet::reset();

0 commit comments

Comments
 (0)