hydra_dx_math/
fee.rs

1use crate::types::Balance;
2use num_traits::Zero;
3
4pub fn calculate_pool_trade_fee(amount: Balance, fee: (u32, u32)) -> Option<Balance> {
5    let numerator = fee.0;
6    let denominator = fee.1;
7
8    if denominator.is_zero() || numerator.is_zero() {
9        return Some(0);
10    }
11
12    if denominator == numerator {
13        return Some(amount);
14    }
15
16    amount
17        .checked_div(denominator as Balance)?
18        .checked_mul(numerator as Balance)
19}
20
21#[cfg(test)]
22mod tests {
23    use super::*;
24
25    #[test]
26    fn fee_calculations_should_work() {
27        let default_fee = (2, 1000).into();
28
29        assert_eq!(calculate_pool_trade_fee(1_000, default_fee), Some(2));
30        assert_eq!(
31            calculate_pool_trade_fee(1_000_000_000_000, default_fee),
32            Some(2_000_000_000)
33        );
34
35        let ten_percent_fee = (1, 10).into();
36
37        assert_eq!(calculate_pool_trade_fee(1_000, ten_percent_fee), Some(100));
38        assert_eq!(
39            calculate_pool_trade_fee(1_000_000_000_000, ten_percent_fee),
40            Some(100_000_000_000)
41        );
42
43        assert_eq!(calculate_pool_trade_fee(1_000, (1, 10).into()), Some(100));
44        assert_eq!(
45            calculate_pool_trade_fee(1_000_000_000_000, (1, 10).into()),
46            Some(100_000_000_000)
47        );
48
49        let max_amount = Balance::MAX;
50
51        assert_eq!(
52            calculate_pool_trade_fee(max_amount, default_fee),
53            Some(680564733841876926926749214863536422)
54        );
55        assert_eq!(
56            calculate_pool_trade_fee(max_amount, ten_percent_fee),
57            Some(34028236692093846346337460743176821145)
58        );
59
60        let max_fee = (1, 1).into();
61
62        assert_eq!(calculate_pool_trade_fee(max_amount, max_fee), Some(max_amount));
63        assert_eq!(calculate_pool_trade_fee(1_000, max_fee), Some(1_000));
64
65        assert_eq!(calculate_pool_trade_fee(max_amount, (1, 1).into()), Some(max_amount));
66        assert_eq!(calculate_pool_trade_fee(1_000, (1, 1).into()), Some(1_000));
67
68        let zero_amount = 0u128;
69        assert_eq!(calculate_pool_trade_fee(zero_amount, default_fee), Some(0));
70
71        let unrealistic_fee = (1, u32::MAX).into();
72
73        assert_eq!(
74            calculate_pool_trade_fee(max_amount, unrealistic_fee),
75            Some(79228162532711081671548469249)
76        );
77
78        assert_eq!(
79            calculate_pool_trade_fee(max_amount, (1, u32::MAX).into()),
80            Some(79228162532711081671548469249)
81        );
82
83        let unrealistic_fee = (u32::MAX, 1).into();
84
85        assert_eq!(calculate_pool_trade_fee(max_amount, unrealistic_fee), None);
86        assert_eq!(calculate_pool_trade_fee(max_amount, (u32::MAX, 1).into()), None);
87
88        let zero_fee = (0, 0).into();
89
90        assert_eq!(calculate_pool_trade_fee(max_amount, zero_fee), Some(0));
91        assert_eq!(calculate_pool_trade_fee(1_000, zero_fee), Some(0));
92
93        assert_eq!(calculate_pool_trade_fee(max_amount, (0, 0).into()), Some(0));
94        assert_eq!(calculate_pool_trade_fee(1_000, (0, 0).into()), Some(0));
95
96        assert_eq!(calculate_pool_trade_fee(max_amount, (1, 0).into()), Some(0));
97        assert_eq!(calculate_pool_trade_fee(1_000, (0, 1).into()), Some(0));
98    }
99}