Skip to content

Commit

Permalink
Implement Combinatorial Betting (#1354)
Browse files Browse the repository at this point in the history
* Revert "New Asset System (#1295)" (#1338)

* Revert "New Asset System (#1295)"

This reverts commit a956877.

* Fix formatting

* Update copyright

* Remove pallet-assets dependency

* Fix fuzz tests

* Merge `main` into `develop` (#1345)

* Update dependencies to Polkadot v1.1.0 (#1331)

* Update dependencies (#1319)

* Update dependencies to polkadot-v1.1.0

* Format code

* Remove duplicate dependencies

* Update zrml-asset-router (#1321)

* Update zrml-primitives

* Partially update asset-router

* Finalize logic adjustments in asset-router

* Make asset-router tests compilable

* Correct Inspect routing for market assets in Currencies

* Directly invoke Inspect API for Currencies

* Add tests for remaining Unbalances functions

* Update remaining Zeitgeist pallets (#1322)

* Update zrml-asset-router (#1321)

* Upgrade zrml-market-commons

* Upgrade zrml-authorized && use MockBlock instead of MockBlockU32

* Upgrade zrml-court

* Upgrade zrml-global-disputes

* Upgrade liquidity mining

* Upgrade zrml-rikiddo

* Upgrade zrml-simple-disputes

* Upgrade zrml-styx

* Upgrade zrml-orderbook

* Upgrade zrml-parimutuel

* Upgrade zrml-swaps

* Upgrade zrml-prediction-markets

* Upgrade zrml-neo-swaps

* Upgrade zrml-hybrid-router

* Update license headers

* Update runtime (#1323)

* Update weight files & Runtime enum

* Use workspace metadata

* Always use serde serialization for asset types

* Make battery station standalone runtime compilable

* Make benchmark and try-runtime feature compilable

* Make BS build with all features

* Make parachain tests compile

* Partially fix xcm tests

* Use safe xcm version 2

* Update Zeitgeist runtime (except xcm tests)

* Format code

* Remove deprecated comment

* Integrate new xcm-emulator (#1324)

* Integrate new xcm-emulator environment

* Utilize new xcm-emulator interfaces

* Spawn relay-para network using patched xcm-emulator

* Use proper collator genesis config

* Fix Rococo tests

* Finalize Battery Station XCM tests

* Finalize Zeitgeist XCM tests

* Update client (#1327)

* Fix rpc and work on client update

* Finalize standalone client

* Update parachain client

* Use same try-runtime subcommand in every case

* Update node/src/cli.rs

Co-authored-by: Malte Kliemann <[email protected]>

* Update try-runtime* Makefile targets

---------

Co-authored-by: Malte Kliemann <[email protected]>

* Make CI succeed and add migrations (#1329)

* Fix rpc and work on client update

* Finalize standalone client

* Update parachain client

* Use same try-runtime subcommand in every case

* Satisfy Clippy

* Fix benchmarks

* Add migrations

* Satisfy Clippy

* Update moonkit depedencies

* Free disk space more aggressively

---------

Co-authored-by: Malte Kliemann <[email protected]>

* Update spec version, try-runtime Makefile

* Fix copyright notices

* Fix broken chain state (#1336)

* Add `StorageVersion` fix and contrats fix migrations

* Don't set pallet-balances' storage version

* Remove migrations from pallet-contracts config

* Clear storage tries of contracts

* Fix migration and info logs in try-runtime

* Fix licenses and comments

* Fix formatting

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>

---------

Co-authored-by: Harald Heckmann <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>

* Merge

* Fix benchmark

* Fix compiler error

* Fix tests and imports

* Fix imports (again...)

* Fix orderbook benchmarks

* Fix fuzz tests

* Fix formatting

* Fix orderbook fuzz

---------

Co-authored-by: Harald Heckmann <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>

* Update versions to v0.5.3

* Restructure math module

* More scaffolding

* Implement combinatorial buy math

* Implement price calculation for combo

* Remove `println!`

* Implement equalization

* Implement selling

* Add tests for combinatorial buying

* Add more tests for combinatorial buying

* Add tests for equalization

* Add more tests/corner cases

* Implement full testing, fix critical bug

---------

Co-authored-by: Harald Heckmann <[email protected]>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 13, 2024
1 parent 2858166 commit ff21a04
Show file tree
Hide file tree
Showing 10 changed files with 1,063 additions and 153 deletions.
2 changes: 1 addition & 1 deletion zrml/neo-swaps/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ mod pallet {
use crate::{
consts::LN_NUMERICAL_LIMIT,
liquidity_tree::types::{BenchmarkInfo, LiquidityTree, LiquidityTreeError},
math::{Math, MathOps},
math::{traits::MathOps, types::Math},
traits::{pool_operations::PoolOperations, LiquiditySharesManager},
types::{FeeDistribution, MaxAssets, Pool},
weights::*,
Expand Down
20 changes: 20 additions & 0 deletions zrml/neo-swaps/src/math/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2023-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/>.

pub(crate) mod traits;
mod transcendental;
pub(crate) mod types;
54 changes: 54 additions & 0 deletions zrml/neo-swaps/src/math/traits/combo_math_ops.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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::{BalanceOf, Config};
use sp_runtime::DispatchError;

pub(crate) trait ComboMathOps<T>
where
T: Config,
{
fn calculate_swap_amount_out_for_buy(
buy: Vec<BalanceOf<T>>,
sell: Vec<BalanceOf<T>>,
amount_in: BalanceOf<T>,
liquidity: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError>;

fn calculate_equalize_amount(
buy: Vec<BalanceOf<T>>,
sell: Vec<BalanceOf<T>>,
amount_buy: BalanceOf<T>,
amount_sell: BalanceOf<T>,
liquidity: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError>;

fn calculate_swap_amount_out_for_sell(
buy: Vec<BalanceOf<T>>,
keep: Vec<BalanceOf<T>>,
sell: Vec<BalanceOf<T>>,
amount_buy: BalanceOf<T>,
amount_keep: BalanceOf<T>,
liquidity: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError>;

fn calculate_spot_price(
buy: Vec<BalanceOf<T>>,
sell: Vec<BalanceOf<T>>,
liquidity: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError>;
}
64 changes: 64 additions & 0 deletions zrml/neo-swaps/src/math/traits/math_ops.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2023-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::{BalanceOf, Config};
use sp_runtime::DispatchError;

pub(crate) trait MathOps<T>
where
T: Config,
{
fn calculate_swap_amount_out_for_buy(
reserve: BalanceOf<T>,
amount_in: BalanceOf<T>,
liquidity: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError>;

fn calculate_swap_amount_out_for_sell(
reserve: BalanceOf<T>,
amount_in: BalanceOf<T>,
liquidity: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError>;

fn calculate_spot_price(
reserve: BalanceOf<T>,
liquidity: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError>;

fn calculate_reserves_from_spot_prices(
amount: BalanceOf<T>,
spot_prices: Vec<BalanceOf<T>>,
) -> Result<(BalanceOf<T>, Vec<BalanceOf<T>>), DispatchError>;

fn calculate_buy_ln_argument(
reserve: BalanceOf<T>,
amount: BalanceOf<T>,
liquidity: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError>;

fn calculate_buy_amount_until(
until: BalanceOf<T>,
liquidity: BalanceOf<T>,
spot_price: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError>;

fn calculate_sell_amount_until(
until: BalanceOf<T>,
liquidity: BalanceOf<T>,
spot_price: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError>;
}
22 changes: 22 additions & 0 deletions zrml/neo-swaps/src/math/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// 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/>.

mod combo_math_ops;
mod math_ops;

pub(crate) use combo_math_ops::ComboMathOps;
pub(crate) use math_ops::MathOps;
120 changes: 120 additions & 0 deletions zrml/neo-swaps/src/math/transcendental.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Copyright 2023-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/>.
//
// This file incorporates work covered by the following copyright and
// permission notice:
//
// Copyright (c) 2019 Alain Brenzikofer, modified by GalacticCouncil(2021)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Original source: https://github.com/encointer/substrate-fixed
//
// The changes applied are: Re-used and extended tests for `exp` and other
// functions.

pub(crate) use hydra_dx_math::transcendental::{exp, ln};

#[cfg(test)]
mod tests {
use super::*;
use alloc::str::FromStr;
use fixed::types::U64F64;
use test_case::test_case;

type S = U64F64;
type D = U64F64;

#[test_case("0", false, "1")]
#[test_case("0", true, "1")]
#[test_case("1", false, "2.7182818284590452353")]
#[test_case("1", true, "0.367879441171442321595523770161460867445")]
#[test_case("2", false, "7.3890560989306502265")]
#[test_case("2", true, "0.13533528323661269186")]
#[test_case("0.1", false, "1.1051709180756476246")]
#[test_case("0.1", true, "0.9048374180359595733")]
#[test_case("0.9", false, "2.4596031111569496633")]
#[test_case("0.9", true, "0.40656965974059911195")]
#[test_case("1.5", false, "4.481689070338064822")]
#[test_case("1.5", true, "0.22313016014842982894")]
#[test_case("3.3", false, "27.1126389206578874259")]
#[test_case("3.3", true, "0.03688316740124000543")]
#[test_case("7.3456", false, "1549.3643050275008503592")]
#[test_case("7.3456", true, "0.00064542599616831253")]
#[test_case("12.3456789", false, "229964.194569082134542849")]
#[test_case("12.3456789", true, "0.00000434850304358833")]
#[test_case("13", false, "442413.39200892050332603603")]
#[test_case("13", true, "0.0000022603294069810542")]
fn exp_works(operand: &str, neg: bool, expected: &str) {
let o = U64F64::from_str(operand).unwrap();
let e = U64F64::from_str(expected).unwrap();
assert_eq!(exp::<S, D>(o, neg).unwrap(), e);
}

#[test_case("1", "0", false)]
#[test_case("2", "0.69314718055994530943", false)]
#[test_case("3", "1.09861228866810969136", false)]
#[test_case("2.718281828459045235360287471352662497757", "1", false)]
#[test_case("1.1051709180756476246", "0.09999999999999999975", false)]
#[test_case("2.4596031111569496633", "0.89999999999999999976", false)]
#[test_case("4.481689070338064822", "1.49999999999999999984", false)]
#[test_case("27.1126389206578874261", "3.3", false)]
#[test_case("1549.3643050275008503592", "7.34560000000000000003", false)]
#[test_case("229964.194569082134542849", "12.3456789000000000002", false)]
#[test_case("442413.39200892050332603603", "13.0000000000000000002", false)]
#[test_case("0.9048374180359595733", "0.09999999999999999975", true)]
#[test_case("0.40656965974059911195", "0.8999999999999999998", true)]
#[test_case("0.22313016014842982894", "1.4999999999999999999", true)]
#[test_case("0.03688316740124000543", "3.3000000000000000005", true)]
#[test_case("0.00064542599616831253", "7.34560000000000002453", true)]
#[test_case("0.00000434850304358833", "12.34567890000000711117", true)]
#[test_case("0.0000022603294069810542", "13.0000000000000045352", true)]
#[test_case("1.0001", "0.00009999500033330827", false)]
#[test_case("1.00000001", "0.0000000099999999499", false)]
#[test_case("0.9999", "0.00010000500033335825", true)]
#[test_case("0.99999999", "0.00000001000000004987", true)]
// Powers of 2 (since we're using squares when calculating the fractional part of log2.
#[test_case("3.999999999", "1.38629436086989061877", false)]
#[test_case("4", "1.38629436111989061886", false)]
#[test_case("4.000000001", "1.3862943613698906188", false)]
#[test_case("7.999999999", "2.07944154155483592824", false)]
#[test_case("8", "2.0794415416798359283", false)]
#[test_case("8.000000001", "2.0794415418048359282", false)]
#[test_case("0.499999999", "0.69314718255994531136", true)]
#[test_case("0.5", "0.69314718055994530943", true)]
#[test_case("0.500000001", "0.69314717855994531135", true)]
#[test_case("0.249999999", "1.38629436511989062684", true)]
#[test_case("0.25", "1.38629436111989061886", true)]
#[test_case("0.250000001", "1.38629435711989062676", true)]
fn ln_works(operand: &str, expected_abs: &str, expected_neg: bool) {
let o = U64F64::from_str(operand).unwrap();
let e = U64F64::from_str(expected_abs).unwrap();
let (a, n) = ln::<S, D>(o).unwrap();
assert_eq!(a, e);
assert_eq!(n, expected_neg);
}
}
Loading

0 comments on commit ff21a04

Please sign in to comment.