1#![allow(clippy::integer_arithmetic)]
2#![deny(missing_docs)]
3#![cfg_attr(not(test), forbid(unsafe_code))]
4
5pub mod error;
8pub mod instruction;
9pub mod native_mint;
10pub mod processor;
11pub mod state;
12
13#[cfg(not(feature = "no-entrypoint"))]
14mod entrypoint;
15
16pub use solana_program;
18use solana_program::{entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey};
19
20pub fn ui_amount_to_amount(ui_amount: f64, decimals: u8) -> u64 {
23 (ui_amount * 10_usize.pow(decimals as u32) as f64) as u64
24}
25
26pub fn amount_to_ui_amount(amount: u64, decimals: u8) -> f64 {
28 amount as f64 / 10_usize.pow(decimals as u32) as f64
29}
30
31pub fn amount_to_ui_amount_string(amount: u64, decimals: u8) -> String {
33 let decimals = decimals as usize;
34 if decimals > 0 {
35 let mut s = format!("{:01$}", amount, decimals + 1);
37 s.insert(s.len() - decimals, '.');
39 s
40 } else {
41 amount.to_string()
42 }
43}
44
45pub fn amount_to_ui_amount_string_trimmed(amount: u64, decimals: u8) -> String {
48 let mut s = amount_to_ui_amount_string(amount, decimals);
49 if decimals > 0 {
50 let zeros_trimmed = s.trim_end_matches('0');
51 s = zeros_trimmed.trim_end_matches('.').to_string();
52 }
53 s
54}
55
56pub fn try_ui_amount_into_amount(ui_amount: String, decimals: u8) -> Result<u64, ProgramError> {
59 let decimals = decimals as usize;
60 let mut parts = ui_amount.split('.');
61 let mut amount_str = parts.next().unwrap().to_string(); let after_decimal = parts.next().unwrap_or("");
63 let after_decimal = after_decimal.trim_end_matches('0');
64 if (amount_str.is_empty() && after_decimal.is_empty())
65 || parts.next().is_some()
66 || after_decimal.len() > decimals
67 {
68 return Err(ProgramError::InvalidArgument);
69 }
70
71 amount_str.push_str(after_decimal);
72 for _ in 0..decimals.saturating_sub(after_decimal.len()) {
73 amount_str.push('0');
74 }
75 amount_str
76 .parse::<u64>()
77 .map_err(|_| ProgramError::InvalidArgument)
78}
79
80solana_program::declare_id!("ToKLx75MGim1d1jRusuVX8xvdvvbSDESVaNXpRA9PHN");
81
82pub fn check_program_account(safe_token_program_id: &Pubkey) -> ProgramResult {
84 if safe_token_program_id != &id() {
85 return Err(ProgramError::IncorrectProgramId);
86 }
87 Ok(())
88}