Skip to content

Commit

Permalink
Merge pull request #634 from galacticcouncil/feat/stableswap-slippage…
Browse files Browse the repository at this point in the history
…-remove

feat: stableswap add limit to remove liquidity [A6]
  • Loading branch information
enthusiastmartin authored Jul 7, 2023
2 parents fa71c82 + 5e7fcf7 commit 34e5951
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 130 deletions.
2 changes: 1 addition & 1 deletion 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 pallets/stableswap/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = 'pallet-stableswap'
version = '2.0.2'
version = '2.1.0'
description = 'AMM for correlated assets'
authors = ['GalacticCouncil']
edition = '2021'
Expand Down
60 changes: 30 additions & 30 deletions pallets/stableswap/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use sp_runtime::Permill;

use hydradx_traits::Registry;

use crate::types::{AssetLiquidity, Balance};
use crate::types::{AssetBalance, Balance};

// Stable benchmarks
// Worst case scenarios in any stableswap calculations are scenarios where "math" does max number of iterations.
Expand Down Expand Up @@ -71,8 +71,8 @@ benchmarks! {
let initial_liquidity = 1_000_000_000_000_000u128;
let liquidity_added = 300_000_000_000_000u128;

let mut initial: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut initial: Vec<AssetBalance<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetBalance<T::AssetId>> = vec![];

let mut asset_ids: Vec<T::AssetId> = Vec::new() ;
for idx in 0..MAX_ASSETS_IN_POOL {
Expand All @@ -81,11 +81,11 @@ benchmarks! {
asset_ids.push(asset_id);
T::Currency::update_balance(asset_id, &caller, 1_000_000_000_000_000i128)?;
T::Currency::update_balance(asset_id, &lp_provider, 1_000_000_000_000_000_000_000i128)?;
initial.push(AssetLiquidity{
initial.push(AssetBalance{
asset_id,
amount: initial_liquidity
});
added_liquidity.push(AssetLiquidity{
added_liquidity.push(AssetBalance{
asset_id,
amount: liquidity_added
});
Expand Down Expand Up @@ -121,8 +121,8 @@ benchmarks! {
let initial_liquidity = 1_000_000_000_000_000u128;
let liquidity_added = 300_000_000_000_000u128;

let mut initial: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut initial: Vec<AssetBalance<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetBalance<T::AssetId>> = vec![];

let mut asset_ids: Vec<T::AssetId> = Vec::new() ;
for idx in 0..MAX_ASSETS_IN_POOL {
Expand All @@ -131,11 +131,11 @@ benchmarks! {
asset_ids.push(asset_id);
T::Currency::update_balance(asset_id, &caller, 1_000_000_000_000_000i128)?;
T::Currency::update_balance(asset_id, &lp_provider, liquidity_added as i128)?;
initial.push(AssetLiquidity{
initial.push(AssetBalance{
asset_id,
amount: initial_liquidity
});
added_liquidity.push(AssetLiquidity{
added_liquidity.push(AssetBalance{
asset_id,
amount: liquidity_added
});
Expand Down Expand Up @@ -173,7 +173,7 @@ benchmarks! {

let shares = T::Currency::free_balance(pool_id, &lp_provider);

}: _(RawOrigin::Signed(lp_provider.clone()), pool_id, asset_id_to_withdraw, shares)
}: _(RawOrigin::Signed(lp_provider.clone()), pool_id, asset_id_to_withdraw, shares, 0)
verify {
assert_eq!(T::Currency::free_balance(pool_id, &lp_provider), 0u128);
assert_eq!(T::Currency::free_balance(asset_id_to_withdraw, &lp_provider), 1296846466078107);
Expand All @@ -185,8 +185,8 @@ benchmarks! {
let initial_liquidity = 1_000_000_000_000_000u128;
let liquidity_added = 300_000_000_000_000u128;

let mut initial: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut initial: Vec<AssetBalance<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetBalance<T::AssetId>> = vec![];

let mut asset_ids: Vec<T::AssetId> = Vec::new() ;
for idx in 0..MAX_ASSETS_IN_POOL {
Expand All @@ -195,11 +195,11 @@ benchmarks! {
asset_ids.push(asset_id);
T::Currency::update_balance(asset_id, &caller, 1_000_000_000_000_000i128)?;
T::Currency::update_balance(asset_id, &lp_provider, 1_000_000_000_000_000_000_000i128)?;
initial.push(AssetLiquidity{
initial.push(AssetBalance{
asset_id,
amount: initial_liquidity
});
added_liquidity.push(AssetLiquidity{
added_liquidity.push(AssetBalance{
asset_id,
amount: liquidity_added
});
Expand Down Expand Up @@ -256,8 +256,8 @@ benchmarks! {
let initial_liquidity = 1_000_000_000_000_000u128;
let liquidity_added = 300_000_000_000_000u128;

let mut initial: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut initial: Vec<AssetBalance<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetBalance<T::AssetId>> = vec![];

let mut asset_ids: Vec<T::AssetId> = Vec::new() ;
for idx in 0..MAX_ASSETS_IN_POOL {
Expand All @@ -266,11 +266,11 @@ benchmarks! {
asset_ids.push(asset_id);
T::Currency::update_balance(asset_id, &caller, 1_000_000_000_000_000i128)?;
T::Currency::update_balance(asset_id, &lp_provider, 1_000_000_000_000_000_000_000i128)?;
initial.push(AssetLiquidity{
initial.push(AssetBalance{
asset_id,
amount: initial_liquidity
});
added_liquidity.push(AssetLiquidity{
added_liquidity.push(AssetBalance{
asset_id,
amount: liquidity_added
});
Expand Down Expand Up @@ -326,8 +326,8 @@ benchmarks! {
let initial_liquidity = 1_000_000_000_000_000u128;
let liquidity_added = 300_000_000_000_000u128;

let mut initial: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut initial: Vec<AssetBalance<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetBalance<T::AssetId>> = vec![];

let mut asset_ids: Vec<T::AssetId> = Vec::new() ;
for idx in 0..MAX_ASSETS_IN_POOL {
Expand All @@ -336,11 +336,11 @@ benchmarks! {
asset_ids.push(asset_id);
T::Currency::update_balance(asset_id, &caller, 1_000_000_000_000_000i128)?;
T::Currency::update_balance(asset_id, &lp_provider, 1_000_000_000_000_000_000_000i128)?;
initial.push(AssetLiquidity{
initial.push(AssetBalance{
asset_id,
amount: initial_liquidity
});
added_liquidity.push(AssetLiquidity{
added_liquidity.push(AssetBalance{
asset_id,
amount: liquidity_added
});
Expand Down Expand Up @@ -374,8 +374,8 @@ benchmarks! {
let initial_liquidity = 1_000_000_000_000_000u128;
let liquidity_added = 300_000_000_000_000u128;

let mut initial: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut initial: Vec<AssetBalance<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetBalance<T::AssetId>> = vec![];

let mut asset_ids: Vec<T::AssetId> = Vec::new() ;
for idx in 0..MAX_ASSETS_IN_POOL {
Expand All @@ -384,11 +384,11 @@ benchmarks! {
asset_ids.push(asset_id);
T::Currency::update_balance(asset_id, &caller, 1_000_000_000_000_000i128)?;
T::Currency::update_balance(asset_id, &lp_provider, 1_000_000_000_000_000_000_000i128)?;
initial.push(AssetLiquidity{
initial.push(AssetBalance{
asset_id,
amount: initial_liquidity
});
added_liquidity.push(AssetLiquidity{
added_liquidity.push(AssetBalance{
asset_id,
amount: liquidity_added
});
Expand Down Expand Up @@ -419,8 +419,8 @@ benchmarks! {
let initial_liquidity = 1_000_000_000_000_000u128;
let liquidity_added = 300_000_000_000_000u128;

let mut initial: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetLiquidity<T::AssetId>> = vec![];
let mut initial: Vec<AssetBalance<T::AssetId>> = vec![];
let mut added_liquidity: Vec<AssetBalance<T::AssetId>> = vec![];

let mut asset_ids: Vec<T::AssetId> = Vec::new() ;
for idx in 0..MAX_ASSETS_IN_POOL {
Expand All @@ -429,11 +429,11 @@ benchmarks! {
asset_ids.push(asset_id);
T::Currency::update_balance(asset_id, &caller, 1_000_000_000_000_000i128)?;
T::Currency::update_balance(asset_id, &lp_provider, 1_000_000_000_000_000_000_000i128)?;
initial.push(AssetLiquidity{
initial.push(AssetBalance{
asset_id,
amount: initial_liquidity
});
added_liquidity.push(AssetLiquidity{
added_liquidity.push(AssetBalance{
asset_id,
amount: liquidity_added
});
Expand Down
21 changes: 13 additions & 8 deletions pallets/stableswap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub mod weights;

pub use trade_execution::*;

use crate::types::{AssetLiquidity, Balance, PoolInfo, Tradability};
use crate::types::{AssetBalance, Balance, PoolInfo, Tradability};
use hydradx_traits::pools::DustRemovalAccountWhitelist;
use orml_traits::MultiCurrency;
use sp_std::collections::btree_map::BTreeMap;
Expand Down Expand Up @@ -179,15 +179,14 @@ pub mod pallet {
pool_id: T::AssetId,
who: T::AccountId,
shares: Balance,
assets: Vec<AssetLiquidity<T::AssetId>>,
assets: Vec<AssetBalance<T::AssetId>>,
},
/// Liquidity removed.
LiquidityRemoved {
pool_id: T::AssetId,
who: T::AccountId,
shares: Balance,
asset: T::AssetId,
amount: Balance,
amounts: Vec<AssetBalance<T::AssetId>>,
fee: Balance,
},
/// Sell trade executed. Trade fee paid in asset leaving the pool (already subtracted from amount_out).
Expand Down Expand Up @@ -305,6 +304,9 @@ pub mod pallet {

/// New amplification is equal to the previous value.
SameAmplification,

/// Desired amount not reached.
MinimumAmountNotReached,
}

#[pallet::call]
Expand Down Expand Up @@ -483,7 +485,7 @@ pub mod pallet {
pub fn add_liquidity(
origin: OriginFor<T>,
pool_id: T::AssetId,
assets: Vec<AssetLiquidity<T::AssetId>>,
assets: Vec<AssetBalance<T::AssetId>>,
) -> DispatchResult {
let who = ensure_signed(origin)?;

Expand Down Expand Up @@ -512,6 +514,7 @@ pub mod pallet {
/// - `pool_id`: Pool Id
/// - `asset_id`: id of asset to receive
/// - 'share_amount': amount of shares to withdraw
/// - 'min_amount_out': minimum amount to receive
///
/// Emits `LiquidityRemoved` event when successful.
#[pallet::call_index(4)]
Expand All @@ -522,6 +525,7 @@ pub mod pallet {
pool_id: T::AssetId,
asset_id: T::AssetId,
share_amount: Balance,
min_amount_out: Balance,
) -> DispatchResult {
let who = ensure_signed(origin)?;

Expand Down Expand Up @@ -565,15 +569,16 @@ pub mod pallet {
)
.ok_or(ArithmeticError::Overflow)?;

ensure!(amount >= min_amount_out, Error::<T>::MinimumAmountNotReached);

T::Currency::withdraw(pool_id, &who, share_amount)?;
T::Currency::transfer(asset_id, &pool_account, &who, amount)?;

Self::deposit_event(Event::LiquidityRemoved {
pool_id,
who,
shares: share_amount,
asset: asset_id,
amount,
amounts: vec![AssetBalance { asset_id, amount }],
fee,
});

Expand Down Expand Up @@ -848,7 +853,7 @@ impl<T: Config> Pallet<T> {
fn do_add_liquidity(
who: &T::AccountId,
pool_id: T::AssetId,
assets: &[AssetLiquidity<T::AssetId>],
assets: &[AssetBalance<T::AssetId>],
) -> Result<Balance, DispatchError> {
let pool = Pools::<T>::get(pool_id).ok_or(Error::<T>::PoolNotFound)?;
ensure!(assets.len() <= pool.assets.len(), Error::<T>::MaxAssetsExceeded);
Expand Down
Loading

0 comments on commit 34e5951

Please sign in to comment.