Skip to content

Commit

Permalink
Fix transaction payment (#1856)
Browse files Browse the repository at this point in the history
* fix initialize_pool

* fix UpdateOrigin

* update integration-tests

* fix benchmarking

* remove transactional
  • Loading branch information
zjb0807 authored Feb 9, 2022
1 parent 3314b33 commit ab8580a
Show file tree
Hide file tree
Showing 15 changed files with 430 additions and 271 deletions.
74 changes: 38 additions & 36 deletions modules/transaction-payment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ pub mod module {
type TreasuryAccount: Get<Self::AccountId>;

/// The origin which change swap balance threshold or enable charge fee pool.
type UpdateOrigin: EnsureOrigin<Self::Origin, Success = Self::AccountId>;
type UpdateOrigin: EnsureOrigin<Self::Origin>;
}

#[pallet::extra_constants]
Expand Down Expand Up @@ -472,6 +472,7 @@ pub mod module {
impl<T: Config> Pallet<T> {
/// Set fee swap path
#[pallet::weight(<T as Config>::WeightInfo::set_alternative_fee_swap_path())]
#[transactional]
pub fn set_alternative_fee_swap_path(
origin: OriginFor<T>,
fee_swap_path: Option<Vec<CurrencyId>>,
Expand All @@ -487,8 +488,8 @@ pub mod module {
&& path[path.len() - 1] == T::NativeCurrencyId::get(),
Error::<T>::InvalidSwapPath
);
AlternativeFeeSwapPath::<T>::insert(&who, &path);
T::Currency::ensure_reserved_named(&DEPOSIT_ID, &who, T::AlternativeFeeSwapDeposit::get())?;
AlternativeFeeSwapPath::<T>::insert(&who, &path);
} else {
AlternativeFeeSwapPath::<T>::remove(&who);
T::Currency::unreserve_all_named(&DEPOSIT_ID, &who);
Expand All @@ -498,6 +499,7 @@ pub mod module {

/// Set swap balance threshold of native asset
#[pallet::weight(<T as Config>::WeightInfo::set_swap_balance_threshold())]
#[transactional]
pub fn set_swap_balance_threshold(
origin: OriginFor<T>,
currency_id: CurrencyId,
Expand All @@ -518,6 +520,7 @@ pub mod module {

/// Enable and initialize charge fee pool.
#[pallet::weight(<T as Config>::WeightInfo::enable_charge_fee_pool())]
#[transactional]
pub fn enable_charge_fee_pool(
origin: OriginFor<T>,
currency_id: CurrencyId,
Expand Down Expand Up @@ -817,8 +820,7 @@ where

/// Initiate a charge fee swap pool. Usually used in `on_runtime_upgrade` or manual
/// `enable_charge_fee_pool` dispatch call.
#[transactional]
pub fn initialize_pool(currency_id: CurrencyId, pool_size: Balance, swap_threshold: Balance) -> DispatchResult {
fn initialize_pool(currency_id: CurrencyId, pool_size: Balance, swap_threshold: Balance) -> DispatchResult {
let treasury_account = T::TreasuryAccount::get();
let sub_account = Self::sub_account_id(currency_id);
let native_existential_deposit = <T as Config>::Currency::minimum_balance();
Expand All @@ -831,39 +833,39 @@ where
Error::<T>::ChargeFeePoolAlreadyExisted
);

let trading_path = Self::get_trading_path_by_currency(&sub_account, currency_id);
if let Some(trading_path) = trading_path {
let (supply_amount, _) = T::DEX::get_swap_amount(
&trading_path,
SwapLimit::ExactTarget(Balance::MAX, native_existential_deposit),
)
.ok_or(Error::<T>::DexNotAvailable)?;
let exchange_rate = Ratio::saturating_from_rational(supply_amount, native_existential_deposit);

T::MultiCurrency::transfer(
currency_id,
&treasury_account,
&sub_account,
T::MultiCurrency::minimum_balance(currency_id),
)?;
T::Currency::transfer(
&treasury_account,
&sub_account,
pool_size,
ExistenceRequirement::KeepAlive,
)?;
let trading_path =
Self::get_trading_path_by_currency(&sub_account, currency_id).ok_or(Error::<T>::DexNotAvailable)?;
let (supply_amount, _) = T::DEX::get_swap_amount(
&trading_path,
SwapLimit::ExactTarget(Balance::MAX, native_existential_deposit),
)
.ok_or(Error::<T>::DexNotAvailable)?;
let exchange_rate = Ratio::saturating_from_rational(supply_amount, native_existential_deposit);

T::MultiCurrency::transfer(
currency_id,
&treasury_account,
&sub_account,
T::MultiCurrency::minimum_balance(currency_id),
)?;
T::Currency::transfer(
&treasury_account,
&sub_account,
pool_size,
ExistenceRequirement::KeepAlive,
)?;

SwapBalanceThreshold::<T>::insert(currency_id, swap_threshold);
TokenExchangeRate::<T>::insert(currency_id, exchange_rate);
PoolSize::<T>::insert(currency_id, pool_size);
Self::deposit_event(Event::ChargeFeePoolEnabled {
sub_account,
currency_id,
exchange_rate,
pool_size,
swap_threshold,
});

SwapBalanceThreshold::<T>::insert(currency_id, swap_threshold);
TokenExchangeRate::<T>::insert(currency_id, exchange_rate);
PoolSize::<T>::insert(currency_id, pool_size);
Self::deposit_event(Event::ChargeFeePoolEnabled {
sub_account,
currency_id,
exchange_rate,
pool_size,
swap_threshold,
});
}
Ok(())
}
}
Expand Down
26 changes: 20 additions & 6 deletions modules/transaction-payment/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ fn do_runtime_upgrade_and_init_balance() {
));

for asset in crate::mock::FeePoolExchangeTokens::get() {
let _ = Pallet::<Runtime>::initialize_pool(asset, FeePoolSize::get(), crate::mock::SwapThreshold::get());
assert_ok!(Pallet::<Runtime>::initialize_pool(
asset,
FeePoolSize::get(),
crate::mock::SwapThreshold::get()
));
}
// MockTransactionPaymentUpgrade::on_runtime_upgrade();

Expand Down Expand Up @@ -967,7 +971,7 @@ fn swap_from_pool_with_enough_balance() {
let expect_treasury_aca = (pool_size - fee) as u128; // 500 ACA
let expect_user_aca = fee; // 500 ACA

let _ = Pallet::<Runtime>::swap_from_pool_or_dex(&BOB, fee, DOT);
assert_ok!(Pallet::<Runtime>::swap_from_pool_or_dex(&BOB, fee, DOT));
assert_eq!(expect_user_dot, Currencies::free_balance(DOT, &BOB));
assert_eq!(
expect_treasury_dot,
Expand All @@ -992,7 +996,7 @@ fn swap_from_pool_with_enough_balance() {
let expect_treasury_aca = pool_size - fee; // 1000 ACA - 500 ACA
let expect_user_aca = expect_user_aca + fee; // 500 ACA

let _ = Pallet::<Runtime>::swap_from_pool_or_dex(&BOB, fee, AUSD);
assert_ok!(Pallet::<Runtime>::swap_from_pool_or_dex(&BOB, fee, AUSD));
assert_eq!(expect_user_ausd, Currencies::free_balance(AUSD, &BOB));
assert_eq!(
expect_treasury_ausd,
Expand Down Expand Up @@ -1052,7 +1056,7 @@ fn swap_from_pool_and_dex_update_rate() {

// the sub account has 9200 ACA, 80 DOT, use 80 DOT to swap out some ACA
let balance2 = 300 as u128;
let _ = Pallet::<Runtime>::swap_from_pool_or_dex(&BOB, balance2, DOT);
assert_ok!(Pallet::<Runtime>::swap_from_pool_or_dex(&BOB, balance2, DOT));
assert_eq!(TokenExchangeRate::<Runtime>::get(DOT).unwrap(), rate);
assert_eq!(PoolSize::<Runtime>::get(DOT), current_native_balance);
});
Expand Down Expand Up @@ -1156,7 +1160,7 @@ fn charge_fee_failed_when_disable_dex() {
assert_eq!(fee_balance - 200, Currencies::free_balance(ACA, &fee_account));

// this tx failed because when execute balance lt threshold, the swap failed
let _ = ChargeTransactionPayment::<Runtime>::from(0).validate(&BOB, CALL2, &INFO2, 50);
assert_ok!(ChargeTransactionPayment::<Runtime>::from(0).validate(&BOB, CALL2, &INFO2, 50));
});
}

Expand Down Expand Up @@ -1216,13 +1220,23 @@ fn enable_init_pool_works() {
(usd_ed * 2).unique_saturated_into(),
));

let _ = Pallet::<Runtime>::enable_charge_fee_pool(Origin::signed(ALICE), AUSD, pool_size, 35);
assert_ok!(Pallet::<Runtime>::enable_charge_fee_pool(
Origin::signed(ALICE),
AUSD,
pool_size,
35
));
let rate = TokenExchangeRate::<Runtime>::get(AUSD);
assert_eq!(rate, Some(Ratio::saturating_from_rational(2, 10)));

assert_noop!(
Pallet::<Runtime>::enable_charge_fee_pool(Origin::signed(ALICE), AUSD, pool_size, 35),
Error::<Runtime>::ChargeFeePoolAlreadyExisted
);

assert_noop!(
Pallet::<Runtime>::enable_charge_fee_pool(Origin::signed(ALICE), KSM, pool_size, 35),
Error::<Runtime>::DexNotAvailable
);
});
}
2 changes: 1 addition & 1 deletion runtime/acala/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1197,7 +1197,7 @@ impl module_transaction_payment::Config for Runtime {
type WeightInfo = weights::module_transaction_payment::WeightInfo<Runtime>;
type PalletId = TransactionPaymentPalletId;
type TreasuryAccount = AcalaTreasuryAccount;
type UpdateOrigin = EnsureAcalaFoundation;
type UpdateOrigin = EnsureRootOrHalfGeneralCouncil;
}

impl module_evm_accounts::Config for Runtime {
Expand Down
2 changes: 1 addition & 1 deletion runtime/integration-tests/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ fn test_multicurrency_precompile_module() {

assert_ok!(Currencies::transfer(
Origin::signed(AccountId::from(ALICE)),
sp_runtime::MultiAddress::Id( TreasuryAccount::get()),
sp_runtime::MultiAddress::Id(TreasuryAccount::get()),
NATIVE_CURRENCY,
10 * dollar(NATIVE_CURRENCY)
));
Expand Down
Loading

0 comments on commit ab8580a

Please sign in to comment.