amount_out calculation

This commit is contained in:
David Rusu 2025-03-10 12:26:01 +04:00
parent 9972df5f23
commit 545d5b822f
2 changed files with 32 additions and 0 deletions

View File

@ -267,6 +267,24 @@ impl ZoneData {
})
}
pub fn amount_out(&self, t_in: Unit, t_out: Unit, amount_in: u64) -> Option<u64> {
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) {

View File

@ -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]