{"record":{"id":"590db6b02dcbc970","repo":"nautechsystems/nautilus_trader","slug":"decimal-exponent-exponent-exceeds-u256-range","errorCode":null,"errorMessage":"Decimal exponent {exponent} exceeds U256 range","messagePattern":"Decimal exponent (.+?) exceeds U256 range","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/tick_map/full_math.rs","lineNumber":153,"sourceCode":"            remainder = remainder.mul_mod(scale, denominator);\n        }\n\n        Ok(quotient)\n    }\n\n    pub(crate) fn check_decimal_exponent(exponent: u8) -> anyhow::Result<()> {\n        anyhow::ensure!(\n            exponent <= DECIMAL_EXPONENT_MAX,\n            \"Decimal exponent {exponent} exceeds supported maximum {DECIMAL_EXPONENT_MAX}\"\n        );\n        Ok(())\n    }\n\n    pub(crate) fn pow10(exponent: u8) -> anyhow::Result<U256> {\n        Self::check_decimal_exponent(exponent)?;\n        U256::from(10)\n            .checked_pow(U256::from(exponent))\n            .ok_or_else(|| anyhow::anyhow!(\"Decimal exponent {exponent} exceeds U256 range\"))\n    }\n\n    /// Calculates ceil(a×b÷denominator) with full precision\n    /// Returns `Ok` with the rounded result or an error when rounding cannot be performed safely.\n    ///\n    /// # Errors\n    ///\n    /// Returns error if `denominator` is zero or the rounded result would overflow `U256`.\n    pub fn mul_div_rounding_up(a: U256, b: U256, denominator: U256) -> anyhow::Result<U256> {\n        let result = Self::mul_div(a, b, denominator)?;\n\n        // Check if there's a remainder\n        if a.mul_mod(b, denominator).is_zero() {\n            Ok(result)\n        } else if result == U256::MAX {\n            anyhow::bail!(\"Result would overflow 256 bits\")\n        } else {\n            Ok(result + U256::from(1))","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/tick_map/full_math.rs#L135-L171","documentation":"`pow10` computes 10^exponent as a U256 after validating the exponent against DECIMAL_EXPONENT_MAX. The library throws this error when `checked_pow` overflows U256 — a defensive backstop for exponents that pass the max check but still cannot fit 10^exponent into 256 bits.","triggerScenarios":"Calling `pow10` with an exponent large enough that 10^exponent >= 2^256 (exponent >= ~78) — either above DECIMAL_EXPONENT_MAX if that constant allows it, or via a path that bypassed `check_decimal_exponent`.","commonSituations":"Corrupt decimals metadata (e.g. u8::MAX from a failed decode), or code paths passing raw exponents from external data without prior validation.","solutions":["Validate the exponent before calling: `ensure!(exponent <= DECIMAL_EXPONENT_MAX)` and that DECIMAL_EXPONENT_MAX < 79.","Fix the source of the bad exponent (token metadata decoding, config parsing).","Use U512 for intermediate powers if larger exponents are genuinely required."],"exampleFix":"// before\nlet pow = pow10(raw_exponent)?;\n// after\nensure!(raw_exponent <= DECIMAL_EXPONENT_MAX, \"bad exponent {raw_exponent}\");\nlet pow = pow10(raw_exponent)?;","handlingStrategy":"validation","validationCode":"fn safe_pow10(exponent: u8) -> Option<U256> {\n    (exponent < 79).then(|| U256::from(10).checked_pow(U256::from(exponent))).flatten()\n}","typeGuard":"fn exponent_fits_u256(e: u8) -> bool { e < 79 }","tryCatchPattern":"match pow10(exponent) {\n    Ok(v) => v,\n    Err(e) if e.to_string().contains(\"U256 range\") => {\n        log::error!(\"exponent {exponent} overflows U256 — check metadata source\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always route exponents through check_decimal_exponent before pow10","Validate decimals at the source (token list / ABI decode) instead of deep in math","Treat u8::MAX or all-ones values from decoders as corruption, not valid exponents"],"tags":["math","u256-overflow","pow10","tick-map"],"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-14T00:17:10.932Z"}