What changed, and why it matters
This commit updates Tron-related code in a hardware wallet firmware. It changes how decimal precision is calculated for token amounts, removes an 'unsupported transaction type' error fallback, and broadens the accepted derivation path prefixes. These are code-quality and review changes, but they could have subtle security implications if the new precision logic mishandles edge cases or if removing the catch-all error allows unexpected transaction types to be signed.
Treat as a routine review update requiring verification. Reviewers should confirm the new precision logic is safe for all divider values (especially very large, very small, non-power-of-ten, or subnormal values), ensure removal of the `_ =>` arm does not allow unsupported transaction types to reach signing, and verify that accepting 44'/194' paths is intentional and documented.
Security signals we found
Floating-point arithmetic now used for financial precision calculation (log10 on divider)
Catch-all error arm removed from transaction type match, narrowing explicit handling
Derivation path validation broadened to accept additional coin types (194')
Removal of unused imports and constants suggests cleanup, but also reduces code traceability
Evidence from the diff
The commit modifies two Rust files. In wrapped_tron.rs, the precision calculation for token amounts is simplified from a loop-based digit count to a floating-point log10().round() approach, with guards for positive finite dividers. In rust_c/src/tron/mod.rs, FRAGMENT_MAX_LENGTH_DEFAULT and PersonalMessage imports are removed, the catch-all _ => arm in tron_sign_request is removed (leaving only two explicit match arms), and parse_trx_sub_path now accepts both 44’/195’/ and 44’/194’/ prefixes (with and without leading ‘m/’). The commit title/message is only ‘update review’ and provides no security context.
Changed components
rust/apps/tron/src/transaction/wrapped_tron.rsrust/rust_c/src/tron/mod.rsTron transaction signing and display flowBIP44 derivation path parsing for TronInspect captured patch +16 / −27
diff --git a/rust/apps/tron/src/transaction/wrapped_tron.rs b/rust/apps/tron/src/transaction/wrapped_tron.rs
index db55759..5c0b75c 100644
--- a/rust/apps/tron/src/transaction/wrapped_tron.rs
+++ b/rust/apps/tron/src/transaction/wrapped_tron.rs
@@ -464,19 +464,12 @@ impl WrappedTron {
let raw_val = f64::from_str(self.value.as_str())?;
let amount = raw_val / self.divider;
let unit = self.format_unit()?;
- let precision = match self.divider as u64 {
- 1 => 0,
- 1_000_000 => 6,
- 1_000_000_000_000_000_000 => 18,
- _ => {
- let mut count = 0;
- let mut d = self.divider as u64;
- while d >= 10 {
- d /= 10;
- count += 1;
- }
- count as usize
- }
+ let precision = if self.divider == 1.0 {
+ 0
+ } else if self.divider.is_sign_positive() && self.divider.is_finite() {
+ self.divider.log10().round() as usize
+ } else {
+ 0
};
let formatted = format!("{:.*}", precision, amount);
let trimmed = if formatted.contains('.') {
diff --git a/rust/rust_c/src/tron/mod.rs b/rust/rust_c/src/tron/mod.rs
index 9011104..b463409 100644
--- a/rust/rust_c/src/tron/mod.rs
+++ b/rust/rust_c/src/tron/mod.rs
@@ -4,7 +4,7 @@ use crate::common::errors::{KeystoneError, RustCError};
use crate::common::keystone;
use crate::common::structs::{SimpleResponse, TransactionCheckResult, TransactionParseResult};
use crate::common::types::{PtrBytes, PtrString, PtrT, PtrUR};
-use crate::common::ur::{QRCodeType, UREncodeResult, FRAGMENT_MAX_LENGTH_DEFAULT};
+use crate::common::ur::{QRCodeType, UREncodeResult};
use crate::common::utils::{convert_c_char, recover_c_char};
use crate::extract_array;
use alloc::boxed::Box;
@@ -16,15 +16,12 @@ use structs::{DisplayTron, TransactionType};
use crate::extract_ptr_with_type;
use alloc::format;
-use app_tron::structs::PersonalMessage;
use keystore::algorithms::secp256k1::derive_public_key;
use structs::DisplayTRONPersonalMessage;
use ur_registry::traits::{RegistryItem, To};
use ur_registry::tron::tron_sign_request::TronSignRequest;
use ur_registry::tron::tron_signature::TronSignature;
-use app_tron::TxParser;
-
const TRON_DEFAULT_PATH: &str = "m/44'/195'/0'/0/0";
#[no_mangle]
@@ -117,11 +114,6 @@ pub unsafe extern "C" fn tron_sign_request(
app_tron::sign_personal_message(&sign_data, &path, seed_slice)
.map_err(|e| KeystoneError::SignTxFailed(e.to_string()))?
}
- _ => {
- return Err(KeystoneError::SignTxFailed(
- "Unsupported Transaction Type".to_string(),
- ));
- }
};
let signed_tx_bytes = hex::decode(signed_tx_hex)
@@ -224,11 +216,15 @@ pub unsafe extern "C" fn tron_get_address(
}
fn parse_trx_sub_path(path: String) -> Option<String> {
- let root_path = "44'/195'/";
- match path.strip_prefix(root_path) {
- Some(path) => path.find('/').map(|index| path[index + 1..].to_string()),
- None => None,
- }
+ let root_paths = ["m/44'/195'/", "44'/195'/", "m/44'/194'/", "44'/194'/"];
+
+ root_paths.iter().find_map(|root| {
+ path.strip_prefix(root).and_then(|remaining| {
+ remaining
+ .find('/')
+ .map(|index| remaining[index + 1..].to_string())
+ })
+ })
}
fn try_get_trx_public_key(
Why this scored 36/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.