Skip to content

Commit

Permalink
Fix lp-gateway routers' weight and fee calculations
Browse files Browse the repository at this point in the history
And adjust the integration tests to use reasonable amounts and verify
the fees being charged.
  • Loading branch information
NunoAlexandre committed Sep 8, 2023
1 parent 8bf76cf commit eed49a9
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 12 deletions.
32 changes: 23 additions & 9 deletions pallets/liquidity-pools-gateway/routers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ use frame_support::{
dispatch::{DispatchError, DispatchResult, Weight},
ensure,
traits::OriginTrait,
weights::constants::WEIGHT_REF_TIME_PER_SECOND,
};
use pallet_xcm_transactor::{Currency, CurrencyPayment, TransactWeights};
use scale_info::TypeInfo;
use sp_core::{bounded::BoundedVec, ConstU32, H160, H256, U256};
use sp_runtime::traits::{BlakeTwo256, EnsureMul, Hash};
use sp_runtime::traits::{BlakeTwo256, EnsureAdd, EnsureMul, Hash};
use sp_std::{boxed::Box, marker::PhantomData, vec::Vec};
use xcm::{
latest::{MultiLocation, OriginKind},
Expand Down Expand Up @@ -228,15 +229,18 @@ where
let ethereum_xcm_call = get_encoded_ethereum_xcm_call::<T>(self.xcm_domain.clone(), msg)
.map_err(|_| DispatchError::Other("encoded ethereum xcm call retrieval"))?;

// Note: We are using moonbeams calculation for the ref time here and their
// estimate for the PoV.
// NOTE: We are using Moonbeam's calculation for the ref time and their estimate
// for the PoV.
//
// - Transact weight: gasLimit * 25000 as moonbeam is doing (Proof size
// limited fixed)
// ref_time:
// GAS_TO_WEIGHT_MULTIPLIER * MAX_GAS_LIMIT + EthereumXcm.transact's Weight + a
// bit extra
let transact_required_weight_at_most = Weight::from_ref_time(
self.xcm_domain
.max_gas_limit
.ensure_mul(GAS_TO_WEIGHT_MULTIPLIER)?,
.ensure_mul(GAS_TO_WEIGHT_MULTIPLIER)?
.ensure_add(25_000_000)?
.ensure_add(5_000_000)?,
)
.set_proof_size(DEFAULT_PROOF_SIZE.saturating_div(2));

Expand All @@ -261,9 +265,10 @@ where
// The currency in which we want to pay fees.
CurrencyPayment {
currency: Currency::AsCurrencyId(self.xcm_domain.fee_currency.clone()),
fee_amount: Some(
self.xcm_domain.fee_per_second * Into::<u128>::into(overall_weight.ref_time()),
),
fee_amount: Some(calculate_fee_amount(
overall_weight.ref_time(),
self.xcm_domain.fee_per_second,
)),
},
// The call to be executed in the destination chain.
ethereum_xcm_call,
Expand All @@ -278,6 +283,15 @@ where
}
}

/// Calculate the fee to be charged for the complete XCM message execution on
/// the destination chain
pub fn calculate_fee_amount(overall_weight_ref_time: u64, fee_per_second: u128) -> u128 {
fee_per_second
.saturating_mul(overall_weight_ref_time as u128)
.saturating_add(WEIGHT_REF_TIME_PER_SECOND as u128 - 1)
.saturating_div(WEIGHT_REF_TIME_PER_SECOND as u128)
}

pub(crate) fn get_encoded_ethereum_xcm_call<T>(
xcm_domain: XcmDomain<T::CurrencyId>,
msg: Vec<u8>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,15 @@ fn transferring_invalid_tranche_tokens_should_fail() {
});
}

#[test]
fn expected_fee_amount() {
// Roughly 0.15 GLMR
assert_eq!(
liquidity_pools_gateway_routers::calculate_fee_amount(15530000000, default_per_second(18)),
155548480000000000
)
}

#[test]
fn add_currency() {
TestNet::reset();
Expand Down Expand Up @@ -814,10 +823,27 @@ fn add_currency() {
})
));

assert_eq!(
OrmlTokens::free_balance(
GLIMMER_CURRENCY_ID,
&<DevelopmentRuntime as pallet_liquidity_pools_gateway::Config>::Sender::get()
),
DEFAULT_BALANCE_GLMR
);

assert_ok!(LiquidityPools::add_currency(
RuntimeOrigin::signed(BOB.into()),
currency_id
));

assert_eq!(
OrmlTokens::free_balance(
GLIMMER_CURRENCY_ID,
&<DevelopmentRuntime as pallet_liquidity_pools_gateway::Config>::Sender::get()
),
/// Ensure it only charged roughly 0.15 GLMR for fees
DEFAULT_BALANCE_GLMR - 155548480000000000
);
});
}

Expand Down Expand Up @@ -1681,14 +1707,17 @@ mod utils {
use liquidity_pools_gateway_routers::{
ethereum_xcm::EthereumXCMRouter, DomainRouter, XCMRouter, XcmTransactInfo,
};
use runtime_common::xcm_fees::native_per_second;
use sp_runtime::traits::{EnsureDiv, EnsureMul};

use super::*;
use crate::{
liquidity_pools::pallet::development::tests::register_ausd,
utils::{AUSD_CURRENCY_ID, GLIMMER_CURRENCY_ID, MOONBEAM_EVM_CHAIN_ID},
};

pub const DEFAULT_BALANCE_GLMR: Balance = 1_000_000_000_000;
// 10 GLMR (18 decimals)
pub const DEFAULT_BALANCE_GLMR: Balance = 10000000000000000000;
pub const DOMAIN_MOONBEAM: Domain = Domain::EVM(MOONBEAM_EVM_CHAIN_ID);
pub const DEFAULT_EVM_ADDRESS_MOONBEAM: [u8; 20] = [99; 20];
pub const DEFAULT_DOMAIN_ADDRESS_MOONBEAM: DomainAddress =
Expand Down Expand Up @@ -1748,7 +1777,7 @@ mod utils {
location: Box::new(xcm_domain_location),
ethereum_xcm_transact_call_index: BoundedVec::truncate_from(vec![38, 0]),
contract_address: H160::from(utils::DEFAULT_EVM_ADDRESS_MOONBEAM),
max_gas_limit: 700_000,
max_gas_limit: 500_000,
fee_currency: currency_id,
fee_per_second: default_per_second(18),
},
Expand Down Expand Up @@ -1805,7 +1834,7 @@ mod utils {
OrmlTokens::deposit(
GLIMMER_CURRENCY_ID,
&<DevelopmentRuntime as pallet_liquidity_pools_gateway::Config>::Sender::get(),
DEFAULT_BALANCE_GLMR * dollar(18),
DEFAULT_BALANCE_GLMR,
);

// Register AUSD in the asset registry which is the default pool currency in
Expand Down

0 comments on commit eed49a9

Please sign in to comment.