{"record":{"id":"c59ef92f9d2a34fe","repo":"nautechsystems/nautilus_trader","slug":"scale-10-exceeds-u256-while-converting-type-na","errorCode":null,"errorMessage":"Scale 10^{} exceeds U256 while converting {type_name}","messagePattern":"Scale 10\\^(.+?) exceeds U256 while converting (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/decode.rs","lineNumber":100,"sourceCode":"    )?;\n    let raw = PriceRaw::try_from(raw)\n        .map_err(|e| anyhow::anyhow!(\"Failed to convert Price raw value: {e}\"))?;\n    Ok(Price::from_raw_checked(raw, precision)?)\n}\n\nfn scale_u256_to_raw(\n    amount: U256,\n    decimals: u8,\n    fixed_precision: u8,\n    raw_max: U256,\n    type_name: &str,\n    raw_max_name: &str,\n) -> anyhow::Result<U256> {\n    let raw = if decimals < fixed_precision {\n        let scale = U256::from(10)\n            .checked_pow(U256::from(fixed_precision - decimals))\n            .ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"Scale 10^{} exceeds U256 while converting {type_name}\",\n                    fixed_precision - decimals\n                )\n            })?;\n        amount.checked_mul(scale).ok_or_else(|| {\n            anyhow::anyhow!(\n                \"{type_name} amount {amount} overflows U256 while scaling from {decimals} to {fixed_precision} decimals\"\n            )\n        })?\n    } else if decimals > fixed_precision {\n        round_u256_half_even(amount, decimals - fixed_precision, type_name)?\n    } else {\n        amount\n    };\n\n    check_raw_range(raw, raw_max, type_name, raw_max_name)?;\n    Ok(raw)\n}","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/decode.rs#L82-L118","documentation":"scale_u256_to_raw computes 10^(fixed_precision − decimals) as a U256 power when decimals < fixed_precision. If checked_pow overflows U256, the exponent is impossibly large and the conversion aborts with this message naming the type being converted (e.g. 'Quantity' or 'Price').","triggerScenarios":"Calling u256_to_quantity/u256_to_price with a decimals value drastically smaller than the fixed precision, such that 10^(fixed_precision − decimals) cannot even be represented in U256 (exponent ≳ 78).","commonSituations":"Passing decimals=0 or garbage decimals (e.g. a u8::MAX sentinel or uninitialized value) for tokens that actually have 6–18 decimals; mis-wired ABI decoding returning 0 for decimals.","solutions":["Verify the decimals argument — fetch ERC20.decimals() on-chain rather than hardcoding 0.","Sanity-check decimals ∈ 0..=18 (typical token range) before calling the conversion.","If decimals is genuinely tiny and the value huge, the amount exceeds domain representability; handle at a higher level.","Trace the value source: a decoded-decimals of 0 often indicates a wrong ABI or failed static call defaulting to zero."],"exampleFix":"// before\nlet qty = u256_to_quantity(amount, 0, FIXED_PRECISION)?;\n\n// after\nlet decimals = token.decimals().call().await?; // e.g. 6 or 18\ndebug_assert!(decimals <= 18);\nlet qty = u256_to_quantity(amount, decimals, FIXED_PRECISION)?;","handlingStrategy":"validation","validationCode":"// reject implausible decimals before scaling\nfn sane_decimals(d: u8) -> Result<u8, String> {\n    match d {\n        0..=18 => Ok(d),\n        other => Err(format!(\"implausible token decimals: {other}\")),\n    }\n}","typeGuard":"fn plausible_decimals(d: u8) -> bool {\n    d <= 18\n}","tryCatchPattern":null,"preventionTips":["Always fetch ERC20.decimals() from chain; never hardcode 0","Validate decimals is within the realistic 0–18 range before conversion","A decoded decimals of 0 usually signals a wrong ABI or failed static call — investigate upstream"],"tags":["u256","overflow","scaling","decimals"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}