123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- #![allow(clippy::arithmetic_side_effects)]
- #![deny(missing_docs)]
- #![cfg_attr(not(test), forbid(unsafe_code))]
- //! An ERC20-like Token program for the Solana blockchain
- pub mod error;
- pub mod instruction;
- pub mod native_mint;
- pub mod processor;
- pub mod state;
- #[cfg(not(feature = "no-entrypoint"))]
- mod entrypoint;
- /// Export current sdk types for downstream users building with a different sdk
- /// version
- pub mod solana_program {
- #![allow(missing_docs)]
- pub mod entrypoint {
- pub use solana_program_error::ProgramResult;
- }
- pub mod instruction {
- pub use solana_instruction::{AccountMeta, Instruction};
- }
- pub mod program_error {
- pub use solana_program_error::ProgramError;
- }
- pub mod program_option {
- pub use solana_program_option::COption;
- }
- pub mod program_pack {
- pub use solana_program_pack::{IsInitialized, Pack, Sealed};
- }
- pub mod pubkey {
- pub use solana_pubkey::{Pubkey, PUBKEY_BYTES};
- }
- }
- use {
- solana_program_error::{ProgramError, ProgramResult},
- solana_pubkey::Pubkey,
- };
- /// Convert the UI representation of a token amount (using the decimals field
- /// defined in its mint) to the raw amount
- pub fn ui_amount_to_amount(ui_amount: f64, decimals: u8) -> u64 {
- (ui_amount * 10_usize.pow(decimals as u32) as f64) as u64
- }
- /// Convert a raw amount to its UI representation (using the decimals field
- /// defined in its mint)
- pub fn amount_to_ui_amount(amount: u64, decimals: u8) -> f64 {
- amount as f64 / 10_usize.pow(decimals as u32) as f64
- }
- /// Convert a raw amount to its UI representation (using the decimals field
- /// defined in its mint)
- pub fn amount_to_ui_amount_string(amount: u64, decimals: u8) -> String {
- let decimals = decimals as usize;
- if decimals > 0 {
- // Left-pad zeros to decimals + 1, so we at least have an integer zero
- let mut s = format!("{:01$}", amount, decimals + 1);
- // Add the decimal point (Sorry, "," locales!)
- s.insert(s.len() - decimals, '.');
- s
- } else {
- amount.to_string()
- }
- }
- /// Convert a raw amount to its UI representation using the given decimals field
- /// Excess zeroes or unneeded decimal point are trimmed.
- pub fn amount_to_ui_amount_string_trimmed(amount: u64, decimals: u8) -> String {
- let mut s = amount_to_ui_amount_string(amount, decimals);
- if decimals > 0 {
- let zeros_trimmed = s.trim_end_matches('0');
- s = zeros_trimmed.trim_end_matches('.').to_string();
- }
- s
- }
- /// Try to convert a UI representation of a token amount to its raw amount using
- /// the given decimals field
- pub fn try_ui_amount_into_amount(ui_amount: String, decimals: u8) -> Result<u64, ProgramError> {
- let decimals = decimals as usize;
- let mut parts = ui_amount.split('.');
- // splitting a string, even an empty one, will always yield an iterator of
- // at least length == 1
- let mut amount_str = parts.next().unwrap().to_string();
- let after_decimal = parts.next().unwrap_or("");
- let after_decimal = after_decimal.trim_end_matches('0');
- if (amount_str.is_empty() && after_decimal.is_empty())
- || parts.next().is_some()
- || after_decimal.len() > decimals
- {
- return Err(ProgramError::InvalidArgument);
- }
- amount_str.push_str(after_decimal);
- for _ in 0..decimals.saturating_sub(after_decimal.len()) {
- amount_str.push('0');
- }
- amount_str
- .parse::<u64>()
- .map_err(|_| ProgramError::InvalidArgument)
- }
- solana_pubkey::declare_id!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
- /// Checks that the supplied program ID is the correct one for SPL-token
- pub fn check_program_account(spl_token_program_id: &Pubkey) -> ProgramResult {
- if spl_token_program_id != &id() {
- return Err(ProgramError::IncorrectProgramId);
- }
- Ok(())
- }
|