fix: Slippage precision calculation

- The resolution wasn't high enough before, so 0.1% slippage would round to 0% slippage. We should instead use basis point resolution to overcome this.
This commit is contained in:
TAMARA LIPOWSKI
2025-03-18 21:28:48 -04:00
parent 0e5eac9aa3
commit d644b63851

View File

@@ -74,10 +74,10 @@ pub fn get_min_amount_for_solution(solution: Solution) -> BigUint {
if let (Some(expected_amount), Some(slippage)) = if let (Some(expected_amount), Some(slippage)) =
(solution.expected_amount.as_ref(), solution.slippage) (solution.expected_amount.as_ref(), solution.slippage)
{ {
let one_hundred = BigUint::from(100u32); let bps = BigUint::from(10_000u32);
let slippage_percent = BigUint::from((slippage * 100.0) as u32); let slippage_percent = BigUint::from((slippage * 10000.0) as u32);
let multiplier = &one_hundred - slippage_percent; let multiplier = &bps - slippage_percent;
let expected_amount_with_slippage = (expected_amount * &multiplier) / &one_hundred; let expected_amount_with_slippage = (expected_amount * &multiplier) / &bps;
min_amount_out = max(min_amount_out, expected_amount_with_slippage); min_amount_out = max(min_amount_out, expected_amount_with_slippage);
} }
min_amount_out min_amount_out
@@ -133,3 +133,27 @@ pub fn get_runtime() -> Result<(Handle, Option<Arc<Runtime>>), EncodingError> {
} }
} }
} }
#[cfg(test)]
mod tests {
use num_bigint::BigUint;
use super::*;
use crate::encoding::models::Solution;
#[test]
fn test_min_amount_out_small_slippage() {
// Tests that the calculation's precision is high enough to support a slippage of 0.1%.
let solution = Solution {
exact_out: false,
given_amount: BigUint::from(1000000000000000000u64),
checked_amount: None,
slippage: Some(0.001f64),
expected_amount: Some(BigUint::from(1000000000000000000u64)),
..Default::default()
};
let min_amount_out = get_min_amount_for_solution(solution);
assert_eq!(min_amount_out, BigUint::from(999000000000000000u64));
}
}