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

refactor: Upgrade math crate #131

Merged
merged 15 commits into from
Mar 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions pallets/amm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ homepage = 'https://github.com/galacticcouncil/hydradx-node'
license = 'Unlicense'
name = 'pallet-amm'
repository = 'https://github.com/galacticcouncil/hydradx-node'
version = '2.0.0'
version = '2.1.0'

[package.metadata.docs.rs]
targets = ['x86_64-unknown-linux-gnu']
Expand All @@ -25,7 +25,7 @@ version = '1.3.4'
primitive-types = {default-features = false, version = '0.8.0'}
serde = {features = ['derive'], optional = true, version = '1.0.101'}

hydra-dx-math = {default-features = false, version = "0.1.0", git = "https://github.com/galacticcouncil/hydraDX-math", tag="v0.1.0"}
hydra-dx-math = {default-features = false, version = "1.0.0", git = "https://github.com/galacticcouncil/hydraDX-math", tag="v1.0.0"}

# Local dependencies
pallet-asset-registry = {path = '../asset-registry', default-features = false, version = '2.0.0'}
Expand Down
39 changes: 15 additions & 24 deletions pallets/amm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,10 @@ decl_module! {
let asset_b_reserve = T::Currency::free_balance(asset_b, &pair_account);
let total_liquidity = Self::total_liquidity(&pair_account);

let amount_b_required = hydra_dx_math::calculate_liquidity_in(asset_a_reserve,
asset_b_reserve,
amount_a).ok_or(Error::<T>::AddAssetAmountInvalid)?;
let amount_b_required = hydra_dx_math::calculate_liquidity_in(asset_a_reserve, asset_b_reserve, amount_a)
.map_err(|_| {
Error::<T>::AddAssetAmountInvalid
})?;

let shares_added = if asset_a < asset_b { amount_a } else { amount_b_required };

Expand Down Expand Up @@ -365,10 +366,10 @@ decl_module! {
let asset_a_reserve = T::Currency::free_balance(asset_a, &pair_account);
let asset_b_reserve = T::Currency::free_balance(asset_b, &pair_account);

let liquidity_out = hydra_dx_math::calculate_liquidity_out(asset_a_reserve,
asset_b_reserve,
liquidity_amount,
total_shares).ok_or(Error::<T>::RemoveAssetAmountInvalid)?;
let liquidity_out = hydra_dx_math::calculate_liquidity_out(asset_a_reserve, asset_b_reserve, liquidity_amount, total_shares)
.map_err(|_| {
Error::<T>::RemoveAssetAmountInvalid
})?;

let (remove_amount_a, remove_amount_b) = liquidity_out;

Expand Down Expand Up @@ -496,8 +497,7 @@ impl<T: Config> AMM<T::AccountId, AssetId, AssetPair, Balance> for Module<T> {
let asset_b_reserve = T::Currency::free_balance(asset_b, &pair_account);

hydra_dx_math::calculate_spot_price(asset_a_reserve, asset_b_reserve, amount)
.or(Some(0))
.unwrap()
.unwrap_or_else(|_| Balance::zero())
}

fn validate_sell(
Expand Down Expand Up @@ -536,13 +536,8 @@ impl<T: Config> AMM<T::AccountId, AssetId, AssetPair, Balance> for Module<T> {

let transfer_fee = Self::calculate_fees(amount, discount, &mut hdx_amount)?;

let sale_price =
match hydra_dx_math::calculate_sell_price(asset_in_total, asset_out_total, amount - transfer_fee) {
Some(x) => x,
None => {
return Err(Error::<T>::SellAssetAmountInvalid.into());
}
};
let sale_price = hydra_dx_math::calculate_out_given_in(asset_in_total, asset_out_total, amount - transfer_fee)
.map_err(|_| Error::<T>::SellAssetAmountInvalid)?;

ensure!(asset_out_total >= sale_price, Error::<T>::InsufficientAssetBalance);

Expand All @@ -560,7 +555,7 @@ impl<T: Config> AMM<T::AccountId, AssetId, AssetPair, Balance> for Module<T> {
let asset_reserve = T::Currency::free_balance(assets.asset_in, &hdx_pair_account);

let hdx_fee_spot_price = hydra_dx_math::calculate_spot_price(asset_reserve, hdx_reserve, hdx_amount)
.ok_or(Error::<T>::CannotApplyDiscount)?;
.map_err(|_| Error::<T>::CannotApplyDiscount)?;

ensure!(
T::Currency::free_balance(hdx_asset, who) >= hdx_fee_spot_price,
Expand Down Expand Up @@ -660,12 +655,8 @@ impl<T: Config> AMM<T::AccountId, AssetId, AssetPair, Balance> for Module<T> {
);

let buy_price =
match hydra_dx_math::calculate_buy_price(asset_in_reserve, asset_out_reserve, amount + transfer_fee) {
Some(x) => x,
None => {
return Err(Error::<T>::BuyAssetAmountInvalid.into());
}
};
hydra_dx_math::calculate_in_given_out(asset_out_reserve, asset_in_reserve, amount + transfer_fee)
.map_err(|_| Error::<T>::BuyAssetAmountInvalid)?;

ensure!(
T::Currency::free_balance(assets.asset_in, who) >= buy_price,
Expand All @@ -686,7 +677,7 @@ impl<T: Config> AMM<T::AccountId, AssetId, AssetPair, Balance> for Module<T> {
let asset_reserve = T::Currency::free_balance(assets.asset_out, &hdx_pair_account);

let hdx_fee_spot_price = hydra_dx_math::calculate_spot_price(asset_reserve, hdx_reserve, hdx_amount)
.ok_or(Error::<T>::CannotApplyDiscount)?;
.map_err(|_| Error::<T>::CannotApplyDiscount)?;

ensure!(
T::Currency::free_balance(hdx_asset, who) >= hdx_fee_spot_price,
Expand Down
49 changes: 25 additions & 24 deletions pallets/amm/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::*;
pub use crate::mock::{Currency, ExtBuilder, Origin, System, Test, TestEvent, ACA, ALICE, AMM, BOB, DOT, HDX};
use frame_support::{assert_noop, assert_ok};
use hydra_dx_math::MathError;
use primitives::traits::AMM as AMMPool;

pub fn new_test_ext() -> sp_io::TestExternalities {
Expand Down Expand Up @@ -1160,45 +1161,45 @@ fn single_sell_more_than_ratio_in_should_not_work() {
}

#[test]
fn test_calculate_sell_price() {
fn test_calculate_out_given_in() {
ExtBuilder::default().build().execute_with(|| {
let sell_reserve: Balance = 10000000000000;
let buy_reserve: Balance = 100000;
let sell_amount: Balance = 100000000000;
let result = hydra_dx_math::calculate_sell_price(sell_reserve, buy_reserve, sell_amount);
assert_eq!(result, Some(991));
let in_reserve: Balance = 10000000000000;
let out_reserve: Balance = 100000;
let in_amount: Balance = 100000000000;
let result = hydra_dx_math::calculate_out_given_in(in_reserve, out_reserve, in_amount);
assert_eq!(result, Ok(991));
});
}

#[test]
fn test_calculate_sell_price_invalid() {
fn test_calculate_out_given_in_invalid() {
ExtBuilder::default().build().execute_with(|| {
let sell_reserve: Balance = 0;
let buy_reserve: Balance = 1000;
let sell_amount: Balance = 0;
let result = hydra_dx_math::calculate_sell_price(sell_reserve, buy_reserve, sell_amount);
assert_eq!(result, None);
let in_reserve: Balance = 0;
let out_reserve: Balance = 1000;
let in_amount: Balance = 0;
let result = hydra_dx_math::calculate_out_given_in(in_reserve, out_reserve, in_amount);
assert_eq!(result, Err(MathError::ZeroInReserve));
});
}

#[test]
fn test_calculate_buy_price_insufficient_pool_balance() {
fn test_calculate_in_given_out_insufficient_pool_balance() {
ExtBuilder::default().build().execute_with(|| {
let sell_reserve: Balance = 10000000000000;
let buy_reserve: Balance = 100000;
let buy_amount: Balance = 100000000000;
let result = hydra_dx_math::calculate_buy_price(sell_reserve, buy_reserve, buy_amount);
assert_eq!(result, None);
let in_reserve: Balance = 10000000000000;
let out_reserve: Balance = 100000;
let out_amount: Balance = 100000000000;
let result = hydra_dx_math::calculate_in_given_out(out_reserve, in_reserve, out_amount);
assert_eq!(result, Err(MathError::InsufficientOutReserve));
});
}

#[test]
fn test_calculate_buy_price() {
fn test_calculate_in_given_out() {
ExtBuilder::default().build().execute_with(|| {
let sell_reserve: Balance = 10000000000000;
let buy_reserve: Balance = 10000000;
let buy_amount: Balance = 1000000;
let result = hydra_dx_math::calculate_buy_price(sell_reserve, buy_reserve, buy_amount);
assert_eq!(result, Some(1111111111112));
let in_reserve: Balance = 10000000000000;
let out_reserve: Balance = 10000000;
let out_amount: Balance = 1000000;
let result = hydra_dx_math::calculate_in_given_out(out_reserve, in_reserve, out_amount);
assert_eq!(result, Ok(1111111111112));
});
}
126 changes: 64 additions & 62 deletions pallets/amm/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,77 +35,79 @@
// --output=weights.rs
// --template=.maintain/pallet-weight-template.hbs


#![allow(unused_parens)]
#![allow(unused_imports)]

use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
use frame_support::{
traits::Get,
weights::{constants::RocksDbWeight, Weight},
};
use sp_std::marker::PhantomData;

/// Weight functions needed for amm.
pub trait WeightInfo {
fn create_pool() -> Weight;
fn add_liquidity() -> Weight;
fn remove_liquidity() -> Weight;
fn sell() -> Weight;
fn buy() -> Weight;
fn create_pool() -> Weight;
fn add_liquidity() -> Weight;
fn remove_liquidity() -> Weight;
fn sell() -> Weight;
fn buy() -> Weight;
}

/// Weights for amm using the hydraDX node and recommended hardware.
pub struct HydraWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for HydraWeight<T> {
fn create_pool() -> Weight {
(250_200_000 as Weight)
.saturating_add(T::DbWeight::get().reads(11 as Weight))
.saturating_add(T::DbWeight::get().writes(13 as Weight))
}
fn add_liquidity() -> Weight {
(239_134_000 as Weight)
.saturating_add(T::DbWeight::get().reads(9 as Weight))
.saturating_add(T::DbWeight::get().writes(8 as Weight))
}
fn remove_liquidity() -> Weight {
(240_260_000 as Weight)
.saturating_add(T::DbWeight::get().reads(8 as Weight))
.saturating_add(T::DbWeight::get().writes(7 as Weight))
}
fn sell() -> Weight {
(169_053_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
fn buy() -> Weight {
(168_649_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
}
impl<T: frame_system::Config> WeightInfo for HydraWeight<T> {
fn create_pool() -> Weight {
(250_200_000 as Weight)
.saturating_add(T::DbWeight::get().reads(11 as Weight))
.saturating_add(T::DbWeight::get().writes(13 as Weight))
}
fn add_liquidity() -> Weight {
(239_134_000 as Weight)
.saturating_add(T::DbWeight::get().reads(9 as Weight))
.saturating_add(T::DbWeight::get().writes(8 as Weight))
}
fn remove_liquidity() -> Weight {
(240_260_000 as Weight)
.saturating_add(T::DbWeight::get().reads(8 as Weight))
.saturating_add(T::DbWeight::get().writes(7 as Weight))
}
fn sell() -> Weight {
(169_053_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
fn buy() -> Weight {
(168_649_000 as Weight)
.saturating_add(T::DbWeight::get().reads(5 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
}

// For backwards compatibility and tests
impl WeightInfo for () {
fn create_pool() -> Weight {
(250_200_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(11 as Weight))
.saturating_add(RocksDbWeight::get().writes(13 as Weight))
}
fn add_liquidity() -> Weight {
(239_134_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(9 as Weight))
.saturating_add(RocksDbWeight::get().writes(8 as Weight))
}
fn remove_liquidity() -> Weight {
(240_260_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(8 as Weight))
.saturating_add(RocksDbWeight::get().writes(7 as Weight))
}
fn sell() -> Weight {
(169_053_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
fn buy() -> Weight {
(168_649_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
}
// For backwards compatibility and tests
impl WeightInfo for () {
fn create_pool() -> Weight {
(250_200_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(11 as Weight))
.saturating_add(RocksDbWeight::get().writes(13 as Weight))
}
fn add_liquidity() -> Weight {
(239_134_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(9 as Weight))
.saturating_add(RocksDbWeight::get().writes(8 as Weight))
}
fn remove_liquidity() -> Weight {
(240_260_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(8 as Weight))
.saturating_add(RocksDbWeight::get().writes(7 as Weight))
}
fn sell() -> Weight {
(169_053_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
fn buy() -> Weight {
(168_649_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
}
2 changes: 1 addition & 1 deletion pallets/exchange/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ primitive-types = {default-features = false, version = '0.8.0'}
serde = {features = ['derive'], optional = true, version = '1.0.101'}

# Local dependencies
pallet-amm = {path = '../amm', default-features = false, version = '2.0.0'}
pallet-amm = {path = '../amm', default-features = false }
pallet-asset-registry = {path = '../asset-registry', default-features = false, version = '2.0.0'}
primitives = {path = '../../primitives', default-features = false, version = '2.0.0'}

Expand Down
2 changes: 1 addition & 1 deletion pallets/exchange/benchmarking/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ serde = { features = ['derive'], optional = true, version = '1.0.101' }
# Local dependencies
primitives = { path = '../../../primitives', default-features = false, version = '2.0.0' }
pallet-asset-registry= { path = '../../asset-registry', default-features = false, version = '2.0.0' }
pallet-amm = { path = '../../amm', default-features = false, version = '2.0.0' }
pallet-amm = { path = '../../amm', default-features = false }
pallet-exchange = { path = '../../exchange', default-features = false, version = '2.0.0' }

# ORML dependencies
Expand Down
2 changes: 1 addition & 1 deletion pallets/transaction-multi-payment/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ sp-runtime = {default-features = false, version = '2.0.0'}
sp-api= {default-features = false, version = '2.0.0'}
pallet-balances = {default-features = false, version = '2.0.0' }
pallet-asset-registry = {path = '../asset-registry', default-features = false, version = '2.0.0'}
pallet-amm = {path = '../amm', default-features = false, version = '2.0.0'}
pallet-amm = {path = '../amm', default-features = false }

[dev-dependencies]
sp-io = {default-features = false, version = '2.0.0'}
Expand Down
2 changes: 1 addition & 1 deletion pallets/transaction-multi-payment/benchmarking/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ serde = { features = ['derive'], optional = true, version = '1.0.101' }
# Local dependencies
primitives = { path = '../../../primitives', default-features = false, version = '2.0.0' }
pallet-asset-registry= { path = '../../asset-registry', default-features = false, version = '2.0.0' }
pallet-amm = { path = '../../amm', default-features = false, version = '2.0.0' }
pallet-amm = { path = '../../amm', default-features = false }
pallet-transaction-multi-payment = { path = '../../transaction-multi-payment', default-features = false, version = '3.0.0' }

# ORML dependencies
Expand Down