Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

358 handle delegation of brz token to automation pallet in xcm config #365

Merged
2 changes: 2 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions runtime/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ sp-consensus-aura = { git = "https://github.com/paritytech/substrate", default-f
sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.40" }

xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.40" }
xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.40" }

orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", default-features = false, branch = "polkadot-v0.9.40" }
orml-asset-registry = { git = "https://github.com/open-web3-stack/open-runtime-module-library", default-features = false, branch = "polkadot-v0.9.40" }
orml-xcm-support = { git = "https://github.com/open-web3-stack/open-runtime-module-library", default-features = false, branch = "polkadot-v0.9.40" }

dia-oracle = { git = "https://github.com/pendulum-chain/oracle-pallet", default-features = false, branch = "polkadot-v0.9.40" }
zenlink-protocol = { git = "https://github.com/pendulum-chain/Zenlink-DEX-Module", default-features = false, branch = "polkadot-v0.9.40-protocol" }
Expand All @@ -49,9 +51,11 @@ std = [
"sp-consensus-aura/std",
"sp-core/std",
"xcm/std",
"xcm-executor/std",
"orml-traits/std",
"dia-oracle/std",
"orml-asset-registry/std",
"orml-xcm-support/std",
"zenlink-protocol/std",
"spacewalk-primitives/std",
]
Expand Down
74 changes: 74 additions & 0 deletions runtime/common/src/custom_transactor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use sp_runtime::{
codec::FullCodec,
traits::{Convert, MaybeSerializeDeserialize, SaturatedConversion},
};
use sp_std::{
cmp::{Eq, PartialEq},
fmt::Debug,
marker::PhantomData,
prelude::*,
result,
};

use orml_xcm_support::{OnDepositFail, UnknownAsset as UnknownAssetT};
use xcm::v3::{prelude::*, Error as XcmError, MultiAsset, MultiLocation, Result};
use xcm_executor::{
traits::{Convert as MoreConvert, MatchesFungible, TransactAsset},
Assets,
};

pub struct AssetData {
pub length: u8,
pub data: [u8; 32],
}

pub trait AutomationPalletConfig {
fn matches_asset(asset: &MultiAsset) -> Option<u128>;
fn matches_beneficiary(beneficiary_location: &MultiLocation) -> Option<AssetData>;
fn callback(length: u8, data: [u8; 32], amount: u128) -> Result;
}

pub struct CustomTransactorInterceptor<WrappedTransactor, AutomationPalletConfigT>(
PhantomData<(WrappedTransactor, AutomationPalletConfigT)>,
);

impl<WrappedTransactor: TransactAsset, AutomationPalletConfigT: AutomationPalletConfig>
TransactAsset for CustomTransactorInterceptor<WrappedTransactor, AutomationPalletConfigT>
{
fn deposit_asset(
asset: &MultiAsset,
location: &MultiLocation,
_context: &XcmContext,
) -> Result {
if let (Some(amount_deposited), Some(asset_data)) = (
AutomationPalletConfigT::matches_asset(asset),
AutomationPalletConfigT::matches_beneficiary(location),
) {
AutomationPalletConfigT::callback(
asset_data.length,
asset_data.data,
amount_deposited,
)?;
return Ok(())
}

WrappedTransactor::deposit_asset(asset, location, _context)
}

fn withdraw_asset(
asset: &MultiAsset,
location: &MultiLocation,
_maybe_context: Option<&XcmContext>,
) -> result::Result<Assets, XcmError> {
WrappedTransactor::withdraw_asset(asset, location, _maybe_context)
}

fn transfer_asset(
asset: &MultiAsset,
from: &MultiLocation,
to: &MultiLocation,
_context: &XcmContext,
) -> result::Result<Assets, XcmError> {
WrappedTransactor::transfer_asset(asset, from, to, _context)
}
}
1 change: 1 addition & 0 deletions runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use sp_runtime::{

pub mod asset_registry;
pub mod chain_ext;
pub mod custom_transactor;
mod proxy_type;
pub mod stellar;
pub mod zenlink;
Expand Down
2 changes: 1 addition & 1 deletion runtime/foucoco/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ runtime-benchmarks = [
"replace/runtime-benchmarks",
"stellar-relay/runtime-benchmarks",
"vault-registry/runtime-benchmarks",

"oracle/testing-utils",
"runtime-common/runtime-benchmarks",
"orml-currencies-allowance-extension/runtime-benchmarks",
"orml-tokens-management-extension/runtime-benchmarks"
Expand Down
3 changes: 2 additions & 1 deletion runtime/integration-tests/src/amplitude_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use crate::{
mock::{kusama_relay_ext, para_ext, ParachainType, USDT_ASSET_ID},
sibling,
test_macros::{
parachain1_transfer_asset_to_parachain2, parachain1_transfer_asset_to_parachain2_and_back,
moonbeam_transfers_token_and_handle_automation, parachain1_transfer_asset_to_parachain2,
parachain1_transfer_asset_to_parachain2_and_back,
parachain1_transfer_incorrect_asset_to_parachain2_should_fail,
transfer_10_relay_token_from_parachain_to_relay_chain,
transfer_20_relay_token_from_relay_chain_to_parachain,
Expand Down
19 changes: 19 additions & 0 deletions runtime/integration-tests/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use sp_io::TestExternalities;
use sp_runtime::traits::AccountIdConversion;
use xcm_emulator::Weight;

use runtime_common::parachains::polkadot::moonbeam::PARA_ID as MOONBEAM_PARA_ID;
use statemine_runtime as kusama_asset_hub_runtime;
use statemint_runtime as polkadot_asset_hub_runtime;

Expand Down Expand Up @@ -116,6 +117,7 @@ pub enum ParachainType {
Pendulum,
Amplitude,
Sibling,
Moonbeam,
}

pub struct ExtBuilderParachain<Currency> {
Expand Down Expand Up @@ -189,6 +191,7 @@ pub fn para_ext(chain: ParachainType) -> sp_io::TestExternalities {
ParachainType::Amplitude =>
ExtBuilderParachain::amplitude_default().balances(vec![]).build(),
ParachainType::Sibling => ExtBuilderParachain::sibling_default().balances(vec![]).build(),
ParachainType::Moonbeam => ExtBuilderParachain::moonbeam_default().balances(vec![]).build(),
}
}

Expand All @@ -200,6 +203,7 @@ impl<Currency> ExtBuilderParachain<Currency> {
ParachainType::Pendulum => PENDULUM_ID,
ParachainType::Sibling => SIBLING_ID,
ParachainType::Amplitude => AMPLITUDE_ID,
ParachainType::Moonbeam => MOONBEAM_PARA_ID,
}
}
}
Expand Down Expand Up @@ -255,6 +259,10 @@ impl ExtBuilderParachain<SiblingCurrencyId> {
pub fn sibling_default() -> Self {
Self { balances: vec![], chain: ParachainType::Sibling }
}

pub fn moonbeam_default() -> Self {
Self { balances: vec![], chain: ParachainType::Moonbeam }
}
}

impl Builder<SiblingCurrencyId> for ExtBuilderParachain<SiblingCurrencyId> {
Expand All @@ -276,6 +284,17 @@ impl Builder<SiblingCurrencyId> for ExtBuilderParachain<SiblingCurrencyId> {
SiblingCurrencyId
)
},
ParachainType::Moonbeam => {
use sibling::{Runtime, System};
build_parachain_with_orml!(
self,
Runtime,
System,
NATIVE_INITIAL_BALANCE,
ORML_INITIAL_BALANCE,
SiblingCurrencyId
)
},
_ => panic!("cannot use this chain to build"),
}
}
Expand Down
28 changes: 27 additions & 1 deletion runtime/integration-tests/src/pendulum_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use crate::{
mock::{para_ext, polkadot_relay_ext, ParachainType, USDT_ASSET_ID},
sibling,
test_macros::{
parachain1_transfer_asset_to_parachain2, parachain1_transfer_asset_to_parachain2_and_back,
moonbeam_transfers_token_and_handle_automation, parachain1_transfer_asset_to_parachain2,
parachain1_transfer_asset_to_parachain2_and_back,
parachain1_transfer_incorrect_asset_to_parachain2_should_fail,
transfer_10_relay_token_from_parachain_to_relay_chain,
transfer_20_relay_token_from_relay_chain_to_parachain,
Expand All @@ -12,6 +13,7 @@ use crate::{
};

use frame_support::assert_ok;
use runtime_common::parachains::polkadot::moonbeam::PARA_ID as MOONBEAM_PARA_ID;
use statemint_runtime as polkadot_asset_hub_runtime;
use xcm::latest::NetworkId;
use xcm_emulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt};
Expand Down Expand Up @@ -56,12 +58,23 @@ decl_test_parachain! {
}
}

decl_test_parachain! {
pub struct MoonbeamParachain {
Runtime = sibling::Runtime,
RuntimeOrigin = sibling::RuntimeOrigin,
XcmpMessageHandler = sibling::XcmpQueue,
DmpMessageHandler = sibling::DmpQueue,
new_ext = para_ext(ParachainType::Moonbeam),
}
}

decl_test_network! {
pub struct PolkadotMockNet {
relay_chain = PolkadotRelay,
parachains = vec![
(1000, AssetHubParachain),
(2094, PendulumParachain),
(2004, MoonbeamParachain),
(9999, SiblingParachain),
],
}
Expand Down Expand Up @@ -142,3 +155,16 @@ fn transfer_native_token_from_pendulum_to_sibling_parachain_and_back() {
SIBLING_ID
);
}

#[test]
fn moonbeam_transfers_token_and_handle_automation() {
moonbeam_transfers_token_and_handle_automation!(
PolkadotMockNet,
pendulum_runtime,
PendulumParachain,
sibling,
MoonbeamParachain,
PENDULUM_ID,
MOONBEAM_PARA_ID
);
}
5 changes: 5 additions & 0 deletions runtime/integration-tests/src/sibling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ use xcm_builder::{

use crate::{AMPLITUDE_ID, ASSETHUB_ID, PENDULUM_ID};

use runtime_common::parachains::polkadot::moonbeam::BRZ_location;

const XCM_ASSET_RELAY_DOT: u8 = 0;
const XCM_ASSET_ASSETHUB_USDT: u8 = 1;

Expand Down Expand Up @@ -92,6 +94,7 @@ pub enum CurrencyId {
Amplitude,
Native,
XCM(u8),
Token,
}

// Convert from u32 parachain id to CurrencyId
Expand Down Expand Up @@ -127,6 +130,7 @@ impl Convert<CurrencyId, Option<MultiLocation>> for CurrencyIdConvert {
Some(MultiLocation::new(1, X2(Parachain(PENDULUM_ID), PalletInstance(10)))),
CurrencyId::Amplitude =>
Some(MultiLocation::new(1, X2(Parachain(AMPLITUDE_ID), PalletInstance(10)))),
CurrencyId::Token => Some(BRZ_location()),
CurrencyId::XCM(f) => match f {
XCM_ASSET_RELAY_DOT => Some(MultiLocation::parent()),
// Handles both Kusama and Polkadot asset hub
Expand Down Expand Up @@ -155,6 +159,7 @@ impl Convert<MultiLocation, Option<CurrencyId>> for CurrencyIdConvert {
Some(CurrencyId::XCM(XCM_ASSET_ASSETHUB_USDT)),
MultiLocation { parents: 1, interior: Here } =>
Some(CurrencyId::XCM(XCM_ASSET_RELAY_DOT)),
loc if loc == BRZ_location() => Some(CurrencyId::Token),
_ => None,
}
}
Expand Down
73 changes: 73 additions & 0 deletions runtime/integration-tests/src/test_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,10 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2_and_back {
// Verify BOB's balance on parachain2 after receiving
// Should increase by the transfer amount
$parachain2::execute_with(|| {
use $parachain2_runtime::{RuntimeEvent, System, XTokens};
for i in System::events().iter() {
println!("para 2 events {}: {:?}\n", stringify!($para2_runtime), i);
}
assert_eq!(
$parachain2_runtime::Tokens::balance(para1_native_currency_on_para2, &BOB.into()),
transfer_amount
Expand Down Expand Up @@ -591,6 +595,10 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2_and_back {
// Verify ALICE's balance on parachain1 after receiving
// Should become the same amount as initial balance before both transfers
$parachain1::execute_with(|| {
use $parachain1_runtime::System;
for i in System::events().iter() {
println!("para 1 events {}: {:?}\n", stringify!($para2_runtime), i);
}
assert_eq!(
$parachain1_runtime::Currencies::free_balance(Parachain1CurrencyId::Native, &ALICE.into()),
native_tokens_before
Expand All @@ -599,7 +607,72 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2_and_back {
}};
}

macro_rules! moonbeam_transfers_token_and_handle_automation {
(
$mocknet:ident,
$parachain1_runtime:ident,
$parachain1:ident,
$parachain2_runtime:ident,
$parachain2:ident,
$parachain1_id:ident,
$parachain2_id:ident
) => {{
use crate::mock::{units, ALICE};
use polkadot_core_primitives::Balance;
use xcm::latest::{
Junction, Junction::{ GeneralKey, PalletInstance}, Junctions::{X1,X2, X3}, MultiLocation, WeightLimit,
};
use $parachain2_runtime::CurrencyId as Parachain2CurrencyId;

$mocknet::reset();

let transfer_amount: Balance = units(10);
// We mock parachain 2 as beeing moonriver in this case.
// Sending "Token" variant which is equivalent to BRZ mock token Multilocation
// in the sibling definition
$parachain2::execute_with(|| {
use $parachain2_runtime::{XTokens, Tokens,RuntimeOrigin, System};

assert_ok!(Tokens::set_balance(RuntimeOrigin::root().into(), ALICE.clone().into(), Parachain2CurrencyId::Token,transfer_amount, 0));

// We must ensure that the destination Multilocation is of the structure
// the intercept excepts so it calls automation pallet

// TODO replace instance 99 with automation pallet index when added
assert_ok!(XTokens::transfer(
$parachain2_runtime::RuntimeOrigin::signed(ALICE.into()),
Parachain2CurrencyId::Token,
transfer_amount,
Box::new(
MultiLocation::new(
1,
X3(
Junction::Parachain($parachain1_id),
PalletInstance(99),
GeneralKey {length:32 , data:[1u8;32]}
)
)
.into()
),
WeightLimit::Unlimited
));
});

$parachain1::execute_with(|| {
use $parachain1_runtime::{RuntimeEvent, System, Tokens};
// given the configuration in pendulum's xcm_config, we expect the callback (in this case a Remark)
// to be executed
assert!(System::events().iter().any(|r| matches!(
r.event,
RuntimeEvent::System(frame_system::Event::Remarked { .. })
)));


});
}};
}
// macros defined at the bottom of this file to prevent unresolved imports
pub(super) use moonbeam_transfers_token_and_handle_automation;
pub(super) use parachain1_transfer_asset_to_parachain2;
pub(super) use parachain1_transfer_asset_to_parachain2_and_back;
pub(super) use parachain1_transfer_incorrect_asset_to_parachain2_should_fail;
Expand Down
Loading
Loading