diff --git a/pallets/flexible-fee/src/lib.rs b/pallets/flexible-fee/src/lib.rs index 462747ca4..e4bfaa9e3 100644 --- a/pallets/flexible-fee/src/lib.rs +++ b/pallets/flexible-fee/src/lib.rs @@ -19,11 +19,10 @@ #![cfg_attr(not(feature = "std"), no_std)] pub use crate::pallet::*; +use bifrost_asset_registry::{AssetMetadata, CurrencyIdMapping, TokenInfo}; use bifrost_primitives::{ - currency::{VGLMR, VMANTA, WETH}, - traits::XcmDestWeightAndFeeHandler, - AssetHubChainId, Balance, BalanceCmp, CurrencyId, DerivativeIndex, OraclePriceProvider, Price, - TryConvertFrom, XcmOperationType, BNC, DOT, GLMR, MANTA, VBNC, VDOT, + traits::XcmDestWeightAndFeeHandler, AssetHubChainId, Balance, BalanceCmp, CurrencyId, + DerivativeIndex, OraclePriceProvider, Price, TryConvertFrom, XcmOperationType, BNC, VBNC, }; use bifrost_xcm_interface::calls::{PolkadotXcmCall, RelaychainCall}; use core::convert::Into; @@ -125,6 +124,8 @@ pub mod pallet { type ParachainId: Get; #[pallet::constant] type PalletId: Get; + // asset registry to get asset metadata + type AssetIdMaps: CurrencyIdMapping>>; } #[pallet::hooks] @@ -743,12 +744,14 @@ impl BalanceCmp for Pallet { let amount = amount.saturating_mul(adjust_precision); // Adjust the balance based on currency type. - let balance_precision_offset = match *currency { - WETH | GLMR | VGLMR | MANTA | VMANTA => standard_precision.saturating_sub(18), - BNC | VBNC => standard_precision.saturating_sub(12), - DOT | VDOT => standard_precision.saturating_sub(10), - _ => return Err(Error::::CurrencyNotSupport), - }; + 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)); diff --git a/pallets/flexible-fee/src/mock.rs b/pallets/flexible-fee/src/mock.rs index 81cef37cd..49981d83d 100644 --- a/pallets/flexible-fee/src/mock.rs +++ b/pallets/flexible-fee/src/mock.rs @@ -20,18 +20,20 @@ use super::*; use crate::{self as flexible_fee, mock_price::MockOraclePriceProvider}; +use bifrost_asset_registry::AssetIdMaps; use bifrost_currencies::BasicCurrencyAdapter; use bifrost_primitives::{ Balance, CurrencyId, EvmPermit, FlexibleFeePalletId, TokenSymbol, ZenlinkPalletId, }; use cumulus_primitives_core::ParaId as Pid; use frame_support::{ - derive_impl, parameter_types, + derive_impl, ord_parameter_types, parameter_types, sp_runtime::{DispatchError, DispatchResult}, traits::{ConstU128, Get, Nothing}, weights::{ConstantMultiplier, IdentityFee}, PalletId, }; +use frame_system::EnsureSignedBy; use frame_system::{self, EnsureRoot}; use orml_traits::MultiCurrency; use pallet_balances::Call as BalancesCall; @@ -74,10 +76,13 @@ pub(crate) const BALANCE_TRANSFER_CALL: ::RuntimeC value: 69, }); +ord_parameter_types! { + pub const CouncilAccount: AccountId = AccountId::from([1u8; 32]); +} impl bifrost_asset_registry::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = Balances; - type RegisterOrigin = EnsureRoot; + type RegisterOrigin = EnsureSignedBy; type WeightInfo = (); } @@ -190,6 +195,7 @@ impl crate::Config for Test { type OraclePriceProvider = MockOraclePriceProvider; type InspectEvmAccounts = EVMAccounts; type EvmPermit = PermitDispatchHandler; + type AssetIdMaps = AssetIdMaps; } pub struct XcmDestWeightAndFee; diff --git a/pallets/flexible-fee/src/tests.rs b/pallets/flexible-fee/src/tests.rs index a4afd8abd..e8756eabd 100644 --- a/pallets/flexible-fee/src/tests.rs +++ b/pallets/flexible-fee/src/tests.rs @@ -23,6 +23,8 @@ use crate::{ impls::on_charge_transaction::PaymentInfo, mock::*, BlockNumberFor, BoundedVec, Config, DispatchError::BadOrigin, Error, UserDefaultFeeCurrency, }; +use bifrost_asset_registry::AssetMetadata; +use bifrost_asset_registry::CurrencyMetadatas; use bifrost_primitives::{ AccountFeeCurrency, BalanceCmp, CurrencyId, TryConvertFrom, BNC, DOT, KSM, MANTA, VBNC, VDOT, WETH, @@ -66,6 +68,185 @@ fn post_info() -> PostDispatchInfo { } } +fn ini_meta_data() { + let metadata = AssetMetadata { + name: b"Polkadot DOT".to_vec(), + symbol: b"DOT".to_vec(), + decimals: 10, + minimal_balance: 1000000, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + assert_ok!(AssetRegistry::register_vtoken_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + 0 + )); + + assert_eq!(CurrencyMetadatas::::get(DOT), Some(metadata.clone())); + + let metadata = AssetMetadata { + name: b"Moonbeam Native Token".to_vec(), + symbol: b"GLMR".to_vec(), + decimals: 18, + minimal_balance: 1000000000000, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + let metadata = AssetMetadata { + name: b"Tether USD".to_vec(), + symbol: b"USDT".to_vec(), + decimals: 6, + minimal_balance: 1000, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + let metadata = AssetMetadata { + name: b"Astar".to_vec(), + symbol: b"ASTR".to_vec(), + decimals: 18, + minimal_balance: 10000000000000000, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + let metadata = AssetMetadata { + name: b"Filecoin Network Token".to_vec(), + symbol: b"FIL".to_vec(), + decimals: 18, + minimal_balance: 1000000000000, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + let metadata = AssetMetadata { + name: b"USD Coin".to_vec(), + symbol: b"USDC".to_vec(), + decimals: 6, + minimal_balance: 1000, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + let metadata = AssetMetadata { + name: b"interBTC".to_vec(), + symbol: b"IBTC".to_vec(), + decimals: 8, + minimal_balance: 100, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + let metadata = AssetMetadata { + name: b"Interlay".to_vec(), + symbol: b"INTR".to_vec(), + decimals: 10, + minimal_balance: 10000000, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + let metadata = AssetMetadata { + name: b"Manta Network".to_vec(), + symbol: b"MANTA".to_vec(), + decimals: 18, + minimal_balance: 1000000000000, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + let metadata = AssetMetadata { + name: b"bncs-20 inscription token BNCS".to_vec(), + symbol: b"BNCS".to_vec(), + decimals: 12, + minimal_balance: 10000000000, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + let metadata = AssetMetadata { + name: b"PINK".to_vec(), + symbol: b"PINK".to_vec(), + decimals: 10, + minimal_balance: 100000000, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + let metadata = AssetMetadata { + name: b"DED".to_vec(), + symbol: b"DED".to_vec(), + decimals: 10, + minimal_balance: 1, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + let metadata = AssetMetadata { + name: b"Pendulum".to_vec(), + symbol: b"PEN".to_vec(), + decimals: 12, + minimal_balance: 100000000, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + let metadata = AssetMetadata { + name: b"Wrapped ETH".to_vec(), + symbol: b"WETH".to_vec(), + decimals: 18, + minimal_balance: 15000000000000, + }; + + assert_ok!(AssetRegistry::register_token_metadata( + RuntimeOrigin::signed(CouncilAccount::get()), + Box::new(metadata.clone()) + )); + + assert_eq!(CurrencyMetadatas::::get(WETH), Some(metadata.clone())); +} + fn basic_setup() { // Deposit some money in Alice, Bob and Charlie's accounts. // Alice @@ -426,6 +607,8 @@ fn get_currency_asset_id_should_work() { #[test] fn get_fee_currency_should_work_with_default_currency() { new_test_ext().execute_with(|| { + ini_meta_data(); + let origin_signed_alice = RuntimeOrigin::signed(ALICE); assert_ok!(FlexibleFee::set_user_default_fee_currency( origin_signed_alice.clone(), @@ -446,6 +629,8 @@ fn get_fee_currency_should_work_with_default_currency() { #[test] fn get_fee_currency_should_work_with_default_currency_poor() { new_test_ext().execute_with(|| { + ini_meta_data(); + let origin_signed_alice = RuntimeOrigin::signed(ALICE); assert_ok!(FlexibleFee::set_user_default_fee_currency( origin_signed_alice.clone(), @@ -466,6 +651,8 @@ fn get_fee_currency_should_work_with_default_currency_poor() { #[test] fn get_fee_currency_should_work_with_weth() { new_test_ext().execute_with(|| { + ini_meta_data(); + assert_ok!(Currencies::deposit(BNC, &ALICE, 100u128.pow(12))); // BNC assert_ok!(Currencies::deposit(DOT, &ALICE, 100u128.pow(10))); // DOT assert_ok!(Currencies::deposit(VDOT, &ALICE, 100u128.pow(10))); // vDOT @@ -480,6 +667,8 @@ fn get_fee_currency_should_work_with_weth() { #[test] fn get_fee_currency_should_work_with_weth_poor() { new_test_ext().execute_with(|| { + ini_meta_data(); + assert_ok!(Currencies::deposit(BNC, &ALICE, 100u128.pow(12))); // BNC assert_ok!(Currencies::deposit(DOT, &ALICE, 100u128.pow(10))); // DOT assert_ok!(Currencies::deposit(VDOT, &ALICE, 100u128.pow(10))); // vDOT @@ -504,6 +693,8 @@ fn get_fee_currency_should_work_with_weth_poor() { #[test] fn get_fee_currency_should_work_with_universal_fee_currency() { new_test_ext().execute_with(|| { + ini_meta_data(); + let origin_signed_alice = RuntimeOrigin::signed(ALICE); assert_ok!(FlexibleFee::set_user_default_fee_currency( origin_signed_alice.clone(), @@ -534,6 +725,8 @@ fn get_fee_currency_should_work_with_universal_fee_currency() { #[test] fn get_fee_currency_should_work_with_universal_fee_currency_poor() { new_test_ext().execute_with(|| { + ini_meta_data(); + assert_ok!(Currencies::deposit(BNC, &ALICE, 1u128.pow(12))); // BNC assert_ok!(Currencies::deposit(DOT, &ALICE, 100u128.pow(10))); // DOT assert_ok!(Currencies::deposit(VDOT, &ALICE, 1u128.pow(10))); // vDOT @@ -558,6 +751,8 @@ fn get_fee_currency_should_work_with_universal_fee_currency_poor() { #[test] fn get_fee_currency_should_work_with_all_currency_poor() { new_test_ext().execute_with(|| { + ini_meta_data(); + let origin_signed_alice = RuntimeOrigin::signed(ALICE); assert_ok!(FlexibleFee::set_user_default_fee_currency( origin_signed_alice.clone(), @@ -588,6 +783,8 @@ fn get_fee_currency_should_work_with_all_currency_poor() { #[test] fn cmp_with_precision_should_work_with_weth() { new_test_ext().execute_with(|| { + ini_meta_data(); + assert_ok!(Currencies::deposit(WETH, &ALICE, 10u128.pow(18) - 1)); // ETH let ordering = @@ -599,6 +796,8 @@ fn cmp_with_precision_should_work_with_weth() { #[test] fn cmp_with_precision_should_work_with_dot() { new_test_ext().execute_with(|| { + ini_meta_data(); + assert_ok!(Currencies::deposit(DOT, &ALICE, 10u128.pow(11) + 1)); // DOT let ordering = diff --git a/runtime/bifrost-kusama/src/lib.rs b/runtime/bifrost-kusama/src/lib.rs index 1d2a2a202..efa7bcd17 100644 --- a/runtime/bifrost-kusama/src/lib.rs +++ b/runtime/bifrost-kusama/src/lib.rs @@ -1133,6 +1133,7 @@ impl bifrost_flexible_fee::Config for Runtime { type OraclePriceProvider = Prices; type InspectEvmAccounts = (); type EvmPermit = bifrost_flexible_fee::impls::evm_permit::DisabledEvmPermitHandler; + type AssetIdMaps = AssetIdMaps; } parameter_types! { diff --git a/runtime/bifrost-polkadot/src/lib.rs b/runtime/bifrost-polkadot/src/lib.rs index 582f1d1bc..10ae22c4f 100644 --- a/runtime/bifrost-polkadot/src/lib.rs +++ b/runtime/bifrost-polkadot/src/lib.rs @@ -988,6 +988,7 @@ impl bifrost_flexible_fee::Config for Runtime { type OraclePriceProvider = Prices; type InspectEvmAccounts = EVMAccounts; type EvmPermit = evm::permit::EvmPermitHandler; + type AssetIdMaps = AssetIdMaps; } parameter_types! {