Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 20 additions & 23 deletions crates/core/src/surfnet/locker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use solana_account_decoder::{
UiAccount, UiAccountEncoding, UiDataSliceConfig,
parse_account_data::AccountAdditionalDataV3,
parse_bpf_loader::{BpfUpgradeableLoaderAccountType, UiProgram, parse_bpf_upgradeable_loader},
parse_token::UiTokenAmount,
parse_token::{UiTokenAmount, real_number_string_trimmed},
};
use solana_address_lookup_table_interface::state::AddressLookupTable;
use solana_client::{
Expand Down Expand Up @@ -3037,8 +3037,8 @@ impl SurfnetSvmLocker {
amount: UiTokenAmount {
amount: token_account.amount().to_string(),
decimals: mint_decimals,
ui_amount: Some(format_ui_amount(token_account.amount(), mint_decimals)),
ui_amount_string: format_ui_amount_string(
ui_amount: format_ui_amount(token_account.amount(), mint_decimals),
ui_amount_string: real_number_string_trimmed(
token_account.amount(),
mint_decimals,
),
Expand Down Expand Up @@ -4548,26 +4548,13 @@ fn update_programdata_account(
}
}

pub fn format_ui_amount_string(amount: u64, decimals: u8) -> String {
if decimals > 0 {
let divisor = 10u64.pow(decimals as u32);
format!(
"{:.decimals$}",
amount as f64 / divisor as f64,
decimals = decimals as usize
)
} else {
amount.to_string()
}
}

pub fn format_ui_amount(amount: u64, decimals: u8) -> f64 {
if decimals > 0 {
let divisor = 10u64.pow(decimals as u32);
amount as f64 / divisor as f64
} else {
amount as f64
}
/// Scales a raw token amount by its mint's decimals for `UiTokenAmount::ui_amount`.
///
/// `None` when `decimals` is too large for `10^decimals` to fit a `usize`.
pub fn format_ui_amount(amount: u64, decimals: u8) -> Option<f64> {
10_usize
.checked_pow(decimals as u32)
.map(|divisor| amount as f64 / divisor as f64)
}

#[cfg(test)]
Expand Down Expand Up @@ -7027,4 +7014,14 @@ mod tests {
"first slot should align with mainnet epoch boundaries when warmup is disabled"
);
}

#[test]
fn test_format_ui_amount_scales_by_decimals() {
assert_eq!(format_ui_amount(0, 0), Some(0.0));
assert_eq!(format_ui_amount(1_500_000, 6), Some(1.5));
assert_eq!(format_ui_amount(42, 0), Some(42.0));
// `Mint::decimals` is an unvalidated u8; 10^decimals stops fitting a usize well
// before 255, and the field is Option<f64> so those mints have somewhere to land.
assert_eq!(format_ui_amount(1, 255), None);
}
}
16 changes: 8 additions & 8 deletions crates/core/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use solana_account::Account;
use solana_account_decoder::{
parse_account_data::{AccountAdditionalDataV3, SplTokenAdditionalDataV2},
parse_token::UiTokenAmount,
parse_token::{UiTokenAmount, real_number_string_trimmed},
};
use solana_clock::{Epoch, Slot};
use solana_hash::Hash;
Expand Down Expand Up @@ -60,7 +60,7 @@ use txtx_addon_kit::indexmap::IndexMap;

use crate::{
error::{SurfpoolError, SurfpoolResult},
surfnet::locker::{format_ui_amount, format_ui_amount_string},
surfnet::locker::format_ui_amount,
};

/// Helper function to serialize a Pod type to base64
Expand Down Expand Up @@ -513,10 +513,10 @@ impl TransactionWithStatusMeta {
account_index: *i as u8,
mint: a.mint().to_string(),
ui_token_amount: UiTokenAmount {
ui_amount: Some(format_ui_amount(a.amount(), mint.decimals())),
ui_amount: format_ui_amount(a.amount(), mint.decimals()),
decimals: mint.decimals(),
amount: a.amount().to_string(),
ui_amount_string: format_ui_amount_string(
ui_amount_string: real_number_string_trimmed(
a.amount(),
mint.decimals(),
),
Expand All @@ -535,10 +535,10 @@ impl TransactionWithStatusMeta {
account_index: *i as u8,
mint: a.mint().to_string(),
ui_token_amount: UiTokenAmount {
ui_amount: Some(format_ui_amount(a.amount(), mint.decimals())),
ui_amount: format_ui_amount(a.amount(), mint.decimals()),
decimals: mint.decimals(),
amount: a.amount().to_string(),
ui_amount_string: format_ui_amount_string(
ui_amount_string: real_number_string_trimmed(
a.amount(),
mint.decimals(),
),
Expand Down Expand Up @@ -729,10 +729,10 @@ impl TransactionWithStatusMeta {
account_index: *i as u8,
mint: a.mint().to_string(),
ui_token_amount: UiTokenAmount {
ui_amount: Some(format_ui_amount(a.amount(), mint.decimals())),
ui_amount: format_ui_amount(a.amount(), mint.decimals()),
decimals: mint.decimals(),
amount: a.amount().to_string(),
ui_amount_string: format_ui_amount_string(a.amount(), mint.decimals()),
ui_amount_string: real_number_string_trimmed(a.amount(), mint.decimals()),
},
owner: a.owner().to_string(),
program_id: token_program.to_string(),
Expand Down
Loading