Skip to content

Commit

Permalink
Merge pull request #773 from galacticcouncil/oracle_with_sufficient_a…
Browse files Browse the repository at this point in the history
…ssets

feat: disable oracle for insufficient assets
  • Loading branch information
mrq1911 authored Feb 29, 2024
2 parents 6e63cb3 + f6e8c47 commit eba70d1
Show file tree
Hide file tree
Showing 23 changed files with 276 additions and 30 deletions.
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "runtime-integration-tests"
version = "1.19.4"
version = "1.19.5"
description = "Integration tests"
authors = ["GalacticCouncil"]
edition = "2021"
Expand Down
4 changes: 2 additions & 2 deletions integration-tests/src/cross_chain_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ fn hydra_should_receive_asset_when_transferred_from_acala_to_eth_address() {
));
// Assert
assert_eq!(
hydradx_runtime::Balances::free_balance(&AccountId::from(ALICE)),
hydradx_runtime::Balances::free_balance(AccountId::from(ALICE)),
ALICE_INITIAL_NATIVE_BALANCE - amount
);
});
Expand Down Expand Up @@ -259,7 +259,7 @@ fn hydra_should_receive_asset_when_transferred_from_acala_to_same_address_repres

// Assert
assert_eq!(
hydradx_runtime::Balances::free_balance(&AccountId::from(ALICE)),
hydradx_runtime::Balances::free_balance(AccountId::from(ALICE)),
ALICE_INITIAL_NATIVE_BALANCE - 2 * amount
);
});
Expand Down
4 changes: 2 additions & 2 deletions integration-tests/src/dca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3398,11 +3398,11 @@ pub fn init_stableswap_with_three_assets_having_different_decimals(
initial.push(AssetAmount::new(asset_id, initial_liquidity));
added_liquidity.push(AssetAmount::new(asset_id, liquidity_added));
}
let pool_id = AssetRegistry::register_insufficient_asset(
let pool_id = AssetRegistry::register_sufficient_asset(
None,
Some(b"pool".to_vec().try_into().unwrap()),
AssetKind::Token,
Some(1u128),
1u128,
None,
None,
None,
Expand Down
1 change: 0 additions & 1 deletion integration-tests/src/exchange_asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ use xcm_emulator::TestExt;
pub const SELL: bool = true;
pub const BUY: bool = false;

pub const HDX: u32 = CORE_ASSET_ID;
pub const ACA: u32 = 1234;
pub const GLMR: u32 = 4567;
pub const IBTC: u32 = 7890;
Expand Down
53 changes: 52 additions & 1 deletion integration-tests/src/oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use hydradx_traits::{
};

use pallet_ema_oracle::OracleError;
use primitives::constants::chain::OMNIPOOL_SOURCE;
use primitives::constants::chain::{OMNIPOOL_SOURCE, XYK_SOURCE};
use xcm_emulator::TestExt;

pub fn hydradx_run_to_block(to: BlockNumber) {
Expand Down Expand Up @@ -141,3 +141,54 @@ fn omnipool_hub_asset_trades_are_ingested_into_oracle() {
}
});
}

#[test]
fn xyk_trades_with_insufficient_asset_are_not_tracked_by_oracle() {
TestNet::reset();

Hydra::execute_with(|| {
// arrange
hydradx_run_to_next_block();

assert_ok!(hydradx_runtime::Tokens::mint_into(
INSUFFICIENT_ASSET,
&ALICE.into(),
200 * UNITS,
));

assert_ok!(hydradx_runtime::XYK::create_pool(
RuntimeOrigin::signed(ALICE.into()),
HDX,
100 * UNITS,
INSUFFICIENT_ASSET,
100 * UNITS,
));

assert_ok!(hydradx_runtime::XYK::buy(
RuntimeOrigin::signed(ALICE.into()),
HDX,
INSUFFICIENT_ASSET,
2 * UNITS,
200 * UNITS,
false,
));

// act
// will store the data received in the sell as oracle values
hydradx_run_to_next_block();

// assert
for supported_period in SUPPORTED_PERIODS {
assert_eq!(
EmaOracle::get_price(HDX, INSUFFICIENT_ASSET, *supported_period, XYK_SOURCE),
Err(OracleError::NotPresent)
);
}
for unsupported_period in UNSUPPORTED_PERIODS {
assert_eq!(
EmaOracle::get_price(HDX, INSUFFICIENT_ASSET, *unsupported_period, XYK_SOURCE),
Err(OracleError::NotPresent)
);
}
});
}
2 changes: 2 additions & 0 deletions integration-tests/src/polkadot_test_net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ pub const BTC: AssetId = 5;
pub const ACA: AssetId = 6;
pub const WETH: AssetId = 20;
pub const PEPE: AssetId = 420;
pub const INSUFFICIENT_ASSET: AssetId = 500;

pub const NOW: Moment = 1689844300000; // unix time in milliseconds

Expand Down Expand Up @@ -479,6 +480,7 @@ pub mod hydra {
None,
true,
),
(Some(INSUFFICIENT_ASSET), None, 1_000u128, None, None, None, false),
// workaround for next_asset_id() to return correct values
(
None,
Expand Down
2 changes: 1 addition & 1 deletion pallets/dca/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = 'pallet-dca'
version = "1.3.5"
version = "1.3.6"
description = 'A pallet to manage DCA scheduling'
authors = ['GalacticCouncil']
edition = '2021'
Expand Down
3 changes: 3 additions & 0 deletions pallets/dca/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,10 @@ impl pallet_ema_oracle::Config for Test {
type WeightInfo = ();
type BlockNumberProvider = MockBlockNumberProvider;
type SupportedPeriods = SupportedPeriods;
type OracleFilter = Everything;
type MaxUniqueEntries = ConstU32<20>;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
}

impl BlockNumberProvider for MockBlockNumberProvider {
Expand Down
2 changes: 1 addition & 1 deletion pallets/ema-oracle/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = 'pallet-ema-oracle'
version = '1.1.3'
version = '1.2.0'
description = 'Exponential moving average oracle for AMM pools'
authors = ['GalacticCouncil']
edition = '2021'
Expand Down
24 changes: 24 additions & 0 deletions pallets/ema-oracle/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ benchmarks! {

let (amount_in, amount_out) = (1_000_000_000_000, 2_000_000_000_000);
let (liquidity_asset_in, liquidity_asset_out) = (1_000_000_000_000_000, 2_000_000_000_000_000);

T::BenchmarkHelper::register_asset(HDX)?;
T::BenchmarkHelper::register_asset(DOT)?;

assert_ok!(OnActivityHandler::<T>::on_trade(
SOURCE, HDX, DOT, amount_in, amount_out, liquidity_asset_in, liquidity_asset_out,
Price::new(liquidity_asset_in, liquidity_asset_out)));
Expand Down Expand Up @@ -82,6 +86,10 @@ benchmarks! {
EmaOracle::<T>::on_initialize(initial_data_block);
let (amount_in, amount_out) = (1_000_000_000_000, 2_000_000_000_000);
let (liquidity_asset_in, liquidity_asset_out) = (1_000_000_000_000_000, 2_000_000_000_000_000);

T::BenchmarkHelper::register_asset(HDX)?;
T::BenchmarkHelper::register_asset(DOT)?;

assert_ok!(OnActivityHandler::<T>::on_trade(
SOURCE, HDX, DOT, amount_in, amount_out, liquidity_asset_in, liquidity_asset_out,
Price::new(liquidity_asset_in, liquidity_asset_out)));
Expand Down Expand Up @@ -121,6 +129,10 @@ benchmarks! {
for i in 0 .. b {
let asset_a = i * 1_000;
let asset_b = asset_a + 500;

T::BenchmarkHelper::register_asset(asset_a)?;
T::BenchmarkHelper::register_asset(asset_b)?;

assert_ok!(OnActivityHandler::<T>::on_trade(
SOURCE, asset_a, asset_b, amount_in, amount_out, liquidity_asset_in, liquidity_asset_out,
Price::new(liquidity_asset_in, liquidity_asset_out)));
Expand Down Expand Up @@ -167,6 +179,10 @@ benchmarks! {
for i in 0 .. b {
let asset_a = i * 1_000;
let asset_b = asset_a + 500;

T::BenchmarkHelper::register_asset(asset_a)?;
T::BenchmarkHelper::register_asset(asset_b)?;

assert_ok!(OnActivityHandler::<T>::on_trade(
SOURCE, asset_a, asset_b, amount_in, amount_out, liquidity_asset_in, liquidity_asset_out,
Price::new(liquidity_asset_in, liquidity_asset_out)));
Expand Down Expand Up @@ -223,6 +239,10 @@ benchmarks! {
for i in 0 .. b {
let asset_a = i * 1_000;
let asset_b = asset_a + 500;

T::BenchmarkHelper::register_asset(asset_a)?;
T::BenchmarkHelper::register_asset(asset_b)?;

assert_ok!(OnActivityHandler::<T>::on_trade(
SOURCE, asset_a, asset_b, amount_a, amount_b, liquidity_asset_a, liquidity_asset_b,
Price::new(liquidity_asset_a, liquidity_asset_b)));
Expand Down Expand Up @@ -281,6 +301,10 @@ benchmarks! {
let (liquidity_asset_in, liquidity_asset_out) = (1_000_000_000_000_000, 2_000_000_000_000_000);
let asset_a = 1_000;
let asset_b = asset_a + 500;

T::BenchmarkHelper::register_asset(asset_a)?;
T::BenchmarkHelper::register_asset(asset_b)?;

assert_ok!(OnActivityHandler::<T>::on_trade(
SOURCE, asset_a, asset_b, amount_in, amount_out, liquidity_asset_in, liquidity_asset_out,
Price::new(liquidity_asset_in, liquidity_asset_out)));
Expand Down
23 changes: 23 additions & 0 deletions pallets/ema-oracle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@

use frame_support::pallet_prelude::*;
use frame_support::sp_runtime::traits::{BlockNumberProvider, One, Zero};
use frame_support::traits::Contains;
use frame_system::pallet_prelude::BlockNumberFor;
use hydradx_traits::{
AggregatedEntry, AggregatedOracle, AggregatedPriceOracle, Liquidity, OnCreatePoolHandler,
Expand Down Expand Up @@ -99,6 +100,17 @@ const LOG_TARGET: &str = "runtime::ema-oracle";
// Re-export pallet items so that they can be accessed from the crate namespace.
pub use pallet::*;

#[cfg(feature = "runtime-benchmarks")]
pub trait BenchmarkHelper<AssetId> {
fn register_asset(asset_id: AssetId) -> DispatchResult;
}
#[cfg(feature = "runtime-benchmarks")]
impl BenchmarkHelper<AssetId> for () {
fn register_asset(_asset_id: AssetId) -> DispatchResult {
Ok(())
}
}

#[allow(clippy::type_complexity)]
#[frame_support::pallet]
pub mod pallet {
Expand All @@ -122,9 +134,15 @@ pub mod pallet {
/// The periods supported by the pallet. I.e. which oracles to track.
type SupportedPeriods: Get<BoundedVec<OraclePeriod, ConstU32<MAX_PERIODS>>>;

/// Filter determining what oracles are tracked by the pallet.
type OracleFilter: Contains<(Source, AssetId, AssetId)>;

/// Maximum number of unique oracle entries expected in one block.
#[pallet::constant]
type MaxUniqueEntries: Get<u32>;

#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper: BenchmarkHelper<AssetId>;
}

#[pallet::error]
Expand Down Expand Up @@ -225,6 +243,10 @@ impl<T: Config> Pallet<T> {
assets: (AssetId, AssetId),
oracle_entry: OracleEntry<BlockNumberFor<T>>,
) -> Result<(), ()> {
if !T::OracleFilter::contains(&(src, assets.0, assets.1)) {
return Ok(());
}

Accumulator::<T>::mutate(|accumulator| {
if let Some(entry) = accumulator.get_mut(&(src, assets)) {
entry.accumulate_volume_and_update_from(&oracle_entry);
Expand Down Expand Up @@ -441,6 +463,7 @@ impl<T: Config> OnLiquidityChangedHandler<AssetId, Balance, Price> for OnActivit
"Liquidity is zero. Source: {source:?}, liquidity: ({liquidity_a},{liquidity_a})"
);
}

let price = determine_normalized_price(asset_a, asset_b, price);
let liquidity = determine_normalized_liquidity(asset_a, asset_b, liquidity_a, liquidity_b);
let updated_at = T::BlockNumberProvider::current_block_number();
Expand Down
Loading

0 comments on commit eba70d1

Please sign in to comment.