From 8d3a6ad23a6efe0e63e134d40f7015f1cacb6cf7 Mon Sep 17 00:00:00 2001 From: zjb0807 Date: Fri, 10 Jan 2025 15:27:48 +0800 Subject: [PATCH 1/8] fix swap_from_pool_or_dex --- modules/auction-manager/src/lib.rs | 10 +- modules/cdp-engine/src/lib.rs | 29 ++++- modules/cdp-treasury/src/lib.rs | 42 ++++++- modules/currencies/src/lib.rs | 101 +++++++++++++---- modules/currencies/src/tests.rs | 40 +++++-- modules/dex/src/lib.rs | 106 +++++++++++++++--- modules/evm/src/tests.rs | 1 + modules/homa/src/lib.rs | 21 +++- modules/homa/src/mock.rs | 7 +- modules/honzon-bridge/src/lib.rs | 34 +++++- modules/incentives/src/lib.rs | 27 ++++- modules/incentives/src/tests.rs | 7 +- modules/liquid-crowdloan/src/lib.rs | 17 ++- modules/loans/src/lib.rs | 18 ++- modules/transaction-payment/src/lib.rs | 63 ++++++++--- modules/transaction-payment/src/tests.rs | 50 +++++++-- orml | 2 +- runtime/common/src/precompile/mock.rs | 19 ++-- .../common/src/precompile/multicurrency.rs | 4 +- 19 files changed, 493 insertions(+), 105 deletions(-) diff --git a/modules/auction-manager/src/lib.rs b/modules/auction-manager/src/lib.rs index e7fcb4b825..0d174c8ce5 100644 --- a/modules/auction-manager/src/lib.rs +++ b/modules/auction-manager/src/lib.rs @@ -30,7 +30,7 @@ #![allow(clippy::upper_case_acronyms)] #![allow(clippy::unnecessary_unwrap)] -use frame_support::{pallet_prelude::*, transactional}; +use frame_support::{pallet_prelude::*, traits::ExistenceRequirement, transactional}; use frame_system::{ offchain::{SendTransactionTypes, SubmitTransaction}, pallet_prelude::*, @@ -554,7 +554,13 @@ impl Pallet { // if there's bid before, return stablecoin from new bidder to last bidder if let Some(last_bidder) = last_bidder { let refund = collateral_auction.payment_amount(last_bid_price); - T::Currency::transfer(T::GetStableCurrencyId::get(), &new_bidder, last_bidder, refund)?; + T::Currency::transfer( + T::GetStableCurrencyId::get(), + &new_bidder, + last_bidder, + refund, + ExistenceRequirement::AllowDeath, + )?; payment = payment .checked_sub(refund) diff --git a/modules/cdp-engine/src/lib.rs b/modules/cdp-engine/src/lib.rs index ad84cff6be..a1d0fa0b81 100644 --- a/modules/cdp-engine/src/lib.rs +++ b/modules/cdp-engine/src/lib.rs @@ -28,7 +28,9 @@ #![allow(clippy::unused_unit)] #![allow(clippy::upper_case_acronyms)] -use frame_support::{pallet_prelude::*, traits::UnixTime, transactional, BoundedVec, PalletId}; +use frame_support::{ + pallet_prelude::*, traits::ExistenceRequirement, traits::UnixTime, transactional, BoundedVec, PalletId, +}; use frame_system::{ offchain::{SendTransactionTypes, SubmitTransaction}, pallet_prelude::*, @@ -1014,10 +1016,22 @@ impl Pallet { // refund unused lp component tokens if let Some(remainer) = available_0.checked_sub(consumption_0) { - ::Currency::transfer(token_0, &loans_module_account, who, remainer)?; + ::Currency::transfer( + token_0, + &loans_module_account, + who, + remainer, + ExistenceRequirement::AllowDeath, + )?; } if let Some(remainer) = available_1.checked_sub(consumption_1) { - ::Currency::transfer(token_1, &loans_module_account, who, remainer)?; + ::Currency::transfer( + token_1, + &loans_module_account, + who, + remainer, + ExistenceRequirement::AllowDeath, + )?; } actual_increase_lp @@ -1119,6 +1133,7 @@ impl Pallet { &loans_module_account, who, actual_stable_amount.saturating_sub(previous_debit_value), + ExistenceRequirement::AllowDeath, )?; (previous_debit_value, debit) @@ -1484,7 +1499,13 @@ impl LiquidateCollateral for LiquidateViaContracts { return Ok(()); } else if repayment > 0 { // insufficient repayment, refund - CurrencyOf::::transfer(stable_coin, &repay_dest_account_id, &contract_account_id, repayment)?; + CurrencyOf::::transfer( + stable_coin, + &repay_dest_account_id, + &contract_account_id, + repayment, + ExistenceRequirement::AllowDeath, + )?; // notify liquidation failed T::LiquidationEvmBridge::on_repayment_refund( InvokeContext { diff --git a/modules/cdp-treasury/src/lib.rs b/modules/cdp-treasury/src/lib.rs index a6a108ae5d..4c0ea96539 100644 --- a/modules/cdp-treasury/src/lib.rs +++ b/modules/cdp-treasury/src/lib.rs @@ -29,7 +29,7 @@ #![allow(clippy::unused_unit)] #![allow(clippy::needless_range_loop)] -use frame_support::{pallet_prelude::*, transactional, PalletId}; +use frame_support::{pallet_prelude::*, traits::ExistenceRequirement, transactional, PalletId}; use frame_system::pallet_prelude::*; use module_support::{AuctionManager, CDPTreasury, CDPTreasuryExtended, DEXManager, Ratio, Swap, SwapLimit}; use nutsfinance_stable_asset::traits::StableAsset; @@ -194,6 +194,7 @@ pub mod module { &Self::account_id(), &T::TreasuryAccount::get(), amount, + ExistenceRequirement::AllowDeath, )?; Ok(()) } @@ -391,23 +392,52 @@ impl CDPTreasury for Pallet { /// This should be the only function in the system that burns stable coin fn burn_debit(who: &T::AccountId, debit: Self::Balance) -> DispatchResult { - T::Currency::withdraw(T::GetStableCurrencyId::get(), who, debit) + T::Currency::withdraw( + T::GetStableCurrencyId::get(), + who, + debit, + ExistenceRequirement::AllowDeath, + ) } fn deposit_surplus(from: &T::AccountId, surplus: Self::Balance) -> DispatchResult { - T::Currency::transfer(T::GetStableCurrencyId::get(), from, &Self::account_id(), surplus) + T::Currency::transfer( + T::GetStableCurrencyId::get(), + from, + &Self::account_id(), + surplus, + ExistenceRequirement::AllowDeath, + ) } fn withdraw_surplus(to: &T::AccountId, surplus: Self::Balance) -> DispatchResult { - T::Currency::transfer(T::GetStableCurrencyId::get(), &Self::account_id(), to, surplus) + T::Currency::transfer( + T::GetStableCurrencyId::get(), + &Self::account_id(), + to, + surplus, + ExistenceRequirement::AllowDeath, + ) } fn deposit_collateral(from: &T::AccountId, currency_id: Self::CurrencyId, amount: Self::Balance) -> DispatchResult { - T::Currency::transfer(currency_id, from, &Self::account_id(), amount) + T::Currency::transfer( + currency_id, + from, + &Self::account_id(), + amount, + ExistenceRequirement::AllowDeath, + ) } fn withdraw_collateral(to: &T::AccountId, currency_id: Self::CurrencyId, amount: Self::Balance) -> DispatchResult { - T::Currency::transfer(currency_id, &Self::account_id(), to, amount) + T::Currency::transfer( + currency_id, + &Self::account_id(), + to, + amount, + ExistenceRequirement::AllowDeath, + ) } } diff --git a/modules/currencies/src/lib.rs b/modules/currencies/src/lib.rs index 7ceb58e6f2..d371820f62 100644 --- a/modules/currencies/src/lib.rs +++ b/modules/currencies/src/lib.rs @@ -184,7 +184,13 @@ pub mod module { ) -> DispatchResult { let from = ensure_signed(origin)?; let to = T::Lookup::lookup(dest)?; - >::transfer(currency_id, &from, &to, amount) + >::transfer( + currency_id, + &from, + &to, + amount, + ExistenceRequirement::AllowDeath, + ) } /// Transfer some native currency to another account. @@ -200,7 +206,7 @@ pub mod module { ) -> DispatchResult { let from = ensure_signed(origin)?; let to = T::Lookup::lookup(dest)?; - >::transfer(&from, &to, amount) + >::transfer(&from, &to, amount, ExistenceRequirement::AllowDeath) } /// Update amount of account `who` under `currency_id`. @@ -380,6 +386,7 @@ impl MultiCurrency for Pallet { from: &T::AccountId, to: &T::AccountId, amount: Self::Balance, + existence_requirement: ExistenceRequirement, ) -> DispatchResult { if amount.is_zero() || from == to { return Ok(()); @@ -400,9 +407,11 @@ impl MultiCurrency for Pallet { )?; } id if id == T::GetNativeCurrencyId::get() => { - >::transfer(from, to, amount)? + >::transfer(from, to, amount, existence_requirement)? + } + _ => { + >::transfer(currency_id, from, to, amount, existence_requirement)? } - _ => >::transfer(currency_id, from, to, amount)?, } Self::deposit_event(Event::Transferred { @@ -457,7 +466,12 @@ impl MultiCurrency for Pallet { } } - fn withdraw(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> DispatchResult { + fn withdraw( + currency_id: Self::CurrencyId, + who: &T::AccountId, + amount: Self::Balance, + existence_requirement: ExistenceRequirement, + ) -> DispatchResult { if amount.is_zero() { return Ok(()); } @@ -491,8 +505,10 @@ impl MultiCurrency for Pallet { }); Ok(()) } - id if id == T::GetNativeCurrencyId::get() => >::withdraw(who, amount), - _ => >::withdraw(currency_id, who, amount), + id if id == T::GetNativeCurrencyId::get() => { + >::withdraw(who, amount, existence_requirement) + } + _ => >::withdraw(currency_id, who, amount, existence_requirement), } } @@ -944,8 +960,14 @@ impl fungibles::Mutate for Pallet { precision: Precision, fortitude: Fortitude, ) -> Result { + let existence_requirement = match preservation { + Preservation::Expendable => ExistenceRequirement::AllowDeath, + Preservation::Protect | Preservation::Preserve => ExistenceRequirement::KeepAlive, + }; match asset_id { - CurrencyId::Erc20(_) => >::withdraw(asset_id, who, amount).map(|_| amount), + CurrencyId::Erc20(_) => { + >::withdraw(asset_id, who, amount, existence_requirement).map(|_| amount) + } id if id == T::GetNativeCurrencyId::get() => { >::burn_from(who, amount, preservation, precision, fortitude) } @@ -967,10 +989,15 @@ impl fungibles::Mutate for Pallet { amount: Self::Balance, preservation: Preservation, ) -> Result { + let existence_requirement = match preservation { + Preservation::Expendable => ExistenceRequirement::AllowDeath, + Preservation::Protect | Preservation::Preserve => ExistenceRequirement::KeepAlive, + }; match asset_id { CurrencyId::Erc20(_) => { // Event is deposited in `fn transfer` - >::transfer(asset_id, source, dest, amount).map(|_| amount) + >::transfer(asset_id, source, dest, amount, existence_requirement) + .map(|_| amount) } id if id == T::GetNativeCurrencyId::get() => { >::transfer(source, dest, amount, preservation).map(|actual| { @@ -1195,16 +1222,31 @@ where as MultiCurrency>::ensure_can_withdraw(GetCurrencyId::get(), who, amount) } - fn transfer(from: &T::AccountId, to: &T::AccountId, amount: Self::Balance) -> DispatchResult { - as MultiCurrency>::transfer(GetCurrencyId::get(), from, to, amount) + fn transfer( + from: &T::AccountId, + to: &T::AccountId, + amount: Self::Balance, + existence_requirement: ExistenceRequirement, + ) -> DispatchResult { + as MultiCurrency>::transfer( + GetCurrencyId::get(), + from, + to, + amount, + existence_requirement, + ) } fn deposit(who: &T::AccountId, amount: Self::Balance) -> DispatchResult { as MultiCurrency>::deposit(GetCurrencyId::get(), who, amount) } - fn withdraw(who: &T::AccountId, amount: Self::Balance) -> DispatchResult { - as MultiCurrency>::withdraw(GetCurrencyId::get(), who, amount) + fn withdraw( + who: &T::AccountId, + amount: Self::Balance, + existence_requirement: ExistenceRequirement, + ) -> DispatchResult { + as MultiCurrency>::withdraw(GetCurrencyId::get(), who, amount, existence_requirement) } fn can_slash(who: &T::AccountId, amount: Self::Balance) -> bool { @@ -1500,8 +1542,13 @@ where >::ensure_can_withdraw(who, amount, WithdrawReasons::all(), new_balance) } - fn transfer(from: &AccountId, to: &AccountId, amount: Self::Balance) -> DispatchResult { - >::transfer(from, to, amount, ExistenceRequirement::AllowDeath) + fn transfer( + from: &AccountId, + to: &AccountId, + amount: Self::Balance, + existence_requirement: ExistenceRequirement, + ) -> DispatchResult { + >::transfer(from, to, amount, existence_requirement) } fn deposit(who: &AccountId, amount: Self::Balance) -> DispatchResult { @@ -1514,8 +1561,8 @@ where Ok(()) } - fn withdraw(who: &AccountId, amount: Self::Balance) -> DispatchResult { - >::withdraw(who, amount, WithdrawReasons::all(), ExistenceRequirement::AllowDeath) + fn withdraw(who: &AccountId, amount: Self::Balance, existence_requirement: ExistenceRequirement) -> DispatchResult { + >::withdraw(who, amount, WithdrawReasons::all(), existence_requirement) .map(|_| ()) } @@ -1556,7 +1603,7 @@ where if by_amount.is_positive() { Self::deposit(who, by_balance) } else { - Self::withdraw(who, by_balance) + Self::withdraw(who, by_balance, ExistenceRequirement::AllowDeath) } } } @@ -1800,6 +1847,7 @@ impl TransferAll for Pallet { source, dest, >::free_balance(source), + ExistenceRequirement::AllowDeath, ) } } @@ -1820,10 +1868,19 @@ where // if failed will leave some dust which still could be recycled. let _ = match currency_id { CurrencyId::Erc20(_) => Ok(()), - id if id == T::GetNativeCurrencyId::get() => { - >::transfer(who, &GetAccountId::get(), amount) - } - _ => >::transfer(currency_id, who, &GetAccountId::get(), amount), + id if id == T::GetNativeCurrencyId::get() => >::transfer( + who, + &GetAccountId::get(), + amount, + ExistenceRequirement::AllowDeath, + ), + _ => >::transfer( + currency_id, + who, + &GetAccountId::get(), + amount, + ExistenceRequirement::AllowDeath, + ), }; } } diff --git a/modules/currencies/src/tests.rs b/modules/currencies/src/tests.rs index 111b18fb41..87f2255eab 100644 --- a/modules/currencies/src/tests.rs +++ b/modules/currencies/src/tests.rs @@ -471,7 +471,12 @@ fn native_currency_should_work() { assert_eq!(NativeCurrency::free_balance(&alice()), 50); assert_eq!(NativeCurrency::free_balance(&bob()), 150); - assert_ok!(NativeCurrency::transfer(&alice(), &bob(), 10)); + assert_ok!(NativeCurrency::transfer( + &alice(), + &bob(), + 10, + ExistenceRequirement::AllowDeath + )); assert_eq!(NativeCurrency::free_balance(&alice()), 40); assert_eq!(NativeCurrency::free_balance(&bob()), 160); @@ -505,12 +510,22 @@ fn basic_currency_adapting_pallet_balances_transfer() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(AdaptedBasicCurrency::transfer(&alice(), &bob(), 50)); + assert_ok!(AdaptedBasicCurrency::transfer( + &alice(), + &bob(), + 50, + ExistenceRequirement::AllowDeath + )); assert_eq!(PalletBalances::total_balance(&alice()), 50); assert_eq!(PalletBalances::total_balance(&bob()), 150); // creation fee - assert_ok!(AdaptedBasicCurrency::transfer(&alice(), &eva(), 10)); + assert_ok!(AdaptedBasicCurrency::transfer( + &alice(), + &eva(), + 10, + ExistenceRequirement::AllowDeath + )); assert_eq!(PalletBalances::total_balance(&alice()), 40); assert_eq!(PalletBalances::total_balance(&eva()), 10); }); @@ -554,7 +569,11 @@ fn basic_currency_adapting_pallet_balances_withdraw() { .one_hundred_for_alice_n_bob() .build() .execute_with(|| { - assert_ok!(AdaptedBasicCurrency::withdraw(&alice(), 100)); + assert_ok!(AdaptedBasicCurrency::withdraw( + &alice(), + 100, + ExistenceRequirement::AllowDeath + )); assert_eq!(PalletBalances::total_balance(&alice()), 0); assert_eq!(PalletBalances::total_issuance(), 100); }); @@ -645,7 +664,8 @@ fn call_event_should_work() { X_TOKEN_ID, &alice(), &bob(), - 10 + 10, + ExistenceRequirement::AllowDeath )); assert_eq!(Currencies::free_balance(X_TOKEN_ID, &alice()), 40); assert_eq!(Currencies::free_balance(X_TOKEN_ID, &bob()), 160); @@ -677,7 +697,8 @@ fn call_event_should_work() { assert_ok!(>::withdraw( X_TOKEN_ID, &alice(), - 20 + 20, + ExistenceRequirement::AllowDeath )); assert_eq!(Currencies::free_balance(X_TOKEN_ID, &alice()), 120); System::assert_last_event(RuntimeEvent::Tokens(orml_tokens::Event::Withdrawn { @@ -1231,7 +1252,12 @@ fn erc20_withdraw_deposit_works() { ); // withdraw: sender to erc20 holding account - assert_ok!(Currencies::withdraw(CurrencyId::Erc20(erc20_address()), &alice(), 100)); + assert_ok!(Currencies::withdraw( + CurrencyId::Erc20(erc20_address()), + &alice(), + 100, + ExistenceRequirement::AllowDeath + )); assert_eq!( 200, Currencies::free_balance(CurrencyId::Erc20(erc20_address()), &erc20_holding_account) diff --git a/modules/dex/src/lib.rs b/modules/dex/src/lib.rs index 728dd33aac..768cbdc962 100644 --- a/modules/dex/src/lib.rs +++ b/modules/dex/src/lib.rs @@ -33,7 +33,7 @@ #![allow(clippy::unused_unit)] #![allow(clippy::collapsible_if)] -use frame_support::{pallet_prelude::*, transactional, PalletId}; +use frame_support::{pallet_prelude::*, traits::ExistenceRequirement, transactional, PalletId}; use frame_system::pallet_prelude::*; use module_support::{DEXBootstrap, DEXIncentives, DEXManager, Erc20InfoMapping, ExchangeRate, Ratio, SwapLimit}; use orml_traits::{Happened, MultiCurrency, MultiCurrencyExtended}; @@ -862,6 +862,7 @@ impl Pallet { &Self::account_id(), who, shares_to_claim, + ExistenceRequirement::AllowDeath, )?; // decrease ref count @@ -901,8 +902,20 @@ impl Pallet { ProvisioningPool::::try_mutate_exists(trading_pair, who, |maybe_contribution| -> DispatchResult { if let Some((contribution_0, contribution_1)) = maybe_contribution.take() { - T::Currency::transfer(trading_pair.first(), &Self::account_id(), who, contribution_0)?; - T::Currency::transfer(trading_pair.second(), &Self::account_id(), who, contribution_1)?; + T::Currency::transfer( + trading_pair.first(), + &Self::account_id(), + who, + contribution_0, + ExistenceRequirement::AllowDeath, + )?; + T::Currency::transfer( + trading_pair.second(), + &Self::account_id(), + who, + contribution_1, + ExistenceRequirement::AllowDeath, + )?; // decrease ref count frame_system::Pallet::::dec_consumers(who); @@ -951,8 +964,20 @@ impl Pallet { pool.1 = pool.1.checked_add(contribution_1).ok_or(ArithmeticError::Overflow)?; let module_account_id = Self::account_id(); - T::Currency::transfer(trading_pair.first(), who, &module_account_id, contribution_0)?; - T::Currency::transfer(trading_pair.second(), who, &module_account_id, contribution_1)?; + T::Currency::transfer( + trading_pair.first(), + who, + &module_account_id, + contribution_0, + ExistenceRequirement::AllowDeath, + )?; + T::Currency::transfer( + trading_pair.second(), + who, + &module_account_id, + contribution_1, + ExistenceRequirement::AllowDeath, + )?; *maybe_pool = Some(pool); @@ -1088,8 +1113,20 @@ impl Pallet { ); let module_account_id = Self::account_id(); - T::Currency::transfer(trading_pair.first(), who, &module_account_id, pool_0_increment)?; - T::Currency::transfer(trading_pair.second(), who, &module_account_id, pool_1_increment)?; + T::Currency::transfer( + trading_pair.first(), + who, + &module_account_id, + pool_0_increment, + ExistenceRequirement::AllowDeath, + )?; + T::Currency::transfer( + trading_pair.second(), + who, + &module_account_id, + pool_1_increment, + ExistenceRequirement::AllowDeath, + )?; T::Currency::deposit(dex_share_currency_id, who, share_increment)?; *pool_0 = pool_0.checked_add(pool_0_increment).ok_or(ArithmeticError::Overflow)?; @@ -1157,9 +1194,26 @@ impl Pallet { if by_unstake { T::DEXIncentives::do_withdraw_dex_share(who, dex_share_currency_id, remove_share)?; } - T::Currency::withdraw(dex_share_currency_id, who, remove_share)?; - T::Currency::transfer(trading_pair.first(), &module_account_id, who, pool_0_decrement)?; - T::Currency::transfer(trading_pair.second(), &module_account_id, who, pool_1_decrement)?; + T::Currency::withdraw( + dex_share_currency_id, + who, + remove_share, + ExistenceRequirement::AllowDeath, + )?; + T::Currency::transfer( + trading_pair.first(), + &module_account_id, + who, + pool_0_decrement, + ExistenceRequirement::AllowDeath, + )?; + T::Currency::transfer( + trading_pair.second(), + &module_account_id, + who, + pool_1_decrement, + ExistenceRequirement::AllowDeath, + )?; *pool_0 = pool_0.checked_sub(pool_0_decrement).ok_or(ArithmeticError::Underflow)?; *pool_1 = pool_1.checked_sub(pool_1_decrement).ok_or(ArithmeticError::Underflow)?; @@ -1380,9 +1434,21 @@ impl Pallet { let module_account_id = Self::account_id(); let actual_target_amount = amounts[amounts.len() - 1]; - T::Currency::transfer(path[0], who, &module_account_id, supply_amount)?; + T::Currency::transfer( + path[0], + who, + &module_account_id, + supply_amount, + ExistenceRequirement::AllowDeath, + )?; Self::_swap_by_path(path, &amounts)?; - T::Currency::transfer(path[path.len() - 1], &module_account_id, who, actual_target_amount)?; + T::Currency::transfer( + path[path.len() - 1], + &module_account_id, + who, + actual_target_amount, + ExistenceRequirement::AllowDeath, + )?; Self::deposit_event(Event::Swap { trader: who.clone(), @@ -1404,9 +1470,21 @@ impl Pallet { let module_account_id = Self::account_id(); let actual_supply_amount = amounts[0]; - T::Currency::transfer(path[0], who, &module_account_id, actual_supply_amount)?; + T::Currency::transfer( + path[0], + who, + &module_account_id, + actual_supply_amount, + ExistenceRequirement::AllowDeath, + )?; Self::_swap_by_path(path, &amounts)?; - T::Currency::transfer(path[path.len() - 1], &module_account_id, who, target_amount)?; + T::Currency::transfer( + path[path.len() - 1], + &module_account_id, + who, + target_amount, + ExistenceRequirement::AllowDeath, + )?; Self::deposit_event(Event::Swap { trader: who.clone(), diff --git a/modules/evm/src/tests.rs b/modules/evm/src/tests.rs index d6adfc2bb6..ad7cf4e625 100644 --- a/modules/evm/src/tests.rs +++ b/modules/evm/src/tests.rs @@ -2484,6 +2484,7 @@ fn reserve_deposit_makes_user_developer() { &::AddressMapping::get_account_id(&alice()), &who, DEVELOPER_DEPOSIT, + ExistenceRequirement::AllowDeath )); assert_ok!(::Currency::ensure_reserved_named( diff --git a/modules/homa/src/lib.rs b/modules/homa/src/lib.rs index 4f150b1878..85b1cd3a23 100644 --- a/modules/homa/src/lib.rs +++ b/modules/homa/src/lib.rs @@ -21,7 +21,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::unused_unit)] -use frame_support::{pallet_prelude::*, transactional, PalletId}; +use frame_support::{pallet_prelude::*, traits::ExistenceRequirement, transactional, PalletId}; use frame_system::{ensure_signed, pallet_prelude::*}; use module_support::{ ExchangeRate, ExchangeRateProvider, FractionalRate, HomaManager, HomaSubAccountXcm, NomineesProvider, Rate, Ratio, @@ -485,6 +485,7 @@ pub mod module { &Self::account_id(), &redeemer, available_staking, + ExistenceRequirement::AllowDeath, )?; Self::deposit_event(Event::::WithdrawRedemption { @@ -742,7 +743,13 @@ pub mod module { Error::::ExceededStakingCurrencySoftCap ); - T::Currency::transfer(T::StakingCurrencyId::get(), &minter, &Self::account_id(), amount)?; + T::Currency::transfer( + T::StakingCurrencyId::get(), + &minter, + &Self::account_id(), + amount, + ExistenceRequirement::AllowDeath, + )?; // calculate the liquid amount by the current exchange rate. let liquid_amount = Self::convert_staking_to_liquid(amount)?; @@ -789,6 +796,7 @@ pub mod module { &redeemer, &Self::account_id(), amount.saturating_sub(previous_request_amount), + ExistenceRequirement::AllowDeath, ) } Ordering::Less => { @@ -798,6 +806,7 @@ pub mod module { &Self::account_id(), &redeemer, previous_request_amount.saturating_sub(amount), + ExistenceRequirement::AllowDeath, ) } _ => Ok(()), @@ -912,6 +921,7 @@ pub mod module { &module_account, redeemer, redeemed_staking, + ExistenceRequirement::AllowDeath, )?; ToBondPool::::mutate(|pool| *pool = pool.saturating_sub(redeemed_staking)); @@ -1207,7 +1217,12 @@ pub mod module { /// This should be the only function in the system that burn liquid currency fn burn_liquid_currency(who: &T::AccountId, amount: Balance) -> DispatchResult { - T::Currency::withdraw(T::LiquidCurrencyId::get(), who, amount) + T::Currency::withdraw( + T::LiquidCurrencyId::get(), + who, + amount, + ExistenceRequirement::AllowDeath, + ) } /// Issue staking currency based on the subaccounts transfer the unbonded staking currency diff --git a/modules/homa/src/mock.rs b/modules/homa/src/mock.rs index 51864f0cdb..1eb989fe89 100644 --- a/modules/homa/src/mock.rs +++ b/modules/homa/src/mock.rs @@ -59,7 +59,12 @@ impl HomaSubAccountXcm for MockHomaSubAccountXcm { type RelayChainAccountId = AccountId; fn transfer_staking_to_sub_account(sender: &AccountId, _: u16, amount: Balance) -> DispatchResult { - Currencies::withdraw(StakingCurrencyId::get(), sender, amount) + Currencies::withdraw( + StakingCurrencyId::get(), + sender, + amount, + ExistenceRequirement::AllowDeath, + ) } fn withdraw_unbonded_from_sub_account(_: u16, _: Balance) -> DispatchResult { diff --git a/modules/honzon-bridge/src/lib.rs b/modules/honzon-bridge/src/lib.rs index 96ba255478..64762731d2 100644 --- a/modules/honzon-bridge/src/lib.rs +++ b/modules/honzon-bridge/src/lib.rs @@ -23,7 +23,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::unused_unit)] -use frame_support::pallet_prelude::*; +use frame_support::{pallet_prelude::*, traits::ExistenceRequirement}; use frame_system::pallet_prelude::*; use primitives::{currency::KUSD, evm::EvmAddress, Balance, CurrencyId}; @@ -133,10 +133,22 @@ pub mod module { Self::bridged_stable_coin_currency_id().ok_or(Error::::BridgedStableCoinCurrencyIdNotSet)?; // transfer amount of StableCoinCurrencyId to PalletId account - T::Currency::transfer(T::StableCoinCurrencyId::get(), &who, &pallet_account, amount)?; + T::Currency::transfer( + T::StableCoinCurrencyId::get(), + &who, + &pallet_account, + amount, + ExistenceRequirement::AllowDeath, + )?; // transfer amount of BridgedStableCoinCurrencyId from PalletId account to origin - T::Currency::transfer(bridged_stable_coin_currency_id, &pallet_account, &who, amount)?; + T::Currency::transfer( + bridged_stable_coin_currency_id, + &pallet_account, + &who, + amount, + ExistenceRequirement::AllowDeath, + )?; Self::deposit_event(Event::::ToBridged { who, amount }); Ok(()) @@ -156,10 +168,22 @@ pub mod module { Self::bridged_stable_coin_currency_id().ok_or(Error::::BridgedStableCoinCurrencyIdNotSet)?; // transfer amount of BridgedStableCoinCurrencyId to PalletId account - T::Currency::transfer(bridged_stable_coin_currency_id, &who, &pallet_account, amount)?; + T::Currency::transfer( + bridged_stable_coin_currency_id, + &who, + &pallet_account, + amount, + ExistenceRequirement::AllowDeath, + )?; // transfer amount of StableCoinCurrencyId from PalletId account to origin - T::Currency::transfer(T::StableCoinCurrencyId::get(), &pallet_account, &who, amount)?; + T::Currency::transfer( + T::StableCoinCurrencyId::get(), + &pallet_account, + &who, + amount, + ExistenceRequirement::AllowDeath, + )?; Self::deposit_event(Event::::FromBridged { who, amount }); Ok(()) diff --git a/modules/incentives/src/lib.rs b/modules/incentives/src/lib.rs index 7114b2d5aa..c3b5c98e4d 100644 --- a/modules/incentives/src/lib.rs +++ b/modules/incentives/src/lib.rs @@ -39,7 +39,7 @@ #![allow(clippy::unused_unit)] #![allow(clippy::upper_case_acronyms)] -use frame_support::{pallet_prelude::*, transactional, PalletId}; +use frame_support::{pallet_prelude::*, traits::ExistenceRequirement, transactional, PalletId}; use frame_system::pallet_prelude::*; use module_support::{DEXIncentives, EmergencyShutdown, FractionalRate, IncentivesManager, PoolId, Rate}; use orml_traits::{Handler, MultiCurrency, RewardHandler}; @@ -408,6 +408,7 @@ impl Pallet { &T::RewardsSource::get(), &Self::account_id(), reward_amount, + ExistenceRequirement::AllowDeath, )?; >::accumulate_reward(&pool_id, reward_currency_id, reward_amount)?; Ok(()) @@ -502,7 +503,13 @@ impl Pallet { if !reaccumulate_amount.is_zero() { >::accumulate_reward(&pool_id, reward_currency_id, reaccumulate_amount)?; } - T::Currency::transfer(reward_currency_id, &Self::account_id(), who, payout_amount)?; + T::Currency::transfer( + reward_currency_id, + &Self::account_id(), + who, + payout_amount, + ExistenceRequirement::AllowDeath, + )?; Ok(()) } } @@ -511,7 +518,13 @@ impl DEXIncentives for Pallet { fn do_deposit_dex_share(who: &T::AccountId, lp_currency_id: CurrencyId, amount: Balance) -> DispatchResult { ensure!(lp_currency_id.is_dex_share_currency_id(), Error::::InvalidCurrencyId); - T::Currency::transfer(lp_currency_id, who, &Self::account_id(), amount)?; + T::Currency::transfer( + lp_currency_id, + who, + &Self::account_id(), + amount, + ExistenceRequirement::AllowDeath, + )?; >::add_share(who, &PoolId::Dex(lp_currency_id), amount.unique_saturated_into())?; Self::deposit_event(Event::DepositDexShare { @@ -529,7 +542,13 @@ impl DEXIncentives for Pallet { Error::::NotEnough, ); - T::Currency::transfer(lp_currency_id, &Self::account_id(), who, amount)?; + T::Currency::transfer( + lp_currency_id, + &Self::account_id(), + who, + amount, + ExistenceRequirement::AllowDeath, + )?; >::remove_share(who, &PoolId::Dex(lp_currency_id), amount.unique_saturated_into())?; Self::deposit_event(Event::WithdrawDexShare { diff --git a/modules/incentives/src/tests.rs b/modules/incentives/src/tests.rs index d80d2c566d..b6a222c005 100644 --- a/modules/incentives/src/tests.rs +++ b/modules/incentives/src/tests.rs @@ -585,7 +585,12 @@ fn transfer_failed_when_claim_rewards() { ); // mock the Vault is enough for some reasons - assert_ok!(TokensModule::withdraw(AUSD, &VAULT::get(), 3)); + assert_ok!(TokensModule::withdraw( + AUSD, + &VAULT::get(), + 3, + ExistenceRequirement::AllowDeath + )); assert_eq!(TokensModule::free_balance(AUSD, &VAULT::get()), 1); assert_eq!(TokensModule::free_balance(AUSD, &BOB::get()), 18); diff --git a/modules/liquid-crowdloan/src/lib.rs b/modules/liquid-crowdloan/src/lib.rs index b1ff967dd0..9293e637f6 100644 --- a/modules/liquid-crowdloan/src/lib.rs +++ b/modules/liquid-crowdloan/src/lib.rs @@ -23,7 +23,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::unused_unit)] -use frame_support::{pallet_prelude::*, traits::EnsureOrigin, PalletId}; +use frame_support::{pallet_prelude::*, traits::EnsureOrigin, traits::ExistenceRequirement, PalletId}; use frame_system::pallet_prelude::*; use orml_traits::MultiCurrency; use primitives::{Balance, CurrencyId}; @@ -141,8 +141,19 @@ impl Pallet { (currency_id, amount) }; - T::Currency::withdraw(T::LiquidCrowdloanCurrencyId::get(), who, amount)?; - T::Currency::transfer(currency_id, &Self::account_id(), who, redeem_amount)?; + T::Currency::withdraw( + T::LiquidCrowdloanCurrencyId::get(), + who, + amount, + ExistenceRequirement::AllowDeath, + )?; + T::Currency::transfer( + currency_id, + &Self::account_id(), + who, + redeem_amount, + ExistenceRequirement::AllowDeath, + )?; Self::deposit_event(Event::Redeemed { currency_id, diff --git a/modules/loans/src/lib.rs b/modules/loans/src/lib.rs index badb6fe9cf..f19625d5b3 100644 --- a/modules/loans/src/lib.rs +++ b/modules/loans/src/lib.rs @@ -27,7 +27,7 @@ #![allow(clippy::unused_unit)] #![allow(clippy::collapsible_if)] -use frame_support::{pallet_prelude::*, transactional, PalletId}; +use frame_support::{pallet_prelude::*, traits::ExistenceRequirement, transactional, PalletId}; use module_support::{CDPTreasury, RiskManager}; use orml_traits::{Handler, MultiCurrency, MultiCurrencyExtended}; use primitives::{Amount, Balance, CurrencyId, Position}; @@ -189,9 +189,21 @@ impl Pallet { let module_account = Self::account_id(); if collateral_adjustment.is_positive() { - T::Currency::transfer(currency_id, who, &module_account, collateral_balance_adjustment)?; + T::Currency::transfer( + currency_id, + who, + &module_account, + collateral_balance_adjustment, + ExistenceRequirement::AllowDeath, + )?; } else if collateral_adjustment.is_negative() { - T::Currency::transfer(currency_id, &module_account, who, collateral_balance_adjustment)?; + T::Currency::transfer( + currency_id, + &module_account, + who, + collateral_balance_adjustment, + ExistenceRequirement::AllowDeath, + )?; } if debit_adjustment.is_positive() { diff --git a/modules/transaction-payment/src/lib.rs b/modules/transaction-payment/src/lib.rs index 094d890143..905d22ecf1 100644 --- a/modules/transaction-payment/src/lib.rs +++ b/modules/transaction-payment/src/lib.rs @@ -59,6 +59,8 @@ use sp_runtime::{ use sp_std::prelude::*; use xcm::v4::prelude::Location; +const LOG_TARGET: &str = "transaction-payment"; + mod mock; mod tests; pub mod weights; @@ -860,7 +862,7 @@ where fee_aggregated_path: &[AggregatedSwapPath], ) -> Result<(T::AccountId, Balance), DispatchError> { log::debug!( - target: "runtime::transaction-payment", + target: LOG_TARGET, "charge_fee_aggregated_path: who: {:?}, fee: {:?}, fee_aggregated_path: {:?}", who, fee, @@ -882,7 +884,7 @@ where fee_currency_id: CurrencyId, ) -> Result<(T::AccountId, Balance), DispatchError> { log::debug!( - target: "runtime::transaction-payment", + target: LOG_TARGET, "charge_fee_currency: who: {:?}, fee: {:?}, fee_currency_id: {:?}", who, fee, @@ -925,7 +927,7 @@ where reason: WithdrawReasons, ) -> Result<(T::AccountId, Balance), DispatchError> { log::debug!( - target: "runtime::transaction-payment", + target: LOG_TARGET, "ensure_can_charge_fee_with_call: who: {:?}, fee: {:?}, call: {:?}", who, fee, @@ -1010,7 +1012,7 @@ where reason: WithdrawReasons, ) -> Result { log::debug!( - target: "runtime::transaction-payment", + target: LOG_TARGET, "native_then_alternative_or_default: who: {:?}, fee: {:?}", who, fee @@ -1113,8 +1115,15 @@ where // use fix rate to calculate the amount of supply asset that equal to native asset. let supply_account = rate.saturating_mul_int(amount); - T::MultiCurrency::transfer(supply_currency_id, who, &sub_account, supply_account)?; + // transfer native token first to ensure it stays alive during swap T::Currency::transfer(&sub_account, who, amount, ExistenceRequirement::KeepAlive)?; + T::MultiCurrency::transfer( + supply_currency_id, + who, + &sub_account, + supply_account, + ExistenceRequirement::AllowDeath, + )?; Ok(()) } @@ -1169,6 +1178,7 @@ where &treasury_account, &sub_account, T::MultiCurrency::minimum_balance(currency_id), + ExistenceRequirement::AllowDeath, )?; T::Currency::transfer( &treasury_account, @@ -1203,7 +1213,13 @@ where let foreign_amount: Balance = T::MultiCurrency::free_balance(currency_id, &sub_account); let native_amount: Balance = T::Currency::free_balance(&sub_account); - T::MultiCurrency::transfer(currency_id, &sub_account, &treasury_account, foreign_amount)?; + T::MultiCurrency::transfer( + currency_id, + &sub_account, + &treasury_account, + foreign_amount, + ExistenceRequirement::AllowDeath, + )?; T::Currency::transfer( &sub_account, &treasury_account, @@ -1315,8 +1331,18 @@ where WithdrawReasons::TRANSACTION_PAYMENT | WithdrawReasons::TIP }; - let (payer, fee_surplus) = Pallet::::ensure_can_charge_fee_with_call(who, fee, call, reason) - .map_err(|_| TransactionValidityError::from(InvalidTransaction::Payment))?; + let (payer, fee_surplus) = + Pallet::::ensure_can_charge_fee_with_call(who, fee, call, reason).map_err(|e| { + log::debug!( + target: LOG_TARGET, + "ensure_can_charge_fee_with_call who: {:?} fee: {:?} call: {:?} error: {:?}", + who, + fee, + call, + e + ); + TransactionValidityError::from(InvalidTransaction::Payment) + })?; // withdraw native currency as fee, also consider surplus when swap from dex or pool. match ::Currency::withdraw(&payer, fee + fee_surplus, reason, ExistenceRequirement::KeepAlive) { @@ -1530,7 +1556,7 @@ where fee: PalletBalanceOf, named: Option, ) -> Result, DispatchError> { - log::debug!(target: "transaction-payment", "reserve_fee: who: {:?}, fee: {:?}, named: {:?}", who, fee, named); + log::debug!(target: LOG_TARGET, "reserve_fee: who: {:?}, fee: {:?}, named: {:?}", who, fee, named); Pallet::::native_then_alternative_or_default(who, fee, WithdrawReasons::TRANSACTION_PAYMENT)?; T::Currency::reserve_named(&named.unwrap_or(RESERVE_ID), who, fee)?; @@ -1542,7 +1568,7 @@ where fee: PalletBalanceOf, named: Option, ) -> PalletBalanceOf { - log::debug!(target: "transaction-payment", "unreserve_fee: who: {:?}, fee: {:?}, named: {:?}", who, fee, named); + log::debug!(target: LOG_TARGET, "unreserve_fee: who: {:?}, fee: {:?}, named: {:?}", who, fee, named); ::Currency::unreserve_named(&named.unwrap_or(RESERVE_ID), who, fee) } @@ -1551,7 +1577,7 @@ where who: &T::AccountId, weight: Weight, ) -> Result<(PalletBalanceOf, NegativeImbalanceOf), TransactionValidityError> { - log::debug!(target: "transaction-payment", "unreserve_and_charge_fee: who: {:?}, weight: {:?}", who, weight); + log::debug!(target: LOG_TARGET, "unreserve_and_charge_fee: who: {:?}, weight: {:?}", who, weight); let fee = Pallet::::weight_to_fee(weight); ::Currency::unreserve_named(&RESERVE_ID, who, fee); @@ -1572,7 +1598,7 @@ where refund_weight: Weight, payed: NegativeImbalanceOf, ) -> Result<(), TransactionValidityError> { - log::debug!(target: "transaction-payment", "refund_fee: who: {:?}, refund_weight: {:?}, payed: {:?}", who, refund_weight, payed.peek()); + log::debug!(target: LOG_TARGET, "refund_fee: who: {:?}, refund_weight: {:?}, payed: {:?}", who, refund_weight, payed.peek()); let refund = Pallet::::weight_to_fee(refund_weight); let actual_payment = match ::Currency::deposit_into_existing(who, refund) { @@ -1603,7 +1629,7 @@ where pays_fee: Pays, class: DispatchClass, ) -> Result<(), TransactionValidityError> { - log::debug!(target: "transaction-payment", "charge_fee: who: {:?}, len: {:?}, weight: {:?}, tip: {:?}, pays_fee: {:?}, class: {:?}", who, len, weight, tip, pays_fee, class); + log::debug!(target: LOG_TARGET, "charge_fee: who: {:?}, len: {:?}, weight: {:?}, tip: {:?}, pays_fee: {:?}, class: {:?}", who, len, weight, tip, pays_fee, class); let fee = Pallet::::compute_fee_raw(len, weight, tip, pays_fee, class).final_fee(); @@ -1614,7 +1640,16 @@ where WithdrawReasons::TRANSACTION_PAYMENT, ExistenceRequirement::KeepAlive, ) - .map_err(|_| InvalidTransaction::Payment)?; + .map_err(|e| { + log::debug!( + target: LOG_TARGET, + "charge_fee withdraw who: {:?} fee: {:?} error: {:?}", + who, + fee, + e + ); + InvalidTransaction::Payment + })?; // distribute fee ::OnTransactionPayment::on_unbalanced(actual_payment); diff --git a/modules/transaction-payment/src/tests.rs b/modules/transaction-payment/src/tests.rs index e58bfec3b1..936664fe4c 100644 --- a/modules/transaction-payment/src/tests.rs +++ b/modules/transaction-payment/src/tests.rs @@ -894,7 +894,13 @@ fn charges_fee_when_validate_and_native_is_not_enough() { // transfer token to Bob, and use Bob as tx sender to test // Bob do not have enough native asset(ACA), but he has AUSD - assert_ok!(>::transfer(AUSD, &ALICE, &BOB, 4000)); + assert_ok!(>::transfer( + AUSD, + &ALICE, + &BOB, + 4000, + ExistenceRequirement::AllowDeath + )); assert_eq!(DEXModule::get_liquidity_pool(ACA, AUSD), (10000, 1000)); assert_eq!(Currencies::total_balance(ACA, &BOB), 0); assert_eq!(>::free_balance(ACA, &BOB), 0); @@ -986,7 +992,13 @@ fn payment_reserve_fee() { assert_eq!(reserve_data, *reserves.get(0).unwrap()); // Bob has not enough native token, but have enough none native token - assert_ok!(>::transfer(AUSD, &ALICE, &BOB, 4000)); + assert_ok!(>::transfer( + AUSD, + &ALICE, + &BOB, + 4000, + ExistenceRequirement::AllowDeath + )); let fee = as TransactionPaymentT>::reserve_fee( &BOB, 100, None, ); @@ -997,7 +1009,13 @@ fn payment_reserve_fee() { // reserve fee not consider multiplier NextFeeMultiplier::::put(Multiplier::saturating_from_rational(3, 2)); - assert_ok!(>::transfer(AUSD, &ALICE, &DAVE, 4000)); + assert_ok!(>::transfer( + AUSD, + &ALICE, + &DAVE, + 4000, + ExistenceRequirement::AllowDeath + )); let fee = as TransactionPaymentT>::reserve_fee( &DAVE, 100, None, ); @@ -1020,7 +1038,13 @@ fn payment_reserve_fee() { #[test] fn charges_fee_failed_by_slippage_limit() { builder_with_dex_and_fee_pool(true).execute_with(|| { - assert_ok!(>::transfer(AUSD, &ALICE, &BOB, 1000)); + assert_ok!(>::transfer( + AUSD, + &ALICE, + &BOB, + 1000, + ExistenceRequirement::AllowDeath + )); assert_eq!(DEXModule::get_liquidity_pool(ACA, AUSD), (10000, 1000)); assert_eq!(Currencies::total_balance(ACA, &BOB), 0); @@ -1129,7 +1153,13 @@ fn charge_fee_by_alternative_swap_first_priority() { ); // charge fee token use `DefaultFeeTokens` as `AlternativeFeeSwapPath` condition is failed. - assert_ok!(>::transfer(DOT, &ALICE, &BOB, 300)); + assert_ok!(>::transfer( + DOT, + &ALICE, + &BOB, + 300, + ExistenceRequirement::AllowDeath + )); assert_eq!( >::free_balance(ACA, &BOB), PalletBalances::minimum_balance() @@ -1199,7 +1229,13 @@ fn charge_fee_by_default_fee_tokens_second_priority() { ); // charge fee token use `AlternativeFeeSwapPath`, although the swap path is invalid. - assert_ok!(>::transfer(DOT, &ALICE, &BOB, 300)); + assert_ok!(>::transfer( + DOT, + &ALICE, + &BOB, + 300, + ExistenceRequirement::AllowDeath + )); assert_eq!( >::free_balance(ACA, &BOB), PalletBalances::minimum_balance() @@ -2045,7 +2081,7 @@ fn charge_fee_pool_operation_works() { RuntimeOrigin::root(), ALICE, ACA, - 10000.unique_saturated_into(), + 20000.unique_saturated_into(), )); assert_ok!(DEXModule::add_liquidity( diff --git a/orml b/orml index 7d608999cb..9edc5cb679 160000 --- a/orml +++ b/orml @@ -1 +1 @@ -Subproject commit 7d608999cbcf79dbb1eb40de4b04a7366e2a8352 +Subproject commit 9edc5cb6790169a230b11cb2c52301ab6e748ead diff --git a/runtime/common/src/precompile/mock.rs b/runtime/common/src/precompile/mock.rs index c1ab61a648..e2461362c9 100644 --- a/runtime/common/src/precompile/mock.rs +++ b/runtime/common/src/precompile/mock.rs @@ -22,8 +22,8 @@ use crate::{AllPrecompiles, Ratio, RuntimeBlockWeights, Weight}; use frame_support::{ derive_impl, ord_parameter_types, parameter_types, traits::{ - ConstU128, ConstU32, ConstU64, EqualPrivilegeOnly, Everything, InstanceFilter, LockIdentifier, Nothing, - OnFinalize, OnInitialize, SortedMembers, + ConstU128, ConstU32, ConstU64, EqualPrivilegeOnly, Everything, ExistenceRequirement, InstanceFilter, + LockIdentifier, Nothing, OnFinalize, OnInitialize, SortedMembers, }, weights::{ConstantMultiplier, IdentityFee}, PalletId, @@ -72,7 +72,7 @@ impl frame_system::Config for Test { } parameter_types! { - pub const ExistenceRequirement: u128 = 1; + pub const ExistentialDeposit: u128 = 1; pub const MinimumCount: u32 = 1; pub const ExpiresIn: u32 = 600; pub const RootOperatorAccountId: AccountId = ALICE; @@ -147,7 +147,7 @@ impl pallet_balances::Config for Test { type Balance = Balance; type DustRemoval = (); type RuntimeEvent = RuntimeEvent; - type ExistentialDeposit = ExistenceRequirement; + type ExistentialDeposit = ExistentialDeposit; type AccountStore = module_support::SystemAccountStore; type WeightInfo = (); type MaxLocks = (); @@ -274,7 +274,7 @@ impl module_transaction_payment::Config for Test { type OperationalFeeMultiplier = ConstU64<5>; type TipPerWeightStep = ConstU128<1>; type MaxTipsOfPriority = ConstU128<1000>; - type AlternativeFeeSwapDeposit = ExistenceRequirement; + type AlternativeFeeSwapDeposit = ExistentialDeposit; type WeightToFee = IdentityFee; type LengthToFee = ConstantMultiplier>; type FeeMultiplierUpdate = (); @@ -682,7 +682,12 @@ pub struct MockHomaSubAccountXcm; impl HomaSubAccountXcm for MockHomaSubAccountXcm { type RelayChainAccountId = AccountId; fn transfer_staking_to_sub_account(sender: &AccountId, _: u16, amount: Balance) -> DispatchResult { - Currencies::withdraw(StakingCurrencyId::get(), sender, amount) + Currencies::withdraw( + StakingCurrencyId::get(), + sender, + amount, + ExistenceRequirement::AllowDeath, + ) } fn withdraw_unbonded_from_sub_account(_: u16, _: Balance) -> DispatchResult { @@ -1107,7 +1112,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { .assimilate_storage(&mut storage) .unwrap(); module_asset_registry::GenesisConfig:: { - assets: vec![(ACA, ExistenceRequirement::get()), (DOT, 0)], + assets: vec![(ACA, ExistentialDeposit::get()), (DOT, 0)], } .assimilate_storage(&mut storage) .unwrap(); diff --git a/runtime/common/src/precompile/multicurrency.rs b/runtime/common/src/precompile/multicurrency.rs index a51fecb69c..1ac99863f8 100644 --- a/runtime/common/src/precompile/multicurrency.rs +++ b/runtime/common/src/precompile/multicurrency.rs @@ -20,7 +20,7 @@ use super::input::{Input, InputPricer, InputT, Output}; use crate::WeightToGas; use frame_support::{ pallet_prelude::IsType, - traits::{Currency, Get}, + traits::{Currency, ExistenceRequirement, Get}, }; use module_currencies::WeightInfo; use module_evm::{ @@ -162,6 +162,7 @@ where &from, &to, amount, + ExistenceRequirement::AllowDeath, ) .map_err(|e| PrecompileFailure::Revert { exit_status: ExitRevert::Reverted, @@ -188,6 +189,7 @@ where &from, &to, amount, + ExistenceRequirement::AllowDeath, ) .map_err(|e| PrecompileFailure::Revert { exit_status: ExitRevert::Reverted, From ec8b787f3c9bd6fe2f6e60da344826fd3d0f8b68 Mon Sep 17 00:00:00 2001 From: zjb0807 Date: Fri, 10 Jan 2025 20:22:40 +0800 Subject: [PATCH 2/8] fix tests --- modules/aggregated-dex/src/mock.rs | 3 + modules/auction-manager/src/mock.rs | 3 + modules/cdp-engine/src/mock.rs | 1 + modules/cdp-treasury/src/mock.rs | 1 + modules/dex/src/lib.rs | 20 ++++- modules/dex/src/mock.rs | 4 +- modules/transaction-payment/src/lib.rs | 36 +++++++- modules/transaction-payment/src/mock.rs | 1 + modules/transaction-payment/src/tests.rs | 2 +- runtime/acala/src/lib.rs | 1 + runtime/common/src/precompile/mock.rs | 1 + runtime/integration-tests/src/evm.rs | 110 +++++++++++++++++++---- runtime/karura/src/lib.rs | 1 + runtime/mandala/src/lib.rs | 1 + 14 files changed, 158 insertions(+), 27 deletions(-) diff --git a/modules/aggregated-dex/src/mock.rs b/modules/aggregated-dex/src/mock.rs index 897f1886fb..ed8ba4c6c8 100644 --- a/modules/aggregated-dex/src/mock.rs +++ b/modules/aggregated-dex/src/mock.rs @@ -41,6 +41,7 @@ mod aggregated_dex { pub const ALICE: AccountId = AccountId32::new([1u8; 32]); pub const BOB: AccountId = AccountId32::new([2u8; 32]); +pub const ACA: CurrencyId = CurrencyId::Token(TokenSymbol::ACA); pub const AUSD: CurrencyId = CurrencyId::Token(TokenSymbol::AUSD); pub const DOT: CurrencyId = CurrencyId::Token(TokenSymbol::DOT); pub const LDOT: CurrencyId = CurrencyId::Token(TokenSymbol::LDOT); @@ -81,6 +82,7 @@ ord_parameter_types! { parameter_types! { pub const DEXPalletId: PalletId = PalletId(*b"aca/dexm"); pub const GetExchangeFee: (u32, u32) = (0, 100); + pub const GetNativeCurrencyId: CurrencyId = ACA; pub EnabledTradingPairs: Vec = vec![]; } @@ -90,6 +92,7 @@ impl module_dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = ConstU32<4>; type PalletId = DEXPalletId; + type GetNativeCurrencyId = GetNativeCurrencyId; type Erc20InfoMapping = (); type DEXIncentives = (); type WeightInfo = (); diff --git a/modules/auction-manager/src/mock.rs b/modules/auction-manager/src/mock.rs index 5c0fc2d1b8..f31963400d 100644 --- a/modules/auction-manager/src/mock.rs +++ b/modules/auction-manager/src/mock.rs @@ -45,6 +45,7 @@ pub type Amount = i64; pub const ALICE: AccountId = 1; pub const BOB: AccountId = 2; pub const CAROL: AccountId = 3; +pub const ACA: CurrencyId = CurrencyId::Token(TokenSymbol::ACA); pub const AUSD: CurrencyId = CurrencyId::Token(TokenSymbol::AUSD); pub const BTC: CurrencyId = CurrencyId::ForeignAsset(255); pub const DOT: CurrencyId = CurrencyId::Token(TokenSymbol::DOT); @@ -141,6 +142,7 @@ impl PriceProvider for MockPriceSource { parameter_types! { pub const DEXPalletId: PalletId = PalletId(*b"aca/dexm"); pub const GetExchangeFee: (u32, u32) = (0, 100); + pub const GetNativeCurrencyId: CurrencyId = ACA; pub EnabledTradingPairs: Vec = vec![ TradingPair::from_currency_ids(AUSD, BTC).unwrap(), TradingPair::from_currency_ids(DOT, BTC).unwrap(), @@ -154,6 +156,7 @@ impl module_dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = ConstU32<4>; type PalletId = DEXPalletId; + type GetNativeCurrencyId = GetNativeCurrencyId; type Erc20InfoMapping = (); type DEXIncentives = (); type WeightInfo = (); diff --git a/modules/cdp-engine/src/mock.rs b/modules/cdp-engine/src/mock.rs index 6656710566..7c2afbcf8b 100644 --- a/modules/cdp-engine/src/mock.rs +++ b/modules/cdp-engine/src/mock.rs @@ -242,6 +242,7 @@ impl module_dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = ConstU32<4>; type PalletId = DEXPalletId; + type GetNativeCurrencyId = GetNativeCurrencyId; type Erc20InfoMapping = (); type DEXIncentives = (); type WeightInfo = (); diff --git a/modules/cdp-treasury/src/mock.rs b/modules/cdp-treasury/src/mock.rs index 18a5f43195..520526079b 100644 --- a/modules/cdp-treasury/src/mock.rs +++ b/modules/cdp-treasury/src/mock.rs @@ -128,6 +128,7 @@ impl module_dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = ConstU32<4>; type PalletId = DEXPalletId; + type GetNativeCurrencyId = GetNativeCurrencyId; type Erc20InfoMapping = (); type DEXIncentives = (); type WeightInfo = (); diff --git a/modules/dex/src/lib.rs b/modules/dex/src/lib.rs index 768cbdc962..0d2a59fc34 100644 --- a/modules/dex/src/lib.rs +++ b/modules/dex/src/lib.rs @@ -114,6 +114,10 @@ pub mod module { #[pallet::constant] type PalletId: Get; + /// The native currency id + #[pallet::constant] + type GetNativeCurrencyId: Get; + /// Mapping between CurrencyId and ERC20 address so user can use Erc20 /// address as LP token. type Erc20InfoMapping: Erc20InfoMapping; @@ -1434,12 +1438,18 @@ impl Pallet { let module_account_id = Self::account_id(); let actual_target_amount = amounts[amounts.len() - 1]; + let path_0_existence_requirement = if path[0] == T::GetNativeCurrencyId::get() { + ExistenceRequirement::KeepAlive + } else { + ExistenceRequirement::AllowDeath + }; + T::Currency::transfer( path[0], who, &module_account_id, supply_amount, - ExistenceRequirement::AllowDeath, + path_0_existence_requirement, )?; Self::_swap_by_path(path, &amounts)?; T::Currency::transfer( @@ -1470,12 +1480,18 @@ impl Pallet { let module_account_id = Self::account_id(); let actual_supply_amount = amounts[0]; + let path_0_existence_requirement = if path[0] == T::GetNativeCurrencyId::get() { + ExistenceRequirement::KeepAlive + } else { + ExistenceRequirement::AllowDeath + }; + T::Currency::transfer( path[0], who, &module_account_id, actual_supply_amount, - ExistenceRequirement::AllowDeath, + path_0_existence_requirement, )?; Self::_swap_by_path(path, &amounts)?; T::Currency::transfer( diff --git a/modules/dex/src/mock.rs b/modules/dex/src/mock.rs index 2e686063e3..d025c9db93 100644 --- a/modules/dex/src/mock.rs +++ b/modules/dex/src/mock.rs @@ -37,10 +37,10 @@ pub type AccountId = u128; pub const ALICE: AccountId = 1; pub const BOB: AccountId = 2; pub const CAROL: AccountId = 3; +pub const ACA: CurrencyId = CurrencyId::Token(TokenSymbol::ACA); pub const AUSD: CurrencyId = CurrencyId::Token(TokenSymbol::AUSD); pub const BTC: CurrencyId = CurrencyId::Token(TokenSymbol::TAP); pub const DOT: CurrencyId = CurrencyId::Token(TokenSymbol::DOT); -pub const ACA: CurrencyId = CurrencyId::Token(TokenSymbol::ACA); parameter_types! { pub static AUSDBTCPair: TradingPair = TradingPair::from_currency_ids(AUSD, BTC).unwrap(); @@ -99,6 +99,7 @@ ord_parameter_types! { parameter_types! { pub const GetExchangeFee: (u32, u32) = (1, 100); pub const DEXPalletId: PalletId = PalletId(*b"aca/dexm"); + pub const GetNativeCurrencyId: CurrencyId = ACA; pub AlternativeSwapPathJointList: Vec> = vec![ vec![DOT], ]; @@ -124,6 +125,7 @@ impl Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = ConstU32<3>; type PalletId = DEXPalletId; + type GetNativeCurrencyId = GetNativeCurrencyId; type Erc20InfoMapping = MockErc20InfoMapping; type WeightInfo = (); type DEXIncentives = MockDEXIncentives; diff --git a/modules/transaction-payment/src/lib.rs b/modules/transaction-payment/src/lib.rs index 905d22ecf1..5bdc74ae5a 100644 --- a/modules/transaction-payment/src/lib.rs +++ b/modules/transaction-payment/src/lib.rs @@ -1049,8 +1049,18 @@ where // default fee tokens, swap from tx fee pool: O(1) for supply_currency_id in T::DefaultFeeTokens::get() { - if Self::swap_from_pool_or_dex(who, fee_amount, supply_currency_id).is_ok() { + let res = Self::swap_from_pool_or_dex(who, fee_amount, supply_currency_id); + if res.is_ok() { return Ok(fee_surplus); + } else { + log::debug!( + target: LOG_TARGET, + "native_then_alternative_or_default swap_from_pool_or_dex : who: {:?}, fee_amount: {:?}, supply_currency_id: {:?}, error: {:?}", + who, + fee_amount, + supply_currency_id, + res + ); } } @@ -1059,8 +1069,18 @@ where .filter(|v| !T::DefaultFeeTokens::get().contains(v)) .collect::>(); for supply_currency_id in tokens_non_default { - if Self::swap_from_pool_or_dex(who, custom_fee_amount, supply_currency_id).is_ok() { + let res = Self::swap_from_pool_or_dex(who, custom_fee_amount, supply_currency_id); + if res.is_ok() { return Ok(custom_fee_surplus); + } else { + log::debug!( + target: LOG_TARGET, + "native_then_alternative_or_default swap_from_pool_or_dex : who: {:?}, custom_fee_amount: {:?}, supply_currency_id: {:?}, error: {:?}", + who, + custom_fee_amount, + supply_currency_id, + res + ); } } @@ -1113,10 +1133,18 @@ where } } + // if the remaining balance is less than ed, swap all to avoid dust + let mut supply_amount = amount; + let supply_free_balance = T::MultiCurrency::free_balance(supply_currency_id, who); + if supply_free_balance > amount + && supply_free_balance.saturating_sub(supply_amount) < T::MultiCurrency::minimum_balance(supply_currency_id) + { + supply_amount = supply_free_balance; + } // use fix rate to calculate the amount of supply asset that equal to native asset. - let supply_account = rate.saturating_mul_int(amount); + let supply_account = rate.saturating_mul_int(supply_amount); // transfer native token first to ensure it stays alive during swap - T::Currency::transfer(&sub_account, who, amount, ExistenceRequirement::KeepAlive)?; + T::Currency::transfer(&sub_account, who, supply_amount, ExistenceRequirement::KeepAlive)?; T::MultiCurrency::transfer( supply_currency_id, who, diff --git a/modules/transaction-payment/src/mock.rs b/modules/transaction-payment/src/mock.rs index 46282cc849..e9062c2893 100644 --- a/modules/transaction-payment/src/mock.rs +++ b/modules/transaction-payment/src/mock.rs @@ -164,6 +164,7 @@ impl module_dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DEXPalletId; + type GetNativeCurrencyId = GetNativeCurrencyId; type Erc20InfoMapping = (); type DEXIncentives = (); type WeightInfo = (); diff --git a/modules/transaction-payment/src/tests.rs b/modules/transaction-payment/src/tests.rs index 936664fe4c..90b05f1d55 100644 --- a/modules/transaction-payment/src/tests.rs +++ b/modules/transaction-payment/src/tests.rs @@ -2081,7 +2081,7 @@ fn charge_fee_pool_operation_works() { RuntimeOrigin::root(), ALICE, ACA, - 20000.unique_saturated_into(), + 10000.unique_saturated_into(), )); assert_ok!(DEXModule::add_liquidity( diff --git a/runtime/acala/src/lib.rs b/runtime/acala/src/lib.rs index 2bb471df0f..471fbb86bd 100644 --- a/runtime/acala/src/lib.rs +++ b/runtime/acala/src/lib.rs @@ -1172,6 +1172,7 @@ impl module_dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DEXPalletId; + type GetNativeCurrencyId = GetNativeCurrencyId; type Erc20InfoMapping = EvmErc20InfoMapping; type DEXIncentives = Incentives; type WeightInfo = weights::module_dex::WeightInfo; diff --git a/runtime/common/src/precompile/mock.rs b/runtime/common/src/precompile/mock.rs index e2461362c9..5e0f2bc54d 100644 --- a/runtime/common/src/precompile/mock.rs +++ b/runtime/common/src/precompile/mock.rs @@ -385,6 +385,7 @@ impl module_dex::Config for Test { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DEXPalletId; + type GetNativeCurrencyId = GetNativeCurrencyId; type Erc20InfoMapping = EvmErc20InfoMapping; type WeightInfo = (); type DEXIncentives = MockDEXIncentives; diff --git a/runtime/integration-tests/src/evm.rs b/runtime/integration-tests/src/evm.rs index da7594954e..9dbf8b2a40 100644 --- a/runtime/integration-tests/src/evm.rs +++ b/runtime/integration-tests/src/evm.rs @@ -1543,6 +1543,7 @@ fn transaction_payment_module_charge_erc20_pool() { len as usize, ) ); + let alice_native_after = Currencies::free_balance(NATIVE_CURRENCY, &alice_evm_account); let alice_erc20_after = Currencies::free_balance(erc20_token, &alice_evm_account); @@ -1550,17 +1551,46 @@ fn transaction_payment_module_charge_erc20_pool() { assert_debug_snapshot!(alice_native_before - alice_native_after, @"2500000934"); assert_eq!(alice_erc20_before - alice_erc20_after, 0); - // cannot charge erc20 fee for the account only hold erc20 + let alice_native_before = Currencies::free_balance(NATIVE_CURRENCY, &account_with_erc20); + let alice_erc20_before = Currencies::free_balance(erc20_token, &account_with_erc20); + + // charge erc20 fee for the account only hold erc20 >::set_origin(account_with_erc20.clone()); - assert_noop!( + assert_ok!( >::from(0).validate( &account_with_erc20, call, &info, len as usize, - ), - TransactionValidityError::Invalid(InvalidTransaction::Payment) + ) ); + let alice_native_after = Currencies::free_balance(NATIVE_CURRENCY, &account_with_erc20); + let alice_erc20_after = Currencies::free_balance(erc20_token, &account_with_erc20); + + #[cfg(feature = "with-mandala-runtime")] + { + assert_debug_snapshot!(alice_native_before, @"0"); + assert_debug_snapshot!(alice_native_after, @"237600000000"); + assert_debug_snapshot!(alice_erc20_before, @"1000000000000"); + assert_debug_snapshot!(alice_erc20_after, @"975197719831"); + assert_debug_snapshot!(alice_erc20_before - alice_erc20_after, @"24802280169"); + } + #[cfg(feature = "with-karura-runtime")] + { + assert_debug_snapshot!(alice_native_before, @"0"); + assert_debug_snapshot!(alice_native_after, @"237600000000"); + assert_debug_snapshot!(alice_erc20_before, @"1000000000000"); + assert_debug_snapshot!(alice_erc20_after, @"975147966009"); + assert_debug_snapshot!(alice_erc20_before - alice_erc20_after, @"24852033991"); + } + #[cfg(feature = "with-acala-runtime")] + { + assert_debug_snapshot!(alice_native_before, @"0"); + assert_debug_snapshot!(alice_native_after, @"512800000000"); + assert_debug_snapshot!(alice_erc20_before, @"1000000000000"); + assert_debug_snapshot!(alice_erc20_after, @"946258417072"); + assert_debug_snapshot!(alice_erc20_before - alice_erc20_after, @"53741582928"); + } let alice_native_before = Currencies::free_balance(NATIVE_CURRENCY, &alice_evm_account); let alice_erc20_before = Currencies::free_balance(erc20_token, &alice_evm_account); @@ -1578,32 +1608,74 @@ fn transaction_payment_module_charge_erc20_pool() { let alice_native_after = Currencies::free_balance(NATIVE_CURRENCY, &alice_evm_account); let alice_erc20_after = Currencies::free_balance(erc20_token, &alice_evm_account); - // charge storage by native + // charge storage and tx fee by erc20 #[cfg(feature = "with-mandala-runtime")] - assert_eq!(alice_native_before - alice_native_after, 6400000000); + { + assert_debug_snapshot!(alice_native_before, @"999998999984699999066"); + assert_debug_snapshot!(alice_native_after, @"999998999984699999066"); + assert_eq!(alice_native_before - alice_native_after, 0); + assert_debug_snapshot!(alice_erc20_before, @"99999999899000000000000"); + assert_debug_snapshot!(alice_erc20_after, @"99999999898999624586944"); + assert_debug_snapshot!(alice_erc20_before - alice_erc20_after, @"375413056"); + } #[cfg(feature = "with-karura-runtime")] - assert_eq!(alice_native_before - alice_native_after, 6400000000); + { + assert_debug_snapshot!(alice_native_before, @"999998999984699999066"); + assert_debug_snapshot!(alice_native_after, @"999998999984699999066"); + assert_eq!(alice_native_before - alice_native_after, 0); + assert_debug_snapshot!(alice_erc20_before, @"99999999899000000000000"); + assert_debug_snapshot!(alice_erc20_after, @"99999999898999623833858"); + assert_debug_snapshot!(alice_erc20_before - alice_erc20_after, @"376166142"); + } #[cfg(feature = "with-acala-runtime")] - assert_eq!(alice_native_before - alice_native_after, 19200000000); + { + assert_debug_snapshot!(alice_native_before, @"999998999959099999066"); + assert_debug_snapshot!(alice_native_after, @"999998999959099999066"); + assert_eq!(alice_native_before - alice_native_after, 0); + assert_debug_snapshot!(alice_erc20_before, @"99999999899000000000000"); + assert_debug_snapshot!(alice_erc20_after, @"99999999898999623833858"); + assert_debug_snapshot!(alice_erc20_before - alice_erc20_after, @"376166142"); + } - // charge tx fee by native - #[cfg(feature = "with-mandala-runtime")] - assert_debug_snapshot!(alice_erc20_before - alice_erc20_after, @"375413056"); - #[cfg(feature = "with-karura-runtime")] - assert_debug_snapshot!(alice_erc20_before - alice_erc20_after, @"376166142"); - #[cfg(feature = "with-acala-runtime")] - assert_debug_snapshot!(alice_erc20_before - alice_erc20_after, @"376166142"); + let alice_native_before = Currencies::free_balance(NATIVE_CURRENCY, &account_with_erc20); + let alice_erc20_before = Currencies::free_balance(erc20_token, &account_with_erc20); - // cannot charge erc20 fee for the account only hold erc20 + // charge erc20 fee for the account only hold erc20 >::set_origin(account_with_erc20.clone()); - assert_noop!( + assert_ok!( >::from(0).validate( &account_with_erc20, &with_fee_call, &info, len as usize, - ), - TransactionValidityError::Invalid(InvalidTransaction::Payment) + ) ); + let alice_native_after = Currencies::free_balance(NATIVE_CURRENCY, &account_with_erc20); + let alice_erc20_after = Currencies::free_balance(erc20_token, &account_with_erc20); + + #[cfg(feature = "with-mandala-runtime")] + { + assert_debug_snapshot!(alice_native_before, @"237600000000"); + assert_debug_snapshot!(alice_native_after, @"237600000000"); + assert_debug_snapshot!(alice_erc20_before, @"975197719831"); + assert_debug_snapshot!(alice_erc20_after, @"974822306775"); + assert_debug_snapshot!(alice_erc20_before - alice_erc20_after, @"375413056"); + } + #[cfg(feature = "with-karura-runtime")] + { + assert_debug_snapshot!(alice_native_before, @"237600000000"); + assert_debug_snapshot!(alice_native_after, @"237600000000"); + assert_debug_snapshot!(alice_erc20_before, @"975147966009"); + assert_debug_snapshot!(alice_erc20_after, @"974771799867"); + assert_debug_snapshot!(alice_erc20_before - alice_erc20_after, @"376166142"); + } + #[cfg(feature = "with-acala-runtime")] + { + assert_debug_snapshot!(alice_native_before, @"512800000000"); + assert_debug_snapshot!(alice_native_after, @"512800000000"); + assert_debug_snapshot!(alice_erc20_before, @"946258417072"); + assert_debug_snapshot!(alice_erc20_after, @"945882250930"); + assert_debug_snapshot!(alice_erc20_before - alice_erc20_after, @"376166142"); + } }); } diff --git a/runtime/karura/src/lib.rs b/runtime/karura/src/lib.rs index f79177e672..21d03c794b 100644 --- a/runtime/karura/src/lib.rs +++ b/runtime/karura/src/lib.rs @@ -1179,6 +1179,7 @@ impl module_dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DEXPalletId; + type GetNativeCurrencyId = GetNativeCurrencyId; type Erc20InfoMapping = EvmErc20InfoMapping; type DEXIncentives = Incentives; type WeightInfo = weights::module_dex::WeightInfo; diff --git a/runtime/mandala/src/lib.rs b/runtime/mandala/src/lib.rs index ac5527149d..8ea32fb8d2 100644 --- a/runtime/mandala/src/lib.rs +++ b/runtime/mandala/src/lib.rs @@ -1218,6 +1218,7 @@ impl module_dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DEXPalletId; + type GetNativeCurrencyId = GetNativeCurrencyId; type Erc20InfoMapping = EvmErc20InfoMapping; type DEXIncentives = Incentives; type WeightInfo = weights::module_dex::WeightInfo; From fc49bf708331ee336fb122e3843c40fb5242a541 Mon Sep 17 00:00:00 2001 From: zjb0807 Date: Fri, 10 Jan 2025 21:12:26 +0800 Subject: [PATCH 3/8] add tests --- modules/dex/src/mock.rs | 16 +++++++++++--- modules/dex/src/tests.rs | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/modules/dex/src/mock.rs b/modules/dex/src/mock.rs index d025c9db93..be68b64899 100644 --- a/modules/dex/src/mock.rs +++ b/modules/dex/src/mock.rs @@ -46,6 +46,7 @@ parameter_types! { pub static AUSDBTCPair: TradingPair = TradingPair::from_currency_ids(AUSD, BTC).unwrap(); pub static AUSDDOTPair: TradingPair = TradingPair::from_currency_ids(AUSD, DOT).unwrap(); pub static DOTBTCPair: TradingPair = TradingPair::from_currency_ids(DOT, BTC).unwrap(); + pub static ACAAUSDPair: TradingPair = TradingPair::from_currency_ids(ACA, AUSD).unwrap(); } mod dex { @@ -61,8 +62,11 @@ impl frame_system::Config for Runtime { } parameter_type_with_key! { - pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { - Default::default() + pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance { + match *currency_id { + ACA => 1, + _ => Default::default(), + } }; } @@ -181,7 +185,12 @@ impl Default for ExtBuilder { impl ExtBuilder { pub fn initialize_enabled_trading_pairs(mut self) -> Self { - self.initial_enabled_trading_pairs = vec![AUSDDOTPair::get(), AUSDBTCPair::get(), DOTBTCPair::get()]; + self.initial_enabled_trading_pairs = vec![ + AUSDDOTPair::get(), + AUSDBTCPair::get(), + DOTBTCPair::get(), + ACAAUSDPair::get(), + ]; self } @@ -192,6 +201,7 @@ impl ExtBuilder { (AUSDDOTPair::get(), (1_000_000u128, 2_000_000u128)), (AUSDBTCPair::get(), (1_000_000u128, 2_000_000u128)), (DOTBTCPair::get(), (1_000_000u128, 2_000_000u128)), + (ACAAUSDPair::get(), (1_000_000u128, 2_000_000u128)), ], )]; self diff --git a/modules/dex/src/tests.rs b/modules/dex/src/tests.rs index 58dad6d530..97440a7621 100644 --- a/modules/dex/src/tests.rs +++ b/modules/dex/src/tests.rs @@ -1993,3 +1993,51 @@ fn specific_joint_swap_work() { ); }); } + +#[test] +fn do_swap_should_keep_alive_work() { + ExtBuilder::default() + .initialize_enabled_trading_pairs() + .build() + .execute_with(|| { + System::set_block_number(1); + + assert_ok!(DexModule::add_liquidity( + RuntimeOrigin::signed(ALICE), + ACA, + AUSD, + 1_000_000_000_000_000, + 2_000_000_000_000_000, + 0, + false, + )); + + assert_ok!(Tokens::transfer( + RuntimeOrigin::signed(ALICE), + CAROL, + ACA, + 100_000_000_000_000 + )); + + assert_eq!(Tokens::free_balance(ACA, &CAROL), 100_000_000_000_000); + + assert_noop!( + DexModule::do_swap_with_exact_supply(&CAROL, &[ACA, AUSD], 100_000_000_000_000, 1,), + orml_tokens::Error::::KeepAlive + ); + + assert_ok!(DexModule::do_swap_with_exact_supply( + &CAROL, + &[ACA, AUSD], + 10_000_000_000_000, + 1 + )); + + assert_ok!(DexModule::do_swap_with_exact_target( + &CAROL, + &[ACA, AUSD], + 10_000_000_000_000, + 20_000_000_000_000 + )); + }); +} From 54611e9585cddc89f81e2101a2024b57053d4054 Mon Sep 17 00:00:00 2001 From: zjb0807 Date: Fri, 10 Jan 2025 21:17:35 +0800 Subject: [PATCH 4/8] update orml --- orml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orml b/orml index 9edc5cb679..8c332b1f02 160000 --- a/orml +++ b/orml @@ -1 +1 @@ -Subproject commit 9edc5cb6790169a230b11cb2c52301ab6e748ead +Subproject commit 8c332b1f025558d198b90b3f4f3de14226fa1846 From 5fa6c4fcac06a341923b297fc90bcfb29cbf5786 Mon Sep 17 00:00:00 2001 From: zjb0807 Date: Fri, 10 Jan 2025 22:32:14 +0800 Subject: [PATCH 5/8] fix tests --- modules/dex/src/mock.rs | 6 +++--- modules/dex/src/tests.rs | 8 ++++---- modules/evm/src/bench/mock.rs | 1 + runtime/mandala/src/benchmarking/homa.rs | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/modules/dex/src/mock.rs b/modules/dex/src/mock.rs index be68b64899..dd48482cdd 100644 --- a/modules/dex/src/mock.rs +++ b/modules/dex/src/mock.rs @@ -46,7 +46,7 @@ parameter_types! { pub static AUSDBTCPair: TradingPair = TradingPair::from_currency_ids(AUSD, BTC).unwrap(); pub static AUSDDOTPair: TradingPair = TradingPair::from_currency_ids(AUSD, DOT).unwrap(); pub static DOTBTCPair: TradingPair = TradingPair::from_currency_ids(DOT, BTC).unwrap(); - pub static ACAAUSDPair: TradingPair = TradingPair::from_currency_ids(ACA, AUSD).unwrap(); + pub static ACABTCPair: TradingPair = TradingPair::from_currency_ids(ACA, BTC).unwrap(); } mod dex { @@ -189,7 +189,7 @@ impl ExtBuilder { AUSDDOTPair::get(), AUSDBTCPair::get(), DOTBTCPair::get(), - ACAAUSDPair::get(), + ACABTCPair::get(), ]; self } @@ -201,7 +201,7 @@ impl ExtBuilder { (AUSDDOTPair::get(), (1_000_000u128, 2_000_000u128)), (AUSDBTCPair::get(), (1_000_000u128, 2_000_000u128)), (DOTBTCPair::get(), (1_000_000u128, 2_000_000u128)), - (ACAAUSDPair::get(), (1_000_000u128, 2_000_000u128)), + (ACABTCPair::get(), (1_000_000u128, 2_000_000u128)), ], )]; self diff --git a/modules/dex/src/tests.rs b/modules/dex/src/tests.rs index 97440a7621..5598647335 100644 --- a/modules/dex/src/tests.rs +++ b/modules/dex/src/tests.rs @@ -2005,7 +2005,7 @@ fn do_swap_should_keep_alive_work() { assert_ok!(DexModule::add_liquidity( RuntimeOrigin::signed(ALICE), ACA, - AUSD, + BTC, 1_000_000_000_000_000, 2_000_000_000_000_000, 0, @@ -2022,20 +2022,20 @@ fn do_swap_should_keep_alive_work() { assert_eq!(Tokens::free_balance(ACA, &CAROL), 100_000_000_000_000); assert_noop!( - DexModule::do_swap_with_exact_supply(&CAROL, &[ACA, AUSD], 100_000_000_000_000, 1,), + DexModule::do_swap_with_exact_supply(&CAROL, &[ACA, BTC], 100_000_000_000_000, 1,), orml_tokens::Error::::KeepAlive ); assert_ok!(DexModule::do_swap_with_exact_supply( &CAROL, - &[ACA, AUSD], + &[ACA, BTC], 10_000_000_000_000, 1 )); assert_ok!(DexModule::do_swap_with_exact_target( &CAROL, - &[ACA, AUSD], + &[ACA, BTC], 10_000_000_000_000, 20_000_000_000_000 )); diff --git a/modules/evm/src/bench/mock.rs b/modules/evm/src/bench/mock.rs index f24dceb4bc..1796f43859 100644 --- a/modules/evm/src/bench/mock.rs +++ b/modules/evm/src/bench/mock.rs @@ -279,6 +279,7 @@ impl module_dex::Config for Runtime { type GetExchangeFee = GetExchangeFee; type TradingPathLimit = TradingPathLimit; type PalletId = DEXPalletId; + type GetNativeCurrencyId = GetNativeCurrencyId; type Erc20InfoMapping = MockErc20InfoMapping; type WeightInfo = (); type DEXIncentives = MockDEXIncentives; diff --git a/runtime/mandala/src/benchmarking/homa.rs b/runtime/mandala/src/benchmarking/homa.rs index e5ee43f6f8..1302771332 100644 --- a/runtime/mandala/src/benchmarking/homa.rs +++ b/runtime/mandala/src/benchmarking/homa.rs @@ -23,7 +23,7 @@ use crate::{ use super::utils::{set_balance, LIQUID, STAKING}; use frame_benchmarking::{account, whitelisted_caller}; -use frame_support::traits::OnInitialize; +use frame_support::traits::{ExistenceRequirement, OnInitialize}; use frame_system::RawOrigin; use module_homa::UnlockChunk; use orml_benchmarking::runtime_benchmarks; @@ -126,7 +126,7 @@ runtime_benchmarks! { let redeem_amount = 10_000_000_000_000; for i in 0 .. n { let redeemer = account("redeemer", i, SEED); - >::transfer(LIQUID, &minter, &redeemer, redeem_amount * 2)?; + >::transfer(LIQUID, &minter, &redeemer, redeem_amount * 2, ExistenceRequirement::AllowDeath)?; Homa::request_redeem(RawOrigin::Signed(redeemer.clone()).into(), redeem_amount, true)?; redeem_request_list.push(redeemer); } From 60c048e5e8f7ba9e30786ca6b6794b99962dfba3 Mon Sep 17 00:00:00 2001 From: zjb0807 Date: Sat, 11 Jan 2025 09:02:56 +0800 Subject: [PATCH 6/8] fix tests --- .github/workflows/coverage.yml | 2 +- Makefile | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b47be97355..6905f70a15 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -18,7 +18,7 @@ concurrency: cancel-in-progress: true env: - TARPAULIN_VERSION: 0.31.2 + TARPAULIN_VERSION: 0.31.4 CARGO_INCREMENTAL: 0 jobs: test: diff --git a/Makefile b/Makefile index 13659c660d..cd372b94ee 100644 --- a/Makefile +++ b/Makefile @@ -258,6 +258,6 @@ bench-evm: .PHONY: tools tools: - cargo install staging-chain-spec-builder - cargo install frame-omni-bencher - cargo install --git https://github.com/paritytech/try-runtime-cli --tag v0.7.0 + cargo install staging-chain-spec-builder --force + cargo install frame-omni-bencher --force + cargo install --git https://github.com/paritytech/try-runtime-cli --tag v0.7.0 --force From e3e5c4ab8d209e5718723f28e8212856c9e24cef Mon Sep 17 00:00:00 2001 From: zjb0807 Date: Sat, 11 Jan 2025 09:28:22 +0800 Subject: [PATCH 7/8] fix --- .github/workflows/test.yml | 2 +- Makefile | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6ed5118507..ca1927ea08 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -134,7 +134,7 @@ jobs: with: node-version: 18.x - name: Install deps - run: cargo install staging-chain-spec-builder + run: cargo install staging-chain-spec-builder --force - name: Run ts tests run: | npm install -g yarn diff --git a/Makefile b/Makefile index cd372b94ee..13659c660d 100644 --- a/Makefile +++ b/Makefile @@ -258,6 +258,6 @@ bench-evm: .PHONY: tools tools: - cargo install staging-chain-spec-builder --force - cargo install frame-omni-bencher --force - cargo install --git https://github.com/paritytech/try-runtime-cli --tag v0.7.0 --force + cargo install staging-chain-spec-builder + cargo install frame-omni-bencher + cargo install --git https://github.com/paritytech/try-runtime-cli --tag v0.7.0 From a9e35653d3f2831c03f5f471256e49eddbba0ff8 Mon Sep 17 00:00:00 2001 From: zjb0807 Date: Sat, 11 Jan 2025 10:28:55 +0800 Subject: [PATCH 8/8] fix --- modules/loans/src/tests.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/loans/src/tests.rs b/modules/loans/src/tests.rs index ec0baa72e0..3a047c62c4 100644 --- a/modules/loans/src/tests.rs +++ b/modules/loans/src/tests.rs @@ -27,10 +27,12 @@ use mock::{RuntimeEvent, *}; #[test] fn debits_key() { ExtBuilder::default().build().execute_with(|| { + assert_eq!(Currencies::free_balance(BTC, &ALICE), 1000); assert_eq!(Currencies::free_balance(BTC, &LoansModule::account_id()), 0); assert_eq!(LoansModule::positions(BTC, &ALICE).debit, 0); assert_ok!(LoansModule::adjust_position(&ALICE, BTC, 200, 200)); assert_eq!(LoansModule::positions(BTC, &ALICE).debit, 200); + assert_eq!(Currencies::free_balance(BTC, &ALICE), 800); assert_eq!(Currencies::free_balance(BTC, &LoansModule::account_id()), 200); assert_ok!(LoansModule::adjust_position(&ALICE, BTC, -100, -100)); assert_eq!(LoansModule::positions(BTC, &ALICE).debit, 100);