Skip to content

Commit

Permalink
Merge pull request #782 from galacticcouncil/manual_oracle_activation
Browse files Browse the repository at this point in the history
feat: manual oracle activation
  • Loading branch information
Roznovjak authored Apr 9, 2024
2 parents ad6046e + 249a797 commit 8abf856
Show file tree
Hide file tree
Showing 20 changed files with 551 additions and 105 deletions.
13 changes: 7 additions & 6 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.20.0"
version = "1.20.1"
description = "Integration tests"
authors = ["GalacticCouncil"]
edition = "2021"
Expand Down
54 changes: 54 additions & 0 deletions integration-tests/src/oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,57 @@ fn xyk_trades_with_insufficient_asset_are_not_tracked_by_oracle() {
}
});
}

#[test]
fn xyk_trades_with_insufficient_asset_are_tracked_by_oracle_when_asset_is_whitelisted() {
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!(EmaOracle::add_oracle(
RuntimeOrigin::root(),
XYK_SOURCE,
(HDX, INSUFFICIENT_ASSET)
));

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!(EmaOracle::get_price(HDX, INSUFFICIENT_ASSET, *supported_period, XYK_SOURCE).is_ok(),);
}
for unsupported_period in UNSUPPORTED_PERIODS {
assert_eq!(
EmaOracle::get_price(HDX, INSUFFICIENT_ASSET, *unsupported_period, XYK_SOURCE),
Err(OracleError::NotPresent)
);
}
});
}
2 changes: 1 addition & 1 deletion pallets/asset-registry/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pallet-asset-registry"
version = "3.2.0"
version = "3.2.1"
description = "Pallet for asset registry management"
authors = ["GalacticCouncil"]
edition = "2021"
Expand Down
11 changes: 11 additions & 0 deletions pallets/asset-registry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use frame_support::pallet_prelude::*;
use frame_support::require_transactional;
use frame_support::sp_runtime::traits::CheckedAdd;
use frame_support::traits::tokens::fungibles::{Inspect as FungiblesInspect, Mutate as FungiblesMutate};
use frame_support::traits::Contains;
use frame_system::pallet_prelude::*;
use scale_info::TypeInfo;
use sp_arithmetic::traits::BaseArithmetic;
Expand Down Expand Up @@ -756,3 +757,13 @@ impl<T: Config> Create<Balance> for Pallet<T> {
}
}
}

/// Oracle whitelist based on the asset sufficiency.
pub struct OracleWhitelist<T>(PhantomData<T>);
impl<T: Config> Contains<(hydradx_traits::Source, <T as Config>::AssetId, <T as Config>::AssetId)>
for OracleWhitelist<T>
{
fn contains(t: &(hydradx_traits::Source, <T as Config>::AssetId, <T as Config>::AssetId)) -> bool {
Pallet::<T>::is_sufficient(t.1) && Pallet::<T>::is_sufficient(t.2)
}
}
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.4.2"
version = "1.4.3"
description = 'A pallet to manage DCA scheduling'
authors = ['GalacticCouncil']
edition = '2021'
Expand Down
3 changes: 2 additions & 1 deletion pallets/dca/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,14 @@ parameter_types! {

impl pallet_ema_oracle::Config for Test {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
type AuthorityOrigin = EnsureRoot<AccountId>;
type BlockNumberProvider = MockBlockNumberProvider;
type SupportedPeriods = SupportedPeriods;
type OracleWhitelist = Everything;
type MaxUniqueEntries = ConstU32<20>;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
type WeightInfo = ();
}

impl BlockNumberProvider for MockBlockNumberProvider {
Expand Down
3 changes: 2 additions & 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.2.1'
version = '1.3.0'
description = 'Exponential moving average oracle for AMM pools'
authors = ['GalacticCouncil']
edition = '2021'
Expand Down Expand Up @@ -35,6 +35,7 @@ pretty_assertions = "1.3.0"
proptest = "1.0.0"
rug = { version = "1.17.0", features = ["num-traits"] }
sp-io = { workspace = true }
test-utils = { workspace = true }

[features]
default = ['std']
Expand Down
49 changes: 48 additions & 1 deletion pallets/ema-oracle/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub const HDX: AssetId = 1_000;
pub const DOT: AssetId = 2_000;

use frame_benchmarking::benchmarks;
use frame_support::{assert_ok, traits::Hooks};
use frame_support::{assert_ok, dispatch::RawOrigin, traits::Hooks};

#[cfg(test)]
use pretty_assertions::assert_eq;
Expand All @@ -33,7 +33,36 @@ use crate::Pallet as EmaOracle;
/// Default oracle source.
const SOURCE: Source = *b"dummysrc";

fn fill_whitelist_storage<T: Config>(n: u32) {
for i in 0..n {
assert_ok!(EmaOracle::<T>::add_oracle(RawOrigin::Root.into(), SOURCE, (HDX, i)));
}
}
benchmarks! {
add_oracle {
let max_entries = <<T as Config>::MaxUniqueEntries as Get<u32>>::get();
fill_whitelist_storage::<T>(max_entries - 1);

assert_eq!(WhitelistedAssets::<T>::get().len(), (max_entries - 1) as usize);

}: _(RawOrigin::Root, SOURCE, (HDX, DOT))
verify {
assert!(WhitelistedAssets::<T>::get().contains(&(SOURCE, (HDX, DOT))));
}

remove_oracle {
let max_entries = <<T as Config>::MaxUniqueEntries as Get<u32>>::get();
fill_whitelist_storage::<T>(max_entries - 1);

assert_ok!(EmaOracle::<T>::add_oracle(RawOrigin::Root.into(), SOURCE, (HDX, DOT)));

assert_eq!(WhitelistedAssets::<T>::get().len(), max_entries as usize);

}: _(RawOrigin::Root, SOURCE, (HDX, DOT))
verify {
assert!(!WhitelistedAssets::<T>::get().contains(&(SOURCE, (HDX, DOT))));
}

on_finalize_no_entry {
let block_num: u32 = 5;
}: { EmaOracle::<T>::on_finalize(block_num.into()); }
Expand All @@ -42,6 +71,9 @@ benchmarks! {

#[extra]
on_finalize_insert_one_token {
let max_entries = <<T as Config>::MaxUniqueEntries as Get<u32>>::get();
fill_whitelist_storage::<T>(max_entries);

let block_num: BlockNumberFor<T> = 5u32.into();
let prev_block = block_num.saturating_sub(One::one());

Expand Down Expand Up @@ -78,6 +110,9 @@ benchmarks! {

#[extra]
on_finalize_update_one_token {
let max_entries = <<T as Config>::MaxUniqueEntries as Get<u32>>::get();
fill_whitelist_storage::<T>(max_entries);

let initial_data_block: BlockNumberFor<T> = 5u32.into();
// higher update time difference might make exponentiation more expensive
let block_num = initial_data_block.saturating_add(1_000_000u32.into());
Expand Down Expand Up @@ -119,6 +154,9 @@ benchmarks! {
on_finalize_multiple_tokens {
let b in 1 .. (T::MaxUniqueEntries::get() - 1);

let max_entries = <<T as Config>::MaxUniqueEntries as Get<u32>>::get();
fill_whitelist_storage::<T>(max_entries);

let initial_data_block: BlockNumberFor<T> = 5u32.into();
let block_num = initial_data_block.saturating_add(1_000_000u32.into());

Expand Down Expand Up @@ -167,6 +205,9 @@ benchmarks! {
on_trade_multiple_tokens {
let b in 1 .. (T::MaxUniqueEntries::get() - 1);

let max_entries = <<T as Config>::MaxUniqueEntries as Get<u32>>::get();
fill_whitelist_storage::<T>(max_entries);

let initial_data_block: BlockNumberFor<T> = 5u32.into();
let block_num = initial_data_block.saturating_add(1_000_000u32.into());

Expand Down Expand Up @@ -229,6 +270,9 @@ benchmarks! {
on_liquidity_changed_multiple_tokens {
let b in 1 .. (T::MaxUniqueEntries::get() - 1);

let max_entries = <<T as Config>::MaxUniqueEntries as Get<u32>>::get();
fill_whitelist_storage::<T>(max_entries);

let initial_data_block: BlockNumberFor<T> = 5u32.into();
let block_num = initial_data_block.saturating_add(1_000_000u32.into());

Expand Down Expand Up @@ -295,6 +339,9 @@ benchmarks! {
}

get_entry {
let max_entries = <<T as Config>::MaxUniqueEntries as Get<u32>>::get();
fill_whitelist_storage::<T>(max_entries);

let initial_data_block: BlockNumberFor<T> = 5u32.into();
let oracle_age: BlockNumberFor<T> = 999_999u32.into();
let block_num = initial_data_block.saturating_add(oracle_age.saturating_add(One::one()));
Expand Down
Loading

0 comments on commit 8abf856

Please sign in to comment.