defituna_core/math/
fixed.rs

1use fusionamm_core::{CoreError, ARITHMETIC_OVERFLOW};
2
3pub enum Rounding {
4    Up,
5    Down,
6}
7
8//pub fn mul_u256(x: u128, y: u128) -> U256 {
9//    U256::from(x).mul(U256::from(y))
10//}
11
12pub fn mul_div_64(x: u64, y: u64, d: u64, rounding: Rounding) -> Result<u64, CoreError> {
13    let x_128 = x as u128;
14    let y_128 = y as u128;
15    let d_128 = d as u128;
16
17    match rounding {
18        Rounding::Up => {
19            let result = (x_128 * y_128)
20                .checked_add(d_128.checked_sub(1).ok_or(ARITHMETIC_OVERFLOW)?)
21                .ok_or(ARITHMETIC_OVERFLOW)?
22                .checked_div(d_128)
23                .ok_or(ARITHMETIC_OVERFLOW)?
24                .try_into()
25                .map_err(|_| ARITHMETIC_OVERFLOW)?;
26            Ok(result)
27        }
28
29        Rounding::Down => {
30            let result: u64 = (x_128 * y_128)
31                .checked_div(d_128)
32                .ok_or(ARITHMETIC_OVERFLOW)?
33                .try_into()
34                .map_err(|_| ARITHMETIC_OVERFLOW)?;
35            Ok(result)
36        }
37    }
38}