stable_swap_client/
fees.rs1use arrayref::{array_mut_ref, array_ref, array_refs, mut_array_refs};
4use solana_program::{
5 program_error::ProgramError,
6 program_pack::{Pack, Sealed},
7};
8
9#[repr(C)]
11#[derive(Clone, Copy, Debug, Default, PartialEq)]
12#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
13pub struct Fees {
14 pub admin_trade_fee_numerator: u64,
16 pub admin_trade_fee_denominator: u64,
18 pub admin_withdraw_fee_numerator: u64,
20 pub admin_withdraw_fee_denominator: u64,
22 pub trade_fee_numerator: u64,
24 pub trade_fee_denominator: u64,
26 pub withdraw_fee_numerator: u64,
28 pub withdraw_fee_denominator: u64,
30}
31
32impl Sealed for Fees {}
33impl Pack for Fees {
34 const LEN: usize = 64;
35 fn unpack_from_slice(input: &[u8]) -> Result<Self, ProgramError> {
36 let input = array_ref![input, 0, 64];
37 #[allow(clippy::ptr_offset_with_cast)]
38 let (
39 admin_trade_fee_numerator,
40 admin_trade_fee_denominator,
41 admin_withdraw_fee_numerator,
42 admin_withdraw_fee_denominator,
43 trade_fee_numerator,
44 trade_fee_denominator,
45 withdraw_fee_numerator,
46 withdraw_fee_denominator,
47 ) = array_refs![input, 8, 8, 8, 8, 8, 8, 8, 8];
48 Ok(Self {
49 admin_trade_fee_numerator: u64::from_le_bytes(*admin_trade_fee_numerator),
50 admin_trade_fee_denominator: u64::from_le_bytes(*admin_trade_fee_denominator),
51 admin_withdraw_fee_numerator: u64::from_le_bytes(*admin_withdraw_fee_numerator),
52 admin_withdraw_fee_denominator: u64::from_le_bytes(*admin_withdraw_fee_denominator),
53 trade_fee_numerator: u64::from_le_bytes(*trade_fee_numerator),
54 trade_fee_denominator: u64::from_le_bytes(*trade_fee_denominator),
55 withdraw_fee_numerator: u64::from_le_bytes(*withdraw_fee_numerator),
56 withdraw_fee_denominator: u64::from_le_bytes(*withdraw_fee_denominator),
57 })
58 }
59
60 fn pack_into_slice(&self, output: &mut [u8]) {
61 let output = array_mut_ref![output, 0, 64];
62 let (
63 admin_trade_fee_numerator,
64 admin_trade_fee_denominator,
65 admin_withdraw_fee_numerator,
66 admin_withdraw_fee_denominator,
67 trade_fee_numerator,
68 trade_fee_denominator,
69 withdraw_fee_numerator,
70 withdraw_fee_denominator,
71 ) = mut_array_refs![output, 8, 8, 8, 8, 8, 8, 8, 8];
72 *admin_trade_fee_numerator = self.admin_trade_fee_numerator.to_le_bytes();
73 *admin_trade_fee_denominator = self.admin_trade_fee_denominator.to_le_bytes();
74 *admin_withdraw_fee_numerator = self.admin_withdraw_fee_numerator.to_le_bytes();
75 *admin_withdraw_fee_denominator = self.admin_withdraw_fee_denominator.to_le_bytes();
76 *trade_fee_numerator = self.trade_fee_numerator.to_le_bytes();
77 *trade_fee_denominator = self.trade_fee_denominator.to_le_bytes();
78 *withdraw_fee_numerator = self.withdraw_fee_numerator.to_le_bytes();
79 *withdraw_fee_denominator = self.withdraw_fee_denominator.to_le_bytes();
80 }
81}
82
83#[cfg(test)]
84#[allow(clippy::unwrap_used)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn pack_fees() {
90 let admin_trade_fee_numerator = 1;
91 let admin_trade_fee_denominator = 2;
92 let admin_withdraw_fee_numerator = 3;
93 let admin_withdraw_fee_denominator = 4;
94 let trade_fee_numerator = 5;
95 let trade_fee_denominator = 6;
96 let withdraw_fee_numerator = 7;
97 let withdraw_fee_denominator = 8;
98 let fees = Fees {
99 admin_trade_fee_numerator,
100 admin_trade_fee_denominator,
101 admin_withdraw_fee_numerator,
102 admin_withdraw_fee_denominator,
103 trade_fee_numerator,
104 trade_fee_denominator,
105 withdraw_fee_numerator,
106 withdraw_fee_denominator,
107 };
108
109 let mut packed = [0u8; Fees::LEN];
110 Pack::pack_into_slice(&fees, &mut packed[..]);
111 let unpacked = Fees::unpack_from_slice(&packed).unwrap();
112 assert_eq!(fees, unpacked);
113
114 let mut packed = vec![];
115 packed.extend_from_slice(&admin_trade_fee_numerator.to_le_bytes());
116 packed.extend_from_slice(&admin_trade_fee_denominator.to_le_bytes());
117 packed.extend_from_slice(&admin_withdraw_fee_numerator.to_le_bytes());
118 packed.extend_from_slice(&admin_withdraw_fee_denominator.to_le_bytes());
119 packed.extend_from_slice(&trade_fee_numerator.to_le_bytes());
120 packed.extend_from_slice(&trade_fee_denominator.to_le_bytes());
121 packed.extend_from_slice(&withdraw_fee_numerator.to_le_bytes());
122 packed.extend_from_slice(&withdraw_fee_denominator.to_le_bytes());
123 let unpacked = Fees::unpack_from_slice(&packed).unwrap();
124 assert_eq!(fees, unpacked);
125 }
126}