diff --git a/pallets/flexible-fee/src/impls/account_fee_currency.rs b/pallets/flexible-fee/src/impls/account_fee_currency.rs index 62620dab7..01676ba0a 100644 --- a/pallets/flexible-fee/src/impls/account_fee_currency.rs +++ b/pallets/flexible-fee/src/impls/account_fee_currency.rs @@ -60,8 +60,13 @@ impl AccountFeeCurrency for Pallet { hopeless_currency = currency; } + // Add a 10% buffer to account for potential inaccuracies in fee estimation. + let fee = fee + .checked_mul(10) + .and_then(|v| v.checked_div(100)) + .ok_or(Error::::PercentageCalculationFailed)?; for maybe_currency in currency_list.iter() { - let comp_res = Self::cmp_with_precision(account, maybe_currency, fee, 18)?; + let comp_res = Self::cmp_with_weth(account, maybe_currency, fee)?; match comp_res { Ordering::Less => { diff --git a/pallets/flexible-fee/src/lib.rs b/pallets/flexible-fee/src/lib.rs index 7ce4222f9..519e9a8d8 100644 --- a/pallets/flexible-fee/src/lib.rs +++ b/pallets/flexible-fee/src/lib.rs @@ -19,10 +19,10 @@ #![cfg_attr(not(feature = "std"), no_std)] pub use crate::pallet::*; -use bifrost_asset_registry::{AssetMetadata, CurrencyIdMapping, TokenInfo}; +use bifrost_asset_registry::{AssetMetadata, CurrencyIdMapping}; use bifrost_primitives::{ traits::XcmDestWeightAndFeeHandler, AssetHubChainId, Balance, BalanceCmp, CurrencyId, - DerivativeIndex, OraclePriceProvider, Price, TryConvertFrom, XcmOperationType, BNC, VBNC, + DerivativeIndex, OraclePriceProvider, Price, TryConvertFrom, XcmOperationType, BNC, VBNC, WETH, }; use bifrost_xcm_interface::calls::{PolkadotXcmCall, RelaychainCall}; use core::convert::Into; @@ -232,6 +232,8 @@ pub mod pallet { EvmPermitCallExecutionError, /// EVM permit call failed. EvmPermitRunnerError, + /// Percentage calculation failed due to overflow. + PercentageCalculationFailed, } #[pallet::call] @@ -718,49 +720,30 @@ impl BalanceCmp for Pallet { /// - `currency`: The currency ID to be compared. /// - `amount`: The amount to compare against the account's balance, with the precision /// specified by `amount_precision`. - /// - `amount_precision`: The precision of the `amount` specified. If greater than 18, the - /// precision of the `currency` will be adjusted accordingly. /// /// # Returns /// - `Ok(std::cmp::Ordering)`: Returns the ordering result (`Less`, `Equal`, `Greater`) based /// on the comparison between the adjusted balance and the adjusted amount. /// - `Err(Error)`: Returns an error if the currency is not supported. - fn cmp_with_precision( + fn cmp_with_weth( account: &T::AccountId, currency: &CurrencyId, amount: u128, - amount_precision: u32, ) -> Result> { // Get the reducible balance for the specified account and currency. - let mut balance = T::MultiCurrency::reducible_balance( + let balance = T::MultiCurrency::reducible_balance( *currency, account, Preservation::Preserve, Fortitude::Polite, ); - // Define the standard precision as 18 decimal places. - let standard_precision: u32 = amount_precision.max(18); - - // Adjust the amount to the standard precision. - let precision_offset = standard_precision.saturating_sub(amount_precision); - let adjust_precision = 10u128.pow(precision_offset); - let amount = amount.saturating_mul(adjust_precision); - - // Adjust the balance based on currency type. - let decimals = currency - .decimals() - .or_else(|| { - T::AssetIdMaps::get_currency_metadata(*currency) - .map(|metadata| metadata.decimals.into()) - }) - .ok_or(Error::::CurrencyNotSupport)?; - let balance_precision_offset = standard_precision.saturating_sub(decimals.into()); - - // Apply precision adjustment to balance. - balance = balance.saturating_mul(10u128.pow(balance_precision_offset)); - - // Compare the adjusted balance with the input amount. - Ok(balance.cmp(&amount)) + let (fee_amount, _, _) = + T::OraclePriceProvider::get_oracle_amount_by_currency_and_amount_in( + &WETH, amount, ¤cy, + ) + .ok_or(Error::::ConversionError)?; + + Ok(balance.cmp(&fee_amount)) } } diff --git a/pallets/flexible-fee/src/mocks/kusama_mock.rs b/pallets/flexible-fee/src/mocks/kusama_mock.rs index eb3e0ae02..3f992bd0d 100644 --- a/pallets/flexible-fee/src/mocks/kusama_mock.rs +++ b/pallets/flexible-fee/src/mocks/kusama_mock.rs @@ -339,13 +339,12 @@ parameter_types! { impl BalanceCmp for Test { type Error = Error; - fn cmp_with_precision( + fn cmp_with_weth( account: &AccountId, currency: &CurrencyId, amount: u128, - amount_precision: u32, ) -> Result { - Pallet::::cmp_with_precision(account, currency, amount, amount_precision) + Pallet::::cmp_with_weth(account, currency, amount) } } diff --git a/pallets/flexible-fee/src/mocks/polkadot_mock.rs b/pallets/flexible-fee/src/mocks/polkadot_mock.rs index 85361dddd..15e7ac2d9 100644 --- a/pallets/flexible-fee/src/mocks/polkadot_mock.rs +++ b/pallets/flexible-fee/src/mocks/polkadot_mock.rs @@ -332,13 +332,12 @@ parameter_types! { impl BalanceCmp for Test { type Error = Error; - fn cmp_with_precision( + fn cmp_with_weth( account: &AccountId, currency: &CurrencyId, amount: u128, - amount_precision: u32, ) -> Result { - Pallet::::cmp_with_precision(account, currency, amount, amount_precision) + Pallet::::cmp_with_weth(account, currency, amount) } } diff --git a/pallets/flexible-fee/src/tests/common_tests.rs b/pallets/flexible-fee/src/tests/common_tests.rs index 36deca851..dd936d78f 100644 --- a/pallets/flexible-fee/src/tests/common_tests.rs +++ b/pallets/flexible-fee/src/tests/common_tests.rs @@ -781,38 +781,39 @@ fn get_fee_currency_should_work_with_all_currency_poor() { } #[test] -fn cmp_with_precision_should_work_with_weth() { +fn cmp_with_weth_should_work_with_weth() { new_test_ext().execute_with(|| { ini_meta_data(); - assert_ok!(Currencies::deposit(WETH, &ALICE, 10u128.pow(18) - 1)); // ETH + assert_ok!(Currencies::deposit(WETH, &ALICE, 10u128.pow(18) - 10)); // ETH - let ordering = - FlexibleFee::cmp_with_precision(&ALICE, &WETH, 10u128.pow(18), 18u32).unwrap(); + let ordering = FlexibleFee::cmp_with_weth(&ALICE, &WETH, 10u128.pow(18)).unwrap(); assert_eq!(ordering, Less); }); } #[test] -fn cmp_with_precision_should_work_with_dot() { +fn cmp_with_weth_should_work_with_dot() { new_test_ext().execute_with(|| { ini_meta_data(); - assert_ok!(Currencies::deposit(DOT, &ALICE, 10u128.pow(11) + 1)); // DOT + assert_ok!(Currencies::deposit( + DOT, + &ALICE, + 600u128 * 10u128.pow(10) + 10 + )); // DOT - let ordering = - FlexibleFee::cmp_with_precision(&ALICE, &DOT, 10u128.pow(18), 18u32).unwrap(); + let ordering = FlexibleFee::cmp_with_weth(&ALICE, &DOT, 10u128.pow(18)).unwrap(); assert_eq!(ordering, Greater); }); } #[test] -fn cmp_with_precision_should_work_with_bnc() { +fn cmp_with_weth_should_work_with_bnc() { new_test_ext().execute_with(|| { assert_ok!(Currencies::deposit(BNC, &ALICE, 11u128.pow(12))); // BNC - let ordering = - FlexibleFee::cmp_with_precision(&ALICE, &BNC, 10u128.pow(18), 18u32).unwrap(); + let ordering = FlexibleFee::cmp_with_weth(&ALICE, &BNC, 10u128.pow(12)).unwrap(); assert_eq!(ordering, Greater); }); } diff --git a/primitives/src/traits.rs b/primitives/src/traits.rs index f179c0210..0d6b0b384 100644 --- a/primitives/src/traits.rs +++ b/primitives/src/traits.rs @@ -494,17 +494,15 @@ pub trait BalanceCmp { /// - `account`: The account ID whose balance is to be compared. /// - `currency`: The currency ID whose balance is to be compared. /// - `amount`: The amount to compare against. - /// - `amount_precision`: The precision of the input amount. /// /// # Returns /// - `Ok(std::cmp::Ordering)`: The result of the comparison, indicating whether the balance is /// less than, equal to, or greater than the input amount. /// - `Err(Self::Error)`: An error if the comparison fails. - fn cmp_with_precision( + fn cmp_with_weth( account: &AccountId, currency: &CurrencyId, amount: u128, - amount_precision: u32, ) -> Result; }