diff --git a/Cargo.lock b/Cargo.lock index a9b700c10..2ef7e3898 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,9 +172,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" @@ -4938,7 +4938,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "246.0.0" +version = "247.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", @@ -8746,7 +8746,7 @@ dependencies = [ [[package]] name = "pallet-otc" -version = "1.1.5" +version = "2.0.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -8768,7 +8768,7 @@ dependencies = [ [[package]] name = "pallet-otc-settlements" -version = "1.0.0" +version = "1.0.1" dependencies = [ "frame-benchmarking", "frame-support", diff --git a/pallets/otc-settlements/Cargo.toml b/pallets/otc-settlements/Cargo.toml index 50280f9d9..eabeedcfd 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.0' +version = '1.0.1' description = 'A pallet with offchain worker closing OTC arbs' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/otc-settlements/src/benchmarks.rs b/pallets/otc-settlements/src/benchmarks.rs index bee2f31aa..ea6cda44f 100644 --- a/pallets/otc-settlements/src/benchmarks.rs +++ b/pallets/otc-settlements/src/benchmarks.rs @@ -35,7 +35,7 @@ benchmarks! { ::Currency::mint_into(DAI.into(), &account, 1_000_000_000 * ONE)?; assert_ok!( - pallet_otc::Pallet::::place_order(RawOrigin::Signed(account).into(), HDX.into(), DAI.into(), 100_000_000 * ONE, 200_000_001 * ONE, true) + pallet_otc::Pallet::::place_order(RawOrigin::Signed(account).into(), HDX.into(), DAI.into(), 100_000_000 * ONE, 202_020_001 * ONE, true) ); let route = ::Router::get_route(AssetPair { diff --git a/pallets/otc-settlements/src/lib.rs b/pallets/otc-settlements/src/lib.rs index d5884e214..aed99cd45 100644 --- a/pallets/otc-settlements/src/lib.rs +++ b/pallets/otc-settlements/src/lib.rs @@ -289,6 +289,10 @@ impl Pallet { /// - `amount`: Amount necessary to close the arb. /// - `route`: The route we trade against. Required for the fee calculation. pub fn settle_otc(otc_id: OrderId, amount: Balance, route: Vec>>) -> DispatchResult { + log::debug!( + target: "offchain_worker::settle_otc", + "calling settle_otc(): otc_id: {:?} amount: {:?} route: {:?}", otc_id, amount, route); + let pallet_acc = Self::account_id(); let otc = >::get(otc_id).ok_or(Error::::OrderNotFound)?; @@ -315,8 +319,7 @@ impl Pallet { ::Currency::mint_into(asset_a, &pallet_acc, amount)?; // get initial otc price - let otc_price = - FixedU128::checked_from_rational(otc.amount_out, otc.amount_in).ok_or(ArithmeticError::Overflow)?; + let otc_price = Self::otc_price(&otc)?; // Router trade is disabled in the benchmarks, so disable this one as well. // Without disabling it, the requirements for the extrinsic cannot be met (e.g. profit). @@ -456,7 +459,7 @@ impl Pallet { let mut list = vec![]; for (otc_id, otc) in >::iter() { - let otc_price = FixedU128::checked_from_rational(otc.amount_out, otc.amount_in); + let otc_price = Self::otc_price(&otc).ok(); let route = T::Router::get_route(AssetPair { // To get the correct price, we need to switch the assets, otherwise @@ -594,4 +597,14 @@ impl Pallet { } None } + + /// Calculates the price (asset_out/asset_in) after subtracting the OTC fee from the amount_out. + fn otc_price(otc: &Order) -> Result { + let fee = pallet_otc::Pallet::::calculate_fee(otc.amount_out); + Ok(FixedU128::checked_from_rational( + otc.amount_out.checked_sub(fee).ok_or(ArithmeticError::Overflow)?, + otc.amount_in, + ) + .ok_or(ArithmeticError::Overflow)?) + } } diff --git a/pallets/otc-settlements/src/mock.rs b/pallets/otc-settlements/src/mock.rs index d319a25fe..4f1052f69 100644 --- a/pallets/otc-settlements/src/mock.rs +++ b/pallets/otc-settlements/src/mock.rs @@ -79,6 +79,7 @@ parameter_types! { pub MinProfitLimit: Balance = 10_000_000_000_000; pub PricePrecision: FixedU128 = FixedU128::from_rational(1, 1_000_000); pub MinProfitPercentage: Perbill = Perbill::from_rational(1u32, 100_000_u32); // 0.001% + pub OtcFee: Permill = Permill::from_percent(1u32); } parameter_type_with_key! { @@ -107,6 +108,8 @@ impl pallet_otc::Config for Test { type RuntimeEvent = RuntimeEvent; type ExistentialDeposits = ExistentialDeposits; type ExistentialDepositMultiplier = ExistentialDepositMultiplier; + type Fee = OtcFee; + type FeeReceiver = TreasuryAccount; type WeightInfo = (); } diff --git a/pallets/otc-settlements/src/tests.rs b/pallets/otc-settlements/src/tests.rs index a8057d4f4..2365a88da 100644 --- a/pallets/otc-settlements/src/tests.rs +++ b/pallets/otc-settlements/src/tests.rs @@ -196,7 +196,7 @@ fn profit_should_be_transferred_to_treasury_when_zero_initial_pallet_balance() { HDX, DAI, 100_000 * ONE, - 201_000 * ONE, + 205_000 * ONE, true, )); @@ -226,7 +226,7 @@ fn profit_should_be_transferred_to_treasury_when_nonzero_initial_pallet_balance( HDX, DAI, 100_000 * ONE, - 201_000 * ONE, + 205_000 * ONE, true, )); @@ -258,7 +258,7 @@ fn existing_arb_opportunity_should_trigger_trade() { HDX, // otc asset_in DAI, // otc asset_out 100_000 * ONE, - 201_000 * ONE, + 205_000 * ONE, true, )); @@ -294,7 +294,7 @@ fn existing_arb_opportunity_should_trigger_trade() { expect_last_events(vec![Event::Executed { asset_id: HDX, - profit: 2_067_802_207_347, + profit: 17_736_110_470_326, } .into()]); }); @@ -308,10 +308,8 @@ fn existing_arb_opportunity_should_trigger_trade_when_otc_is_not_partially_filla RuntimeOrigin::signed(ALICE), HDX, // otc asset_in DAI, // otc asset_out - // we got following 2 values from the logs of - // existing_arb_opportunity_should_trigger_trade test - 828_170_776_368_178, - 1_664_623_260_500_037, + 100_000 * ONE, + 300_000 * ONE, false, // not partially fillable )); @@ -347,7 +345,7 @@ fn existing_arb_opportunity_should_trigger_trade_when_otc_is_not_partially_filla expect_last_events(vec![Event::Executed { asset_id: HDX, - profit: 2_067_802_207_347, + profit: 2_732_618_471_117_260, } .into()]); }); @@ -365,7 +363,7 @@ fn existing_arb_opportunity_of_insufficient_asset_should_trigger_trade() { BTC, // otc asset_in HDX, // otc asset_out 200_000 * ONE, - 101_000 * ONE, + 105_000 * ONE, true, )); @@ -401,7 +399,7 @@ fn existing_arb_opportunity_of_insufficient_asset_should_trigger_trade() { expect_last_events(vec![Event::Executed { asset_id: BTC, - profit: 16_419_654_005_878, + profit: 245_338_363_920_576, } .into()]); }); @@ -416,7 +414,7 @@ fn multiple_arb_opportunities_should_trigger_trades() { HDX, // otc asset_in DAI, // otc asset_out 100_000 * ONE, - 201_000 * ONE, + 205_000 * ONE, true, )); assert_ok!(OTC::place_order( @@ -424,7 +422,7 @@ fn multiple_arb_opportunities_should_trigger_trades() { DOT, // otc asset_in KSM, // otc asset_out 100_000 * ONE, - 101_000 * ONE, + 102_000 * ONE, true, )); @@ -433,12 +431,12 @@ fn multiple_arb_opportunities_should_trigger_trades() { expect_events(vec![ Event::Executed { asset_id: HDX, - profit: 2_067_802_207_347, + profit: 17736110470326, } .into(), Event::Executed { asset_id: DOT, - profit: 12_345_450_557_916, + profit: 11860096179879, } .into(), ]); @@ -476,7 +474,7 @@ fn trade_should_be_triggered_when_arb_opportunity_appears() { >>::offchain_worker(System::block_number()); // make a trade to move the price and create an arb opportunity - assert_ok!(Omnipool::sell(RuntimeOrigin::signed(ALICE), HDX, DAI, 1_000 * ONE, ONE,)); + assert_ok!(Omnipool::sell(RuntimeOrigin::signed(ALICE), HDX, DAI, 3_000 * ONE, ONE,)); System::set_block_number(System::block_number() + 1); @@ -510,7 +508,7 @@ fn trade_should_be_triggered_when_arb_opportunity_appears() { expect_last_events(vec![Event::Executed { asset_id: HDX, - profit: 2_981_065_139_674, + profit: 5_173_145_606_735, } .into()]); }); @@ -619,7 +617,7 @@ fn test_offchain_worker_unsigned_transaction_submission() { HDX, // otc asset_in DAI, // otc asset_out 100_000 * ONE, - 201_000 * ONE, + 205_000 * ONE, true, )); @@ -641,7 +639,7 @@ fn test_offchain_worker_unsigned_transaction_submission() { tx.call, crate::mock::RuntimeCall::OtcSettlements(crate::Call::settle_otc_order { otc_id: 0, - amount: 828_170_776_368_178, + amount: 2_413_749_694_825_193, route, }) ); @@ -657,7 +655,7 @@ fn test_offchain_worker_signed_transaction_submission() { HDX, // otc asset_in DAI, // otc asset_out 100_000 * ONE, - 201_000 * ONE, + 205_000 * ONE, true, )); @@ -671,7 +669,7 @@ fn test_offchain_worker_signed_transaction_submission() { assert_ok!(OtcSettlements::settle_otc_order( RuntimeOrigin::signed(ALICE), otc_id, - 828_170_776_368_178, + 2_413_749_694_825_193, route, )); }) diff --git a/pallets/otc-settlements/src/weights.rs b/pallets/otc-settlements/src/weights.rs index 91c17c391..7e40e9064 100644 --- a/pallets/otc-settlements/src/weights.rs +++ b/pallets/otc-settlements/src/weights.rs @@ -1,3 +1,6 @@ +// This file is part of HydraDX. + +// Copyright (C) 2020-2023 Intergalactic, Limited (GIB). // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,7 +18,7 @@ //! Autogenerated weights for `pallet_otc_settlements` //! //! 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-12, 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` @@ -61,8 +64,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `747` // Estimated: `6196` - // Minimum execution time: 100_657_000 picoseconds. - Weight::from_parts(101_597_000, 6196) + // Minimum execution time: 97_577_000 picoseconds. + Weight::from_parts(98_741_000, 6196) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/pallets/otc/Cargo.toml b/pallets/otc/Cargo.toml index 6bf56e1e0..5c46fdfa6 100644 --- a/pallets/otc/Cargo.toml +++ b/pallets/otc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-otc' -version = '1.1.5' +version = '2.0.0' description = 'A pallet for trustless over-the-counter trading' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/otc/README.md b/pallets/otc/README.md index f7c5f9bca..e75f14c33 100644 --- a/pallets/otc/README.md +++ b/pallets/otc/README.md @@ -2,7 +2,8 @@ ## General description This pallet provides basic over-the-counter (OTC) trading functionality. It allows anyone to `place_order` by specifying a pair of assets (in and out), their respective amounts, and -whether the order is partially fillable. The order price is static and calculated as `amount_out / amount_in`. +whether the order is partially fillable. Fee is applied to all trades and is deducted from the `amount_out`. +Because of the fee, the order price is static and calculated as `(amount_out - fee) / amount_in`. ## Notes The pallet implements a minimum order size as an alternative to storage fees. The amounts of an open order cannot diff --git a/pallets/otc/src/lib.rs b/pallets/otc/src/lib.rs index 674a9f16d..a4604329d 100644 --- a/pallets/otc/src/lib.rs +++ b/pallets/otc/src/lib.rs @@ -17,7 +17,8 @@ // ## General description // This pallet provides basic over-the-counter (OTC) trading functionality. // It allows anyone to `place_order` by specifying a pair of assets (in and out), their respective amounts, and -// whether the order is partially fillable. The order price is static and calculated as `amount_out / amount_in`. +// whether the order is partially fillable. Fee is applied to all trades and is deducted from the `amount_out`. +// Because of the fee, the order price is static and calculated as `(amount_out - fee) / amount_in`. // // ## Notes // The pallet implements a minimum order size as an alternative to storage fees. The amounts of an open order cannot @@ -40,6 +41,7 @@ use hydradx_traits::Inspect; use orml_traits::{GetByKey, MultiCurrency, NamedMultiReservableCurrency}; use sp_core::U256; use sp_runtime::traits::{One, Zero}; +use sp_runtime::Permill; #[cfg(test)] mod tests; @@ -83,10 +85,10 @@ pub mod pallet { /// Identifier for the class of asset. type AssetId: Member + Parameter + Copy + HasCompact + MaybeSerializeDeserialize + MaxEncodedLen; - /// Asset Registry mechanism - used to check if asset is correctly registered in asset registry + /// Asset Registry mechanism - used to check if asset is correctly registered in asset registry. type AssetRegistry: Inspect; - /// Named reservable multi currency + /// Named reservable multi currency. type Currency: NamedMultiReservableCurrency< Self::AccountId, ReserveIdentifier = NamedReserveIdentifier, @@ -94,13 +96,24 @@ pub mod pallet { Balance = Balance, >; + /// The overarching event type. type RuntimeEvent: From> + IsType<::RuntimeEvent>; + /// Existential deposits provider. type ExistentialDeposits: GetByKey; #[pallet::constant] + /// Multiplier used to compute minimal amounts of asset_in and asset_out in an OTC. type ExistentialDepositMultiplier: Get; + /// Fee deducted from amount_out. + #[pallet::constant] + type Fee: Get; + + /// Fee receiver. + #[pallet::constant] + type FeeReceiver: Get; + /// Weight information for the extrinsics. type WeightInfo: WeightInfo; } @@ -116,6 +129,7 @@ pub mod pallet { who: T::AccountId, amount_in: Balance, amount_out: Balance, + fee: Balance, }, /// An Order has been partially filled PartiallyFilled { @@ -123,6 +137,7 @@ pub mod pallet { who: T::AccountId, amount_in: Balance, amount_out: Balance, + fee: Balance, }, /// An Order has been placed Placed { @@ -207,8 +222,15 @@ pub mod pallet { }; ensure!(T::AssetRegistry::exists(order.asset_in), Error::::AssetNotRegistered); + + let fee = Self::calculate_fee(order.amount_out); + Self::ensure_min_order_amount(order.asset_in, order.amount_in)?; - Self::ensure_min_order_amount(order.asset_out, amount_out)?; + // the fee is applied to amount_out + Self::ensure_min_order_amount( + order.asset_out, + order.amount_out.checked_sub(fee).ok_or(Error::::MathError)?, + )?; >::try_mutate(|next_id| -> DispatchResult { let order_id = *next_id; @@ -263,16 +285,23 @@ pub mod pallet { order.amount_in = order.amount_in.checked_sub(amount_in).ok_or(Error::::MathError)?; order.amount_out = order.amount_out.checked_sub(amount_out).ok_or(Error::::MathError)?; - Self::ensure_min_order_amount(order.asset_out, order.amount_out)?; + let fee = Self::calculate_fee(amount_out); + Self::ensure_min_order_amount(order.asset_in, order.amount_in)?; + // the fee is applied to amount_out + Self::ensure_min_order_amount( + order.asset_out, + order.amount_out.checked_sub(fee).ok_or(Error::::MathError)?, + )?; - Self::execute_order(order, &who, amount_in, amount_out)?; + Self::execute_order(order, &who, amount_in, amount_out, fee)?; Self::deposit_event(Event::PartiallyFilled { order_id, who, amount_in, amount_out, + fee, }); Ok(()) }) @@ -291,7 +320,9 @@ pub mod pallet { let who = ensure_signed(origin)?; let order = >::get(order_id).ok_or(Error::::OrderNotFound)?; - Self::execute_order(&order, &who, order.amount_in, order.amount_out)?; + let fee = Self::calculate_fee(order.amount_out); + + Self::execute_order(&order, &who, order.amount_in, order.amount_out, fee)?; >::remove(order_id); Self::deposit_event(Event::Filled { @@ -299,6 +330,7 @@ pub mod pallet { who, amount_in: order.amount_in, amount_out: order.amount_out, + fee, }); Ok(()) } @@ -352,13 +384,23 @@ impl Pallet { who: &T::AccountId, amount_in: Balance, amount_out: Balance, + fee: Balance, ) -> DispatchResult { T::Currency::transfer(order.asset_in, who, &order.owner, amount_in)?; let remaining_to_unreserve = + // returns any amount that was unable to be unreserved T::Currency::unreserve_named(&NAMED_RESERVE_ID, order.asset_out, &order.owner, amount_out); ensure!(remaining_to_unreserve.is_zero(), Error::::InsufficientReservedAmount); - T::Currency::transfer(order.asset_out, &order.owner, who, amount_out)?; + + let amount_out_without_fee = amount_out.checked_sub(fee).ok_or(Error::::MathError)?; + + T::Currency::transfer(order.asset_out, &order.owner, who, amount_out_without_fee)?; + T::Currency::transfer(order.asset_out, &order.owner, &T::FeeReceiver::get(), fee)?; Ok(()) } + + pub fn calculate_fee(amount: Balance) -> Balance { + T::Fee::get().mul_ceil(amount) + } } diff --git a/pallets/otc/src/tests/fill_order.rs b/pallets/otc/src/tests/fill_order.rs index 12e489739..42fb8fa70 100644 --- a/pallets/otc/src/tests/fill_order.rs +++ b/pallets/otc/src/tests/fill_order.rs @@ -24,12 +24,14 @@ use pretty_assertions::assert_eq; fn complete_fill_order_should_work() { ExtBuilder::default().build().execute_with(|| { // Arrange + let amount_in = 20 * ONE; + let amount_out = 100 * ONE; assert_ok!(OTC::place_order( RuntimeOrigin::signed(ALICE), DAI, HDX, - 20 * ONE, - 100 * ONE, + amount_in, + amount_out, true )); @@ -40,13 +42,14 @@ fn complete_fill_order_should_work() { let bob_dai_balance_before = Tokens::free_balance(DAI, &BOB); // Act - let amount = 20 * ONE; assert_ok!(OTC::fill_order(RuntimeOrigin::signed(BOB), 0)); // Assert let order = OTC::orders(0); assert!(order.is_none()); + let fee = OTC::calculate_fee(amount_out); + let alice_free_hdx_balance_after = Tokens::free_balance(HDX, &ALICE); let bob_hdx_balance_after = Tokens::free_balance(HDX, &BOB); @@ -56,17 +59,24 @@ fn complete_fill_order_should_work() { // Alice: HDX *free* balance remains the same, reserved balance decreases with amount_receive; DAI grows assert_eq!(alice_free_hdx_balance_after, alice_free_hdx_balance_before); assert_eq!(Tokens::reserved_balance_named(&otc::NAMED_RESERVE_ID, HDX, &ALICE), 0); - assert_eq!(alice_dai_balance_after, alice_dai_balance_before + amount); + assert_eq!(alice_dai_balance_after, alice_dai_balance_before + amount_in); // Bob: HDX grows, DAI decreases - assert_eq!(bob_hdx_balance_after, bob_hdx_balance_before + 100 * ONE); - assert_eq!(bob_dai_balance_after, bob_dai_balance_before - amount); + assert_eq!(bob_hdx_balance_after, bob_hdx_balance_before + 100 * ONE - fee); + assert_eq!(bob_dai_balance_after, bob_dai_balance_before - amount_in); + + // fee should be transferred to Treasury + assert_eq!( + Tokens::free_balance(HDX, &TreasuryAccount::get()), + TREASURY_INITIAL_BALANCE + fee + ); expect_events(vec![Event::Filled { order_id: 0, who: BOB, amount_in: 20 * ONE, amount_out: 100 * ONE, + fee: ONE, } .into()]); }); @@ -76,12 +86,14 @@ fn complete_fill_order_should_work() { fn complete_fill_order_should_work_when_order_is_not_partially_fillable() { ExtBuilder::default().build().execute_with(|| { // Arrange + let amount_in = 20 * ONE; + let amount_out = 100 * ONE; assert_ok!(OTC::place_order( RuntimeOrigin::signed(ALICE), DAI, HDX, - 20 * ONE, - 100 * ONE, + amount_in, + amount_out, false )); @@ -92,13 +104,14 @@ fn complete_fill_order_should_work_when_order_is_not_partially_fillable() { let bob_dai_balance_before = Tokens::free_balance(DAI, &BOB); // Act - let amount = 20 * ONE; assert_ok!(OTC::fill_order(RuntimeOrigin::signed(BOB), 0)); // Assert let order = OTC::orders(0); assert!(order.is_none()); + let fee = OTC::calculate_fee(amount_out); + let alice_free_hdx_balance_after = Tokens::free_balance(HDX, &ALICE); let bob_hdx_balance_after = Tokens::free_balance(HDX, &BOB); @@ -108,17 +121,24 @@ fn complete_fill_order_should_work_when_order_is_not_partially_fillable() { // Alice: HDX *free* balance remains the same, reserved balance decreases with amount_receive; DAI grows assert_eq!(alice_free_hdx_balance_after, alice_free_hdx_balance_before); assert_eq!(Tokens::reserved_balance_named(&otc::NAMED_RESERVE_ID, HDX, &ALICE), 0); - assert_eq!(alice_dai_balance_after, alice_dai_balance_before + amount); + assert_eq!(alice_dai_balance_after, alice_dai_balance_before + amount_in); // Bob: HDX grows, DAI decreases - assert_eq!(bob_hdx_balance_after, bob_hdx_balance_before + 100 * ONE); - assert_eq!(bob_dai_balance_after, bob_dai_balance_before - amount); + assert_eq!(bob_hdx_balance_after, bob_hdx_balance_before + 100 * ONE - fee); + assert_eq!(bob_dai_balance_after, bob_dai_balance_before - amount_in); + + // fee should be transferred to Treasury + assert_eq!( + Tokens::free_balance(HDX, &TreasuryAccount::get()), + TREASURY_INITIAL_BALANCE + fee + ); expect_events(vec![Event::Filled { order_id: 0, who: BOB, amount_in: 20 * ONE, amount_out: 100 * ONE, + fee: ONE, } .into()]); }); @@ -128,12 +148,14 @@ fn complete_fill_order_should_work_when_order_is_not_partially_fillable() { fn complete_fill_order_should_work_when_there_are_multiple_orders() { ExtBuilder::default().build().execute_with(|| { // Arrange + let amount_in = 20 * ONE; + let amount_out = 100 * ONE; assert_ok!(OTC::place_order( RuntimeOrigin::signed(ALICE), DAI, HDX, - 20 * ONE, - 100 * ONE, + amount_in, + amount_out, true )); @@ -153,13 +175,14 @@ fn complete_fill_order_should_work_when_there_are_multiple_orders() { let bob_dai_balance_before = Tokens::free_balance(DAI, &BOB); // Act - let amount = 20 * ONE; assert_ok!(OTC::fill_order(RuntimeOrigin::signed(BOB), 0)); // Assert let order = OTC::orders(0); assert!(order.is_none()); + let fee = OTC::calculate_fee(amount_out); + let alice_free_hdx_balance_after = Tokens::free_balance(HDX, &ALICE); let bob_hdx_balance_after = Tokens::free_balance(HDX, &BOB); @@ -172,17 +195,24 @@ fn complete_fill_order_should_work_when_there_are_multiple_orders() { Tokens::reserved_balance_named(&otc::NAMED_RESERVE_ID, HDX, &ALICE), 50 * ONE ); - assert_eq!(alice_dai_balance_after, alice_dai_balance_before + amount); + assert_eq!(alice_dai_balance_after, alice_dai_balance_before + amount_in); // Bob: HDX grows, DAI decreases - assert_eq!(bob_hdx_balance_after, bob_hdx_balance_before + 100 * ONE); - assert_eq!(bob_dai_balance_after, bob_dai_balance_before - amount); + assert_eq!(bob_hdx_balance_after, bob_hdx_balance_before + 100 * ONE - fee); + assert_eq!(bob_dai_balance_after, bob_dai_balance_before - amount_in); + + // fee should be transferred to Treasury + assert_eq!( + Tokens::free_balance(HDX, &TreasuryAccount::get()), + TREASURY_INITIAL_BALANCE + fee + ); expect_events(vec![Event::Filled { order_id: 0, who: BOB, amount_in: 20 * ONE, amount_out: 100 * ONE, + fee: ONE, } .into()]); }); diff --git a/pallets/otc/src/tests/invariants.rs b/pallets/otc/src/tests/invariants.rs index 26ba2956f..421b2d930 100644 --- a/pallets/otc/src/tests/invariants.rs +++ b/pallets/otc/src/tests/invariants.rs @@ -29,7 +29,7 @@ fn decimals() -> impl Strategy { } fn asset_amount(max: Balance, precision: u32) -> impl Strategy { - let min_order = 5 * 10u128.pow(precision) + 10u128.pow(precision); + let min_order = 6 * 10u128.pow(precision); let max_amount = max * 10u128.pow(precision); min_order..max_amount } @@ -40,12 +40,14 @@ fn amount_fill( precision_in: u32, precision_out: u32, ) -> impl Strategy { + let fee = OTC::calculate_fee(amount_in); + let price = FixedU128::from_rational(amount_in, amount_out); let m = price .checked_mul_int(MIN_ORDER_SIZE * 10u128.pow(precision_out)) .unwrap(); - let max_remaining_amount_out = amount_in - m; - let max_remaining_amount_in = amount_in - MIN_ORDER_SIZE * 10u128.pow(precision_in); + let max_remaining_amount_out = amount_in - m - fee; + let max_remaining_amount_in = amount_in - MIN_ORDER_SIZE * 10u128.pow(precision_in) - fee; 0..min(max_remaining_amount_out, max_remaining_amount_in) } diff --git a/pallets/otc/src/tests/mock.rs b/pallets/otc/src/tests/mock.rs index aff2a0daf..e314193d6 100644 --- a/pallets/otc/src/tests/mock.rs +++ b/pallets/otc/src/tests/mock.rs @@ -18,6 +18,7 @@ use crate::Config; use frame_support::{ parameter_types, traits::{Everything, Nothing}, + PalletId, }; use frame_system as system; use hydradx_traits::{registry::Inspect, AssetKind}; @@ -25,8 +26,8 @@ use orml_tokens::AccountData; use orml_traits::parameter_type_with_key; use sp_core::H256; use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup}, - BuildStorage, + traits::{AccountIdConversion, BlakeTwo256, IdentityLookup}, + BuildStorage, Permill, }; use std::{cell::RefCell, collections::HashMap}; @@ -48,6 +49,8 @@ pub const ONE: Balance = 1_000_000_000_000; pub const ALICE: AccountId = 1; pub const BOB: AccountId = 2; +pub const TREASURY_INITIAL_BALANCE: Balance = 1_000_000 * ONE; + frame_support::construct_runtime!( pub enum Test { @@ -66,11 +69,14 @@ thread_local! { parameter_types! { pub NativeCurrencyId: AssetId = HDX; pub ExistentialDepositMultiplier: u8 = 5; + pub OtcFee: Permill = Permill::from_percent(1u32); + pub const TreasuryPalletId: PalletId = PalletId(*b"aca/trsy"); + pub TreasuryAccount: AccountId = TreasuryPalletId::get().into_account_truncating(); } parameter_type_with_key! { pub ExistentialDeposits: |currency_id: AssetId| -> Balance { - EXISTENTIAL_DEPOSIT.with(|v| *v.borrow().get(currency_id).unwrap_or(&ONE)) + EXISTENTIAL_DEPOSIT.with(|v| *v.borrow().get(currency_id).unwrap_or(&(ONE / 10))) }; } @@ -81,6 +87,8 @@ impl otc::Config for Test { type RuntimeEvent = RuntimeEvent; type ExistentialDeposits = ExistentialDeposits; type ExistentialDepositMultiplier = ExistentialDepositMultiplier; + type Fee = OtcFee; + type FeeReceiver = TreasuryAccount; type WeightInfo = (); } @@ -245,6 +253,7 @@ impl Default for ExtBuilder { (BOB, HDX, 10_000), (ALICE, DAI, 100), (BOB, DAI, 100), + (TreasuryAccount::get(), HDX, 1_000_000), ], registered_assets: vec![HDX, DAI], } diff --git a/pallets/otc/src/tests/partial_fill_order.rs b/pallets/otc/src/tests/partial_fill_order.rs index 5657c3ec4..2b97f4509 100644 --- a/pallets/otc/src/tests/partial_fill_order.rs +++ b/pallets/otc/src/tests/partial_fill_order.rs @@ -48,6 +48,8 @@ fn partial_fill_order_should_work_when_order_is_partially_fillable() { let expected_amount_out = 25_000_000_000_000_u128; let expected_new_amount_in = 15_000_000_000_000_u128; let expected_new_amount_out = 75_000_000_000_000_u128; + let fee = OTC::calculate_fee(expected_amount_out); + assert_eq!(fee, 25 * ONE / 100); let alice_free_hdx_balance_after = Tokens::free_balance(HDX, &ALICE); let alice_reserved_hdx_balance_after = Tokens::reserved_balance_named(&otc::NAMED_RESERVE_ID, HDX, &ALICE); @@ -65,18 +67,28 @@ fn partial_fill_order_should_work_when_order_is_partially_fillable() { assert_eq!(alice_dai_balance_after, alice_dai_balance_before + amount); // Bob: HDX grows, DAI decreases - assert_eq!(bob_hdx_balance_after, bob_hdx_balance_before + expected_amount_out); + assert_eq!( + bob_hdx_balance_after, + bob_hdx_balance_before + expected_amount_out - fee + ); assert_eq!(bob_dai_balance_after, bob_dai_balance_before - amount); let order = OTC::orders(0).unwrap(); assert_eq!(order.amount_in, expected_new_amount_in); assert_eq!(order.amount_out, expected_new_amount_out); + // fee should be transferred to Treasury + assert_eq!( + Tokens::free_balance(HDX, &TreasuryAccount::get()), + TREASURY_INITIAL_BALANCE + fee + ); + expect_events(vec![Event::PartiallyFilled { order_id: 0, who: BOB, amount_in: 5 * ONE, amount_out: expected_amount_out, + fee, } .into()]); }); @@ -195,7 +207,7 @@ fn partial_fill_order_should_throw_error_when_remaining_amounts_are_too_low() { let bob_dai_balance_before = Tokens::free_balance(DAI, &BOB); // Act - let amount = 16 * ONE; + let amount = 20 * ONE - (ONE / 100); assert_noop!( OTC::partial_fill_order(RuntimeOrigin::signed(BOB), 0, amount), Error::::OrderAmountTooSmall diff --git a/pallets/otc/src/tests/place_order.rs b/pallets/otc/src/tests/place_order.rs index 3187c1bcd..7f43d2380 100644 --- a/pallets/otc/src/tests/place_order.rs +++ b/pallets/otc/src/tests/place_order.rs @@ -128,9 +128,10 @@ fn place_order_should_throw_error_when_asset_in_is_not_registered() { #[test] fn place_order_should_throw_error_when_amount_in_is_too_low() { ExtBuilder::default().build().execute_with(|| { - // Act + let amount_in = 4 * ONE / 10; // needs to be less than 5 * ED + let amount_out = 100 * ONE; assert_noop!( - OTC::place_order(RuntimeOrigin::signed(ALICE), DAI, HDX, 4 * ONE, 100 * ONE, true), + OTC::place_order(RuntimeOrigin::signed(ALICE), DAI, HDX, amount_in, amount_out, true), Error::::OrderAmountTooSmall ); }); @@ -139,9 +140,10 @@ fn place_order_should_throw_error_when_amount_in_is_too_low() { #[test] fn place_order_should_throw_error_when_amount_out_is_too_low() { ExtBuilder::default().build().execute_with(|| { - // Act + let amount_in = 100 * ONE; + let amount_out = 4 * ONE / 10; // needs to be less than 5 * ED assert_noop!( - OTC::place_order(RuntimeOrigin::signed(ALICE), DAI, HDX, 20 * ONE, 4 * ONE, true), + OTC::place_order(RuntimeOrigin::signed(ALICE), DAI, HDX, amount_in, amount_out, true), Error::::OrderAmountTooSmall ); }); diff --git a/pallets/otc/src/weights.rs b/pallets/otc/src/weights.rs index 4af2df9b9..cd8a19cdd 100644 --- a/pallets/otc/src/weights.rs +++ b/pallets/otc/src/weights.rs @@ -18,29 +18,24 @@ //! Autogenerated weights for `pallet_otc` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-05-23, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-12, 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: `None`, DB CACHE: `1024` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/release/hydradx +// target/release/hydradx // benchmark // pallet +// --chain=dev +// --steps=10 +// --repeat=30 // --wasm-execution=compiled -// --pallet -// * -// --extrinsic -// * -// --heap-pages -// 4096 -// --steps -// 50 -// --repeat -// 20 +// --heap-pages=4096 // --template=scripts/pallet-weight-template.hbs -// --output -// weights/ +// --pallet=pallet-otc +// --output=weights/otc.rs +// --extrinsic=* #![allow(unused_parens)] #![allow(unused_imports)] @@ -76,8 +71,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `963` // Estimated: `6190` - // Minimum execution time: 46_410_000 picoseconds. - Weight::from_parts(46_985_000, 6190) + // Minimum execution time: 46_746_000 picoseconds. + Weight::from_parts(47_337_000, 6190) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -89,20 +84,24 @@ impl WeightInfo for () { /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::BannedAssets` (r:2 w:0) /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) - /// Storage: `Tokens::Accounts` (r:4 w:4) + /// Storage: `Tokens::Accounts` (r:5 w:5) /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:0) + /// Storage: `System::Account` (r:3 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Tokens::Reserves` (r:1 w:1) /// Proof: `Tokens::Reserves` (`max_values`: None, `max_size`: Some(1261), added: 3736, mode: `MaxEncodedLen`) + /// Storage: `MultiTransactionPayment::AccountCurrencyMap` (r:1 w:0) + /// Proof: `MultiTransactionPayment::AccountCurrencyMap` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `MultiTransactionPayment::AcceptedCurrencies` (r:1 w:0) + /// Proof: `MultiTransactionPayment::AcceptedCurrencies` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) fn partial_fill_order() -> Weight { // Proof Size summary in bytes: - // Measured: `2034` - // Estimated: `11322` - // Minimum execution time: 116_670_000 picoseconds. - Weight::from_parts(117_660_000, 11322) - .saturating_add(RocksDbWeight::get().reads(14_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + // Measured: `2228` + // Estimated: `13905` + // Minimum execution time: 164_109_000 picoseconds. + Weight::from_parts(164_977_000, 13905) + .saturating_add(RocksDbWeight::get().reads(18_u64)) + .saturating_add(RocksDbWeight::get().writes(8_u64)) } /// Storage: `OTC::Orders` (r:1 w:1) /// Proof: `OTC::Orders` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `MaxEncodedLen`) @@ -110,22 +109,26 @@ impl WeightInfo for () { /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::BannedAssets` (r:2 w:0) /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) - /// Storage: `Tokens::Accounts` (r:4 w:4) + /// Storage: `Tokens::Accounts` (r:5 w:5) /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::Assets` (r:2 w:0) /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:0) + /// Storage: `System::Account` (r:3 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Tokens::Reserves` (r:1 w:1) /// Proof: `Tokens::Reserves` (`max_values`: None, `max_size`: Some(1261), added: 3736, mode: `MaxEncodedLen`) + /// Storage: `MultiTransactionPayment::AccountCurrencyMap` (r:1 w:0) + /// Proof: `MultiTransactionPayment::AccountCurrencyMap` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `MultiTransactionPayment::AcceptedCurrencies` (r:1 w:0) + /// Proof: `MultiTransactionPayment::AcceptedCurrencies` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) fn fill_order() -> Weight { // Proof Size summary in bytes: - // Measured: `2034` - // Estimated: `11322` - // Minimum execution time: 114_236_000 picoseconds. - Weight::from_parts(114_837_000, 11322) - .saturating_add(RocksDbWeight::get().reads(14_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + // Measured: `2228` + // Estimated: `13905` + // Minimum execution time: 159_500_000 picoseconds. + Weight::from_parts(161_112_000, 13905) + .saturating_add(RocksDbWeight::get().reads(18_u64)) + .saturating_add(RocksDbWeight::get().writes(8_u64)) } /// Storage: `OTC::Orders` (r:1 w:1) /// Proof: `OTC::Orders` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `MaxEncodedLen`) @@ -139,8 +142,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1197` // Estimated: `4726` - // Minimum execution time: 41_852_000 picoseconds. - Weight::from_parts(42_296_000, 4726) + // Minimum execution time: 42_224_000 picoseconds. + Weight::from_parts(42_776_000, 4726) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index 5db73f849..758161f11 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "246.0.0" +version = "247.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index d417620d4..03eda657b 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -1114,6 +1114,7 @@ parameter_types! { pub const ExistentialDepositMultiplier: u8 = 5; pub const PricePrecision: FixedU128 = FixedU128::from_rational(1, 100); pub MinProfitPercentage: Perbill = Perbill::from_rational(1u32, 100_000_u32); // 0.001% + pub OtcFee: Permill = Permill::from_rational(1u32, 1_000_u32); // 0.1% } impl pallet_otc::Config for Runtime { @@ -1123,6 +1124,8 @@ impl pallet_otc::Config for Runtime { type RuntimeEvent = RuntimeEvent; type ExistentialDeposits = AssetRegistry; type ExistentialDepositMultiplier = ExistentialDepositMultiplier; + type Fee = OtcFee; + type FeeReceiver = TreasuryAccount; type WeightInfo = weights::pallet_otc::HydraWeight; } diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index b4e698756..0543cc488 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: 246, + spec_version: 247, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/runtime/hydradx/src/weights/pallet_otc.rs b/runtime/hydradx/src/weights/pallet_otc.rs index 90abcc0ff..722bc4702 100644 --- a/runtime/hydradx/src/weights/pallet_otc.rs +++ b/runtime/hydradx/src/weights/pallet_otc.rs @@ -19,29 +19,24 @@ //! Autogenerated weights for `pallet_otc` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-05-23, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-07-12, 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: `None`, DB CACHE: `1024` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// ./target/release/hydradx +// target/release/hydradx // benchmark // pallet +// --chain=dev +// --steps=10 +// --repeat=30 // --wasm-execution=compiled -// --pallet -// * -// --extrinsic -// * -// --heap-pages -// 4096 -// --steps -// 50 -// --repeat -// 20 +// --heap-pages=4096 // --template=scripts/pallet-weight-template.hbs -// --output -// weights/ +// --pallet=pallet-otc +// --output=weights/otc.rs +// --extrinsic=* #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -71,8 +66,8 @@ impl pallet_otc::WeightInfo for HydraWeight { // Proof Size summary in bytes: // Measured: `963` // Estimated: `6190` - // Minimum execution time: 46_410_000 picoseconds. - Weight::from_parts(46_985_000, 6190) + // Minimum execution time: 46_746_000 picoseconds. + Weight::from_parts(47_337_000, 6190) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -84,20 +79,24 @@ impl pallet_otc::WeightInfo for HydraWeight { /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::BannedAssets` (r:2 w:0) /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) - /// Storage: `Tokens::Accounts` (r:4 w:4) + /// Storage: `Tokens::Accounts` (r:5 w:5) /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:0) + /// Storage: `System::Account` (r:3 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Tokens::Reserves` (r:1 w:1) /// Proof: `Tokens::Reserves` (`max_values`: None, `max_size`: Some(1261), added: 3736, mode: `MaxEncodedLen`) + /// Storage: `MultiTransactionPayment::AccountCurrencyMap` (r:1 w:0) + /// Proof: `MultiTransactionPayment::AccountCurrencyMap` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `MultiTransactionPayment::AcceptedCurrencies` (r:1 w:0) + /// Proof: `MultiTransactionPayment::AcceptedCurrencies` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) fn partial_fill_order() -> Weight { // Proof Size summary in bytes: - // Measured: `2034` - // Estimated: `11322` - // Minimum execution time: 116_670_000 picoseconds. - Weight::from_parts(117_660_000, 11322) - .saturating_add(T::DbWeight::get().reads(14_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + // Measured: `2228` + // Estimated: `13905` + // Minimum execution time: 164_109_000 picoseconds. + Weight::from_parts(164_977_000, 13905) + .saturating_add(T::DbWeight::get().reads(18_u64)) + .saturating_add(T::DbWeight::get().writes(8_u64)) } /// Storage: `OTC::Orders` (r:1 w:1) /// Proof: `OTC::Orders` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `MaxEncodedLen`) @@ -105,22 +104,26 @@ impl pallet_otc::WeightInfo for HydraWeight { /// Proof: `Duster::AccountBlacklist` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::BannedAssets` (r:2 w:0) /// Proof: `AssetRegistry::BannedAssets` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`) - /// Storage: `Tokens::Accounts` (r:4 w:4) + /// Storage: `Tokens::Accounts` (r:5 w:5) /// Proof: `Tokens::Accounts` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`) /// Storage: `AssetRegistry::Assets` (r:2 w:0) /// Proof: `AssetRegistry::Assets` (`max_values`: None, `max_size`: Some(125), added: 2600, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:0) + /// Storage: `System::Account` (r:3 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Tokens::Reserves` (r:1 w:1) /// Proof: `Tokens::Reserves` (`max_values`: None, `max_size`: Some(1261), added: 3736, mode: `MaxEncodedLen`) + /// Storage: `MultiTransactionPayment::AccountCurrencyMap` (r:1 w:0) + /// Proof: `MultiTransactionPayment::AccountCurrencyMap` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `MultiTransactionPayment::AcceptedCurrencies` (r:1 w:0) + /// Proof: `MultiTransactionPayment::AcceptedCurrencies` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) fn fill_order() -> Weight { // Proof Size summary in bytes: - // Measured: `2034` - // Estimated: `11322` - // Minimum execution time: 114_236_000 picoseconds. - Weight::from_parts(114_837_000, 11322) - .saturating_add(T::DbWeight::get().reads(14_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + // Measured: `2228` + // Estimated: `13905` + // Minimum execution time: 159_500_000 picoseconds. + Weight::from_parts(161_112_000, 13905) + .saturating_add(T::DbWeight::get().reads(18_u64)) + .saturating_add(T::DbWeight::get().writes(8_u64)) } /// Storage: `OTC::Orders` (r:1 w:1) /// Proof: `OTC::Orders` (`max_values`: None, `max_size`: Some(93), added: 2568, mode: `MaxEncodedLen`) @@ -134,8 +137,8 @@ impl pallet_otc::WeightInfo for HydraWeight { // Proof Size summary in bytes: // Measured: `1197` // Estimated: `4726` - // Minimum execution time: 41_852_000 picoseconds. - Weight::from_parts(42_296_000, 4726) + // Minimum execution time: 42_224_000 picoseconds. + Weight::from_parts(42_776_000, 4726) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } diff --git a/runtime/hydradx/src/weights/pallet_otc_settlements.rs b/runtime/hydradx/src/weights/pallet_otc_settlements.rs index b5957e31e..f0a613d50 100644 --- a/runtime/hydradx/src/weights/pallet_otc_settlements.rs +++ b/runtime/hydradx/src/weights/pallet_otc_settlements.rs @@ -1,3 +1,6 @@ +// This file is part of HydraDX. + +// Copyright (C) 2020-2023 Intergalactic, Limited (GIB). // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,7 +19,7 @@ //! Autogenerated weights for `pallet_otc_settlements` //! //! 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-12, 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` @@ -58,8 +61,8 @@ impl WeightInfo for HydraWeight { // Proof Size summary in bytes: // Measured: `747` // Estimated: `6196` - // Minimum execution time: 100_657_000 picoseconds. - Weight::from_parts(101_597_000, 6196) + // Minimum execution time: 97_577_000 picoseconds. + Weight::from_parts(98_741_000, 6196) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) }