Skip to content

Commit

Permalink
Optimised calculation of evm fee (#1434)
Browse files Browse the repository at this point in the history
* Optimised calculation of evm fee

* Update gas_fee_price to weth_price
  • Loading branch information
hqwangningbo authored Sep 23, 2024
1 parent 7d34b0f commit 394f729
Show file tree
Hide file tree
Showing 23 changed files with 215 additions and 473 deletions.
8 changes: 4 additions & 4 deletions pallets/fee-share/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ mod benchmarking;

pub mod weights;

use bifrost_primitives::{CurrencyId, DistributionId, Price, PriceFeeder};
use bifrost_primitives::{CurrencyId, DistributionId, OraclePriceProvider, Price};
use frame_support::{
pallet_prelude::*,
sp_runtime::{
Expand Down Expand Up @@ -102,7 +102,7 @@ pub mod pallet {
type FeeSharePalletId: Get<PalletId>;

/// The oracle price feeder
type PriceFeeder: PriceFeeder;
type OraclePriceProvider: OraclePriceProvider;
}

#[pallet::event]
Expand Down Expand Up @@ -492,8 +492,8 @@ pub mod pallet {
}

pub fn get_price(currency_id: CurrencyIdOf<T>) -> Result<Price, DispatchError> {
let (price, _) =
T::PriceFeeder::get_price(&currency_id).ok_or(Error::<T>::PriceOracleNotReady)?;
let (price, _) = T::OraclePriceProvider::get_price(&currency_id)
.ok_or(Error::<T>::PriceOracleNotReady)?;
log::trace!(
target: "fee-share::get_price", "price: {:?}", price.into_inner()
);
Expand Down
12 changes: 4 additions & 8 deletions pallets/fee-share/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ impl bifrost_fee_share::Config for Runtime {
type ControlOrigin = EnsureSignedBy<One, AccountId>;
type WeightInfo = ();
type FeeSharePalletId = FeeSharePalletId;
type PriceFeeder = MockPriceFeeder;
type OraclePriceProvider = MockOraclePriceProvider;
}

impl pallet_prices::Config for Runtime {
Expand Down Expand Up @@ -224,7 +224,7 @@ impl DataFeeder<CurrencyId, TimeStampedPrice, AccountId> for MockDataProvider {
Ok(())
}
}
pub struct MockPriceFeeder;
pub struct MockOraclePriceProvider;
#[derive(Encode, Decode, Clone, Copy, RuntimeDebug)]
pub struct CurrencyIdWrap(CurrencyId);

Expand All @@ -242,7 +242,7 @@ impl PartialEq for CurrencyIdWrap {

impl Eq for CurrencyIdWrap {}

impl MockPriceFeeder {
impl MockOraclePriceProvider {
thread_local! {
pub static PRICES: RefCell<HashMap<CurrencyIdWrap, Option<PriceDetail>>> = {
RefCell::new(
Expand All @@ -269,15 +269,11 @@ impl MockPriceFeeder {
}
}

impl PriceFeeder for MockPriceFeeder {
impl OraclePriceProvider for MockOraclePriceProvider {
fn get_price(asset_id: &CurrencyId) -> Option<PriceDetail> {
Self::PRICES.with(|prices| *prices.borrow().get(&CurrencyIdWrap(*asset_id)).unwrap())
}

fn get_normal_price(_asset_id: &CurrencyId) -> Option<u128> {
todo!()
}

fn get_amount_by_prices(
_currency_in: &CurrencyId,
_amount_in: bifrost_primitives::Balance,
Expand Down
6 changes: 3 additions & 3 deletions pallets/flexible-fee/src/impls/on_charge_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::{Config, ExtraFeeByCall, Pallet};
use bifrost_primitives::{Balance, CurrencyId, Price, PriceFeeder, BNC};
use bifrost_primitives::{Balance, CurrencyId, OraclePriceProvider, Price, BNC};
use orml_traits::MultiCurrency;
use pallet_transaction_payment::OnChargeTransaction;
use parity_scale_codec::Encode;
Expand Down Expand Up @@ -124,7 +124,7 @@ where
),
PaymentInfo::NonNative(paid_fee, fee_currency, bnc_price, fee_currency_price) => {
// calculate corrected_fee in the non-native currency
let converted_corrected_fee = T::PriceFeeder::get_amount_by_prices(
let converted_corrected_fee = T::OraclePriceProvider::get_amount_by_prices(
&BNC,
corrected_fee,
bnc_price,
Expand All @@ -133,7 +133,7 @@ where
)
.ok_or(TransactionValidityError::Invalid(InvalidTransaction::Payment))?;
let refund = paid_fee.saturating_sub(converted_corrected_fee);
let converted_tip = T::PriceFeeder::get_amount_by_prices(
let converted_tip = T::OraclePriceProvider::get_amount_by_prices(
&BNC,
tip,
bnc_price,
Expand Down
8 changes: 4 additions & 4 deletions pallets/flexible-fee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub use crate::pallet::*;
use bifrost_primitives::{
currency::{VGLMR, VMANTA, WETH},
traits::XcmDestWeightAndFeeHandler,
Balance, BalanceCmp, CurrencyId, DerivativeIndex, Price, PriceFeeder, TryConvertFrom,
Balance, BalanceCmp, CurrencyId, DerivativeIndex, OraclePriceProvider, Price, TryConvertFrom,
XcmOperationType, BNC, DOT, GLMR, MANTA, VBNC, VDOT,
};
use bifrost_xcm_interface::{polkadot::RelaychainCall, traits::parachains, PolkadotXcmCall};
Expand Down Expand Up @@ -74,7 +74,7 @@ pub enum TargetChain {
#[frame_support::pallet]
pub mod pallet {
use super::*;
use bifrost_primitives::{Balance, PriceFeeder};
use bifrost_primitives::{Balance, OraclePriceProvider};
use frame_support::traits::fungibles::Inspect;

#[pallet::config]
Expand All @@ -91,7 +91,7 @@ pub mod pallet {
/// Zenlink interface
type DexOperator: ExportZenlink<Self::AccountId, AssetId>;
/// The oracle price feeder
type PriceFeeder: PriceFeeder;
type OraclePriceProvider: OraclePriceProvider;
/// The only origin that can set universal fee currency order list
type ControlOrigin: EnsureOrigin<Self::RuntimeOrigin>;
/// Get the weight and fee for executing Xcm.
Expand Down Expand Up @@ -389,7 +389,7 @@ impl<T: Config> Pallet<T> {
}
} else {
let (fee_amount, price_in, price_out) =
T::PriceFeeder::get_oracle_amount_by_currency_and_amount_in(
T::OraclePriceProvider::get_oracle_amount_by_currency_and_amount_in(
&BNC,
fee_amount,
&currency_id,
Expand Down
4 changes: 2 additions & 2 deletions pallets/flexible-fee/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#![cfg(test)]

use super::*;
use crate::{self as flexible_fee, mock_price::MockPriceFeeder};
use crate::{self as flexible_fee, mock_price::MockOraclePriceProvider};
use bifrost_currencies::BasicCurrencyAdapter;
use bifrost_primitives::{Balance, CurrencyId, TokenSymbol};
use cumulus_primitives_core::ParaId as Pid;
Expand Down Expand Up @@ -167,7 +167,7 @@ impl crate::Config for Test {
type RelaychainCurrencyId = RelayCurrencyId;
type XcmRouter = ();
type PalletId = FlexibleFeePalletId;
type PriceFeeder = MockPriceFeeder;
type OraclePriceProvider = MockOraclePriceProvider;
}

pub struct XcmDestWeightAndFee;
Expand Down
48 changes: 28 additions & 20 deletions pallets/flexible-fee/src/mock_price.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
#![cfg(test)]

use bifrost_primitives::{
Balance, CurrencyId, Price, PriceDetail, PriceFeeder, BNC, DOT, DOT_U, KSM, MANTA, VDOT, VKSM,
WETH,
Balance, CurrencyId, OraclePriceProvider, Price, PriceDetail, BNC, DOT, DOT_U, KSM, MANTA,
VDOT, VKSM, WETH,
};
use frame_support::parameter_types;
use sp_runtime::FixedU128;
Expand All @@ -39,8 +39,8 @@ parameter_types! {
]);
}

pub struct MockPriceFeeder;
impl MockPriceFeeder {
pub struct MockOraclePriceProvider;
impl MockOraclePriceProvider {
pub fn set_price(currency_id: CurrencyId, price: Price) {
let mut storage_price = StoragePrice::get();
match storage_price.get(&currency_id) {
Expand All @@ -55,18 +55,14 @@ impl MockPriceFeeder {
}
}

impl PriceFeeder for MockPriceFeeder {
impl OraclePriceProvider for MockOraclePriceProvider {
fn get_price(currency_id: &CurrencyId) -> Option<PriceDetail> {
match StoragePrice::get().get(currency_id) {
Some((price, _)) => Some((*price, 0)),
None => None,
}
}

fn get_normal_price(_asset_id: &CurrencyId) -> Option<u128> {
todo!()
}

fn get_amount_by_prices(
currency_in: &CurrencyId,
amount_in: Balance,
Expand Down Expand Up @@ -119,14 +115,14 @@ mod test {
#[test]
fn set_price() {
assert_eq!(
MockPriceFeeder::get_price(&BNC),
MockOraclePriceProvider::get_price(&BNC),
Some((FixedU128::from_inner(200_000_000_000_000_000), 0))
);
MockPriceFeeder::set_price(BNC, FixedU128::from(100));
assert_eq!(MockPriceFeeder::get_price(&BNC), Some((FixedU128::from(100), 0)));
MockOraclePriceProvider::set_price(BNC, FixedU128::from(100));
assert_eq!(MockOraclePriceProvider::get_price(&BNC), Some((FixedU128::from(100), 0)));

MockPriceFeeder::set_price(DOT, FixedU128::from(100));
assert_eq!(MockPriceFeeder::get_price(&DOT), Some((FixedU128::from(100), 0)));
MockOraclePriceProvider::set_price(DOT, FixedU128::from(100));
assert_eq!(MockOraclePriceProvider::get_price(&DOT), Some((FixedU128::from(100), 0)));
}

#[test]
Expand All @@ -137,31 +133,43 @@ mod test {
let usdt_amount = 20 * 10u128.pow(6);
let manta_amount = 25 * 10u128.pow(18);
assert_eq!(
MockPriceFeeder::get_oracle_amount_by_currency_and_amount_in(&BNC, bnc_amount, &DOT),
MockOraclePriceProvider::get_oracle_amount_by_currency_and_amount_in(
&BNC, bnc_amount, &DOT
),
Some((dot_amount, FixedU128::from_inner(200_000_000_000_000_000), FixedU128::from(5)))
);
assert_eq!(
MockPriceFeeder::get_oracle_amount_by_currency_and_amount_in(&BNC, bnc_amount, &DOT_U),
MockOraclePriceProvider::get_oracle_amount_by_currency_and_amount_in(
&BNC, bnc_amount, &DOT_U
),
Some((usdt_amount, FixedU128::from_inner(200_000_000_000_000_000), FixedU128::from(1)))
);
assert_eq!(
MockPriceFeeder::get_oracle_amount_by_currency_and_amount_in(&BNC, bnc_amount, &KSM),
MockOraclePriceProvider::get_oracle_amount_by_currency_and_amount_in(
&BNC, bnc_amount, &KSM
),
Some((ksm_amount, FixedU128::from_inner(200_000_000_000_000_000), FixedU128::from(20)))
);
assert_eq!(
MockPriceFeeder::get_oracle_amount_by_currency_and_amount_in(&BNC, bnc_amount, &MANTA),
MockOraclePriceProvider::get_oracle_amount_by_currency_and_amount_in(
&BNC, bnc_amount, &MANTA
),
Some((
manta_amount,
FixedU128::from_inner(200_000_000_000_000_000),
FixedU128::from_inner(800_000_000_000_000_000)
))
);
assert_eq!(
MockPriceFeeder::get_oracle_amount_by_currency_and_amount_in(&DOT, dot_amount, &DOT_U),
MockOraclePriceProvider::get_oracle_amount_by_currency_and_amount_in(
&DOT, dot_amount, &DOT_U
),
Some((usdt_amount, FixedU128::from(5), FixedU128::from(1)))
);
assert_eq!(
MockPriceFeeder::get_oracle_amount_by_currency_and_amount_in(&DOT, dot_amount, &KSM),
MockOraclePriceProvider::get_oracle_amount_by_currency_and_amount_in(
&DOT, dot_amount, &KSM
),
Some((ksm_amount, FixedU128::from(5), FixedU128::from(20)))
);
}
Expand Down
6 changes: 3 additions & 3 deletions pallets/lend-market/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use core::cmp::max;

pub use crate::rate_model::*;
use bifrost_primitives::{
Balance, CurrencyId, Liquidity, Price, PriceFeeder, Rate, Ratio, Shortfall, Timestamp,
Balance, CurrencyId, Liquidity, OraclePriceProvider, Price, Rate, Ratio, Shortfall, Timestamp,
};
use frame_support::{
pallet_prelude::*,
Expand Down Expand Up @@ -103,7 +103,7 @@ pub mod pallet {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

/// The oracle price feeder
type PriceFeeder: PriceFeeder;
type OraclePriceProvider: OraclePriceProvider;

/// The loan's module id, keep all collaterals of CDPs.
#[pallet::constant]
Expand Down Expand Up @@ -1959,7 +1959,7 @@ impl<T: Config> Pallet<T> {
// Returns `Err` if the oracle price not ready
pub fn get_price(asset_id: AssetIdOf<T>) -> Result<Price, DispatchError> {
let (price, _) =
T::PriceFeeder::get_price(&asset_id).ok_or(Error::<T>::PriceOracleNotReady)?;
T::OraclePriceProvider::get_price(&asset_id).ok_or(Error::<T>::PriceOracleNotReady)?;
if price.is_zero() {
return Err(Error::<T>::PriceIsZero.into());
}
Expand Down
12 changes: 4 additions & 8 deletions pallets/lend-market/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ impl SortedMembers<AccountId> for AliceCreatePoolOrigin {
}
}

pub struct MockPriceFeeder;
pub struct MockOraclePriceProvider;
#[derive(Encode, Decode, Clone, Copy, RuntimeDebug)]
pub struct CurrencyIdWrap(CurrencyId);

Expand All @@ -223,7 +223,7 @@ impl PartialEq for CurrencyIdWrap {

impl Eq for CurrencyIdWrap {}

impl MockPriceFeeder {
impl MockOraclePriceProvider {
thread_local! {
pub static PRICES: RefCell<HashMap<CurrencyIdWrap, Option<PriceDetail>>> = {
RefCell::new(
Expand All @@ -250,15 +250,11 @@ impl MockPriceFeeder {
}
}

impl PriceFeeder for MockPriceFeeder {
impl OraclePriceProvider for MockOraclePriceProvider {
fn get_price(asset_id: &CurrencyId) -> Option<PriceDetail> {
Self::PRICES.with(|prices| *prices.borrow().get(&CurrencyIdWrap(*asset_id)).unwrap())
}

fn get_normal_price(_asset_id: &CurrencyId) -> Option<u128> {
todo!()
}

fn get_amount_by_prices(
_currency_in: &CurrencyId,
_amount_in: Balance,
Expand Down Expand Up @@ -327,7 +323,7 @@ parameter_types! {

impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type PriceFeeder = MockPriceFeeder;
type OraclePriceProvider = MockOraclePriceProvider;
type PalletId = LendMarketPalletId;
type ReserveOrigin = EnsureRoot<AccountId>;
type UpdateOrigin = EnsureRoot<AccountId>;
Expand Down
10 changes: 5 additions & 5 deletions pallets/lend-market/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ fn get_account_liquidation_threshold_liquidity_works() {
assert_eq!(liquidity, FixedU128::from_inner(unit(20)));
assert_eq!(lf_liquidity, FixedU128::from_inner(unit(10)));

MockPriceFeeder::set_price(KSM, 2.into());
MockOraclePriceProvider::set_price(KSM, 2.into());
let (liquidity, shortfall, lf_liquidity, _) =
LendMarket::get_account_liquidation_threshold_liquidity(&ALICE).unwrap();

Expand Down Expand Up @@ -1259,10 +1259,10 @@ fn get_price_works() {
BNC,
vec![DOT, BNC, KSM, DOT_U, PHA]
));
MockPriceFeeder::set_price(DOT, 0.into());
MockOraclePriceProvider::set_price(DOT, 0.into());
assert_noop!(LendMarket::get_price(DOT), Error::<Test>::PriceIsZero);

MockPriceFeeder::set_price(DOT, 2.into());
MockOraclePriceProvider::set_price(DOT, 2.into());
assert_eq!(LendMarket::get_price(DOT).unwrap(), Price::saturating_from_integer(2));
})
}
Expand Down Expand Up @@ -1813,7 +1813,7 @@ fn reward_calculation_after_liquidate_borrow_works() {
assert_eq!(almost_equal(RewardAccrued::<Test>::get(ALICE), unit(14)), true);
assert_eq!(almost_equal(RewardAccrued::<Test>::get(BOB), unit(16)), true);

MockPriceFeeder::set_price(KSM, 2.into());
MockOraclePriceProvider::set_price(KSM, 2.into());
// since we set liquidate_threshold more than collateral_factor,with KSM price as 2 alice
// not shortfall yet. so we can not liquidate_borrow here
assert_noop!(
Expand All @@ -1828,7 +1828,7 @@ fn reward_calculation_after_liquidate_borrow_works() {
// Bob KSM Deposit: 500
// Bob KSM Borrow: 75
// incentive_reward_account DOT Deposit: 75*0.03 = 2.25
MockPriceFeeder::set_price(KSM, 3.into());
MockOraclePriceProvider::set_price(KSM, 3.into());
assert_ok!(LendMarket::liquidate_borrow(
RuntimeOrigin::signed(BOB),
ALICE,
Expand Down
2 changes: 1 addition & 1 deletion pallets/lend-market/src/tests/interest_rate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ fn accrue_interest_works_after_liquidate_borrow() {
assert_eq!(BorrowIndex::<Test>::get(KSM), Rate::one());
TimestampPallet::set_timestamp(12000);
// Adjust KSM price to make shortfall
MockPriceFeeder::set_price(KSM, 2.into());
MockOraclePriceProvider::set_price(KSM, 2.into());
// BOB repay the KSM loan and get DOT callateral from ALICE
assert_ok!(LendMarket::liquidate_borrow(
RuntimeOrigin::signed(BOB),
Expand Down
Loading

0 comments on commit 394f729

Please sign in to comment.