Skip to content
Merged
Next Next commit
OrderBook: market maker network fee (#762)
Signed-off-by: Mikhail Tagirov <[email protected]>
  • Loading branch information
wer1st authored Oct 5, 2023
commit 399e016e89d4ddbd6cea0a06cb0a900fee4fc46c
83 changes: 83 additions & 0 deletions pallets/order-book/src/fee_calculator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// This file is part of the SORA network and Polkaswap app.

// Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved.
// SPDX-License-Identifier: BSD-4-Clause

// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:

// Redistributions of source code must retain the above copyright notice, this list
// of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright notice, this
// list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// All advertising materials mentioning features or use of this software must display
// the following acknowledgement: This product includes software developed by Polka Biome
// Ltd., SORA, and Polkaswap.
//
// Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use crate::Config;
use common::prelude::FixedWrapper;
use common::Balance;
use sp_std::marker::PhantomData;

use common::prelude::constants::SMALL_FEE as BASE_FEE;

/// Calculator for order book custom fees
pub struct FeeCalculator<T: Config>(PhantomData<T>);

impl<T: Config> FeeCalculator<T> {
/// Calculates the fee for `place_limit_order` extrinsic.
///
/// The idea is to provide the reduced fee for market maker.
/// If extrinsic is successfull, user pays maximum half network fee.
/// If extrinsic failed, user pays full network fee.
///
/// The actual fee contains two parts: constant and dynamic.
/// Dynamic part depends on limit order lifetime. The longer the lifetime, the higher the dynamic fee.
///
/// const part = (4 / 7) * (base fee / 2)
/// dynamic part = (3 / 7) * (base fee / 2) * (lifetime / max_lifetime)
pub fn place_limit_order_fee(
lifetime: Option<u64>,
has_weight: bool,
is_err: bool,
) -> Option<Balance> {
// if place_limit_order() doesn't return a weight, it means that the limit order was converted into market order and the exchange fee should be taken
// if some error occurred, it means we don't prvide the reduced market maker fee for this call
if !has_weight || is_err {
return Some(BASE_FEE);
}

let market_maker_max_fee = BASE_FEE.checked_div(2)?;

// Maximum lifetime is used if `None` was supplied
let Some(lifetime) = lifetime else {
return Some(market_maker_max_fee);
};

let max_lifetime: u64 = T::MAX_ORDER_LIFESPAN.try_into().ok()?;

let life_ratio = FixedWrapper::from(lifetime) / FixedWrapper::from(max_lifetime);

let const_part = (FixedWrapper::from(market_maker_max_fee) / FixedWrapper::from(7))
* FixedWrapper::from(4);
let dynamic_part = (FixedWrapper::from(market_maker_max_fee) / FixedWrapper::from(7))
* FixedWrapper::from(3)
* life_ratio;

(const_part + dynamic_part).try_into_balance().ok()
}
}
10 changes: 7 additions & 3 deletions pallets/order-book/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ mod tests;
mod benchmarking;

pub mod cache_data_layer;
pub mod fee_calculator;
mod limit_order;
mod market_order;
mod order_book;
Expand Down Expand Up @@ -1093,7 +1094,8 @@ impl<T: Config> LiquiditySource<T::DEXId, T::AccountId, T::AssetId, Balance, Dis

ensure!(deal_info.is_valid(), Error::<T>::PriceCalculationFailed);

let fee = 0; // todo (m.tagirov)
// order-book doesn't take fee
let fee = Balance::zero();

match amount {
QuoteAmount::WithDesiredInput { .. } => Ok((
Expand Down Expand Up @@ -1161,7 +1163,8 @@ impl<T: Config> LiquiditySource<T::DEXId, T::AccountId, T::AssetId, Balance, Dis
let (input_amount, output_amount, executed_orders_count) =
order_book.execute_market_order(market_order, &mut data)?;

let fee = 0; // todo (m.tagirov)
// order-book doesn't take fee
let fee = Balance::zero();

let result = match desired_amount {
SwapAmount::WithDesiredInput { min_amount_out, .. } => {
Expand Down Expand Up @@ -1277,7 +1280,8 @@ impl<T: Config> LiquiditySource<T::DEXId, T::AccountId, T::AssetId, Balance, Dis
Error::<T>::InvalidOrderAmount
);

let fee = 0; // todo (m.tagirov)
// order-book doesn't take fee
let fee = Balance::zero();

Ok(SwapOutcome::new(*target_amount.balance(), fee))
}
Expand Down
112 changes: 112 additions & 0 deletions pallets/order-book/src/tests/fee_calculator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// This file is part of the SORA network and Polkaswap app.

// Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved.
// SPDX-License-Identifier: BSD-4-Clause

// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:

// Redistributions of source code must retain the above copyright notice, this list
// of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright notice, this
// list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// All advertising materials mentioning features or use of this software must display
// the following acknowledgement: This product includes software developed by Polka Biome
// Ltd., SORA, and Polkaswap.
//
// Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#![cfg(feature = "wip")] // order-book

use common::balance;
use common::prelude::constants::SMALL_FEE;
use framenode_runtime::order_book::fee_calculator::FeeCalculator;
use framenode_runtime::order_book::Config;
use framenode_runtime::Runtime;

#[test]
fn should_calculate_place_limit_order_fee() {
let max_lifetime = <Runtime as Config>::MAX_ORDER_LIFESPAN;

assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(Some(0), true, false).unwrap(),
balance!(0.0002)
);

assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(Some(max_lifetime / 10), true, false)
.unwrap(),
balance!(0.000215)
);

assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(Some(max_lifetime / 5), true, false)
.unwrap(),
balance!(0.00023)
);

assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(Some(max_lifetime / 2), true, false)
.unwrap(),
balance!(0.000275)
);

assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(Some(max_lifetime), true, false).unwrap(),
SMALL_FEE / 2
);
}

#[test]
fn should_calculate_place_limit_order_fee_without_weight() {
assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(Some(1000), false, false).unwrap(),
SMALL_FEE
);
assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(Some(0), false, false).unwrap(),
SMALL_FEE
);
assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(Some(1000000000000000), false, false)
.unwrap(),
SMALL_FEE
);
assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(None, false, false).unwrap(),
SMALL_FEE
);
}

#[test]
fn should_calculate_place_limit_order_fee_with_error() {
assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(Some(1000), true, true).unwrap(),
SMALL_FEE
);
assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(Some(0), true, true).unwrap(),
SMALL_FEE
);
assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(Some(1000000000000000), true, true)
.unwrap(),
SMALL_FEE
);
assert_eq!(
FeeCalculator::<Runtime>::place_limit_order_fee(None, true, true).unwrap(),
SMALL_FEE
);
}
1 change: 1 addition & 0 deletions pallets/order-book/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

mod data_layer;
mod extrinsics;
mod fee_calculator;
mod order_book;
mod orders;
mod pallet;
Expand Down
2 changes: 0 additions & 2 deletions pallets/order-book/src/tests/pallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,6 @@ fn should_quote() {
SwapOutcome::new(balance!(251.66326).into(), 0)
);

// todo (m.tagirov) remake when fee introduced
// with fee
assert_eq!(
OrderBookPallet::quote(
Expand Down Expand Up @@ -1390,7 +1389,6 @@ fn should_quote_without_impact() {
SwapOutcome::new(balance!(250).into(), 0)
);

// todo (m.tagirov) remake when fee introduced
// with fee
assert_eq!(
OrderBookPallet::quote_without_impact(
Expand Down
30 changes: 30 additions & 0 deletions runtime/src/migrations.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
// This file is part of the SORA network and Polkaswap app.

// Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved.
// SPDX-License-Identifier: BSD-4-Clause

// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:

// Redistributions of source code must retain the above copyright notice, this list
// of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright notice, this
// list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// All advertising materials mentioning features or use of this software must display
// the following acknowledgement: This product includes software developed by Polka Biome
// Ltd., SORA, and Polkaswap.
//
// Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use crate::*;
use bridge_types::GenericNetworkId;
use sp_runtime::traits::Zero;
Expand Down
30 changes: 30 additions & 0 deletions runtime/src/mock.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
// This file is part of the SORA network and Polkaswap app.

// Copyright (c) 2020, 2021, Polka Biome Ltd. All rights reserved.
// SPDX-License-Identifier: BSD-4-Clause

// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:

// Redistributions of source code must retain the above copyright notice, this list
// of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright notice, this
// list of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// All advertising materials mentioning features or use of this software must display
// the following acknowledgement: This product includes software developed by Polka Biome
// Ltd., SORA, and Polkaswap.
//
// Neither the name of the Polka Biome Ltd. nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY Polka Biome Ltd. AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Polka Biome Ltd. BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use common::mock::alice;
use common::PriceVariant;
use price_tools::AVG_BLOCK_SPAN;
Expand Down
Loading