Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AMM-CDA-7 Add event information for indexer for Hybrid Orderbook AMM #1288

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ default-members = [
"runtime/zeitgeist",
"zrml/authorized",
"zrml/court",
"zrml/hybrid-router",
"zrml/global-disputes",
"zrml/liquidity-mining",
"zrml/market-commons",
Expand All @@ -32,6 +33,7 @@ members = [
"runtime/zeitgeist",
"zrml/authorized",
"zrml/court",
"zrml/hybrid-router",
"zrml/global-disputes",
"zrml/liquidity-mining",
"zrml/market-commons",
Expand Down Expand Up @@ -235,6 +237,7 @@ zeitgeist-primitives = { path = "primitives", default-features = false }
zrml-authorized = { path = "zrml/authorized", default-features = false }
zrml-court = { path = "zrml/court", default-features = false }
zrml-global-disputes = { path = "zrml/global-disputes", default-features = false }
zrml-hybrid-router = { path = "zrml/hybrid-router", default-features = false }
zrml-liquidity-mining = { path = "zrml/liquidity-mining", default-features = false }
zrml-market-commons = { path = "zrml/market-commons", default-features = false }
zrml-neo-swaps = { path = "zrml/neo-swaps", default-features = false }
Expand Down
4 changes: 3 additions & 1 deletion primitives/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022-2023 Forecasting Technologies LTD.
// Copyright 2022-2024 Forecasting Technologies LTD.
// Copyright 2021-2022 Zeitgeist PM LLC.
//
// This file is part of Zeitgeist.
Expand All @@ -22,6 +22,8 @@
clippy::arithmetic_side_effects
)]

#[cfg(feature = "mock")]
pub mod base_multiples;
#[cfg(feature = "mock")]
pub mod mock;
pub mod ztg;
Expand Down
70 changes: 70 additions & 0 deletions primitives/src/constants/base_multiples.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright 2024 Forecasting Technologies LTD.
//
// This file is part of Zeitgeist.
//
// Zeitgeist is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// Zeitgeist is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Zeitgeist. If not, see <https://www.gnu.org/licenses/>.

#![cfg(feature = "mock")]

use crate::constants::BASE;

pub const _1: u128 = BASE;
pub const _2: u128 = 2 * _1;
pub const _3: u128 = 3 * _1;
pub const _4: u128 = 4 * _1;
pub const _5: u128 = 5 * _1;
pub const _6: u128 = 6 * _1;
pub const _7: u128 = 7 * _1;
pub const _8: u128 = 8 * _1;
pub const _9: u128 = 9 * _1;
pub const _10: u128 = 10 * _1;
pub const _11: u128 = 11 * _1;
pub const _12: u128 = 12 * _1;
pub const _14: u128 = 14 * _1;
pub const _17: u128 = 17 * _1;
pub const _20: u128 = 20 * _1;
pub const _23: u128 = 23 * _1;
pub const _24: u128 = 24 * _1;
pub const _30: u128 = 30 * _1;
pub const _36: u128 = 36 * _1;
pub const _40: u128 = 40 * _1;
pub const _70: u128 = 70 * _1;
pub const _80: u128 = 80 * _1;
pub const _100: u128 = 100 * _1;
pub const _101: u128 = 101 * _1;
pub const _444: u128 = 444 * _1;
pub const _500: u128 = 500 * _1;
pub const _777: u128 = 777 * _1;
pub const _1000: u128 = 1_000 * _1;

pub const _1_2: u128 = _1 / 2;

pub const _1_3: u128 = _1 / 3;
pub const _2_3: u128 = _2 / 3;

pub const _1_4: u128 = _1 / 4;
pub const _3_4: u128 = _3 / 4;

pub const _1_5: u128 = _1 / 5;

pub const _1_6: u128 = _1 / 6;
pub const _5_6: u128 = _5 / 6;

pub const _1_10: u128 = _1 / 10;
pub const _2_10: u128 = _2 / 10;
pub const _3_10: u128 = _3 / 10;
pub const _4_10: u128 = _4 / 10;
pub const _9_10: u128 = _9 / 10;

pub const _1_100: u128 = _1 / 100;
37 changes: 37 additions & 0 deletions primitives/src/hybrid_router_api_types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2024 Forecasting Technologies LTD.
//
// This file is part of Zeitgeist.
//
// Zeitgeist is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// Zeitgeist is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Zeitgeist. If not, see <https://www.gnu.org/licenses/>.

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct AmmTrade<Balance> {
pub amount_in: Balance,
pub amount_out: Balance,
pub swap_fee_amount: Balance,
pub external_fee_amount: Balance,
}

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct ExternalFee<AccountId, Balance> {
pub account: AccountId,
pub amount: Balance,
}

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct OrderbookTrade<AccountId, Balance> {
pub filled_maker_amount: Balance,
pub filled_taker_amount: Balance,
pub external_fee: ExternalFee<AccountId, Balance>,
}
1 change: 1 addition & 0 deletions primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ extern crate alloc;

mod asset;
pub mod constants;
pub mod hybrid_router_api_types;
mod market;
pub mod math;
mod max_runtime_usize;
Expand Down
2 changes: 2 additions & 0 deletions primitives/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ mod complete_set_operations_api;
mod deploy_pool_api;
mod dispute_api;
mod distribute_fees;
mod hybrid_router_amm_api;
mod hybrid_router_orderbook_api;
mod market_commons_pallet_api;
mod market_id;
Expand All @@ -31,6 +32,7 @@ pub use complete_set_operations_api::CompleteSetOperationsApi;
pub use deploy_pool_api::DeployPoolApi;
pub use dispute_api::{DisputeApi, DisputeMaxWeightApi, DisputeResolutionApi};
pub use distribute_fees::DistributeFees;
pub use hybrid_router_amm_api::HybridRouterAmmApi;
pub use hybrid_router_orderbook_api::HybridRouterOrderbookApi;
pub use market_commons_pallet_api::MarketCommonsPalletApi;
pub use market_id::MarketId;
Expand Down
9 changes: 9 additions & 0 deletions primitives/src/traits/distribute_fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
// You should have received a copy of the GNU General Public License
// along with Zeitgeist. If not, see <https://www.gnu.org/licenses/>.

use sp_runtime::Perbill;

/// Trait for distributing fees collected from trading to external recipients like the treasury.
pub trait DistributeFees {
type Asset;
Expand All @@ -40,4 +42,11 @@ pub trait DistributeFees {
account: &Self::AccountId,
amount: Self::Balance,
) -> Self::Balance;

/// Returns the percentage of the fee that is distributed.
///
/// # Arguments
///
/// - `market_id`: The market on which the fees belong to.
fn fee_percentage(market_id: Self::MarketId) -> Perbill;
}
137 changes: 137 additions & 0 deletions primitives/src/traits/hybrid_router_amm_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright 2024 Forecasting Technologies LTD.
//
// This file is part of Zeitgeist.
//
// Zeitgeist is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// Zeitgeist is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Zeitgeist. If not, see <https://www.gnu.org/licenses/>.

use crate::hybrid_router_api_types::AmmTrade;
use frame_support::dispatch::DispatchError;

/// A type alias for the return struct of AMM buy and sell.
pub type AmmTradeOf<T> = AmmTrade<<T as HybridRouterAmmApi>::Balance>;

/// Trait for handling the AMM part of the hybrid router.
pub trait HybridRouterAmmApi {
type AccountId;
type Asset;
type Balance;
type MarketId;

/// Checks if a pool exists for the given market ID.
///
/// # Arguments
///
/// - `market_id`: The market ID to check.
///
/// # Returns
///
/// Returns `true` if the pool exists, `false` otherwise.
fn pool_exists(market_id: Self::MarketId) -> bool;

/// Gets the spot price for the given market ID and asset.
///
/// # Arguments
///
/// - `market_id`: The market ID.
/// - `asset`: The asset to get the spot price for.
///
/// # Returns
///
/// Returns the spot price as a `Result` containing the balance, or an error if the spot price
/// cannot be retrieved.
fn get_spot_price(
market_id: Self::MarketId,
asset: Self::Asset,
) -> Result<Self::Balance, DispatchError>;

/// Calculates the amount a user has to buy to move the price of `asset` to `until`. Returns
/// zero if the current spot price is above or equal to `until`.
///
/// # Arguments
///
/// - `market_id`: The market ID for which to calculate the buy amount.
/// - `asset`: The asset to calculate the buy amount for.
/// - `until`: The maximum price.
///
/// # Returns
///
/// Returns the buy amount as a `Result` containing the balance, or an error if the buy amount
/// cannot be calculated.
fn calculate_buy_amount_until(
market_id: Self::MarketId,
asset: Self::Asset,
until: Self::Balance,
) -> Result<Self::Balance, DispatchError>;

/// Executes a buy transaction.
///
/// # Arguments
///
/// - `who`: The account ID of the user performing the buy.
/// - `market_id`: The market ID.
/// - `asset_out`: The asset to receive from the buy.
/// - `amount_in`: The base asset amount to input for the buy.
/// - `min_amount_out`: The minimum amount to receive from the buy.
///
/// # Returns
///
/// Returns `Ok(())` if the buy is successful, or an error if the buy fails.
fn buy(
who: Self::AccountId,
market_id: Self::MarketId,
asset_out: Self::Asset,
amount_in: Self::Balance,
min_amount_out: Self::Balance,
) -> Result<AmmTradeOf<Self>, DispatchError>;

/// Calculates the amount a user has to sell to move the price of `asset` to `until`. Returns
/// zero if the current spot price is below or equal to `until`.
///
/// # Arguments
///
/// - `market_id`: The market ID for which to calculate the sell amount.
/// - `asset`: The asset to calculate the sell amount for.
/// - `until`: The minimum price.
///
/// # Returns
///
/// Returns the sell amount as a `Result` containing the balance, or an error if the sell amount
/// cannot be calculated.
fn calculate_sell_amount_until(
market_id: Self::MarketId,
asset: Self::Asset,
until: Self::Balance,
) -> Result<Self::Balance, DispatchError>;

/// Executes a sell transaction.
///
/// # Arguments
///
/// - `who`: The account ID of the user performing the sell.
/// - `market_id`: The market ID.
/// - `asset_in`: The asset to sell.
/// - `amount_in`: The amount to input for the sell.
/// - `min_amount_out`: The minimum amount to receive from the sell.
///
/// # Returns
///
/// Returns `Ok(())` if the sell is successful, or an error if the sell fails.
fn sell(
who: Self::AccountId,
market_id: Self::MarketId,
asset_in: Self::Asset,
amount_in: Self::Balance,
min_amount_out: Self::Balance,
) -> Result<AmmTradeOf<Self>, DispatchError>;
}
Loading