diff --git a/porteer/src/benchmarking.rs b/porteer/src/benchmarking.rs index e44dadae..5e2375b8 100644 --- a/porteer/src/benchmarking.rs +++ b/porteer/src/benchmarking.rs @@ -49,7 +49,7 @@ benchmarks! { assert_eq!(LastHeartBeat::::get(), now); } set_xcm_fee_params { - let fee_params = XcmFeeParams { hop1: 1u32.into(), hop2: 2u32.into(), hop3: 3u32.into() }; + let fee_params = XcmFeeParams { local_equivalent_sum: 6u32.into(), hop1: 1u32.into(), hop2: 2u32.into(), hop3: 3u32.into() }; }: _(RawOrigin::Root, fee_params) verify { assert_eq!(XcmFeeConfig::::get(), fee_params); diff --git a/porteer/src/lib.rs b/porteer/src/lib.rs index a4396cc9..0925687c 100644 --- a/porteer/src/lib.rs +++ b/porteer/src/lib.rs @@ -112,8 +112,17 @@ pub mod pallet { /// or /// 2. AHP -> AHK -> IK pub struct XcmFeeParams { + /// to be paid by the `port_tokens` caller to cover all subsequent fees + #[codec(compact)] + pub local_equivalent_sum: Balance, + /// fees to be paid by sovereign account for source side Asset Hub execution involving swapping to KSM/DOT [TEER] + #[codec(compact)] pub hop1: Balance, + /// fees to be paid by sovereign account for destination side Asset Hub execution involving swapping to DOT/KSM [KSM/DOT] + #[codec(compact)] pub hop2: Balance, + /// fees to be paid by sovereign account for destination side Integritee execution involving swapping to TEER [DOT/KSM] + #[codec(compact)] pub hop3: Balance, } @@ -148,6 +157,7 @@ pub mod pallet { Location = Self::Location, >; + type FeeCollectorAccount: Get>; /// The location representation used by this pallet. type Location: Parameter + Member + MaybeSerializeDeserialize + Debug + Ord + MaxEncodedLen; @@ -381,6 +391,14 @@ pub mod pallet { return Err(Error::::WatchdogHeartbeatIsTooOld.into()); }; + let user_fee = Self::xcm_fee_config().local_equivalent_sum; + >::transfer( + &signer, + &T::FeeCollectorAccount::get(), + user_fee, + Preservation::Preserve, + )?; + >::burn_from( &signer, amount, diff --git a/porteer/src/mock.rs b/porteer/src/mock.rs index 067ba909..286b24ed 100644 --- a/porteer/src/mock.rs +++ b/porteer/src/mock.rs @@ -82,6 +82,7 @@ impl pallet_balances::Config for Test { ord_parameter_types! { pub const Alice: AccountId = AccountId::new(hex2array!("d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d")); + pub const Ferdie: AccountId = AccountId::new(hex2array!("1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c")); } parameter_types! { @@ -106,6 +107,7 @@ impl crate::Config for Test { EitherOfDiverse, EnsureRoot>; type PortTokensToDestination = MockPortTokens; type ForwardPortedTokensToDestinations = MockPortTokens; + type FeeCollectorAccount = Ferdie; type Location = TestLocation; type Fungible = Balances; #[cfg(feature = "runtime-benchmarks")] diff --git a/porteer/src/tests.rs b/porteer/src/tests.rs index 38ce88b5..641cc281 100644 --- a/porteer/src/tests.rs +++ b/porteer/src/tests.rs @@ -121,7 +121,7 @@ fn set_xcm_fee_params_works() { assert_eq!(XcmFeeConfig::::get(), XcmFeeParams::default()); - let new_fee_params = XcmFeeParams { hop1: 1, hop2: 2, hop3: 3 }; + let new_fee_params = XcmFeeParams { local_equivalent_sum: 6, hop1: 1, hop2: 2, hop3: 3 }; assert_ok!(Porteer::set_xcm_fee_params( RuntimeOrigin::signed(alice.clone()), new_fee_params @@ -259,6 +259,36 @@ fn port_tokens_works_at_timeout_threshold() { }) } +#[test] +fn port_tokens_charges_fees_if_port_possible() { + new_test_ext().execute_with(|| { + let alice = Keyring::Alice.to_account_id(); + let bob = Keyring::Bob.to_account_id(); + let ferdie = Keyring::Ferdie.to_account_id(); + let bob_free: BalanceOf = 15_000_000_000_000u128; + ::Fungible::make_free_balance_be(&bob, bob_free); + ::Fungible::make_free_balance_be(&ferdie, 0); + + assert_eq!(XcmFeeConfig::::get(), XcmFeeParams::default()); + + let new_fee_params = + XcmFeeParams { local_equivalent_sum: 600_000_000_000, hop1: 1, hop2: 2, hop3: 3 }; + assert_ok!(Porteer::set_xcm_fee_params( + RuntimeOrigin::signed(alice.clone()), + new_fee_params + )); + + let port_amount: BalanceOf = 10_000_000_000_000u128; + + assert_ok!(Porteer::port_tokens(RuntimeOrigin::signed(bob.clone()), port_amount, None)); + assert_eq!( + Balances::free_balance(bob), + bob_free - port_amount - new_fee_params.local_equivalent_sum + ); + assert_eq!(Balances::free_balance(ferdie), new_fee_params.local_equivalent_sum); + }) +} + #[test] fn port_tokens_system_test_works() { // This test tests the whole logic: