diff --git a/Cargo.lock b/Cargo.lock index f6be7d76e..3212c443c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4888,7 +4888,7 @@ dependencies = [ [[package]] name = "hydradx-adapters" -version = "1.3.4" +version = "1.3.5" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -4938,7 +4938,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "249.0.0" +version = "252.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", @@ -7938,7 +7938,7 @@ dependencies = [ [[package]] name = "pallet-dca" -version = "1.5.0" +version = "1.5.1" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -8746,7 +8746,7 @@ dependencies = [ [[package]] name = "pallet-otc" -version = "2.0.0" +version = "2.0.1" dependencies = [ "frame-benchmarking", "frame-support", @@ -8768,7 +8768,7 @@ dependencies = [ [[package]] name = "pallet-otc-settlements" -version = "1.0.1" +version = "1.0.2" dependencies = [ "frame-benchmarking", "frame-support", @@ -8936,7 +8936,7 @@ dependencies = [ [[package]] name = "pallet-route-executor" -version = "2.4.1" +version = "2.5.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -11929,7 +11929,7 @@ dependencies = [ [[package]] name = "runtime-integration-tests" -version = "1.23.0" +version = "1.23.1" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 00ecc5b21..83ee43671 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runtime-integration-tests" -version = "1.23.0" +version = "1.23.1" description = "Integration tests" authors = ["GalacticCouncil"] edition = "2021" diff --git a/integration-tests/src/router.rs b/integration-tests/src/router.rs index 34fffcda6..943425782 100644 --- a/integration-tests/src/router.rs +++ b/integration-tests/src/router.rs @@ -2955,23 +2955,23 @@ mod set_route { use sp_runtime::TransactionOutcome; mod when_prestored_route_is_invalid { - use super::*; + use frame_support::assert_ok; + use hydradx_runtime::EmaOracle; + use hydradx_traits::AssetKind; + use primitives::constants::chain::XYK_SOURCE; #[test] - fn set_route_should_work_with_all_pools_involved() { + fn set_route_should_work_with_omnipool_xyk_and_stable_pools() { { TestNet::reset(); Hydra::execute_with(|| { let _ = with_transaction(|| { //Arrange - let (pool_id, stable_asset_1, _) = init_stableswap_with_details( - 1_000_000_000_000_000_000u128, - 300_000_000_000_000_000u128, - 18, - ) - .unwrap(); + let (pool_id, stable_asset_1, _) = + init_stableswap_with_details(1_000_000_000_000_000u128, 300_000_000_000_000u128, 18) + .unwrap(); init_omnipool(); @@ -2979,7 +2979,7 @@ mod set_route { hydradx_runtime::RuntimeOrigin::root(), Omnipool::protocol_account(), pool_id, - 60000 * UNITS as i128, + 1000 * UNITS as i128, )); assert_ok!(hydradx_runtime::Omnipool::add_token( @@ -2990,11 +2990,8 @@ mod set_route { AccountId::from(BOB), )); - create_xyk_pool_with_amounts(DOT, 1000000 * UNITS, stable_asset_1, 20000 * UNITS); - - create_lbp_pool_with_amounts(DOT, 1000000 * UNITS, stable_asset_1, 20000 * UNITS); - //Start lbp campaign - set_relaychain_block_number(LBP_SALE_START + 15); + create_xyk_pool_with_amounts(DOT, 1000 * UNITS, stable_asset_1, 2000 * UNITS); + create_xyk_pool_with_amounts(HDX, 10000000 * UNITS, DOT, 10000 * UNITS); let route1 = vec![ Trade { @@ -3014,28 +3011,16 @@ mod set_route { }, ]; - let route2_cheaper = vec![ - Trade { - pool: PoolType::Omnipool, - asset_in: HDX, - asset_out: pool_id, - }, - Trade { - pool: PoolType::Stableswap(pool_id), - asset_in: pool_id, - asset_out: stable_asset_1, - }, - Trade { - pool: PoolType::LBP, - asset_in: stable_asset_1, - asset_out: DOT, - }, - ]; + let route2_cheaper = vec![Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: DOT, + }]; let asset_pair = Pair::new(HDX, DOT); //Verify if the cheaper route is indeed cheaper in both ways - let amount_to_sell = 100 * UNITS; + let amount_to_sell = 1 * UNITS; //Check for normal route let dot_amount_out = with_transaction::<_, _, _>(|| { @@ -3111,6 +3096,7 @@ mod set_route { assert!(amount_out_for_inverse_with_chaper_route > amount_out_for_inverse); //ACT AND ASSERT + populate_oracle(HDX, DOT, route1.clone(), Some(10), None); //We set first the more expensive route assert_ok!(Router::set_route( @@ -3120,7 +3106,8 @@ mod set_route { )); assert_eq!(Router::route(asset_pair).unwrap(), route1); - //We set the cheaper one so it should replace + //We set the cheaper one so it should replace existing one + populate_oracle(HDX, DOT, route2_cheaper.clone(), Some(11), None); assert_ok!(Router::set_route( hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, @@ -3215,7 +3202,7 @@ mod set_route { let asset_pair = Pair::new(HDX, BTC); - let route2 = vec![ + let route = vec![ Trade { pool: PoolType::Omnipool, asset_in: HDX, @@ -3228,11 +3215,13 @@ mod set_route { }, ]; + populate_oracle(HDX, BTC, route.clone(), None, None); + //Act and assert assert_ok!(Router::set_route( hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, - route2 + route ),); }); } @@ -3276,6 +3265,8 @@ mod set_route { }, ]; + populate_oracle(HDX, BTC, route1.clone(), None, None); + let asset_pair = Pair::new(HDX, BTC); assert_ok!(Router::set_route( @@ -3290,7 +3281,7 @@ mod set_route { Tradability::FROZEN )); - let route2 = vec![ + let route = vec![ Trade { pool: PoolType::XYK, asset_in: HDX, @@ -3303,11 +3294,13 @@ mod set_route { }, ]; + populate_oracle(HDX, BTC, route.clone(), Some(11), None); + //Act and assert assert_ok!(Router::set_route( hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, - route2 + route ),); }); } @@ -3339,7 +3332,7 @@ mod set_route { let asset_pair = Pair::new(HDX, BTC); - let route2 = vec![ + let route = vec![ Trade { pool: PoolType::Omnipool, asset_in: HDX, @@ -3352,6 +3345,8 @@ mod set_route { }, ]; + populate_oracle(HDX, BTC, route.clone(), None, None); + assert_ok!(hydradx_runtime::Omnipool::set_asset_tradable_state( hydradx_runtime::RuntimeOrigin::root(), DOT, @@ -3360,7 +3355,7 @@ mod set_route { //Act and assert assert_noop!( - Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route2), + Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route), pallet_omnipool::Error::::NotAllowed ); }); @@ -3393,7 +3388,7 @@ mod set_route { let asset_pair = Pair::new(HDX, BTC); - let route2 = vec![ + let route = vec![ Trade { pool: PoolType::Omnipool, asset_in: HDX, @@ -3406,6 +3401,8 @@ mod set_route { }, ]; + populate_oracle(HDX, BTC, route.clone(), None, None); + assert_ok!(hydradx_runtime::Omnipool::set_asset_tradable_state( hydradx_runtime::RuntimeOrigin::root(), DOT, @@ -3414,7 +3411,7 @@ mod set_route { //Act and assert assert_noop!( - Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route2), + Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route), pallet_omnipool::Error::::NotAllowed ); }); @@ -3445,12 +3442,12 @@ mod set_route { create_xyk_pool_with_amounts(DOT, 10 * UNITS, BTC, 1000000 * UNITS); - let asset_pair = Pair::new(HDX, BTC); + let asset_pair = Pair::new(DAI, BTC); - let route2 = vec![ + let route = vec![ Trade { pool: PoolType::Omnipool, - asset_in: HDX, + asset_in: DAI, asset_out: DOT, }, Trade { @@ -3460,11 +3457,22 @@ mod set_route { }, ]; + //To prevent ED error + assert_ok!(hydradx_runtime::Tokens::set_balance( + RawOrigin::Root.into(), + DAVE.into(), + BTC, + 1 * UNITS, + 0, + )); + + populate_oracle(DAI, BTC, route.clone(), None, Some(90 * UNITS)); + //Act and assert assert_ok!(Router::set_route( hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, - route2 + route ),); }); } @@ -3496,7 +3504,7 @@ mod set_route { let asset_pair = Pair::new(HDX, BTC); - let route2 = vec![ + let route = vec![ Trade { pool: PoolType::Omnipool, asset_in: HDX, @@ -3509,11 +3517,13 @@ mod set_route { }, ]; + populate_oracle(HDX, BTC, route.clone(), None, None); + //Act and assert assert_ok!(Router::set_route( hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, - route2 + route ),); }); } @@ -3540,6 +3550,8 @@ mod set_route { }, ]; + populate_oracle(HDX, BTC, route1.clone(), None, None); + let asset_pair = Pair::new(HDX, BTC); assert_ok!(Router::set_route( @@ -3549,6 +3561,101 @@ mod set_route { )); }); } + + #[test] + fn set_route_should_not_work_when_route_has_insufficient_asset_without_oracle() { + { + TestNet::reset(); + + Hydra::execute_with(|| { + let _ = with_transaction(|| { + 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(); + + let route1 = vec![Trade { + pool: PoolType::XYK, + asset_in: DOT, + asset_out: insufficient_asset, + }]; + + create_xyk_pool_with_amounts(DOT, 10000 * UNITS, insufficient_asset, 10000 * UNITS); + + //Act + assert_noop!( + Router::set_route( + hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), + Pair::new(DOT, insufficient_asset), + route1.clone() + ), + pallet_route_executor::Error::::RouteHasNoOracle + ); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }); + } + } + + #[test] + fn set_route_should_work_when_route_has_insufficient_asset_with_oracle() { + { + TestNet::reset(); + + Hydra::execute_with(|| { + let _ = with_transaction(|| { + 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(); + + let route1 = vec![Trade { + pool: PoolType::XYK, + asset_in: DOT, + asset_out: insufficient_asset, + }]; + + create_xyk_pool_with_amounts(DOT, 10000 * UNITS, insufficient_asset, 10000 * UNITS); + + //Whitelist insufficient asset in oracle + EmaOracle::add_oracle( + hydradx_runtime::RuntimeOrigin::root(), + XYK_SOURCE, + (DOT, insufficient_asset), + ) + .unwrap(); + + populate_oracle(DOT, insufficient_asset, route1.clone(), None, Some(10 * UNITS)); + + //Act + assert_ok!(Router::set_route( + hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), + Pair::new(DOT, insufficient_asset), + route1.clone() + ),); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }); + } + } } mod when_prestored_route_is_valid { @@ -3592,6 +3699,8 @@ mod set_route { }, ]; + populate_oracle(HDX, BTC, route1.clone(), None, None); + let asset_pair = Pair::new(HDX, BTC); //Act and assert @@ -3665,6 +3774,8 @@ mod set_route { }, ]; + populate_oracle(HDX, BTC, route1.clone(), None, None); + let asset_pair = Pair::new(HDX, BTC); assert_ok!(Router::set_route( @@ -3747,6 +3858,8 @@ mod set_route { }, ]; + populate_oracle(HDX, BTC, prestored_route.clone(), None, None); + assert_ok!(Router::set_route( hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, @@ -3821,6 +3934,8 @@ mod set_route { }, ]; + populate_oracle(HDX, BTC, prestored_route.clone(), None, None); + assert_ok!(Router::set_route( hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, @@ -3897,7 +4012,7 @@ mod set_route { let asset_pair = Pair::new(BTC, ETH); - let route2 = vec![ + let route = vec![ Trade { pool: PoolType::Omnipool, asset_in: BTC, @@ -3910,9 +4025,11 @@ mod set_route { }, ]; + populate_oracle(BTC, ETH, route.clone(), None, Some(UNITS / 1000000)); + //Validation is fine so no AMM error, but since the route is not better, it results in unsuccessfull route setting assert_noop!( - Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route2), + Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route), pallet_route_executor::Error::::RouteUpdateIsNotSuccessful ); }); @@ -3961,7 +4078,7 @@ mod set_route { let asset_pair = Pair::new(BTC, ETH); - let route2 = vec![ + let route = vec![ Trade { pool: PoolType::Omnipool, asset_in: BTC, @@ -3974,9 +4091,11 @@ mod set_route { }, ]; + populate_oracle(BTC, ETH, route.clone(), None, Some(UNITS / 100)); + //Validation is fine, but since the route is not better, it results in unsuccessfull route setting assert_noop!( - Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route2), + Router::set_route(hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), asset_pair, route), pallet_route_executor::Error::::RouteUpdateIsNotSuccessful ); }); @@ -4011,6 +4130,8 @@ mod set_route { asset_out: DOT, }]; + populate_oracle(HDX, DOT, route1.clone(), None, None); + let asset_pair = Pair::new(HDX, DOT); assert_noop!( @@ -4024,6 +4145,7 @@ mod set_route { mod with_on_chain_and_default_route { use super::*; + use frame_support::assert_ok; #[test] fn buy_should_work_with_onchain_route() { @@ -4071,6 +4193,8 @@ mod with_on_chain_and_default_route { }, ]; + populate_oracle(HDX, DOT, route1.clone(), None, None); + let asset_pair = Pair::new(HDX, DOT); let amount_to_buy = 100 * UNITS; @@ -4151,6 +4275,8 @@ mod with_on_chain_and_default_route { }, ]; + populate_oracle(HDX, DOT, route1.clone(), None, None); + let asset_pair = Pair::new(HDX, DOT); let amount_to_sell = 100 * UNITS; @@ -4224,6 +4350,8 @@ mod with_on_chain_and_default_route { }, ]; + populate_oracle(HDX, DOT, route1.clone(), None, None); + let asset_pair = Pair::new(HDX, DOT); let amount_to_sell = 100 * UNITS; @@ -4684,51 +4812,6 @@ fn create_lbp_pool(accumulated_asset: u32, distributed_asset: u32) { )); } -fn create_lbp_pool_with_amounts(accumulated_asset: u32, amount_a: u128, distributed_asset: u32, amount_b: u128) { - assert_ok!(Currencies::update_balance( - hydradx_runtime::RuntimeOrigin::root(), - DAVE.into(), - accumulated_asset, - amount_a as i128, - )); - assert_ok!(Currencies::update_balance( - hydradx_runtime::RuntimeOrigin::root(), - DAVE.into(), - distributed_asset, - amount_b as i128, - )); - - assert_ok!(LBP::create_pool( - RuntimeOrigin::root(), - DAVE.into(), - accumulated_asset, - amount_a, - distributed_asset, - amount_b, - 20_000_000, - 80_000_000, - WeightCurveType::Linear, - (2, 1_000), - CHARLIE.into(), - 0, - )); - - let account_id = get_lbp_pair_account_id(accumulated_asset, distributed_asset); - - assert_ok!(LBP::update_pool_data( - RuntimeOrigin::signed(DAVE.into()), - account_id, - None, - Some(LBP_SALE_START), - Some(LBP_SALE_END), - None, - None, - None, - None, - None, - )); -} - fn get_lbp_pair_account_id(asset_a: AssetId, asset_b: AssetId) -> AccountId { let asset_pair = pallet_lbp::AssetPair { asset_in: asset_a, @@ -4850,3 +4933,28 @@ pub fn init_stableswap_with_details( Ok((pool_id, asset_in, asset_out)) } + +fn populate_oracle( + asset_in: AssetId, + asset_out: AssetId, + route: Vec>, + block: Option, + amount: Option, +) { + assert_ok!(hydradx_runtime::Tokens::set_balance( + RawOrigin::Root.into(), + DAVE.into(), + asset_in, + amount.unwrap_or(100 * UNITS), + 0, + )); + assert_ok!(Router::sell( + hydradx_runtime::RuntimeOrigin::signed(DAVE.into()), + asset_in, + asset_out, + amount.unwrap_or(1 * UNITS), + 0, + route.clone() + )); + set_relaychain_block_number(block.unwrap_or(10)); +} diff --git a/pallets/dca/Cargo.toml b/pallets/dca/Cargo.toml index 46d04cf67..89d83ea1a 100644 --- a/pallets/dca/Cargo.toml +++ b/pallets/dca/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-dca' -version = "1.5.0" +version = "1.5.1" 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 376724cd5..2092d36aa 100644 --- a/pallets/dca/src/tests/mock.rs +++ b/pallets/dca/src/tests/mock.rs @@ -350,6 +350,8 @@ pub const ASSET_PAIR_ACCOUNT: AccountId = 12; parameter_types! { pub MaxNumberOfTrades: u8 = 3; pub DefaultRoutePoolType: PoolType = PoolType::Omnipool; + pub const RouteValidationOraclePeriod: OraclePeriod = OraclePeriod::TenMinutes; + } type Pools = (OmniPool, Xyk); @@ -366,6 +368,8 @@ impl pallet_route_executor::Config for Test { type WeightInfo = (); type TechnicalOrigin = EnsureRoot; type EdToRefundCalculator = MockedEdCalculator; + type OraclePriceProvider = PriceProviderMock; + type OraclePeriod = RouteValidationOraclePeriod; } pub struct MockedEdCalculator; @@ -376,6 +380,19 @@ impl RefundEdCalculator for MockedEdCalculator { } } +pub struct PriceProviderMock {} + +impl PriceOracle for crate::tests::mock::PriceProviderMock { + type Price = Ratio; + + fn price(_: &[Trade], period: OraclePeriod) -> Option { + if period == OraclePeriod::Short { + return Some(Ratio::new(80, 100)); + } + Some(Ratio::new(88, 100)) + } +} + type OriginForRuntime = OriginFor; pub const INVALID_CALCULATION_AMOUNT: Balance = 999; pub const CALCULATED_AMOUNT_IN_FOR_OMNIPOOL_BUY: Balance = 10 * ONE; @@ -625,19 +642,6 @@ impl TradeExecution for Xyk { } } -pub struct PriceProviderMock {} - -impl PriceOracle for PriceProviderMock { - type Price = Ratio; - - fn price(_: &[Trade], period: OraclePeriod) -> Option { - if period == OraclePeriod::Short { - return Some(Ratio::new(80, 100)); - } - Some(Ratio::new(88, 100)) - } -} - parameter_types! { pub NativeCurrencyId: AssetId = HDX; pub MinBudgetInNativeCurrency: Balance= MIN_BUDGET.with(|v| *v.borrow()); diff --git a/pallets/otc-settlements/Cargo.toml b/pallets/otc-settlements/Cargo.toml index eabeedcfd..bfc59eae6 100644 --- a/pallets/otc-settlements/Cargo.toml +++ b/pallets/otc-settlements/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-otc-settlements' -version = '1.0.1' +version = '1.0.2' description = 'A pallet with offchain worker closing OTC arbs' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/otc-settlements/src/mock.rs b/pallets/otc-settlements/src/mock.rs index 4f1052f69..50b7bc7c9 100644 --- a/pallets/otc-settlements/src/mock.rs +++ b/pallets/otc-settlements/src/mock.rs @@ -27,8 +27,11 @@ use frame_support::{ }, }; use frame_system::{EnsureRoot, EnsureSigned}; -use hydra_dx_math::ema::EmaPrice; -use hydradx_traits::router::{PoolType, RefundEdCalculator}; +use hydra_dx_math::{ema::EmaPrice, ratio::Ratio}; +use hydradx_traits::{ + router::{PoolType, RefundEdCalculator}, + OraclePeriod, PriceOracle, +}; use orml_traits::{parameter_type_with_key, GetByKey}; use pallet_currencies::{fungibles::FungibleCurrencies, BasicCurrencyAdapter}; use pallet_omnipool::traits::ExternalPriceProvider; @@ -115,6 +118,7 @@ impl pallet_otc::Config for Test { parameter_types! { pub DefaultRoutePoolType: PoolType = PoolType::Omnipool; + pub const RouteValidationOraclePeriod: OraclePeriod = OraclePeriod::TenMinutes; } pub struct MockedEdCalculator; @@ -125,18 +129,34 @@ impl RefundEdCalculator for MockedEdCalculator { } } +pub struct PriceProviderMock {} + +impl PriceOracle for PriceProviderMock { + type Price = Ratio; + + fn price(route: &[Trade], _: OraclePeriod) -> Option { + let has_insufficient_asset = route.iter().any(|t| t.asset_in > 2000 || t.asset_out > 2000); + if has_insufficient_asset { + return None; + } + Some(Ratio::new(88, 100)) + } +} + impl pallet_route_executor::Config for Test { type RuntimeEvent = RuntimeEvent; type AssetId = AssetId; type Balance = Balance; type NativeAssetId = HDXAssetId; type Currency = FungibleCurrencies; - type AMM = Omnipool; type InspectRegistry = AssetRegistry; + type AMM = Omnipool; + type EdToRefundCalculator = MockedEdCalculator; + type OraclePriceProvider = PriceProviderMock; + type OraclePeriod = RouteValidationOraclePeriod; type DefaultRoutePoolType = DefaultRoutePoolType; - type WeightInfo = (); type TechnicalOrigin = EnsureRoot; - type EdToRefundCalculator = MockedEdCalculator; + type WeightInfo = (); } parameter_types! { diff --git a/pallets/otc/Cargo.toml b/pallets/otc/Cargo.toml index 5c46fdfa6..97633fbdf 100644 --- a/pallets/otc/Cargo.toml +++ b/pallets/otc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-otc' -version = '2.0.0' +version = '2.0.1' description = 'A pallet for trustless over-the-counter trading' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/route-executor/Cargo.toml b/pallets/route-executor/Cargo.toml index fea3e10ed..5457d35c0 100644 --- a/pallets/route-executor/Cargo.toml +++ b/pallets/route-executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-route-executor' -version = '2.4.1' +version = '2.5.0' description = 'A pallet to execute a route containing a sequence of trades' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/route-executor/src/lib.rs b/pallets/route-executor/src/lib.rs index 6cc429eac..b393bf8b6 100644 --- a/pallets/route-executor/src/lib.rs +++ b/pallets/route-executor/src/lib.rs @@ -59,7 +59,9 @@ pub mod pallet { use super::*; use frame_support::traits::fungibles::Mutate; use frame_system::pallet_prelude::OriginFor; + use hydra_dx_math::ema::EmaPrice; use hydradx_traits::router::{ExecutorError, RefundEdCalculator}; + use hydradx_traits::{OraclePeriod, PriceOracle}; use sp_runtime::traits::{AtLeast32BitUnsigned, CheckedDiv, Zero}; use sp_runtime::Saturating; @@ -106,8 +108,16 @@ pub mod pallet { Error = DispatchError, >; + ///Calculate ED for tolerating currency balance difference type EdToRefundCalculator: RefundEdCalculator; + ///Oracle price provider to validate if new route has oracle price data + type OraclePriceProvider: PriceOracle; + + /// Oracle's price aggregation period. + #[pallet::constant] + type OraclePeriod: Get; + /// Pool type used in the default route type DefaultRoutePoolType: Get>; @@ -148,8 +158,8 @@ pub mod pallet { InvalidRoute, ///The route update was not successful RouteUpdateIsNotSuccessful, - ///Insufficient asset is not supported for on chain routing - InsufficientAssetNotSupported, + ///Route contains assets that has no oracle data + RouteHasNoOracle, ///The route execution failed in the underlying AMM InvalidRouteExecution, /// Trading same assets is not allowed. @@ -367,7 +377,7 @@ pub mod pallet { let _ = ensure_signed(origin.clone())?; Self::ensure_route_size(new_route.len())?; Self::ensure_route_arguments(&asset_pair, &new_route)?; - Self::ensure_route_has_no_insufficient_asset(&new_route)?; + T::OraclePriceProvider::price(&new_route, T::OraclePeriod::get()).ok_or(Error::::RouteHasNoOracle)?; if !asset_pair.is_ordered() { asset_pair = asset_pair.ordered_pair(); @@ -494,23 +504,6 @@ impl Pallet { Ok(()) } - fn ensure_route_has_no_insufficient_asset(new_route: &[Trade]) -> DispatchResult { - let mut unique_assets = sp_std::collections::btree_set::BTreeSet::new(); - - for trade in new_route.iter() { - unique_assets.insert(trade.asset_in); - unique_assets.insert(trade.asset_out); - } - for asset in unique_assets.iter() { - ensure!( - T::InspectRegistry::is_sufficient(*asset), - Error::::InsufficientAssetNotSupported - ); - } - - Ok(()) - } - fn ensure_that_user_received_asset_out_at_most( who: T::AccountId, asset_in: T::AssetId, @@ -628,6 +621,13 @@ impl Pallet { let Ok(who) = ensure_signed(origin.clone()) else { return TransactionOutcome::Rollback(Err(Error::::InvalidRoute.into())); }; + //NOTE: This is necessary so router's account can pay ED for insufficient assets in the + //route. Value is 10K to make sure we can pay ED for really long routes. + let _ = T::Currency::mint_into( + T::NativeAssetId::get(), + &Self::router_account(), + 10_000_000_000_000_000_u128.into(), + ); let _ = T::Currency::mint_into(asset_in, &Self::router_account(), amount_in); let sell_result = Self::sell(origin, asset_in, asset_out, amount_in, u128::MIN.into(), route.clone()); diff --git a/pallets/route-executor/src/tests/mock.rs b/pallets/route-executor/src/tests/mock.rs index 354ab60e9..0363cf739 100644 --- a/pallets/route-executor/src/tests/mock.rs +++ b/pallets/route-executor/src/tests/mock.rs @@ -23,6 +23,7 @@ use frame_support::{ }; use frame_system::EnsureRoot; use frame_system::{ensure_signed, pallet_prelude::OriginFor}; +use hydra_dx_math::ratio::Ratio; use hydradx_traits::router::{ExecutorError, PoolType, RefundEdCalculator, TradeExecution}; use orml_traits::parameter_type_with_key; use pallet_currencies::{fungibles::FungibleCurrencies, BasicCurrencyAdapter}; @@ -140,6 +141,8 @@ type Pools = (XYK, StableSwap, OmniPool, LBP); parameter_types! { pub NativeCurrencyId: AssetId = HDX; pub DefaultRoutePoolType: PoolType = PoolType::Omnipool; + pub const RouteValidationOraclePeriod: OraclePeriod = OraclePeriod::TenMinutes; + } impl Config for Test { @@ -151,6 +154,8 @@ impl Config for Test { type InspectRegistry = MockedAssetRegistry; type AMM = Pools; type EdToRefundCalculator = MockedEdCalculator; + type OraclePriceProvider = PriceProviderMock; + type OraclePeriod = RouteValidationOraclePeriod; type DefaultRoutePoolType = DefaultRoutePoolType; type TechnicalOrigin = EnsureRoot; type WeightInfo = (); @@ -164,7 +169,21 @@ impl RefundEdCalculator for MockedEdCalculator { } } -use hydradx_traits::AssetKind; +pub struct PriceProviderMock {} + +impl PriceOracle for PriceProviderMock { + type Price = Ratio; + + fn price(route: &[Trade], _: OraclePeriod) -> Option { + let has_insufficient_asset = route.iter().any(|t| t.asset_in > 2000 || t.asset_out > 2000); + if has_insufficient_asset { + return None; + } + Some(Ratio::new(88, 100)) + } +} + +use hydradx_traits::{AssetKind, OraclePeriod, PriceOracle}; pub struct MockedAssetRegistry; impl hydradx_traits::registry::Inspect for MockedAssetRegistry { diff --git a/pallets/route-executor/src/tests/set_route.rs b/pallets/route-executor/src/tests/set_route.rs index 3e7cc8e69..ab0b9e485 100644 --- a/pallets/route-executor/src/tests/set_route.rs +++ b/pallets/route-executor/src/tests/set_route.rs @@ -450,7 +450,7 @@ fn set_route_should_fail_with_insufficient_asset() { //Act assert_noop!( Router::set_route(RuntimeOrigin::signed(ALICE), asset_pair, route), - Error::::InsufficientAssetNotSupported + Error::::RouteHasNoOracle ); }); } @@ -481,7 +481,7 @@ fn set_route_should_fail_with_insufficient_asset_as_intermediare() { //Act assert_noop!( Router::set_route(RuntimeOrigin::signed(ALICE), asset_pair, route), - Error::::InsufficientAssetNotSupported + Error::::RouteHasNoOracle ); }); } diff --git a/pallets/route-executor/src/weights.rs b/pallets/route-executor/src/weights.rs index e221631b1..018fd4a51 100644 --- a/pallets/route-executor/src/weights.rs +++ b/pallets/route-executor/src/weights.rs @@ -52,6 +52,8 @@ pub trait WeightInfo { fn calculate_and_execute_buy_in_lbp(c: u32, b: u32, ) -> Weight; fn set_route_for_xyk() -> Weight; fn force_insert_route() -> Weight; + fn get_oracle_price_for_xyk() -> Weight; + fn get_oracle_price_for_omnipool() -> Weight; fn get_route() -> Weight; fn calculate_spot_price_with_fee_in_lbp() -> Weight; } @@ -166,6 +168,28 @@ impl WeightInfo for () { Weight::from_parts(7_748_000, 3555) .saturating_add(RocksDbWeight::get().reads(1_u64)) } + + /// Storage: `EmaOracle::Oracles` (r:2 w:0) + /// Proof: `EmaOracle::Oracles` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + fn get_oracle_price_for_xyk() -> Weight { + // Proof Size summary in bytes: + // Measured: `1452` + // Estimated: `6294` + // Minimum execution time: 21_820_000 picoseconds. + Weight::from_parts(22_320_000, 6294) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + } + /// Storage: `EmaOracle::Oracles` (r:4 w:0) + /// Proof: `EmaOracle::Oracles` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + fn get_oracle_price_for_omnipool() -> Weight { + // Proof Size summary in bytes: + // Measured: `1814` + // Estimated: `11598` + // Minimum execution time: 35_720_000 picoseconds. + Weight::from_parts(36_110_000, 11598) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + } + /// Storage: `LBP::PoolData` (r:1 w:0) /// Proof: `LBP::PoolData` (`max_values`: None, `max_size`: Some(163), added: 2638, mode: `MaxEncodedLen`) /// Storage: `Tokens::Locks` (r:1 w:0) diff --git a/runtime/adapters/Cargo.toml b/runtime/adapters/Cargo.toml index 05baabe02..d6ca4836a 100644 --- a/runtime/adapters/Cargo.toml +++ b/runtime/adapters/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-adapters" -version = "1.3.4" +version = "1.3.5" description = "Structs and other generic types for building runtimes." authors = ["GalacticCouncil"] edition = "2021" diff --git a/runtime/adapters/src/tests/mock.rs b/runtime/adapters/src/tests/mock.rs index c244d849d..149ef9140 100644 --- a/runtime/adapters/src/tests/mock.rs +++ b/runtime/adapters/src/tests/mock.rs @@ -28,13 +28,14 @@ use frame_support::{ }; use frame_system::EnsureRoot; use hydra_dx_math::ema::EmaPrice; +use hydra_dx_math::ratio::Ratio; use hydra_dx_math::support::rational::Rounding; use hydra_dx_math::to_u128_wrapper; use hydradx_traits::pools::DustRemovalAccountWhitelist; -use hydradx_traits::router::RefundEdCalculator; +use hydradx_traits::router::{RefundEdCalculator, Trade}; use hydradx_traits::{ router::PoolType, AssetKind, AssetPairAccountIdFor, CanCreatePool, Create as CreateRegistry, - Inspect as InspectRegistry, + Inspect as InspectRegistry, OraclePeriod, PriceOracle, }; use orml_traits::{parameter_type_with_key, GetByKey}; use pallet_currencies::fungibles::FungibleCurrencies; @@ -316,6 +317,7 @@ pub const ASSET_PAIR_ACCOUNT: AccountId = 12; parameter_types! { pub NativeCurrencyId: AssetId = HDX; pub DefaultRoutePoolType: PoolType = PoolType::Omnipool; + pub const RouteValidationOraclePeriod: OraclePeriod = OraclePeriod::TenMinutes; } type Pools = (Omnipool, XYK); @@ -329,8 +331,10 @@ impl pallet_route_executor::Config for Test { type InspectRegistry = DummyRegistry; type AMM = Pools; type EdToRefundCalculator = MockedEdCalculator; + type OraclePriceProvider = PriceProviderMock; type DefaultRoutePoolType = DefaultRoutePoolType; type TechnicalOrigin = EnsureRoot; + type OraclePeriod = RouteValidationOraclePeriod; type WeightInfo = (); } @@ -342,6 +346,19 @@ impl RefundEdCalculator for MockedEdCalculator { } } +pub struct PriceProviderMock {} + +impl PriceOracle for PriceProviderMock { + type Price = Ratio; + + fn price(_: &[Trade], period: OraclePeriod) -> Option { + if period == OraclePeriod::Short { + return Some(Ratio::new(80, 100)); + } + Some(Ratio::new(88, 100)) + } +} + pub struct ExtBuilder { endowed_accounts: Vec<(u64, AssetId, Balance)>, registered_assets: Vec, diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index eeafc0f93..ca49513a1 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "249.0.0" +version = "252.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" @@ -398,5 +398,4 @@ try-runtime = [ metadata-hash = [ "substrate-wasm-builder/metadata-hash", - "sp-api/disable-logging", ] diff --git a/runtime/hydradx/build.rs b/runtime/hydradx/build.rs index fc9df33bb..641960547 100644 --- a/runtime/hydradx/build.rs +++ b/runtime/hydradx/build.rs @@ -1,11 +1,11 @@ -#[cfg(all(feature = "std", feature = "release-build"))] +#[cfg(all(feature = "std", feature = "metadata-hash"))] fn main() { substrate_wasm_builder::WasmBuilder::init_with_defaults() .enable_metadata_hash("HDX", 12) .build(); } -#[cfg(all(feature = "std", not(feature = "release-build")))] +#[cfg(all(feature = "std", not(feature = "metadata-hash")))] fn main() { substrate_wasm_builder::WasmBuilder::build_using_defaults(); } diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index af43db7b7..3d555f48f 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -853,10 +853,13 @@ impl RouterWeightInfo { let set_route_overweight = weights::pallet_route_executor::HydraWeight::::set_route_for_xyk(); - set_route_overweight.saturating_sub(weights::pallet_xyk::HydraWeight::::router_execution_sell( - number_of_times_calculate_sell_amounts_executed, - number_of_times_execute_sell_amounts_executed, - )) + // we substract weight of getting oracle price too as we add this back later based on the length of the route + set_route_overweight + .saturating_sub(weights::pallet_xyk::HydraWeight::::router_execution_sell( + number_of_times_calculate_sell_amounts_executed, + number_of_times_execute_sell_amounts_executed, + )) + .saturating_sub(weights::pallet_route_executor::HydraWeight::::get_oracle_price_for_xyk()) } pub fn calculate_spot_price_overweight() -> Weight { @@ -1066,6 +1069,14 @@ impl AmmTradeWeights> for RouterWeightInfo { weight.saturating_accrue(amm_weight); } + // Incorporate oracle price calculation + // We use omnipool as reference as it is the worst case for calculating oracle price + let weight_of_get_oracle_price_for_2_assets = + weights::pallet_route_executor::HydraWeight::::get_oracle_price_for_omnipool(); + let weight_of_get_oracle_price_for_route = + weight_of_get_oracle_price_for_2_assets.saturating_mul(route.len() as u64); + weight.saturating_accrue(weight_of_get_oracle_price_for_route); + weight } @@ -1100,6 +1111,8 @@ impl AmmTradeWeights> for RouterWeightInfo { parameter_types! { pub const DefaultRoutePoolType: PoolType = PoolType::Omnipool; + pub const RouteValidationOraclePeriod: OraclePeriod = OraclePeriod::TenMinutes; + } impl pallet_route_executor::Config for Runtime { @@ -1114,6 +1127,8 @@ impl pallet_route_executor::Config for Runtime { type InspectRegistry = AssetRegistry; type TechnicalOrigin = SuperMajorityTechCommittee; type EdToRefundCalculator = RefundAndLockedEdCalculator; + type OraclePriceProvider = hydradx_adapters::OraclePriceProvider; + type OraclePeriod = RouteValidationOraclePeriod; } parameter_types! { diff --git a/runtime/hydradx/src/benchmarking/route_executor.rs b/runtime/hydradx/src/benchmarking/route_executor.rs index b23494c85..d7cca10a9 100644 --- a/runtime/hydradx/src/benchmarking/route_executor.rs +++ b/runtime/hydradx/src/benchmarking/route_executor.rs @@ -15,13 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. #![allow(clippy::result_large_err)] +#![allow(unused_assignments)] //Benchmark test leads to unused assignment, which is not true use crate::{ - AccountId, AssetId, Balance, Currencies, InsufficientEDinHDX, Router, Runtime, RuntimeOrigin, System, LBP, XYK, + AccountId, AssetId, Balance, Currencies, EmaOracle, InsufficientEDinHDX, Router, Runtime, RuntimeOrigin, System, + LBP, XYK, }; use super::*; use crate::benchmarking::dca::{DAI, HDX}; +use crate::Omnipool; use frame_benchmarking::{account, BenchmarkError}; use frame_support::dispatch::DispatchResult; use frame_support::{assert_ok, ensure}; @@ -29,10 +32,14 @@ use frame_system::RawOrigin; use hydradx_traits::router::inverse_route; use hydradx_traits::router::{AssetPair, RouteProvider, RouteSpotPriceProvider}; use hydradx_traits::router::{PoolType, RouterT, Trade}; +use hydradx_traits::PriceOracle; use orml_benchmarking::runtime_benchmarks; use orml_traits::{MultiCurrency, MultiCurrencyExtended}; +use pallet_ema_oracle::OraclePeriod; use primitives::constants::currency::UNITS; +use primitives::BlockNumber; use sp_std::vec; + pub const INITIAL_BALANCE: Balance = 10_000_000 * UNITS; fn funded_account(name: &'static str, index: u32, assets: &[AssetId]) -> AccountId { @@ -132,6 +139,17 @@ fn create_xyk_pool(asset_a: u32, asset_b: u32) { asset_b, amount, )); + + let seller: AccountId = funded_account("caller", 0, &[asset_a]); + + assert_ok!(XYK::sell( + RuntimeOrigin::signed(seller), + asset_a, + asset_b, + 10 * UNITS, + u128::MIN, + false + )); } runtime_benchmarks! { @@ -255,6 +273,9 @@ runtime_benchmarks! { asset_in: asset_5, asset_out: asset_6 }]; + + set_period(10); + Router::set_route( RawOrigin::Signed(caller.clone()).into(), AssetPair::new(HDX, asset_6), @@ -345,6 +366,51 @@ runtime_benchmarks! { Router::get_route(AssetPair::new(HDX, DAI)) } + //To calculate the overweight poperly we use this to substract + get_oracle_price_for_xyk { + let asset_2 = register_asset(b"AS2".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?; + + let caller: AccountId = funded_account("caller", 0, &[asset_2]); + create_xyk_pool(HDX, asset_2); + + let route = vec![Trade { + pool: PoolType::XYK, + asset_in: HDX, + asset_out: asset_2 + }]; + + set_period(10); + let mut price = None; + }: { + price = ::OraclePriceProvider::price(&route, OraclePeriod::TenMinutes); + } + verify { + assert!(price.is_some()); + } + + //We use omnipool as it contains 4 reads when getting oracle price, so we can use it as worst case, and multiplying it with the length of the route + get_oracle_price_for_omnipool { + let asset_2 = register_asset(b"AS2".to_vec(), 1u128).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?; + + crate::benchmarking::omnipool::init()?; + let caller: AccountId = funded_account("caller", 0, &[HDX, DAI]); + Omnipool::sell(RawOrigin::Signed(caller).into(), HDX, DAI, 10 * UNITS, 0)?; + + set_period(10); + + let route = vec![Trade { + pool: PoolType::Omnipool, + asset_in: HDX, + asset_out: DAI + }]; + let mut price = None; + }: { + price = ::OraclePriceProvider::price(&route, OraclePeriod::TenMinutes); + } + verify { + assert!(price.is_some()); + } + // Calculates the weight of LBP spot price with fee calculation. Used in the calculation to determine the weight of the overhead. calculate_spot_price_with_fee_in_lbp { let asset_in = register_external_asset(b"FCA".to_vec()).map_err(|_| BenchmarkError::Stop("Failed to register asset"))?; @@ -414,3 +480,20 @@ mod tests { impl_benchmark_test_suite!(new_test_ext(),); } + +use frame_support::traits::OnFinalize; +use frame_support::traits::OnInitialize; + +fn set_period(to: u32) { + while System::block_number() < Into::::into(to) { + let b = System::block_number(); + + System::on_finalize(b); + EmaOracle::on_finalize(b); + + System::on_initialize(b + 1_u32); + EmaOracle::on_initialize(b + 1_u32); + + System::set_block_number(b + 1_u32); + } +} diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index a1c2b9bf0..8cd9d41c4 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: 249, + spec_version: 252, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/runtime/hydradx/src/weights/pallet_route_executor.rs b/runtime/hydradx/src/weights/pallet_route_executor.rs index 47258545f..c24ae0a0a 100644 --- a/runtime/hydradx/src/weights/pallet_route_executor.rs +++ b/runtime/hydradx/src/weights/pallet_route_executor.rs @@ -19,7 +19,7 @@ //! Autogenerated weights for `pallet_route_executor` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-20, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-23, STEPS: `10`, REPEAT: `30`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `bench-bot`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` @@ -35,7 +35,7 @@ // --heap-pages=4096 // --template=scripts/pallet-weight-template.hbs // --pallet=pallet-route-executor -// --output=weights/router.rs +// --output=router.rs // --extrinsic=* #![cfg_attr(rustfmt, rustfmt_skip)] @@ -71,10 +71,10 @@ impl pallet_route_executor::WeightInfo for HydraWeight< // Proof Size summary in bytes: // Measured: `3535` // Estimated: `13905` - // Minimum execution time: 354_159_000 picoseconds. - Weight::from_parts(358_572_573, 13905) - // Standard Error: 306_143 - .saturating_add(Weight::from_parts(70_834_738, 0).saturating_mul(c.into())) + // Minimum execution time: 347_049_000 picoseconds. + Weight::from_parts(350_762_308, 13905) + // Standard Error: 214_404 + .saturating_add(Weight::from_parts(69_087_003, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(16_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -98,25 +98,27 @@ impl pallet_route_executor::WeightInfo for HydraWeight< // Proof Size summary in bytes: // Measured: `1637 + b * (1923 ±0)` // Estimated: `6156 + b * (7749 ±228_644_766_292_339_040)` - // Minimum execution time: 94_614_000 picoseconds. - Weight::from_parts(96_046_000, 6156) - // Standard Error: 876_130 - .saturating_add(Weight::from_parts(3_658_596, 0).saturating_mul(c.into())) - // Standard Error: 1_923_356 - .saturating_add(Weight::from_parts(272_645_114, 0).saturating_mul(b.into())) + // Minimum execution time: 94_096_000 picoseconds. + Weight::from_parts(95_234_000, 6156) + // Standard Error: 881_744 + .saturating_add(Weight::from_parts(3_499_280, 0).saturating_mul(c.into())) + // Standard Error: 1_935_679 + .saturating_add(Weight::from_parts(266_101_120, 0).saturating_mul(b.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().reads((13_u64).saturating_mul(b.into()))) .saturating_add(T::DbWeight::get().writes((7_u64).saturating_mul(b.into()))) .saturating_add(Weight::from_parts(0, 7749).saturating_mul(b.into())) } - /// Storage: `AssetRegistry::Assets` (r:6 w:0) - /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) + /// Storage: `EmaOracle::Oracles` (r:2 w:0) + /// Proof: `EmaOracle::Oracles` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) /// Storage: `Router::Routes` (r:1 w:1) /// Proof: `Router::Routes` (`max_values`: None, `max_size`: Some(90), added: 2565, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:7 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Tokens::Accounts` (r:15 w:0) /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) + /// Storage: `AssetRegistry::Assets` (r:6 w:0) + /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) /// Storage: `XYK::ShareToken` (r:6 w:0) /// Proof: `XYK::ShareToken` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) /// Storage: `Duster::AccountBlacklist` (r:7 w:0) @@ -133,11 +135,11 @@ impl pallet_route_executor::WeightInfo for HydraWeight< /// Proof: `Tokens::TotalIssuance` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) fn set_route_for_xyk() -> Weight { // Proof Size summary in bytes: - // Measured: `6426` + // Measured: `7004` // Estimated: `39735` - // Minimum execution time: 1_917_993_000 picoseconds. - Weight::from_parts(1_930_602_000, 39735) - .saturating_add(T::DbWeight::get().reads(55_u64)) + // Minimum execution time: 1_880_149_000 picoseconds. + Weight::from_parts(1_889_973_000, 39735) + .saturating_add(T::DbWeight::get().reads(57_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Router::Routes` (r:0 w:1) @@ -146,8 +148,8 @@ impl pallet_route_executor::WeightInfo for HydraWeight< // Proof Size summary in bytes: // Measured: `1012` // Estimated: `0` - // Minimum execution time: 25_174_000 picoseconds. - Weight::from_parts(25_689_000, 0) + // Minimum execution time: 25_566_000 picoseconds. + Weight::from_parts(26_013_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Router::Routes` (r:1 w:0) @@ -156,10 +158,30 @@ impl pallet_route_executor::WeightInfo for HydraWeight< // Proof Size summary in bytes: // Measured: `800` // Estimated: `3555` - // Minimum execution time: 7_562_000 picoseconds. - Weight::from_parts(7_748_000, 3555) + // Minimum execution time: 7_753_000 picoseconds. + Weight::from_parts(7_998_000, 3555) .saturating_add(T::DbWeight::get().reads(1_u64)) } + /// Storage: `EmaOracle::Oracles` (r:2 w:0) + /// Proof: `EmaOracle::Oracles` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + fn get_oracle_price_for_xyk() -> Weight { + // Proof Size summary in bytes: + // Measured: `1452` + // Estimated: `6294` + // Minimum execution time: 26_531_000 picoseconds. + Weight::from_parts(27_010_000, 6294) + .saturating_add(T::DbWeight::get().reads(2_u64)) + } + /// Storage: `EmaOracle::Oracles` (r:4 w:0) + /// Proof: `EmaOracle::Oracles` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`) + fn get_oracle_price_for_omnipool() -> Weight { + // Proof Size summary in bytes: + // Measured: `1814` + // Estimated: `11598` + // Minimum execution time: 40_726_000 picoseconds. + Weight::from_parts(41_280_000, 11598) + .saturating_add(T::DbWeight::get().reads(4_u64)) + } /// Storage: `LBP::PoolData` (r:1 w:0) /// Proof: `LBP::PoolData` (`max_values`: None, `max_size`: Some(163), added: 2638, mode: `MaxEncodedLen`) /// Storage: `Tokens::Locks` (r:1 w:0) @@ -170,8 +192,8 @@ impl pallet_route_executor::WeightInfo for HydraWeight< // Proof Size summary in bytes: // Measured: `1674` // Estimated: `6156` - // Minimum execution time: 36_086_000 picoseconds. - Weight::from_parts(36_646_000, 6156) + // Minimum execution time: 35_350_000 picoseconds. + Weight::from_parts(35_956_000, 6156) .saturating_add(T::DbWeight::get().reads(4_u64)) } } \ No newline at end of file