From 545d5b822fa147d45dea0c6cdf847e8448171be3 Mon Sep 17 00:00:00 2001 From: David Rusu Date: Mon, 10 Mar 2025 12:26:01 +0400 Subject: [PATCH] amount_out calculation --- emmarin/apps/swapvm/app/src/lib.rs | 18 ++++++++++++++++++ emmarin/apps/swapvm/app/tests/swap.rs | 14 ++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/emmarin/apps/swapvm/app/src/lib.rs b/emmarin/apps/swapvm/app/src/lib.rs index 00bb85c..efbf4e3 100644 --- a/emmarin/apps/swapvm/app/src/lib.rs +++ b/emmarin/apps/swapvm/app/src/lib.rs @@ -267,6 +267,24 @@ impl ZoneData { }) } + pub fn amount_out(&self, t_in: Unit, t_out: Unit, amount_in: u64) -> Option { + let pair = Pair::new(t_in, t_out); + let pool = self.pools.get(&pair)?; + + let (balance_in, balance_out) = if pair.t0 == t_in { + (pool.balance_0, pool.balance_1) + } else { + (pool.balance_1, pool.balance_0) + }; + + let amount_in_after_fee = amount_in * 1000 - amount_in * 3; + + let amount_out = + (balance_out * 1000 * amount_in_after_fee) / (balance_in * 1000 + amount_in_after_fee); + + Some(amount_out / 1000) + } + /// A swap does not need to directly modify the pool balances, but the executor /// should make sure that required funds are provided. pub fn swap(&mut self, swap: &Swap) { diff --git a/emmarin/apps/swapvm/app/tests/swap.rs b/emmarin/apps/swapvm/app/tests/swap.rs index 2d791c7..33774b9 100644 --- a/emmarin/apps/swapvm/app/tests/swap.rs +++ b/emmarin/apps/swapvm/app/tests/swap.rs @@ -41,6 +41,20 @@ fn pair_price() { swapvm_state.pair_price(mem().unit(), nmo().unit()), Some(0.1) ); + + // Due to slippage, the amount we get out is less than what the price would imply + assert_eq!( + swapvm_state.amount_out(nmo().unit(), mem().unit(), 1), + Some(9) // 1 MEM slippage + ); + assert_eq!( + swapvm_state.amount_out(nmo().unit(), mem().unit(), 2), + Some(18) // 2 MEM slippage + ); + assert_eq!( + swapvm_state.amount_out(nmo().unit(), mem().unit(), 5), + Some(39) // 11 MEM slippage + ); } #[test]