|
| 1 | +use crate::{PolimecAccountId, PolimecBalances, PolimecCall, PolimecForeignAssets, PolimecNet, PolimecRuntime, ALICE}; |
| 2 | +use parity_scale_codec::Encode; |
| 3 | +use polimec_runtime::{xcm_config::SupportedAssets, TreasuryAccount}; |
| 4 | +use sp_runtime::traits::MaybeEquivalence; |
| 5 | +use xcm::prelude::*; |
| 6 | +use xcm_emulator::{Chain, TestExt}; |
| 7 | +pub fn fake_message_hash<T>(message: &Xcm<T>) -> XcmHash { |
| 8 | + message.using_encoded(sp_io::hashing::blake2_256) |
| 9 | +} |
| 10 | +#[test] |
| 11 | +fn execution_fees_go_to_treasury() { |
| 12 | + let dot_amount = MultiAsset { id: Concrete(MultiLocation::parent()), fun: Fungible(100_0_000_000_000) }; |
| 13 | + let usdt_amount = MultiAsset { |
| 14 | + id: Concrete(MultiLocation { |
| 15 | + parents: 1, |
| 16 | + interior: X3(Parachain(1000), PalletInstance(50), GeneralIndex(1984)), |
| 17 | + }), |
| 18 | + fun: Fungible(100_000_000), |
| 19 | + }; |
| 20 | + let usdc_amount = MultiAsset { |
| 21 | + id: Concrete(MultiLocation { |
| 22 | + parents: 1, |
| 23 | + interior: X3(Parachain(1000), PalletInstance(50), GeneralIndex(1337)), |
| 24 | + }), |
| 25 | + fun: Fungible(100_000_000), |
| 26 | + }; |
| 27 | + |
| 28 | + let beneficiary: PolimecAccountId = [0u8; 32].into(); |
| 29 | + |
| 30 | + let assert_reserve_asset_fee_goes_to_treasury = |multi_asset: MultiAsset| { |
| 31 | + let asset_multilocation = |
| 32 | + if let Concrete(asset_multilocation) = multi_asset.id { asset_multilocation } else { unreachable!() }; |
| 33 | + let asset_id = SupportedAssets::convert(&asset_multilocation).unwrap(); |
| 34 | + let asset_amount = if let Fungible(amount) = multi_asset.fun { amount } else { unreachable!() }; |
| 35 | + |
| 36 | + let xcm = Xcm::<PolimecCall>(vec![ |
| 37 | + ReserveAssetDeposited(vec![multi_asset.clone()].into()), |
| 38 | + ClearOrigin, |
| 39 | + BuyExecution { fees: multi_asset, weight_limit: Unlimited }, |
| 40 | + DepositAsset { |
| 41 | + assets: WildMultiAsset::All.into(), |
| 42 | + beneficiary: MultiLocation::new(0, X1(AccountId32 { network: None, id: beneficiary.clone().into() })), |
| 43 | + }, |
| 44 | + ]) |
| 45 | + .into(); |
| 46 | + PolimecNet::execute_with(|| { |
| 47 | + let prev_treasury_balance = PolimecForeignAssets::balance(asset_id, TreasuryAccount::get()); |
| 48 | + let prev_beneficiary_balance = PolimecForeignAssets::balance(asset_id, beneficiary.clone()); |
| 49 | + |
| 50 | + let outcome = <PolimecRuntime as pallet_xcm::Config>::XcmExecutor::execute_xcm( |
| 51 | + MultiLocation::new(1, X1(Parachain(1000))), |
| 52 | + xcm.clone(), |
| 53 | + fake_message_hash(&xcm), |
| 54 | + Weight::MAX, |
| 55 | + ); |
| 56 | + assert!(outcome.ensure_complete().is_ok()); |
| 57 | + |
| 58 | + let post_treasury_balance = PolimecForeignAssets::balance(asset_id, TreasuryAccount::get()); |
| 59 | + let post_beneficiary_balance = PolimecForeignAssets::balance(asset_id, beneficiary.clone()); |
| 60 | + |
| 61 | + let net_treasury_balance = post_treasury_balance - prev_treasury_balance; |
| 62 | + let net_beneficiary_balance = post_beneficiary_balance - prev_beneficiary_balance; |
| 63 | + |
| 64 | + let net_total = net_treasury_balance + net_beneficiary_balance; |
| 65 | + |
| 66 | + assert_eq!(net_total, asset_amount); |
| 67 | + assert!(net_treasury_balance > 0); |
| 68 | + }); |
| 69 | + }; |
| 70 | + |
| 71 | + let assert_plmc_fee_goes_to_treasury = || { |
| 72 | + let asset_amount = 100_0_000_000_000; |
| 73 | + let multi_asset = MultiAsset { id: Concrete(MultiLocation::here()), fun: Fungible(asset_amount) }; |
| 74 | + |
| 75 | + let xcm = Xcm::<PolimecCall>(vec![ |
| 76 | + WithdrawAsset(vec![multi_asset.clone()].into()), |
| 77 | + BuyExecution { fees: multi_asset, weight_limit: Unlimited }, |
| 78 | + DepositAsset { |
| 79 | + assets: WildMultiAsset::All.into(), |
| 80 | + beneficiary: MultiLocation::new(0, X1(AccountId32 { network: None, id: beneficiary.clone().into() })), |
| 81 | + }, |
| 82 | + ]) |
| 83 | + .into(); |
| 84 | + PolimecNet::execute_with(|| { |
| 85 | + let prev_treasury_balance = PolimecBalances::free_balance(TreasuryAccount::get()); |
| 86 | + let prev_beneficiary_balance = PolimecBalances::free_balance(beneficiary.clone()); |
| 87 | + |
| 88 | + let outcome = <PolimecRuntime as pallet_xcm::Config>::XcmExecutor::execute_xcm( |
| 89 | + MultiLocation::new(0, X1(AccountId32 { network: None, id: PolimecNet::account_id_of(ALICE).into() })), |
| 90 | + xcm.clone(), |
| 91 | + fake_message_hash(&xcm), |
| 92 | + Weight::MAX, |
| 93 | + ); |
| 94 | + assert!(outcome.ensure_complete().is_ok()); |
| 95 | + |
| 96 | + let post_treasury_balance = PolimecBalances::free_balance(TreasuryAccount::get()); |
| 97 | + let post_beneficiary_balance = PolimecBalances::free_balance(beneficiary.clone()); |
| 98 | + |
| 99 | + let net_treasury_balance = post_treasury_balance - prev_treasury_balance; |
| 100 | + let net_beneficiary_balance = post_beneficiary_balance - prev_beneficiary_balance; |
| 101 | + |
| 102 | + let net_total = net_treasury_balance + net_beneficiary_balance; |
| 103 | + |
| 104 | + assert_eq!(net_total, asset_amount); |
| 105 | + assert!(net_treasury_balance > 0); |
| 106 | + }); |
| 107 | + }; |
| 108 | + |
| 109 | + assert_reserve_asset_fee_goes_to_treasury(dot_amount); |
| 110 | + assert_reserve_asset_fee_goes_to_treasury(usdt_amount); |
| 111 | + assert_reserve_asset_fee_goes_to_treasury(usdc_amount); |
| 112 | + assert_plmc_fee_goes_to_treasury(); |
| 113 | +} |
0 commit comments