Skip to content

bug(utils): tokens_to_base_units validates parts independently but re-parses combined string, giving misleading error on overflow #2505

Description

@Sertug17

Packages versions

main branch, crates/rust-client

Bug description

In tokens_to_base_units (crates/rust-client/src/utils.rs), each numeric part is validated independently via u64::parse, but then the parts are concatenated and re-parsed as a combined string:

// Early validation each part checked independently
for part in &parts {
    part.parse::<u64>().map_err(TokenParseError::ParseU64)?;
}

// ...later...
let combined = format!("{}{}", integer_part, &fractional_part[0..n_decimals.into()]);
let units = combined.parse::<u64>().map_err(TokenParseError::ParseU64)?;

The combined string can overflow u64 even when both parts individually fit. For example:

  • integer_part = "18446744073" (valid u64)
  • fractional_part = "709551616" with n_decimals = 9
  • Combined: "18446744073709551616" = u64::MAX + 1 → parse fails

The error returned is TokenParseError::ParseU64("invalid digit found in string") or similar not a meaningful "amount too large" message. The early per-part validation gives false confidence and is a latent refactoring hazard: if someone trusts the early check and removes the late parse::<u64>(), combined overflow would pass silently.

Affected: crates/rust-client/src/utils.rs, tokens_to_base_units.

How can this be reproduced?

Call tokens_to_base_units("18446744073.709551616", 9). Both parts parse as valid u64 individually, but the combined value exceeds u64::MAX. The function returns Err(TokenParseError::ParseU64(...)) with a misleading message instead of a clear overflow error.

Fix: remove the redundant per-part pre-validation loop and add a dedicated overflow check after the combined parse, returning a descriptive TokenParseError::AmountTooLarge (or similar) variant.

Relevant log output

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions