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}