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

feat: stableswap gradual amplification change #629

Merged
merged 22 commits into from
Jul 6, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
13a78c4
feat: use nonzerou16 type for amplification
enthusiastmartin Jul 3, 2023
97c113f
add test of amplication 0
enthusiastmartin Jul 3, 2023
204711d
reword amplification calculation - gradual change
enthusiastmartin Jul 4, 2023
174766b
fix amp math
enthusiastmartin Jul 4, 2023
7ebc401
remove amp change from update pool call
enthusiastmartin Jul 4, 2023
2fb6409
rename pool params
enthusiastmartin Jul 4, 2023
cb43244
use better error message
enthusiastmartin Jul 4, 2023
683c6a5
reformat
enthusiastmartin Jul 4, 2023
ff4b2b3
use correct non-std
enthusiastmartin Jul 4, 2023
7c89def
temporarily remove update pool benchmark - need to be updated for fee…
enthusiastmartin Jul 4, 2023
c551c55
Merge branch 'master' into feat/stableswap-amplification-rework
enthusiastmartin Jul 4, 2023
1daf5d5
renamed amplification fields
enthusiastmartin Jul 4, 2023
45addda
add additional checks when chagning amplification
enthusiastmartin Jul 4, 2023
717e4b5
add ampl change error test scenarios
enthusiastmartin Jul 4, 2023
9225cbe
add test of changing amplification across 1000 blocks
enthusiastmartin Jul 4, 2023
86113c3
add invariants tests while amp is changing
enthusiastmartin Jul 4, 2023
0958cf6
add ampl update event to create pool
enthusiastmartin Jul 4, 2023
a4581c1
allow change of ongoiing amplification change
enthusiastmartin Jul 5, 2023
a2c2fbd
update branch to reflect recent change in amplifcation change
enthusiastmartin Jul 5, 2023
3c038a0
happy clippy happy life
enthusiastmartin Jul 5, 2023
2ed11b8
update weights calls
enthusiastmartin Jul 5, 2023
e574d29
simplify condition
enthusiastmartin Jul 6, 2023
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
5 changes: 3 additions & 2 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion math/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ license = 'Apache-2.0'
name = "hydra-dx-math"
description = "A collection of utilities to make performing liquidity pool calculations more convenient."
repository = 'https://github.com/galacticcouncil/hydradx-math'
version = "7.3.0"
version = "7.4.0"

[dependencies]
primitive-types = {default-features = false, version = '0.12.0'}
Expand Down
30 changes: 30 additions & 0 deletions math/src/stableswap/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::types::Balance;
use num_traits::{CheckedDiv, CheckedMul, Zero};
use primitive_types::U256;
use sp_arithmetic::{FixedPointNumber, FixedU128, Permill};
use sp_std::ops::Div;
use sp_std::prelude::*;

pub const MAX_Y_ITERATIONS: u8 = 128;
Expand Down Expand Up @@ -346,6 +347,35 @@ pub(crate) fn calculate_y<const N: u8>(xp: &[Balance], d: Balance, amplification
Balance::try_from(y).ok()
}

pub fn calculate_amplification(
initial_amplification: u128,
final_amplification: u128,
initial_block: u128,
final_block: u128,
current_block: u128,
) -> u128 {
// short circuit if block parameters are invalid or start block is not reached yet
if current_block < initial_block || final_block <= initial_block {
return initial_amplification;
}

// short circuit if already reached desired block
if current_block >= final_block {
return final_amplification;
}

let step = final_amplification
.abs_diff(initial_amplification)
.saturating_mul(current_block.saturating_sub(initial_block))
.div(final_block.saturating_sub(initial_block));

if final_amplification > initial_amplification {
initial_amplification.saturating_add(step)
} else {
initial_amplification.saturating_sub(step)
}
}

#[inline]
fn has_converged(v0: U256, v1: U256, precision: U256) -> bool {
let diff = abs_diff(v0, v1);
Expand Down
41 changes: 41 additions & 0 deletions math/src/stableswap/tests/amplification.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use crate::stableswap::calculate_amplification;

#[test]
fn calculate_amplification_should_short_circuit_when_future_and_initial_amp_are_equal() {
let result = calculate_amplification(10, 10, 0, 100, 50);
assert_eq!(result, 10);
}

#[test]
fn calculate_amplification_should_short_circuit_when_current_timestamp_is_greater_than_future_timestamp() {
let result = calculate_amplification(10, 20, 0, 100, 150);
assert_eq!(result, 20);
}

#[test]
fn test_calculate_amplification_increase_amplification() {
let result = calculate_amplification(10, 20, 0, 100, 50);
assert_eq!(result, 15);
}

#[test]
fn test_calculate_amplification_decrease_amplification() {
let result = calculate_amplification(20, 10, 0, 100, 50);
assert_eq!(result, 15);
}

#[test]
fn test_calculate_amplification_step_increase_amplification() {
for idx in 0..1000 {
let result = calculate_amplification(2000, 5000, 0, 1000, idx);
assert_eq!(result, 2000 + idx * 3);
}
}

#[test]
fn test_calculate_amplification_step_decrease_amplification() {
for idx in 0..1000 {
let result = calculate_amplification(5000, 2000, 0, 1000, idx);
assert_eq!(result, 5000 - idx * 3);
}
}
1 change: 1 addition & 0 deletions math/src/stableswap/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod amplification;
mod invariants;
mod multi_assets;
mod two_assets;
Expand Down
6 changes: 4 additions & 2 deletions pallets/stableswap/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = 'pallet-stableswap'
version = '1.3.0'
version = '2.0.0'
description = 'AMM for correlated assets'
authors = ['GalacticCouncil']
edition = '2021'
Expand All @@ -17,6 +17,7 @@ bitflags = "1.3.2"
# parity
scale-info = { version = "2.1.2", default-features = false, features = ["derive"] }
codec = { default-features = false, features = ["derive"], package = "parity-scale-codec", version = "3.4.0" }
serde = { features = ["derive"], optional = true, version = "1.0.137" }

# primitives
sp-runtime = { workspace = true }
Expand Down Expand Up @@ -55,14 +56,15 @@ runtime-benchmarks = [
"hydra-dx-math/runtime-benchmarks",
]
std = [
"serde/std",
'codec/std',
"scale-info/std",
'frame-support/std',
'frame-system/std',
'sp-runtime/std',
'sp-core/std',
'sp-io/std',
'sp-std/std',
"scale-info/std",
"orml-tokens/std",
"frame-benchmarking/std",
"hydra-dx-math/std",
Expand Down
5 changes: 3 additions & 2 deletions pallets/stableswap/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ benchmarks! {
assert_eq!(T::Currency::free_balance(asset_id_to_withdraw, &lp_provider), 1296846466078107);
}


sell{
let caller: T::AccountId = account("caller", 0, 1);
let lp_provider: T::AccountId = account("provider", 0, 1);
Expand Down Expand Up @@ -351,6 +350,7 @@ benchmarks! {
assert_ne!(asset_tradability_old, asset_tradability_new);
}

/*
update_pool {
let caller: T::AccountId = account("caller", 0, 1);
let lp_provider: T::AccountId = account("provider", 0, 1);
Expand Down Expand Up @@ -393,10 +393,11 @@ benchmarks! {
}: _<T::RuntimeOrigin>(successful_origin, pool_id, amplification_new, trade_fee_new, withdraw_fee_new)
verify {
let pool = crate::Pallet::<T>::pools(pool_id).unwrap();
assert_eq!(pool.amplification, amplification_new.unwrap());
assert_eq!(pool.initial_amplification, amplification_new.unwrap());
assert_eq!(pool.trade_fee, trade_fee_new.unwrap());
assert_eq!(pool.withdraw_fee, withdraw_fee_new.unwrap());
}
*/

impl_benchmark_test_suite!(Pallet, crate::tests::mock::ExtBuilder::default().build(), crate::tests::mock::Test);
}
Loading
Loading