1use crate::errors::{ProgramError, Result};
4use solana_program::pubkey::Pubkey;
5
6pub fn calculate_bps_amount(amount: u64, bps: u16) -> Result<u64> {
8 let result = (amount as u128 * bps as u128) / 10_000;
9 Ok(result as u64)
10}
11
12pub fn validate_account(account: &Pubkey) -> Result<()> {
14 if account == &Pubkey::default() {
15 return Err(ProgramError::Unauthorized);
16 }
17 Ok(())
18}
19
20pub fn safe_mul(a: u64, b: u64) -> Result<u64> {
22 a.checked_mul(b).ok_or(ProgramError::Overflow)
23}
24
25pub fn safe_div(a: u64, b: u64) -> Result<u64> {
27 if b == 0 {
28 return Err(ProgramError::InvalidAmount);
29 }
30 Ok(a / b)
31}
32
33pub fn safe_sub(a: u64, b: u64) -> Result<u64> {
35 a.checked_sub(b).ok_or(ProgramError::Overflow)
36}
37
38pub fn safe_add(a: u64, b: u64) -> Result<u64> {
40 a.checked_add(b).ok_or(ProgramError::Overflow)
41}
42
43pub fn format_lamports_to_sol(lamports: u64) -> String {
45 let sol = lamports as f64 / 1_000_000_000.0;
46 format!("{:.9}", sol)
47}
48
49pub fn parse_sol_to_lamports(sol_str: &str) -> Result<u64> {
51 let sol: f64 = sol_str.parse().map_err(|_| ProgramError::InvalidAmount)?;
52 Ok((sol * 1_000_000_000.0) as u64)
53}
54
55pub fn calculate_percentage_change(from: u64, to: u64) -> Result<i32> {
57 if from == 0 {
58 return Ok(0);
59 }
60
61 if to >= from {
62 let change = ((to - from) as i128 * 10_000) / from as i128;
63 Ok(change as i32)
64 } else {
65 let change = -((from - to) as i128 * 10_000) as i32 / from as i32;
66 Ok(change)
67 }
68}
69
70pub fn next_power_of_2(mut n: u64) -> u64 {
72 if n == 0 {
73 return 1;
74 }
75 n -= 1;
76 n |= n >> 1;
77 n |= n >> 2;
78 n |= n >> 4;
79 n |= n >> 8;
80 n |= n >> 16;
81 n |= n >> 32;
82 n + 1
83}
84
85pub fn clamp<T: PartialOrd>(value: T, min: T, max: T) -> T {
87 if value < min {
88 min
89 } else if value > max {
90 max
91 } else {
92 value
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn test_calculate_bps_amount() {
102 let result = calculate_bps_amount(1_000_000, 500);
103 assert!(result.is_ok());
104 assert_eq!(result.unwrap(), 50_000);
105 }
106
107 #[test]
108 fn test_safe_mul() {
109 let result = safe_mul(1000, 2000);
110 assert!(result.is_ok());
111 assert_eq!(result.unwrap(), 2_000_000);
112 }
113
114 #[test]
115 fn test_percentage_change() {
116 let result = calculate_percentage_change(100, 110);
117 assert!(result.is_ok());
118 assert_eq!(result.unwrap(), 1000); }
120}