Skip to content

Commit

Permalink
Calculate classical sells with combinatorial math
Browse files Browse the repository at this point in the history
  • Loading branch information
maltekliemann committed Sep 16, 2024
1 parent ba0fec9 commit 64b5ee9
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 11 deletions.
14 changes: 12 additions & 2 deletions zrml/neo-swaps/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,14 +628,24 @@ mod pallet {
amount_in <= pool.calculate_numerical_threshold(),
Error::<T>::NumericalLimits(NumericalLimitsError::MaxAmountExceeded),
);

let buy = vec![asset_in];
let keep = vec![];
let sell = pool.assets_complement(&buy);
let amount_out = pool.calculate_swap_amount_out_for_sell(
buy,
keep,
sell,
amount_in,
Zero::zero(),
)?;

// Instead of first executing a swap with `(n-1)` transfers from the pool account to
// `who` and then selling complete sets, we prevent `(n-1)` storage reads: 1)
// Transfer `amount_in` units of `asset_in` to the pool account, 2) sell
// `amount_out` complete sets using the pool account, 3) transfer
// `amount_out_minus_fees` units of collateral to `who`. The fees automatically end
// up in the pool.
let amount_out = pool.calculate_swap_amount_out_for_sell(asset_in, amount_in)?;
// Beware! This transfer **must** happen _after_ calculating `amount_out`:
T::MultiCurrency::transfer(asset_in, &who, &pool.account_id, amount_in)?;
T::CompleteSetOperations::sell_complete_set(
pool.account_id.clone(),
Expand Down
16 changes: 11 additions & 5 deletions zrml/neo-swaps/src/traits/pool_operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,22 @@ pub(crate) trait PoolOperations<T: Config> {
amount_in: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError>;

/// Calculate the amount receives from selling an outcome to the pool.
/// Calculate the amount receives from closing the specified combinatorial bet.
///
/// # Parameters
///
/// - `asset_in`: The outcome being sold.
/// - `amount_in`: The amount of `asset_in` sold.
/// - `buy`: The buy of the combinatorial bet to close.
/// - `keep`: The keep of the combinatorial bet to close.
/// - `sell`: The sell of the combinatorial bet to close.
/// - `amount_buy`: The amount of the buy held in the combinatorial position.
/// - `amount_sell`: The amount of the sell held in the combinatorial position.
fn calculate_swap_amount_out_for_sell(
&self,
asset_in: AssetOf<T>,
amount_in: BalanceOf<T>,
buy: Vec<AssetOf<T>>,
keep: Vec<AssetOf<T>>,
sell: Vec<AssetOf<T>>,
amount_buy: BalanceOf<T>,
amount_sell: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError>;

/// Calculate the spot price of `asset`.
Expand Down
21 changes: 17 additions & 4 deletions zrml/neo-swaps/src/types/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,24 @@ where

fn calculate_swap_amount_out_for_sell(
&self,
asset_in: AssetOf<T>,
amount_in: BalanceOf<T>,
buy: Vec<AssetOf<T>>,
keep: Vec<AssetOf<T>>,
sell: Vec<AssetOf<T>>,
amount_buy: BalanceOf<T>,
amount_sell: BalanceOf<T>,
) -> Result<BalanceOf<T>, DispatchError> {
let reserve = self.reserve_of(&asset_in)?;
Math::<T>::calculate_swap_amount_out_for_sell(reserve, amount_in, self.liquidity_parameter)
let reserves_buy = self.reserves_of(&buy)?;
let reserves_keep = self.reserves_of(&keep)?;
let reserves_sell = self.reserves_of(&sell)?;

ComboMath::<T>::calculate_swap_amount_out_for_sell(
reserves_buy,
reserves_keep,
reserves_sell,
amount_buy,
amount_sell,
self.liquidity_parameter,
)
}

fn calculate_spot_price(&self, asset: AssetOf<T>) -> Result<BalanceOf<T>, DispatchError> {
Expand Down

0 comments on commit 64b5ee9

Please sign in to comment.