use crate::errors::{ProgramError, Result};
use solana_program::pubkey::Pubkey;
pub fn calculate_bps_amount(amount: u64, bps: u16) -> Result<u64> {
let result = (amount as u128 * bps as u128) / 10_000;
Ok(result as u64)
}
pub fn validate_account(account: &Pubkey) -> Result<()> {
if account == &Pubkey::default() {
return Err(ProgramError::Unauthorized);
}
Ok(())
}
pub fn safe_mul(a: u64, b: u64) -> Result<u64> {
a.checked_mul(b).ok_or(ProgramError::Overflow)
}
pub fn safe_div(a: u64, b: u64) -> Result<u64> {
if b == 0 {
return Err(ProgramError::InvalidAmount);
}
Ok(a / b)
}
pub fn safe_sub(a: u64, b: u64) -> Result<u64> {
a.checked_sub(b).ok_or(ProgramError::Overflow)
}
pub fn safe_add(a: u64, b: u64) -> Result<u64> {
a.checked_add(b).ok_or(ProgramError::Overflow)
}
pub fn format_lamports_to_sol(lamports: u64) -> String {
let sol = lamports as f64 / 1_000_000_000.0;
format!("{:.9}", sol)
}
pub fn parse_sol_to_lamports(sol_str: &str) -> Result<u64> {
let sol: f64 = sol_str.parse().map_err(|_| ProgramError::InvalidAmount)?;
Ok((sol * 1_000_000_000.0) as u64)
}
pub fn calculate_percentage_change(from: u64, to: u64) -> Result<i32> {
if from == 0 {
return Ok(0);
}
if to >= from {
let change = ((to - from) as i128 * 10_000) / from as i128;
Ok(change as i32)
} else {
let change = -((from - to) as i128 * 10_000) as i32 / from as i32;
Ok(change)
}
}
pub fn next_power_of_2(mut n: u64) -> u64 {
if n == 0 {
return 1;
}
n -= 1;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
n |= n >> 32;
n + 1
}
pub fn clamp<T: PartialOrd>(value: T, min: T, max: T) -> T {
if value < min {
min
} else if value > max {
max
} else {
value
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_calculate_bps_amount() {
let result = calculate_bps_amount(1_000_000, 500);
assert!(result.is_ok());
assert_eq!(result.unwrap(), 50_000);
}
#[test]
fn test_safe_mul() {
let result = safe_mul(1000, 2000);
assert!(result.is_ok());
assert_eq!(result.unwrap(), 2_000_000);
}
#[test]
fn test_percentage_change() {
let result = calculate_percentage_change(100, 110);
assert!(result.is_ok());
assert_eq!(result.unwrap(), 1000); }
}