From b9348f6f187ebf97806e6b7368ac1843e536c3c8 Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 4 Oct 2024 07:47:49 +0200 Subject: [PATCH 01/24] add insufficient fee asset support to EVM --- integration-tests/src/evm_permit.rs | 452 +++++++++++++++++++++++++++- runtime/adapters/src/price.rs | 70 ++++- runtime/hydradx/src/assets.rs | 10 + runtime/hydradx/src/evm/evm_fee.rs | 89 +++++- runtime/hydradx/src/evm/mod.rs | 9 +- traits/src/fee.rs | 6 + 6 files changed, 611 insertions(+), 25 deletions(-) diff --git a/integration-tests/src/evm_permit.rs b/integration-tests/src/evm_permit.rs index 784098314..210520b5e 100644 --- a/integration-tests/src/evm_permit.rs +++ b/integration-tests/src/evm_permit.rs @@ -1,31 +1,47 @@ #![cfg(test)] +use crate::dca::add_dot_as_payment_currency; use crate::polkadot_test_net::*; use crate::utils::accounts::*; use frame_support::dispatch::GetDispatchInfo; use frame_support::pallet_prelude::ValidateUnsigned; +use frame_support::storage::with_transaction; use frame_support::traits::fungible::Mutate; use frame_support::traits::Contains; use frame_support::{assert_noop, assert_ok, sp_runtime::codec::Encode}; use frame_system::RawOrigin; +use hydra_dx_math::types::Ratio; +use hydradx_adapters::price::ConvertAmount; use hydradx_runtime::evm::precompiles::{CALLPERMIT, DISPATCH_ADDR}; +use hydradx_runtime::types::ShortOraclePrice; +use hydradx_runtime::AssetRegistry; +use hydradx_runtime::DOT_ASSET_LOCATION; +use hydradx_runtime::XYK; use hydradx_runtime::{ - Balances, Currencies, EVMAccounts, MultiTransactionPayment, Omnipool, RuntimeCall, RuntimeOrigin, Tokens, + Balances, Currencies, DotAssetId, EVMAccounts, MultiTransactionPayment, Omnipool, RuntimeCall, RuntimeOrigin, + Tokens, XykPaymentAssetSupport, }; +use hydradx_traits::AssetKind; +use hydradx_traits::Create; +use hydradx_traits::Mutate as AssetRegistryMutate; use libsecp256k1::{sign, Message, SecretKey}; use orml_traits::MultiCurrency; use pallet_evm_accounts::EvmNonceProvider; use pallet_transaction_multi_payment::EVMPermit; use pretty_assertions::assert_eq; +use primitives::constants::currency::UNITS; use primitives::{AssetId, Balance}; +use scraper::BOB; use sp_core::{H256, U256}; +use sp_runtime::traits::Convert; use sp_runtime::traits::SignedExtension; use sp_runtime::transaction_validity::InvalidTransaction; use sp_runtime::transaction_validity::TransactionValidityError; use sp_runtime::transaction_validity::{TransactionSource, ValidTransaction}; +use sp_runtime::DispatchResult; +use sp_runtime::TransactionOutcome; use sp_runtime::{FixedU128, Permill}; use xcm_emulator::TestExt; - pub const TREASURY_ACCOUNT_INIT_BALANCE: Balance = 1000 * UNITS; #[test] @@ -750,6 +766,438 @@ fn evm_permit_set_currency_dispatch_should_pay_evm_fee_in_chosen_currency() { }) } +#[test] +fn evm_permit_set_currency_dispatch_should_pay_evm_fee_in_insufficient_asset() { + TestNet::reset(); + let user_evm_address = alith_evm_address(); + let user_secret_key = alith_secret_key(); + let user_acc = MockAccount::new(alith_truncated_account()); + + Hydra::execute_with(|| { + let _ = with_transaction(|| { + init_omnipool_with_oracle_for_block_10(); + pallet_transaction_payment::pallet::NextFeeMultiplier::::put( + hydradx_runtime::MinimumMultiplier::get(), + ); + assert_ok!(hydradx_runtime::AssetRegistry::set_location(DOT, DOT_ASSET_LOCATION)); + + let name = b"INSUF1".to_vec(); + + let insufficient_asset = AssetRegistry::register_insufficient_asset( + None, + Some(name.try_into().unwrap()), + AssetKind::External, + Some(1_000), + None, + None, + None, + None, + ) + .unwrap(); + + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + user_acc.address(), + 0, + 100_000_000_000_000_000_000i128, + )); + + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + user_acc.address(), + insufficient_asset, + 100_000_000_000_000_000_000i128, + )); + + let initial_user_weth_balance = user_acc.balance(WETH); + + // just reset the weth balance to 0 - to make sure we dont have enough WETH + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + user_acc.address(), + WETH, + -(initial_user_weth_balance as i128), + )); + let initial_user_weth_balance = user_acc.balance(WETH); + assert_eq!(initial_user_weth_balance, 0); + + assert_ok!(hydradx_runtime::MultiTransactionPayment::add_currency( + hydradx_runtime::RuntimeOrigin::root(), + DOT, + FixedU128::from_rational(1, 100000), + )); + + create_xyk_pool(insufficient_asset, 100000000000 * UNITS, DOT, 120000000000 * UNITS); + assert_ok!(hydradx_runtime::EmaOracle::add_oracle( + RuntimeOrigin::root(), + primitives::constants::chain::XYK_SOURCE, + (DOT, insufficient_asset) + )); + //Populate oracle + assert_ok!(Currencies::update_balance( + RawOrigin::Root.into(), + BOB.into(), + insufficient_asset, + 2 * UNITS as i128, + )); + assert_ok!(XYK::sell( + RuntimeOrigin::signed(BOB.into()), + insufficient_asset, + DOT, + UNITS, + 0, + false + )); + + let initial_user_insufficient_balance = user_acc.balance(insufficient_asset); + let initial_insuff_asset_issuance = Currencies::total_issuance(insufficient_asset); + + let set_currency_call = hydradx_runtime::RuntimeCall::MultiTransactionPayment( + pallet_transaction_multi_payment::Call::set_currency { + currency: insufficient_asset, + }, + ); + + let gas_limit = 1000000; + let deadline = U256::from(1000000000000u128); + + let permit = + pallet_evm_precompile_call_permit::CallPermitPrecompile::::generate_permit( + CALLPERMIT, + user_evm_address, + DISPATCH_ADDR, + U256::from(0), + set_currency_call.encode(), + gas_limit, + U256::zero(), + deadline, + ); + let secret_key = SecretKey::parse(&user_secret_key).unwrap(); + let message = Message::parse(&permit); + let (rs, v) = sign(&message, &secret_key); + + // Validate unsigned first + let call = pallet_transaction_multi_payment::Call::dispatch_permit { + from: user_evm_address, + to: DISPATCH_ADDR, + value: U256::from(0), + data: set_currency_call.encode(), + gas_limit, + deadline, + v: v.serialize(), + r: H256::from(rs.r.b32()), + s: H256::from(rs.s.b32()), + }; + + let tag: Vec = ("EVMPermit", (U256::zero(), user_evm_address)).encode(); + assert_eq!( + MultiTransactionPayment::validate_unsigned(TransactionSource::External, &call), + Ok(ValidTransaction { + priority: 0, + requires: vec![], + provides: vec![tag], + longevity: 64, + propagate: true, + }) + ); + + // And Dispatch + assert_ok!(MultiTransactionPayment::dispatch_permit( + hydradx_runtime::RuntimeOrigin::none(), + user_evm_address, + DISPATCH_ADDR, + U256::from(0), + set_currency_call.encode(), + gas_limit, + deadline, + v.serialize(), + H256::from(rs.r.b32()), + H256::from(rs.s.b32()), + )); + + let currency = pallet_transaction_multi_payment::Pallet::::account_currency( + &user_acc.address(), + ); + assert_eq!(currency, insufficient_asset); + + let insuff_asset_issuance = Currencies::total_issuance(insufficient_asset); + assert_eq!(initial_insuff_asset_issuance, insuff_asset_issuance); + + let user_insufficient_asset_balance = user_acc.balance(insufficient_asset); + assert!(user_insufficient_asset_balance < initial_user_insufficient_balance); + let payed_fee = initial_user_insufficient_balance - user_insufficient_asset_balance; + //assert_eq!(payed_fee, 107314200); + assert!(payed_fee > 100_000_000); + assert!(payed_fee < 120_000_000); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }) +} + +#[test] +fn convert_amount_should_work_when_converting_insufficient_to_sufficient_asset() { + TestNet::reset(); + let user_evm_address = alith_evm_address(); + let user_secret_key = alith_secret_key(); + let user_acc = MockAccount::new(alith_truncated_account()); + + Hydra::execute_with(|| { + let _ = with_transaction(|| { + init_omnipool_with_oracle_for_block_10(); + pallet_transaction_payment::pallet::NextFeeMultiplier::::put( + hydradx_runtime::MinimumMultiplier::get(), + ); + assert_ok!(hydradx_runtime::AssetRegistry::set_location(DOT, DOT_ASSET_LOCATION)); + + let name = b"INSUF1".to_vec(); + + let insufficient_asset = AssetRegistry::register_insufficient_asset( + None, + Some(name.try_into().unwrap()), + AssetKind::External, + Some(1_000), + None, + None, + None, + None, + ) + .unwrap(); + + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + user_acc.address(), + 0, + 100_000_000_000_000_000_000i128, + )); + + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + user_acc.address(), + insufficient_asset, + 100_000_000_000_000_000_000i128, + )); + + let initial_user_weth_balance = user_acc.balance(WETH); + + // just reset the weth balance to 0 - to make sure we dont have enough WETH + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + user_acc.address(), + WETH, + -(initial_user_weth_balance as i128), + )); + let initial_user_weth_balance = user_acc.balance(WETH); + assert_eq!(initial_user_weth_balance, 0); + + assert_ok!(hydradx_runtime::MultiTransactionPayment::add_currency( + hydradx_runtime::RuntimeOrigin::root(), + DOT, + FixedU128::from_rational(1, 100000), + )); + + create_xyk_pool(insufficient_asset, 100000000000 * UNITS, DOT, 120000000000 * UNITS); + assert_ok!(hydradx_runtime::EmaOracle::add_oracle( + RuntimeOrigin::root(), + primitives::constants::chain::XYK_SOURCE, + (DOT, insufficient_asset) + )); + //Populate oracle + assert_ok!(Currencies::update_balance( + RawOrigin::Root.into(), + BOB.into(), + insufficient_asset, + 2 * UNITS as i128, + )); + assert_ok!(XYK::sell( + RuntimeOrigin::signed(BOB.into()), + insufficient_asset, + DOT, + UNITS, + 0, + false + )); + + // + //Convert insufficient to sufficient (WETH) + type Convert = ConvertAmount; + + let insufficient_amount = 10 * UNITS; + let amount_in_weth = Convert::convert((insufficient_asset, WETH, insufficient_amount)).unwrap(); + assert_eq!( + (4293122621256764998, Ratio::new(4293122621256764998, 10000000000000)), + amount_in_weth + ); + + //Assert if we get similar result when selling WETH for insufficient + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + BOB.into(), + WETH, + 100000000 * UNITS as i128, + )); + let bob_init_dot = Currencies::free_balance(DOT, &AccountId::from(BOB)); + assert_ok!(hydradx_runtime::Omnipool::sell( + hydradx_runtime::RuntimeOrigin::signed(BOB.into()), + WETH, + DOT, + amount_in_weth.0, //weth needed for the transaction + 0 + )); + let bob_new_dot = Currencies::free_balance(DOT, &AccountId::from(BOB)); + let dot_diff = bob_new_dot - bob_init_dot; + + let initial_user_insufficient_balance = Currencies::free_balance(insufficient_asset, &AccountId::from(BOB)); + + assert_ok!(XYK::sell( + RuntimeOrigin::signed(BOB.into()), + DOT, + insufficient_asset, + dot_diff, + 0, + false + )); + let new_user_insufficient_balance = Currencies::free_balance(insufficient_asset, &AccountId::from(BOB)); + let diff = new_user_insufficient_balance - initial_user_insufficient_balance; + + let difference = insufficient_amount - diff; + let relative_difference = FixedU128::from_rational(difference, insufficient_amount); + let tolerated_difference = FixedU128::from_rational(2, 100); //2% due to fees, etc + assert!(relative_difference < tolerated_difference); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }) +} + +#[test] +fn convert_amount_should_work_when_converting_sufficient_to_insufficient_asset() { + TestNet::reset(); + let user_evm_address = alith_evm_address(); + let user_secret_key = alith_secret_key(); + let user_acc = MockAccount::new(alith_truncated_account()); + + Hydra::execute_with(|| { + let _ = with_transaction(|| { + init_omnipool_with_oracle_for_block_10(); + pallet_transaction_payment::pallet::NextFeeMultiplier::::put( + hydradx_runtime::MinimumMultiplier::get(), + ); + assert_ok!(hydradx_runtime::AssetRegistry::set_location(DOT, DOT_ASSET_LOCATION)); + + let name = b"INSUF1".to_vec(); + + let insufficient_asset = AssetRegistry::register_insufficient_asset( + None, + Some(name.try_into().unwrap()), + AssetKind::External, + Some(1_000), + None, + None, + None, + None, + ) + .unwrap(); + + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + user_acc.address(), + 0, + 100_000_000_000_000_000_000i128, + )); + + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + user_acc.address(), + insufficient_asset, + 100_000_000_000_000_000_000i128, + )); + + let initial_user_weth_balance = user_acc.balance(WETH); + + // just reset the weth balance to 0 - to make sure we dont have enough WETH + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + user_acc.address(), + WETH, + -(initial_user_weth_balance as i128), + )); + let initial_user_weth_balance = user_acc.balance(WETH); + assert_eq!(initial_user_weth_balance, 0); + + assert_ok!(hydradx_runtime::MultiTransactionPayment::add_currency( + hydradx_runtime::RuntimeOrigin::root(), + DOT, + FixedU128::from_rational(1, 100000), + )); + + create_xyk_pool(insufficient_asset, 100000000000 * UNITS, DOT, 120000000000 * UNITS); + assert_ok!(hydradx_runtime::EmaOracle::add_oracle( + RuntimeOrigin::root(), + primitives::constants::chain::XYK_SOURCE, + (DOT, insufficient_asset) + )); + //Populate oracle + assert_ok!(Currencies::update_balance( + RawOrigin::Root.into(), + BOB.into(), + insufficient_asset, + 2 * UNITS as i128, + )); + assert_ok!(XYK::sell( + RuntimeOrigin::signed(BOB.into()), + insufficient_asset, + DOT, + UNITS, + 0, + false + )); + + //Convert sufficient (WETH) to insufficient + type Convert = ConvertAmount; + + let weth_amount = 10 * UNITS; + let amount_in_insufficient_asset = Convert::convert((WETH, insufficient_asset, weth_amount)).unwrap(); + assert_eq!( + (23293070, Ratio::new(23293070, 10000000000000)), + amount_in_insufficient_asset + ); + + let initial_user_dot_balance = Currencies::free_balance(DOT, &AccountId::from(BOB)); + + assert_ok!(XYK::sell( + RuntimeOrigin::signed(BOB.into()), + insufficient_asset, + DOT, + amount_in_insufficient_asset.0, + 0, + false + )); + let new_user_dot_balance = Currencies::free_balance(DOT, &AccountId::from(BOB)); + let dot_diff = new_user_dot_balance - initial_user_dot_balance; + + //Assert if we get similar result when selling WETH for insufficient + let bob_init_weth = Currencies::free_balance(WETH, &AccountId::from(BOB)); + assert_ok!(hydradx_runtime::Omnipool::sell( + hydradx_runtime::RuntimeOrigin::signed(BOB.into()), + DOT, + WETH, + dot_diff, + 0 + )); + let bob_new_weth = Currencies::free_balance(WETH, &AccountId::from(BOB)); + let weth_diff = bob_new_weth - bob_init_weth; + + let difference = weth_amount - weth_diff; + let relative_difference = FixedU128::from_rational(difference, weth_amount); + let tolerated_difference = FixedU128::from_rational(1, 100); //1% due to fees, etc + assert!(relative_difference < tolerated_difference); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }) +} + #[test] fn evm_permit_dispatch_flow_should_work() { TestNet::reset(); diff --git a/runtime/adapters/src/price.rs b/runtime/adapters/src/price.rs index f1b68b988..c568c129f 100644 --- a/runtime/adapters/src/price.rs +++ b/runtime/adapters/src/price.rs @@ -1,12 +1,13 @@ use frame_support::traits::tokens::{Fortitude, Preservation}; use frame_support::weights::Weight; use hydra_dx_math::ema::EmaPrice; +use hydradx_traits::fee::SwappablePaymentAssetTrader; use hydradx_traits::price::PriceProvider; use hydradx_traits::router::{AssetPair, RouteProvider}; use hydradx_traits::{ AccountFeeCurrency, AccountFeeCurrencyBalanceInCurrency, AggregatedPriceOracle, OraclePeriod, PriceOracle, }; -use primitives::{AssetId, Balance}; +use primitives::{AccountId, AssetId, Balance}; use sp_core::Get; use sp_runtime::helpers_128bit::multiply_by_rational_with_rounding; use sp_runtime::traits::Convert; @@ -55,6 +56,10 @@ where // if this gets removed (eg. Convert returns weight), the constraint on T and ema-oracle is not necessary price_weight.saturating_accrue(pallet_ema_oracle::Pallet::::get_price_weight().saturating_mul(2)); + //2 reads as we are checking if from and to assets are transaction fee currencies + let is_transaction_fee_currency_check_weight = T::DbWeight::get().reads(2); + price_weight.saturating_accrue(is_transaction_fee_currency_check_weight); + let Some((converted, _)) = C::convert((from_currency, to_currency, account_balance)) else { return (0, price_weight); }; @@ -62,21 +67,70 @@ where } } -pub struct ConvertAmount

(sp_std::marker::PhantomData

); +pub struct ConvertAmount( + sp_std::marker::PhantomData<(PriceProv, SwappablePaymentAssetSupport, DotAssetId)>, +); -// Converts `amount` of `from_currency` to `to_currency` using given oracle +// Converts `amount` of `from_currency` to `to_currency` using given oracle, +// or XYK math calculations in case of swappable (insufficient) assets. // Input: (from_currency, to_currency, amount) // Output: Option<(converted_amount, price)> -impl

Convert<(AssetId, AssetId, Balance), Option<(Balance, EmaPrice)>> for crate::price::ConvertAmount

+impl + Convert<(AssetId, AssetId, Balance), Option<(Balance, EmaPrice)>> + for crate::price::ConvertAmount where - P: PriceProvider, + PriceProv: PriceProvider, + SwappablePaymentAssetSupport: SwappablePaymentAssetTrader, + DotAssetId: Get, { fn convert((from_currency, to_currency, amount): (AssetId, AssetId, Balance)) -> Option<(Balance, EmaPrice)> { if from_currency == to_currency { return Some((amount, EmaPrice::one())); } - let price = P::get_price(to_currency, from_currency)?; - let converted = multiply_by_rational_with_rounding(amount, price.n, price.d, Rounding::Up)?; - Some((converted, price)) + + let dot = DotAssetId::get(); + + let from_currency_is_tx_fee_asset = SwappablePaymentAssetSupport::is_transaction_fee_currency(from_currency); + let to_currency_is_tx_fee_asset = SwappablePaymentAssetSupport::is_transaction_fee_currency(to_currency); + + if from_currency_is_tx_fee_asset && to_currency_is_tx_fee_asset + { + let price = PriceProv::get_price(to_currency, from_currency)?; + let converted = multiply_by_rational_with_rounding(amount, price.n, price.d, Rounding::Up)?; + return Some((converted, price)); + } else if !from_currency_is_tx_fee_asset && to_currency_is_tx_fee_asset + { + let amount_in_dot = SwappablePaymentAssetSupport::calculate_out_given_in(from_currency, amount, dot).ok()?; + + let price_between_to_currency_and_dot = PriceProv::get_price(to_currency, dot)?; + let amount_in_to_currency = multiply_by_rational_with_rounding( + amount_in_dot, + price_between_to_currency_and_dot.n, + price_between_to_currency_and_dot.d, + Rounding::Up, + )?; + + let price = EmaPrice { + n: amount_in_to_currency, + d: amount, + }; + + return Some((amount_in_to_currency, price)); + } else if from_currency_is_tx_fee_asset && !to_currency_is_tx_fee_asset + { + let price_dot_to_from_currency = PriceProv::get_price(dot, from_currency)?; + let amount_in_dot = + multiply_by_rational_with_rounding(amount, price_dot_to_from_currency.n, price_dot_to_from_currency.d, Rounding::Up)?; + let amount_in_to_currency = + SwappablePaymentAssetSupport::calculate_in_given_out(to_currency, dot, amount_in_dot).ok()?; + let price = EmaPrice { + n: amount_in_to_currency, + d: amount, + }; + Some((amount_in_to_currency, price)) + } else { + //Not supported when both asset is insufficient asset + return None; + } } } diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index 480f643b4..2223fe45d 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -1780,6 +1780,16 @@ impl SwappablePaymentAssetTrader for XykPaymentAsse .map_err(|_err| ArithmeticError::Overflow.into()) } + + fn calculate_out_given_in(asset_in: AssetId, asset_in_amount: Balance, asset_out: AssetId) -> Result { + let asset_pair_account = XYK::get_pair_id(AssetPair::new(asset_in, asset_out)); + let in_reserve = Currencies::free_balance(asset_in, &asset_pair_account.clone()); + let out_reserve = Currencies::free_balance(asset_out, &asset_pair_account); + + hydra_dx_math::xyk::calculate_out_given_in(in_reserve,out_reserve, asset_in_amount) + .map_err(|_err| ArithmeticError::Overflow.into()) + } + fn buy( origin: &AccountId, asset_in: AssetId, diff --git a/runtime/hydradx/src/evm/evm_fee.rs b/runtime/hydradx/src/evm/evm_fee.rs index 237994144..ea78ed8cc 100644 --- a/runtime/hydradx/src/evm/evm_fee.rs +++ b/runtime/hydradx/src/evm/evm_fee.rs @@ -22,13 +22,15 @@ use crate::{Runtime, TreasuryAccount}; use frame_support::traits::tokens::{Fortitude, Precision}; use frame_support::traits::{Get, TryDrop}; use hydra_dx_math::ema::EmaPrice; +use hydradx_traits::fee::SwappablePaymentAssetTrader; use hydradx_traits::AccountFeeCurrency; +use orml_traits::arithmetic::One; use pallet_evm::{AddressMapping, Error}; -use pallet_transaction_multi_payment::{DepositAll, DepositFee}; +use pallet_transaction_multi_payment::{DepositAll, DepositFee, Pallet}; use primitives::{AccountId, AssetId, Balance}; use sp_runtime::helpers_128bit::multiply_by_rational_with_rounding; use sp_runtime::traits::Convert; -use sp_runtime::Rounding; +use sp_runtime::{FixedPointNumber, FixedPointOperand, FixedU128, Rounding}; use sp_std::marker::PhantomData; use { frame_support::traits::OnUnbalanced, @@ -66,19 +68,32 @@ impl TryDrop for EvmPaymentInfo { /// Implements the transaction payment for EVM transactions. /// Supports multi-currency fees based on what is provided by AC - account currency. -pub struct TransferEvmFees(PhantomData<(OU, AC, EC, C, MC)>); +pub struct TransferEvmFees( + PhantomData<( + OU, + AccountCurrency, + EvmFeeAsset, + C, + MC, + SwappablePaymentAssetSupport, + DotAssetId, + )>, +); -impl OnChargeEVMTransaction for TransferEvmFees +impl OnChargeEVMTransaction + for TransferEvmFees where T: pallet_evm::Config, OU: OnUnbalanced>, U256: UniqueSaturatedInto, - AC: AccountFeeCurrency, // AccountCurrency - EC: Get, // Evm default fee asset + AccountCurrency: AccountFeeCurrency, + EvmFeeAsset: Get, C: Convert<(AssetId, AssetId, Balance), Option<(Balance, EmaPrice)>>, // Conversion from default fee asset to account currency U256: UniqueSaturatedInto, MC: frame_support::traits::tokens::fungibles::Mutate + frame_support::traits::tokens::fungibles::Inspect, + SwappablePaymentAssetSupport: SwappablePaymentAssetTrader, + DotAssetId: Get, { type LiquidityInfo = Option>; @@ -87,10 +102,51 @@ where return Ok(None); } let account_id = T::AddressMapping::into_account_id(*who); - let fee_currency = AC::get(&account_id); - let Some((converted, price)) = C::convert((EC::get(), fee_currency, fee.unique_saturated_into())) else { - return Err(Error::::WithdrawFailed); - }; + let account_fee_currency = AccountCurrency::get(&account_id); + + let dot = DotAssetId::get(); + + let (converted, fee_currency, price) = + if SwappablePaymentAssetSupport::is_transaction_fee_currency(account_fee_currency) { + let Some((converted, price)) = + C::convert((EvmFeeAsset::get(), account_fee_currency, fee.unique_saturated_into())) + else { + return Err(Error::::WithdrawFailed); + }; + (converted, account_fee_currency, price) + } else { + //In case of insufficient asset we buy DOT with insufficient asset, and using that DOT and amount as fee currency + let Some((_, eth_dot_price)) = C::convert((EvmFeeAsset::get(), dot, fee.unique_saturated_into())) + else { + return Err(Error::::WithdrawFailed); + }; + + let Some(eth_dot_price_as_fixed) = FixedU128::checked_from_rational(eth_dot_price.n, eth_dot_price.d) else { + return Err(Error::::WithdrawFailed); + }; + + let fee_in_dot: Balance = convert_fee_with_price(fee.unique_saturated_into(), eth_dot_price_as_fixed) + .ok_or(Error::::WithdrawFailed)?; + + let amount_in = + SwappablePaymentAssetSupport::calculate_in_given_out(account_fee_currency, dot, fee_in_dot.into()) + .map_err(|_| Error::::WithdrawFailed)?; + let pool_fee = SwappablePaymentAssetSupport::calculate_fee_amount(amount_in) + .map_err(|_| Error::::WithdrawFailed)?; + let max_limit = amount_in.saturating_add(pool_fee); + + SwappablePaymentAssetSupport::buy( + &account_id.clone(), + account_fee_currency, + dot, + fee_in_dot.into(), + max_limit, + &account_id.clone(), + ) + .map_err(|_| Error::::WithdrawFailed)?; + + (fee_in_dot, dot, eth_dot_price) + }; // Ensure that converted fee is not zero if converted == 0 { @@ -115,8 +171,9 @@ where fn can_withdraw(who: &H160, amount: U256) -> Result<(), pallet_evm::Error> { let account_id = T::AddressMapping::into_account_id(*who); - let fee_currency = AC::get(&account_id); - let Some((converted, _)) = C::convert((EC::get(), fee_currency, amount.unique_saturated_into())) else { + let fee_currency = AccountCurrency::get(&account_id); + let Some((converted, _)) = C::convert((EvmFeeAsset::get(), fee_currency, amount.unique_saturated_into())) + else { return Err(Error::::BalanceLow); }; @@ -189,6 +246,14 @@ where } } +fn convert_fee_with_price(fee: B, price: FixedU128) -> Option +where + B: FixedPointOperand + Ord + One, +{ + // Make sure that the fee is never less than 1 + price.checked_mul_int(fee).map(|f| f.max(One::one())) +} + pub struct DepositEvmFeeToTreasury; impl OnUnbalanced> for DepositEvmFeeToTreasury { // this is called for substrate-based transactions diff --git a/runtime/hydradx/src/evm/mod.rs b/runtime/hydradx/src/evm/mod.rs index a9d3cfe98..8f94da728 100644 --- a/runtime/hydradx/src/evm/mod.rs +++ b/runtime/hydradx/src/evm/mod.rs @@ -26,7 +26,7 @@ pub use crate::{ evm::accounts_conversion::{ExtendedAddressMapping, FindAuthorTruncated}, AssetLocation, Aura, NORMAL_DISPATCH_RATIO, }; -use crate::{NativeAssetId, LRNA}; +use crate::{DotAssetId, NativeAssetId, TreasuryAccount, XykPaymentAssetSupport, LRNA}; pub use fp_evm::GenesisAccount as EvmGenesisAccount; use frame_support::{ parameter_types, @@ -37,6 +37,7 @@ use frame_support::{ use hex_literal::hex; use hydradx_adapters::price::ConvertAmount; use hydradx_adapters::{AssetFeeOraclePriceProvider, OraclePriceProvider}; +use hydradx_traits::fee::SwappablePaymentAssetTrader; use hydradx_traits::oracle::OraclePeriod; use orml_tokens::CurrencyAdapter; use pallet_currencies::fungibles::FungibleCurrencies; @@ -141,8 +142,10 @@ impl pallet_evm::Config for crate::Runtime { evm_fee::DepositEvmFeeToTreasury, FeeCurrencyOverrideOrDefault, // Get account's fee payment asset WethAssetId, - ConvertAmount, + ConvertAmount, FungibleCurrencies, // Multi currency support + XykPaymentAssetSupport, + DotAssetId, >; type OnCreate = (); type PrecompilesType = precompiles::HydraDXPrecompiles; @@ -152,7 +155,7 @@ impl pallet_evm::Config for crate::Runtime { pallet_evm::runner::stack::Runner, // Evm runner that we wrap hydradx_adapters::price::FeeAssetBalanceInCurrency< crate::Runtime, - ConvertAmount, + ConvertAmount, FeeCurrencyOverrideOrDefault, // Get account's fee payment asset FungibleCurrencies, // Account balance inspector >, diff --git a/traits/src/fee.rs b/traits/src/fee.rs index 914af80e1..a4b0fbd43 100644 --- a/traits/src/fee.rs +++ b/traits/src/fee.rs @@ -17,6 +17,12 @@ pub trait SwappablePaymentAssetTrader: InspectTransa asset_out_amount: Amount, ) -> Result; + fn calculate_out_given_in( + asset_in: AssetId, + asset_in_amount: Amount, + asset_out: AssetId, + ) -> Result; + fn buy( origin: &AccountId, asset_in: AssetId, From d744a3d5a21f1bc1803af93430dfafd4f38d3aaf Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 4 Oct 2024 07:50:22 +0200 Subject: [PATCH 02/24] bump versions --- Cargo.lock | 6 +++--- integration-tests/Cargo.toml | 2 +- runtime/adapters/Cargo.toml | 2 +- runtime/hydradx/Cargo.toml | 2 +- runtime/hydradx/src/lib.rs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6fa34f48f..813eb3ace 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4888,7 +4888,7 @@ dependencies = [ [[package]] name = "hydradx-adapters" -version = "1.3.5" +version = "1.4.0" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -4938,7 +4938,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "260.0.0" +version = "261.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", @@ -11931,7 +11931,7 @@ dependencies = [ [[package]] name = "runtime-integration-tests" -version = "1.23.6" +version = "1.23.7" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index fdafaaffb..32f247a96 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runtime-integration-tests" -version = "1.23.6" +version = "1.23.7" description = "Integration tests" authors = ["GalacticCouncil"] edition = "2021" diff --git a/runtime/adapters/Cargo.toml b/runtime/adapters/Cargo.toml index d6ca4836a..eeffbdbb9 100644 --- a/runtime/adapters/Cargo.toml +++ b/runtime/adapters/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-adapters" -version = "1.3.5" +version = "1.4.0" description = "Structs and other generic types for building runtimes." authors = ["GalacticCouncil"] edition = "2021" diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index 0c1c72c61..41a63980c 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "260.0.0" +version = "261.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index e52d92d9c..534c1e9c5 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -113,7 +113,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("hydradx"), impl_name: create_runtime_str!("hydradx"), authoring_version: 1, - spec_version: 260, + spec_version: 261, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 87afc81f384a5531c201cd90818ea47669fe1f2e Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 4 Oct 2024 07:52:01 +0200 Subject: [PATCH 03/24] formatting --- runtime/adapters/src/price.rs | 20 +++++++++++--------- runtime/hydradx/src/assets.rs | 9 ++++++--- runtime/hydradx/src/evm/evm_fee.rs | 3 ++- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/runtime/adapters/src/price.rs b/runtime/adapters/src/price.rs index c568c129f..df4b53352 100644 --- a/runtime/adapters/src/price.rs +++ b/runtime/adapters/src/price.rs @@ -93,14 +93,13 @@ where let from_currency_is_tx_fee_asset = SwappablePaymentAssetSupport::is_transaction_fee_currency(from_currency); let to_currency_is_tx_fee_asset = SwappablePaymentAssetSupport::is_transaction_fee_currency(to_currency); - if from_currency_is_tx_fee_asset && to_currency_is_tx_fee_asset - { + if from_currency_is_tx_fee_asset && to_currency_is_tx_fee_asset { let price = PriceProv::get_price(to_currency, from_currency)?; let converted = multiply_by_rational_with_rounding(amount, price.n, price.d, Rounding::Up)?; return Some((converted, price)); - } else if !from_currency_is_tx_fee_asset && to_currency_is_tx_fee_asset - { - let amount_in_dot = SwappablePaymentAssetSupport::calculate_out_given_in(from_currency, amount, dot).ok()?; + } else if !from_currency_is_tx_fee_asset && to_currency_is_tx_fee_asset { + let amount_in_dot = + SwappablePaymentAssetSupport::calculate_out_given_in(from_currency, amount, dot).ok()?; let price_between_to_currency_and_dot = PriceProv::get_price(to_currency, dot)?; let amount_in_to_currency = multiply_by_rational_with_rounding( @@ -116,11 +115,14 @@ where }; return Some((amount_in_to_currency, price)); - } else if from_currency_is_tx_fee_asset && !to_currency_is_tx_fee_asset - { + } else if from_currency_is_tx_fee_asset && !to_currency_is_tx_fee_asset { let price_dot_to_from_currency = PriceProv::get_price(dot, from_currency)?; - let amount_in_dot = - multiply_by_rational_with_rounding(amount, price_dot_to_from_currency.n, price_dot_to_from_currency.d, Rounding::Up)?; + let amount_in_dot = multiply_by_rational_with_rounding( + amount, + price_dot_to_from_currency.n, + price_dot_to_from_currency.d, + Rounding::Up, + )?; let amount_in_to_currency = SwappablePaymentAssetSupport::calculate_in_given_out(to_currency, dot, amount_in_dot).ok()?; let price = EmaPrice { diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index 5c20e9cbf..910f10948 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -1781,13 +1781,16 @@ impl SwappablePaymentAssetTrader for XykPaymentAsse .map_err(|_err| ArithmeticError::Overflow.into()) } - - fn calculate_out_given_in(asset_in: AssetId, asset_in_amount: Balance, asset_out: AssetId) -> Result { + fn calculate_out_given_in( + asset_in: AssetId, + asset_in_amount: Balance, + asset_out: AssetId, + ) -> Result { let asset_pair_account = XYK::get_pair_id(AssetPair::new(asset_in, asset_out)); let in_reserve = Currencies::free_balance(asset_in, &asset_pair_account.clone()); let out_reserve = Currencies::free_balance(asset_out, &asset_pair_account); - hydra_dx_math::xyk::calculate_out_given_in(in_reserve,out_reserve, asset_in_amount) + hydra_dx_math::xyk::calculate_out_given_in(in_reserve, out_reserve, asset_in_amount) .map_err(|_err| ArithmeticError::Overflow.into()) } diff --git a/runtime/hydradx/src/evm/evm_fee.rs b/runtime/hydradx/src/evm/evm_fee.rs index 537d3b8f3..d4185e7bc 100644 --- a/runtime/hydradx/src/evm/evm_fee.rs +++ b/runtime/hydradx/src/evm/evm_fee.rs @@ -121,7 +121,8 @@ where return Err(Error::::WithdrawFailed); }; - let Some(eth_dot_price_as_fixed) = FixedU128::checked_from_rational(eth_dot_price.n, eth_dot_price.d) else { + let Some(eth_dot_price_as_fixed) = FixedU128::checked_from_rational(eth_dot_price.n, eth_dot_price.d) + else { return Err(Error::::WithdrawFailed); }; From 061e90ce09209aa806f742b554064a2d5e3f68bb Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 4 Oct 2024 07:54:57 +0200 Subject: [PATCH 04/24] bump versions --- Cargo.lock | 2 +- runtime/adapters/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8e2df769..09f01d2dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4946,7 +4946,7 @@ dependencies = [ [[package]] name = "hydradx-adapters" -version = "1.3.6" +version = "1.3.7" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", diff --git a/runtime/adapters/Cargo.toml b/runtime/adapters/Cargo.toml index a2ceb0eb5..2cec31fd3 100644 --- a/runtime/adapters/Cargo.toml +++ b/runtime/adapters/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-adapters" -version = "1.3.5" +version = "1.3.7" description = "Structs and other generic types for building runtimes." authors = ["GalacticCouncil"] edition = "2021" From dd1133f3af6444706bad01bee166e852b059bb7f Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 4 Oct 2024 07:58:13 +0200 Subject: [PATCH 05/24] bump versions --- Cargo.lock | 6 +++--- integration-tests/Cargo.toml | 2 +- runtime/hydradx/Cargo.toml | 2 +- runtime/hydradx/src/lib.rs | 2 +- traits/Cargo.toml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 09f01d2dd..7522779b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4996,7 +4996,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "261.0.0" +version = "262.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", @@ -5132,7 +5132,7 @@ dependencies = [ [[package]] name = "hydradx-traits" -version = "3.7.1" +version = "3.8.0" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -12259,7 +12259,7 @@ dependencies = [ [[package]] name = "runtime-integration-tests" -version = "1.23.7" +version = "1.23.8" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index a5f2455a2..266bda451 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runtime-integration-tests" -version = "1.23.7" +version = "1.23.8" description = "Integration tests" authors = ["GalacticCouncil"] edition = "2021" diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index ef58b2c8f..1c4e838b9 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "261.0.0" +version = "262.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index 334e65987..e66472652 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -108,7 +108,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("hydradx"), impl_name: create_runtime_str!("hydradx"), authoring_version: 1, - spec_version: 261, + spec_version: 262, impl_version: 0, apis: apis::RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/traits/Cargo.toml b/traits/Cargo.toml index 18e42626c..b02875517 100644 --- a/traits/Cargo.toml +++ b/traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-traits" -version = "3.7.1" +version = "3.8.0" description = "Shared traits" authors = ["GalacticCouncil"] edition = "2021" From b80d2a5175601577e77d2ce5e94db12692b7b888 Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 4 Oct 2024 08:13:59 +0200 Subject: [PATCH 06/24] fix compilation errors --- integration-tests/src/evm_permit.rs | 5 ----- pallets/dca/src/tests/mock.rs | 8 ++++++++ pallets/transaction-multi-payment/src/mock.rs | 8 ++++++++ runtime/hydradx/src/evm/evm_fee.rs | 2 +- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/integration-tests/src/evm_permit.rs b/integration-tests/src/evm_permit.rs index dd1170c9c..eb2cf18fb 100644 --- a/integration-tests/src/evm_permit.rs +++ b/integration-tests/src/evm_permit.rs @@ -1,6 +1,5 @@ #![cfg(test)] -use crate::dca::add_dot_as_payment_currency; use crate::polkadot_test_net::*; use crate::utils::accounts::*; use frame_support::dispatch::GetDispatchInfo; @@ -938,8 +937,6 @@ fn evm_permit_set_currency_dispatch_should_pay_evm_fee_in_insufficient_asset() { #[test] fn convert_amount_should_work_when_converting_insufficient_to_sufficient_asset() { TestNet::reset(); - let user_evm_address = alith_evm_address(); - let user_secret_key = alith_secret_key(); let user_acc = MockAccount::new(alith_truncated_account()); Hydra::execute_with(|| { @@ -1073,8 +1070,6 @@ fn convert_amount_should_work_when_converting_insufficient_to_sufficient_asset() #[test] fn convert_amount_should_work_when_converting_sufficient_to_insufficient_asset() { TestNet::reset(); - let user_evm_address = alith_evm_address(); - let user_secret_key = alith_secret_key(); let user_acc = MockAccount::new(alith_truncated_account()); Hydra::execute_with(|| { diff --git a/pallets/dca/src/tests/mock.rs b/pallets/dca/src/tests/mock.rs index 0b7f8cd1d..3b707e0f9 100644 --- a/pallets/dca/src/tests/mock.rs +++ b/pallets/dca/src/tests/mock.rs @@ -736,6 +736,14 @@ impl SwappablePaymentAssetTrader for MockedInsuffic ) -> Result { unimplemented!() } + + fn calculate_out_given_in( + _asset_in: AssetId, + _asset_in_amount: Balance, + _asset_out: AssetId, + ) -> Result { + unimplemented!() + } } pub struct NativePriceOracleMock; diff --git a/pallets/transaction-multi-payment/src/mock.rs b/pallets/transaction-multi-payment/src/mock.rs index 27d160e2b..61e090773 100644 --- a/pallets/transaction-multi-payment/src/mock.rs +++ b/pallets/transaction-multi-payment/src/mock.rs @@ -215,6 +215,14 @@ impl SwappablePaymentAssetTrader for MockedInsuffic ) -> Result { unimplemented!() } + + fn calculate_out_given_in( + _asset_in: AssetId, + _asset_in_amount: Balance, + _asset_out: AssetId, + ) -> Result { + unimplemented!() + } } pub struct DummyRegistry(sp_std::marker::PhantomData); diff --git a/runtime/hydradx/src/evm/evm_fee.rs b/runtime/hydradx/src/evm/evm_fee.rs index d4185e7bc..ea607bdcd 100644 --- a/runtime/hydradx/src/evm/evm_fee.rs +++ b/runtime/hydradx/src/evm/evm_fee.rs @@ -26,7 +26,7 @@ use hydradx_traits::fee::SwappablePaymentAssetTrader; use hydradx_traits::AccountFeeCurrency; use orml_traits::arithmetic::One; use pallet_evm::{AddressMapping, Error}; -use pallet_transaction_multi_payment::{DepositAll, DepositFee, Pallet}; +use pallet_transaction_multi_payment::{DepositAll, DepositFee}; use primitives::{AccountId, AssetId, Balance}; use sp_runtime::helpers_128bit::multiply_by_rational_with_rounding; use sp_runtime::traits::Convert; From 7ffaff17de79832a2f5a562e7bc6ac3ce98e3675 Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 4 Oct 2024 13:01:40 +0200 Subject: [PATCH 07/24] keep param order consistent --- Cargo.lock | 4 ++-- pallets/dca/Cargo.toml | 2 +- pallets/dca/src/tests/mock.rs | 2 +- pallets/transaction-multi-payment/Cargo.toml | 2 +- pallets/transaction-multi-payment/src/mock.rs | 2 +- runtime/adapters/src/price.rs | 2 +- runtime/hydradx/src/assets.rs | 2 +- traits/src/fee.rs | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7522779b0..8ed49a41d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8045,7 +8045,7 @@ dependencies = [ [[package]] name = "pallet-dca" -version = "1.6.1" +version = "1.6.2" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -9334,7 +9334,7 @@ dependencies = [ [[package]] name = "pallet-transaction-multi-payment" -version = "10.1.1" +version = "10.1.2" dependencies = [ "frame-support", "frame-system", diff --git a/pallets/dca/Cargo.toml b/pallets/dca/Cargo.toml index 03d8fe8ac..eef6231b7 100644 --- a/pallets/dca/Cargo.toml +++ b/pallets/dca/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-dca' -version = "1.6.1" +version = "1.6.2" description = 'A pallet to manage DCA scheduling' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/dca/src/tests/mock.rs b/pallets/dca/src/tests/mock.rs index 3b707e0f9..debb56790 100644 --- a/pallets/dca/src/tests/mock.rs +++ b/pallets/dca/src/tests/mock.rs @@ -739,8 +739,8 @@ impl SwappablePaymentAssetTrader for MockedInsuffic fn calculate_out_given_in( _asset_in: AssetId, - _asset_in_amount: Balance, _asset_out: AssetId, + _asset_in_amount: Balance, ) -> Result { unimplemented!() } diff --git a/pallets/transaction-multi-payment/Cargo.toml b/pallets/transaction-multi-payment/Cargo.toml index 6bc89f94b..76946e34f 100644 --- a/pallets/transaction-multi-payment/Cargo.toml +++ b/pallets/transaction-multi-payment/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-multi-payment" -version = "10.1.1" +version = "10.1.2" description = "Transaction multi currency payment support module" authors = ["GalacticCoucil"] edition = "2021" diff --git a/pallets/transaction-multi-payment/src/mock.rs b/pallets/transaction-multi-payment/src/mock.rs index 61e090773..e4827c81e 100644 --- a/pallets/transaction-multi-payment/src/mock.rs +++ b/pallets/transaction-multi-payment/src/mock.rs @@ -218,8 +218,8 @@ impl SwappablePaymentAssetTrader for MockedInsuffic fn calculate_out_given_in( _asset_in: AssetId, - _asset_in_amount: Balance, _asset_out: AssetId, + _asset_in_amount: Balance, ) -> Result { unimplemented!() } diff --git a/runtime/adapters/src/price.rs b/runtime/adapters/src/price.rs index df4b53352..b96145df2 100644 --- a/runtime/adapters/src/price.rs +++ b/runtime/adapters/src/price.rs @@ -99,7 +99,7 @@ where return Some((converted, price)); } else if !from_currency_is_tx_fee_asset && to_currency_is_tx_fee_asset { let amount_in_dot = - SwappablePaymentAssetSupport::calculate_out_given_in(from_currency, amount, dot).ok()?; + SwappablePaymentAssetSupport::calculate_out_given_in(from_currency, dot, amount).ok()?; let price_between_to_currency_and_dot = PriceProv::get_price(to_currency, dot)?; let amount_in_to_currency = multiply_by_rational_with_rounding( diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index 910f10948..5bcc4d145 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -1783,8 +1783,8 @@ impl SwappablePaymentAssetTrader for XykPaymentAsse fn calculate_out_given_in( asset_in: AssetId, - asset_in_amount: Balance, asset_out: AssetId, + asset_in_amount: Balance, ) -> Result { let asset_pair_account = XYK::get_pair_id(AssetPair::new(asset_in, asset_out)); let in_reserve = Currencies::free_balance(asset_in, &asset_pair_account.clone()); diff --git a/traits/src/fee.rs b/traits/src/fee.rs index a4b0fbd43..1a143aa8b 100644 --- a/traits/src/fee.rs +++ b/traits/src/fee.rs @@ -19,8 +19,8 @@ pub trait SwappablePaymentAssetTrader: InspectTransa fn calculate_out_given_in( asset_in: AssetId, - asset_in_amount: Amount, asset_out: AssetId, + asset_in_amount: Amount, ) -> Result; fn buy( From 2324a0a344fc5cc611dedb9d121e8a493d5c268a Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 4 Oct 2024 13:35:11 +0200 Subject: [PATCH 08/24] make clippy happy --- runtime/adapters/src/price.rs | 2 +- runtime/hydradx/src/evm/evm_fee.rs | 4 ++-- runtime/hydradx/src/evm/mod.rs | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/runtime/adapters/src/price.rs b/runtime/adapters/src/price.rs index b96145df2..c466183ff 100644 --- a/runtime/adapters/src/price.rs +++ b/runtime/adapters/src/price.rs @@ -96,7 +96,7 @@ where if from_currency_is_tx_fee_asset && to_currency_is_tx_fee_asset { let price = PriceProv::get_price(to_currency, from_currency)?; let converted = multiply_by_rational_with_rounding(amount, price.n, price.d, Rounding::Up)?; - return Some((converted, price)); + Some((converted, price)) } else if !from_currency_is_tx_fee_asset && to_currency_is_tx_fee_asset { let amount_in_dot = SwappablePaymentAssetSupport::calculate_out_given_in(from_currency, dot, amount).ok()?; diff --git a/runtime/hydradx/src/evm/evm_fee.rs b/runtime/hydradx/src/evm/evm_fee.rs index ea607bdcd..063c1422c 100644 --- a/runtime/hydradx/src/evm/evm_fee.rs +++ b/runtime/hydradx/src/evm/evm_fee.rs @@ -130,7 +130,7 @@ where .ok_or(Error::::WithdrawFailed)?; let amount_in = - SwappablePaymentAssetSupport::calculate_in_given_out(account_fee_currency, dot, fee_in_dot.into()) + SwappablePaymentAssetSupport::calculate_in_given_out(account_fee_currency, dot, fee_in_dot) .map_err(|_| Error::::WithdrawFailed)?; let pool_fee = SwappablePaymentAssetSupport::calculate_fee_amount(amount_in) .map_err(|_| Error::::WithdrawFailed)?; @@ -140,7 +140,7 @@ where &account_id.clone(), account_fee_currency, dot, - fee_in_dot.into(), + fee_in_dot, max_limit, &account_id.clone(), ) diff --git a/runtime/hydradx/src/evm/mod.rs b/runtime/hydradx/src/evm/mod.rs index 8d1857d21..98515870b 100644 --- a/runtime/hydradx/src/evm/mod.rs +++ b/runtime/hydradx/src/evm/mod.rs @@ -26,7 +26,7 @@ pub use crate::{ evm::accounts_conversion::{ExtendedAddressMapping, FindAuthorTruncated}, AssetLocation, Aura, NORMAL_DISPATCH_RATIO, }; -use crate::{DotAssetId, NativeAssetId, TreasuryAccount, XykPaymentAssetSupport, LRNA}; +use crate::{DotAssetId, NativeAssetId, XykPaymentAssetSupport, LRNA}; pub use fp_evm::GenesisAccount as EvmGenesisAccount; use frame_support::{ parameter_types, @@ -37,7 +37,6 @@ use frame_support::{ use hex_literal::hex; use hydradx_adapters::price::ConvertAmount; use hydradx_adapters::{AssetFeeOraclePriceProvider, OraclePriceProvider}; -use hydradx_traits::fee::SwappablePaymentAssetTrader; use hydradx_traits::oracle::OraclePeriod; use orml_tokens::CurrencyAdapter; use pallet_currencies::fungibles::FungibleCurrencies; From 6722861c38559f186cdbaeeb0c1880a7c8e3e53e Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 18 Oct 2024 15:06:37 +0200 Subject: [PATCH 09/24] remove unnecessary fee in dot calculation as we already do it in conversion --- runtime/hydradx/src/evm/evm_fee.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/runtime/hydradx/src/evm/evm_fee.rs b/runtime/hydradx/src/evm/evm_fee.rs index 063c1422c..e71907616 100644 --- a/runtime/hydradx/src/evm/evm_fee.rs +++ b/runtime/hydradx/src/evm/evm_fee.rs @@ -116,7 +116,8 @@ where (converted, account_fee_currency, price) } else { //In case of insufficient asset we buy DOT with insufficient asset, and using that DOT and amount as fee currency - let Some((_, eth_dot_price)) = C::convert((EvmFeeAsset::get(), dot, fee.unique_saturated_into())) + let Some((fee_in_dot, eth_dot_price)) = + C::convert((EvmFeeAsset::get(), dot, fee.unique_saturated_into())) else { return Err(Error::::WithdrawFailed); }; @@ -126,9 +127,6 @@ where return Err(Error::::WithdrawFailed); }; - let fee_in_dot: Balance = convert_fee_with_price(fee.unique_saturated_into(), eth_dot_price_as_fixed) - .ok_or(Error::::WithdrawFailed)?; - let amount_in = SwappablePaymentAssetSupport::calculate_in_given_out(account_fee_currency, dot, fee_in_dot) .map_err(|_| Error::::WithdrawFailed)?; From 8bccbdbb9674ffe57922772cf8a6fb5c2b7d0486 Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 18 Oct 2024 15:15:21 +0200 Subject: [PATCH 10/24] upgrade lock --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e8c95cc1..286e26e30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5057,7 +5057,7 @@ dependencies = [ [[package]] name = "hydradx-traits" -version = "3.7.2" +version = "3.8.0" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -12197,7 +12197,7 @@ dependencies = [ [[package]] name = "runtime-integration-tests" -version = "1.23.7" +version = "1.23.8" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", From 30409147fba154656c260684c0060e60d4f9dc70 Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 18 Oct 2024 15:19:08 +0200 Subject: [PATCH 11/24] bump versions --- Cargo.lock | 8 ++++---- pallets/dca/Cargo.toml | 2 +- pallets/transaction-multi-payment/Cargo.toml | 2 +- runtime/adapters/Cargo.toml | 2 +- runtime/hydradx/Cargo.toml | 2 +- runtime/hydradx/src/lib.rs | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 286e26e30..453ccae3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4868,7 +4868,7 @@ dependencies = [ [[package]] name = "hydradx-adapters" -version = "1.3.7" +version = "1.3.8" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -4918,7 +4918,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "264.0.0" +version = "265.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", @@ -7983,7 +7983,7 @@ dependencies = [ [[package]] name = "pallet-dca" -version = "1.6.2" +version = "1.6.3" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -9272,7 +9272,7 @@ dependencies = [ [[package]] name = "pallet-transaction-multi-payment" -version = "10.1.2" +version = "10.1.3" dependencies = [ "frame-support", "frame-system", diff --git a/pallets/dca/Cargo.toml b/pallets/dca/Cargo.toml index eef6231b7..29f35f51f 100644 --- a/pallets/dca/Cargo.toml +++ b/pallets/dca/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-dca' -version = "1.6.2" +version = "1.6.3" description = 'A pallet to manage DCA scheduling' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/transaction-multi-payment/Cargo.toml b/pallets/transaction-multi-payment/Cargo.toml index 86163edca..a5c9d5237 100644 --- a/pallets/transaction-multi-payment/Cargo.toml +++ b/pallets/transaction-multi-payment/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-multi-payment" -version = "10.1.2" +version = "10.1.3" description = "Transaction multi currency payment support module" authors = ["GalacticCoucil"] edition = "2021" diff --git a/runtime/adapters/Cargo.toml b/runtime/adapters/Cargo.toml index a7ff45676..86b03463c 100644 --- a/runtime/adapters/Cargo.toml +++ b/runtime/adapters/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-adapters" -version = "1.3.7" +version = "1.3.8" description = "Structs and other generic types for building runtimes." authors = ["GalacticCouncil"] edition = "2021" diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index 2763a8943..52d3801da 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "264.0.0" +version = "265.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index c43d03c37..e7b2b1028 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -112,7 +112,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("hydradx"), impl_name: create_runtime_str!("hydradx"), authoring_version: 1, - spec_version: 264, + spec_version: 265, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From f9a15f58df3fcac3ea160844aa8d8720e8d609fe Mon Sep 17 00:00:00 2001 From: dmoka Date: Tue, 22 Oct 2024 16:43:27 +0200 Subject: [PATCH 12/24] make clippy happy --- runtime/hydradx/src/evm/evm_fee.rs | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/runtime/hydradx/src/evm/evm_fee.rs b/runtime/hydradx/src/evm/evm_fee.rs index e71907616..5a2255b56 100644 --- a/runtime/hydradx/src/evm/evm_fee.rs +++ b/runtime/hydradx/src/evm/evm_fee.rs @@ -24,13 +24,12 @@ use frame_support::traits::{Get, TryDrop}; use hydra_dx_math::ema::EmaPrice; use hydradx_traits::fee::SwappablePaymentAssetTrader; use hydradx_traits::AccountFeeCurrency; -use orml_traits::arithmetic::One; use pallet_evm::{AddressMapping, Error}; use pallet_transaction_multi_payment::{DepositAll, DepositFee}; use primitives::{AccountId, AssetId, Balance}; use sp_runtime::helpers_128bit::multiply_by_rational_with_rounding; use sp_runtime::traits::Convert; -use sp_runtime::{FixedPointNumber, FixedPointOperand, FixedU128, Rounding}; +use sp_runtime::{Rounding}; use sp_std::marker::PhantomData; use { frame_support::traits::OnUnbalanced, @@ -122,11 +121,6 @@ where return Err(Error::::WithdrawFailed); }; - let Some(eth_dot_price_as_fixed) = FixedU128::checked_from_rational(eth_dot_price.n, eth_dot_price.d) - else { - return Err(Error::::WithdrawFailed); - }; - let amount_in = SwappablePaymentAssetSupport::calculate_in_given_out(account_fee_currency, dot, fee_in_dot) .map_err(|_| Error::::WithdrawFailed)?; @@ -244,15 +238,6 @@ where } } } - -fn convert_fee_with_price(fee: B, price: FixedU128) -> Option -where - B: FixedPointOperand + Ord + One, -{ - // Make sure that the fee is never less than 1 - price.checked_mul_int(fee).map(|f| f.max(One::one())) -} - pub struct DepositEvmFeeToTreasury; impl OnUnbalanced> for DepositEvmFeeToTreasury { // this is called for substrate-based transactions From 52266bc5218efb136d3438944a59bc8fdc2a6575 Mon Sep 17 00:00:00 2001 From: dmoka Date: Tue, 22 Oct 2024 16:49:50 +0200 Subject: [PATCH 13/24] formatting --- runtime/hydradx/src/evm/evm_fee.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/hydradx/src/evm/evm_fee.rs b/runtime/hydradx/src/evm/evm_fee.rs index 5a2255b56..f1ce40703 100644 --- a/runtime/hydradx/src/evm/evm_fee.rs +++ b/runtime/hydradx/src/evm/evm_fee.rs @@ -29,7 +29,7 @@ use pallet_transaction_multi_payment::{DepositAll, DepositFee}; use primitives::{AccountId, AssetId, Balance}; use sp_runtime::helpers_128bit::multiply_by_rational_with_rounding; use sp_runtime::traits::Convert; -use sp_runtime::{Rounding}; +use sp_runtime::Rounding; use sp_std::marker::PhantomData; use { frame_support::traits::OnUnbalanced, From 6a92c1d7019ef9c08f90fd70953a28a5ba3972bd Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 28 Oct 2024 10:31:20 +0100 Subject: [PATCH 14/24] update lock file --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66c9de77c..1d1d863fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4868,7 +4868,7 @@ dependencies = [ [[package]] name = "hydradx-adapters" -version = "1.3.7" +version = "1.3.8" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -4918,7 +4918,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "266.0.0" +version = "267.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", @@ -5057,7 +5057,7 @@ dependencies = [ [[package]] name = "hydradx-traits" -version = "3.7.2" +version = "3.8.0" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -7983,7 +7983,7 @@ dependencies = [ [[package]] name = "pallet-dca" -version = "1.6.2" +version = "1.6.3" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -9272,7 +9272,7 @@ dependencies = [ [[package]] name = "pallet-transaction-multi-payment" -version = "10.1.2" +version = "10.1.3" dependencies = [ "frame-support", "frame-system", @@ -12197,7 +12197,7 @@ dependencies = [ [[package]] name = "runtime-integration-tests" -version = "1.23.7" +version = "1.23.8" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", From 470e6ba13e9d7c6a73cec914fb364b461d129fe6 Mon Sep 17 00:00:00 2001 From: dmoka Date: Mon, 28 Oct 2024 14:18:54 +0100 Subject: [PATCH 15/24] incorporate swam in dispatch permits --- integration-tests/src/evm_permit.rs | 2 +- runtime/hydradx/src/evm/permit.rs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/integration-tests/src/evm_permit.rs b/integration-tests/src/evm_permit.rs index d4270e867..fc5bb5349 100644 --- a/integration-tests/src/evm_permit.rs +++ b/integration-tests/src/evm_permit.rs @@ -17,7 +17,7 @@ use hydradx_runtime::AssetRegistry; use hydradx_runtime::DOT_ASSET_LOCATION; use hydradx_runtime::XYK; use hydradx_runtime::{ - Balances, Currencies, DotAssetId, EVMAccounts, MultiTransactionPayment, Omnipool, RuntimeCall, RuntimeOrigin, + Balances, Currencies, DotAssetId, MultiTransactionPayment, Omnipool, RuntimeCall, RuntimeOrigin, Tokens, XykPaymentAssetSupport, }; use hydradx_traits::AssetKind; diff --git a/runtime/hydradx/src/evm/permit.rs b/runtime/hydradx/src/evm/permit.rs index bce544985..256c13c05 100644 --- a/runtime/hydradx/src/evm/permit.rs +++ b/runtime/hydradx/src/evm/permit.rs @@ -16,6 +16,7 @@ use sp_io::hashing::keccak_256; use sp_runtime::traits::{One, UniqueSaturatedInto}; use sp_runtime::DispatchResult; use sp_std::vec::Vec; +use crate::{ExtrinsicBaseWeight}; pub struct EvmPermitHandler(sp_std::marker::PhantomData); @@ -164,7 +165,10 @@ where fn dispatch_weight(gas_limit: u64) -> Weight { let without_base_extrinsic_weight = true; - ::GasWeightMapping::gas_to_weight(gas_limit, without_base_extrinsic_weight) + let weight = ::GasWeightMapping::gas_to_weight(gas_limit, without_base_extrinsic_weight); + + // As GasWeightMapping implementation does not exclude the weight-with-swap (only the frame_system::constants::ExtrinsicBaseWeight), therefore we need to substract it manually + weight.saturating_sub(ExtrinsicBaseWeight::get()) } fn permit_nonce(account: H160) -> U256 { From 8a11813a7c9706011e19570805b153e6979f6b19 Mon Sep 17 00:00:00 2001 From: dmoka Date: Tue, 29 Oct 2024 13:14:45 +0100 Subject: [PATCH 16/24] fix: we need to incporporate the swap with fee here --- integration-tests/src/evm_permit.rs | 4 ++-- runtime/hydradx/src/evm/mod.rs | 2 +- runtime/hydradx/src/evm/permit.rs | 10 ++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/integration-tests/src/evm_permit.rs b/integration-tests/src/evm_permit.rs index fc5bb5349..b6c1eb0bb 100644 --- a/integration-tests/src/evm_permit.rs +++ b/integration-tests/src/evm_permit.rs @@ -17,8 +17,8 @@ use hydradx_runtime::AssetRegistry; use hydradx_runtime::DOT_ASSET_LOCATION; use hydradx_runtime::XYK; use hydradx_runtime::{ - Balances, Currencies, DotAssetId, MultiTransactionPayment, Omnipool, RuntimeCall, RuntimeOrigin, - Tokens, XykPaymentAssetSupport, + Balances, Currencies, DotAssetId, MultiTransactionPayment, Omnipool, RuntimeCall, RuntimeOrigin, Tokens, + XykPaymentAssetSupport, }; use hydradx_traits::AssetKind; use hydradx_traits::Create; diff --git a/runtime/hydradx/src/evm/mod.rs b/runtime/hydradx/src/evm/mod.rs index 71958d408..4febc47e1 100644 --- a/runtime/hydradx/src/evm/mod.rs +++ b/runtime/hydradx/src/evm/mod.rs @@ -164,7 +164,7 @@ impl pallet_evm::Config for crate::Runtime { crate::Runtime, ConvertAmount, FeeCurrencyOverrideOrDefault>, // Get account's fee payment asset - FungibleCurrencies, // Account balance inspector + FungibleCurrencies, // Account balance inspector >, >; type RuntimeEvent = crate::RuntimeEvent; diff --git a/runtime/hydradx/src/evm/permit.rs b/runtime/hydradx/src/evm/permit.rs index 256c13c05..8e23d11ce 100644 --- a/runtime/hydradx/src/evm/permit.rs +++ b/runtime/hydradx/src/evm/permit.rs @@ -1,4 +1,5 @@ use crate::evm::precompiles; +use crate::ExtrinsicBaseWeight; use evm::ExitReason; use fp_evm::FeeCalculator; use frame_support::dispatch::{DispatchErrorWithPostInfo, Pays, PostDispatchInfo, RawOrigin}; @@ -16,7 +17,6 @@ use sp_io::hashing::keccak_256; use sp_runtime::traits::{One, UniqueSaturatedInto}; use sp_runtime::DispatchResult; use sp_std::vec::Vec; -use crate::{ExtrinsicBaseWeight}; pub struct EvmPermitHandler(sp_std::marker::PhantomData); @@ -165,10 +165,12 @@ where fn dispatch_weight(gas_limit: u64) -> Weight { let without_base_extrinsic_weight = true; - let weight = ::GasWeightMapping::gas_to_weight(gas_limit, without_base_extrinsic_weight); + let weight = + ::GasWeightMapping::gas_to_weight(gas_limit, without_base_extrinsic_weight); - // As GasWeightMapping implementation does not exclude the weight-with-swap (only the frame_system::constants::ExtrinsicBaseWeight), therefore we need to substract it manually - weight.saturating_sub(ExtrinsicBaseWeight::get()) + // As GasWeightMapping implementation does not include/exclude the weight-with-swap (only the frame_system::constants::ExtrinsicBaseWeight) + // therefore we need to add it manually here + weight.saturating_add(ExtrinsicBaseWeight::get()) } fn permit_nonce(account: H160) -> U256 { From a942123d2a96f06a4308b6c0803198512bd01245 Mon Sep 17 00:00:00 2001 From: dmoka Date: Fri, 1 Nov 2024 15:44:57 +0100 Subject: [PATCH 17/24] bump runtime version --- Cargo.lock | 2 +- runtime/hydradx/Cargo.toml | 2 +- runtime/hydradx/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d1d863fa..76aee5c77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4918,7 +4918,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "267.0.0" +version = "268.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index d85e28926..19d1e9e3e 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "267.0.0" +version = "268.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index d534c5428..019c18e94 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -111,7 +111,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("hydradx"), impl_name: create_runtime_str!("hydradx"), authoring_version: 1, - spec_version: 267, + spec_version: 268, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 75dfd5d10724c57e0ebce11c653cbe41f5ae1320 Mon Sep 17 00:00:00 2001 From: dmoka Date: Sat, 2 Nov 2024 08:21:50 +0100 Subject: [PATCH 18/24] add debug asserts and checked price creation --- runtime/adapters/src/price.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/runtime/adapters/src/price.rs b/runtime/adapters/src/price.rs index c466183ff..6a0eacf48 100644 --- a/runtime/adapters/src/price.rs +++ b/runtime/adapters/src/price.rs @@ -109,10 +109,9 @@ where Rounding::Up, )?; - let price = EmaPrice { - n: amount_in_to_currency, - d: amount, - }; + debug_assert!(amount_in_to_currency > 0, "amount in to-currency should be positive"); + debug_assert!(amount > 0, "amount in out-currency should be positive"); + let price = EmaPrice::new(amount_in_to_currency, amount); return Some((amount_in_to_currency, price)); } else if from_currency_is_tx_fee_asset && !to_currency_is_tx_fee_asset { @@ -125,10 +124,10 @@ where )?; let amount_in_to_currency = SwappablePaymentAssetSupport::calculate_in_given_out(to_currency, dot, amount_in_dot).ok()?; - let price = EmaPrice { - n: amount_in_to_currency, - d: amount, - }; + + debug_assert!(amount_in_to_currency > 0, "amount in to-currency should be positive"); + debug_assert!(amount > 0, "amount in out-currency should be positive"); + let price = EmaPrice::new(amount_in_to_currency, amount); Some((amount_in_to_currency, price)) } else { //Not supported when both asset is insufficient asset From 4bcbfd134faaf16ba6da9c81ae87120ade9fd455 Mon Sep 17 00:00:00 2001 From: dmoka Date: Sat, 2 Nov 2024 08:22:48 +0100 Subject: [PATCH 19/24] replace dot variable creation to optimize its usage --- runtime/hydradx/src/evm/evm_fee.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime/hydradx/src/evm/evm_fee.rs b/runtime/hydradx/src/evm/evm_fee.rs index ee3eff89d..c29d5861b 100644 --- a/runtime/hydradx/src/evm/evm_fee.rs +++ b/runtime/hydradx/src/evm/evm_fee.rs @@ -104,8 +104,6 @@ where let account_id = T::AddressMapping::into_account_id(*who); let account_fee_currency = AccountCurrency::get(&account_id); - let dot = DotAssetId::get(); - let (converted, fee_currency, price) = if SwappablePaymentAssetSupport::is_transaction_fee_currency(account_fee_currency) { let Some((converted, price)) = @@ -116,6 +114,7 @@ where (converted, account_fee_currency, price) } else { //In case of insufficient asset we buy DOT with insufficient asset, and using that DOT and amount as fee currency + let dot = DotAssetId::get(); let Some((fee_in_dot, eth_dot_price)) = C::convert((EvmFeeAsset::get(), dot, fee.unique_saturated_into())) else { From eec7342eafb0a3d31241f9fc6cb03041d579ff19 Mon Sep 17 00:00:00 2001 From: dmoka Date: Sat, 2 Nov 2024 08:25:23 +0100 Subject: [PATCH 20/24] fix generic type name to stay consistent, as we pass Balance unsighed type there in runtime --- traits/src/fee.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/traits/src/fee.rs b/traits/src/fee.rs index 1a143aa8b..40db4bd2c 100644 --- a/traits/src/fee.rs +++ b/traits/src/fee.rs @@ -6,29 +6,29 @@ pub trait InspectTransactionFeeCurrency { } ///Enabling trading of assets that are swappable but not part of AcceptedCurrencies of multi payment pallet -pub trait SwappablePaymentAssetTrader: InspectTransactionFeeCurrency { +pub trait SwappablePaymentAssetTrader: InspectTransactionFeeCurrency { fn is_trade_supported(from: AssetId, into: AssetId) -> bool; - fn calculate_fee_amount(swap_amount: Amount) -> Result; + fn calculate_fee_amount(swap_amount: Balance) -> Result; fn calculate_in_given_out( insuff_asset_id: AssetId, asset_out: AssetId, - asset_out_amount: Amount, - ) -> Result; + asset_out_amount: Balance, + ) -> Result; fn calculate_out_given_in( asset_in: AssetId, asset_out: AssetId, - asset_in_amount: Amount, - ) -> Result; + asset_in_amount: Balance, + ) -> Result; fn buy( origin: &AccountId, asset_in: AssetId, asset_out: AssetId, - amount: Amount, - max_limit: Amount, + amount: Balance, + max_limit: Balance, dest: &AccountId, ) -> DispatchResult; } From fba6af4cce05b4949d05d968906cab62dc40914f Mon Sep 17 00:00:00 2001 From: dmoka Date: Sat, 2 Nov 2024 08:25:53 +0100 Subject: [PATCH 21/24] simplify code --- runtime/adapters/src/price.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime/adapters/src/price.rs b/runtime/adapters/src/price.rs index 6a0eacf48..26fb6adf2 100644 --- a/runtime/adapters/src/price.rs +++ b/runtime/adapters/src/price.rs @@ -57,8 +57,7 @@ where price_weight.saturating_accrue(pallet_ema_oracle::Pallet::::get_price_weight().saturating_mul(2)); //2 reads as we are checking if from and to assets are transaction fee currencies - let is_transaction_fee_currency_check_weight = T::DbWeight::get().reads(2); - price_weight.saturating_accrue(is_transaction_fee_currency_check_weight); + price_weight.saturating_accrue(T::DbWeight::get().reads(2)); let Some((converted, _)) = C::convert((from_currency, to_currency, account_balance)) else { return (0, price_weight); From 0bf3031a12de3076859157189c40aec43159962d Mon Sep 17 00:00:00 2001 From: dmoka Date: Sat, 2 Nov 2024 08:27:59 +0100 Subject: [PATCH 22/24] fix naming --- integration-tests/src/evm_permit.rs | 7 +++---- runtime/adapters/src/price.rs | 4 ++-- runtime/hydradx/src/evm/mod.rs | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/integration-tests/src/evm_permit.rs b/integration-tests/src/evm_permit.rs index b6c1eb0bb..e2a0f496f 100644 --- a/integration-tests/src/evm_permit.rs +++ b/integration-tests/src/evm_permit.rs @@ -10,7 +10,7 @@ use frame_support::traits::Contains; use frame_support::{assert_noop, assert_ok, sp_runtime::codec::Encode}; use frame_system::RawOrigin; use hydra_dx_math::types::Ratio; -use hydradx_adapters::price::ConvertAmount; +use hydradx_adapters::price::ConvertBalance; use hydradx_runtime::evm::precompiles::{CALLPERMIT, DISPATCH_ADDR}; use hydradx_runtime::types::ShortOraclePrice; use hydradx_runtime::AssetRegistry; @@ -911,9 +911,8 @@ fn convert_amount_should_work_when_converting_insufficient_to_sufficient_asset() false )); - // //Convert insufficient to sufficient (WETH) - type Convert = ConvertAmount; + type Convert = ConvertBalance; let insufficient_amount = 10 * UNITS; let amount_in_weth = Convert::convert((insufficient_asset, WETH, insufficient_amount)).unwrap(); @@ -1045,7 +1044,7 @@ fn convert_amount_should_work_when_converting_sufficient_to_insufficient_asset() )); //Convert sufficient (WETH) to insufficient - type Convert = ConvertAmount; + type Convert = ConvertBalance; let weth_amount = 10 * UNITS; let amount_in_insufficient_asset = Convert::convert((WETH, insufficient_asset, weth_amount)).unwrap(); diff --git a/runtime/adapters/src/price.rs b/runtime/adapters/src/price.rs index 26fb6adf2..0b13874c2 100644 --- a/runtime/adapters/src/price.rs +++ b/runtime/adapters/src/price.rs @@ -66,7 +66,7 @@ where } } -pub struct ConvertAmount( +pub struct ConvertBalance( sp_std::marker::PhantomData<(PriceProv, SwappablePaymentAssetSupport, DotAssetId)>, ); @@ -76,7 +76,7 @@ pub struct ConvertAmount( // Output: Option<(converted_amount, price)> impl Convert<(AssetId, AssetId, Balance), Option<(Balance, EmaPrice)>> - for crate::price::ConvertAmount + for crate::price::ConvertBalance where PriceProv: PriceProvider, SwappablePaymentAssetSupport: SwappablePaymentAssetTrader, diff --git a/runtime/hydradx/src/evm/mod.rs b/runtime/hydradx/src/evm/mod.rs index 4febc47e1..7aa1684e4 100644 --- a/runtime/hydradx/src/evm/mod.rs +++ b/runtime/hydradx/src/evm/mod.rs @@ -36,7 +36,7 @@ use frame_support::{ ConsensusEngineId, }; use hex_literal::hex; -use hydradx_adapters::price::ConvertAmount; +use hydradx_adapters::price::ConvertBalance; use hydradx_adapters::{AssetFeeOraclePriceProvider, OraclePriceProvider}; use hydradx_traits::oracle::OraclePeriod; use orml_tokens::CurrencyAdapter; @@ -149,7 +149,7 @@ impl pallet_evm::Config for crate::Runtime { evm_fee::DepositEvmFeeToTreasury, FeeCurrencyOverrideOrDefault>, // Get account's fee payment asset WethAssetId, - ConvertAmount, + ConvertBalance, FungibleCurrencies, // Multi currency support XykPaymentAssetSupport, DotAssetId, @@ -162,7 +162,7 @@ impl pallet_evm::Config for crate::Runtime { pallet_evm::runner::stack::Runner, // Evm runner that we wrap hydradx_adapters::price::FeeAssetBalanceInCurrency< crate::Runtime, - ConvertAmount, + ConvertBalance, FeeCurrencyOverrideOrDefault>, // Get account's fee payment asset FungibleCurrencies, // Account balance inspector >, From 13b278312e5f3a4ae5b98481c00724f961b05d71 Mon Sep 17 00:00:00 2001 From: dmoka Date: Sat, 2 Nov 2024 08:31:52 +0100 Subject: [PATCH 23/24] update lock --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e16bf2df7..a61025b84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4868,7 +4868,7 @@ dependencies = [ [[package]] name = "hydradx-adapters" -version = "1.3.7" +version = "1.3.8" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -5057,7 +5057,7 @@ dependencies = [ [[package]] name = "hydradx-traits" -version = "3.7.3" +version = "3.8.0" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -7983,7 +7983,7 @@ dependencies = [ [[package]] name = "pallet-dca" -version = "1.6.2" +version = "1.6.3" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -9273,7 +9273,7 @@ dependencies = [ [[package]] name = "pallet-transaction-multi-payment" -version = "10.1.2" +version = "10.1.3" dependencies = [ "frame-support", "frame-system", @@ -12199,7 +12199,7 @@ dependencies = [ [[package]] name = "runtime-integration-tests" -version = "1.24.0" +version = "1.24.1" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", From bb63fb1883db23d7d19fa8edc86566ec8eb28162 Mon Sep 17 00:00:00 2001 From: dmoka Date: Sat, 2 Nov 2024 08:32:31 +0100 Subject: [PATCH 24/24] bump runtime version --- Cargo.lock | 2 +- runtime/hydradx/Cargo.toml | 2 +- runtime/hydradx/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a61025b84..d01f376d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4918,7 +4918,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "268.0.0" +version = "269.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index 19d1e9e3e..ffbeaf18f 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "268.0.0" +version = "269.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index 019c18e94..a401efa91 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -111,7 +111,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("hydradx"), impl_name: create_runtime_str!("hydradx"), authoring_version: 1, - spec_version: 268, + spec_version: 269, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1,