{"record":{"id":"84b5d45ac4963854","repo":"nautechsystems/nautilus_trader","slug":"overflow-in-quantity-from-mantissa-exponent","errorCode":null,"errorMessage":"Overflow in Quantity::from_mantissa_exponent","messagePattern":"Overflow in Quantity::from_mantissa_exponent","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/model/src/types/quantity.rs","lineNumber":533,"sourceCode":"\n    /// Creates a new [`Quantity`] from a mantissa/exponent pair using pure integer arithmetic.\n    ///\n    /// The value is `mantissa * 10^exponent`. This avoids all floating-point and Decimal\n    /// operations, making it ideal for exchange data that arrives as mantissa/exponent pairs.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the resulting raw value exceeds [`QUANTITY_RAW_MAX`].\n    #[must_use]\n    pub fn from_mantissa_exponent(mantissa: u64, exponent: i8, precision: u8) -> Self {\n        check_fixed_precision(precision).expect_display(FAILED);\n\n        if mantissa == 0 {\n            return Self { raw: 0, precision };\n        }\n\n        let raw_i128 = mantissa_exponent_to_fixed_i128(i128::from(mantissa), exponent, precision)\n            .expect(\"Overflow in Quantity::from_mantissa_exponent\");\n\n        let raw: QuantityRaw = raw_i128\n            .try_into()\n            .expect(\"Raw value exceeds QuantityRaw range in Quantity::from_mantissa_exponent\");\n        assert!(\n            raw <= QUANTITY_RAW_MAX,\n            \"`raw` value {raw} exceeded QUANTITY_RAW_MAX={QUANTITY_RAW_MAX} for Quantity\"\n        );\n\n        Self { raw, precision }\n    }\n\n    /// Checked variant of [`Quantity::from_mantissa_exponent`].\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the precision is invalid or the resulting raw value\n    /// exceeds [`QUANTITY_RAW_MAX`].","sourceCodeStart":515,"sourceCodeEnd":551,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/types/quantity.rs#L515-L551","documentation":"Quantity::from_mantissa_exponent scales the mantissa by 10^(exponent - precision) (or divides) into an i128 via mantissa_exponent_to_fixed_i128; when the scaled value overflows i128 the helper returns None and this expect panics. It exists to prevent silently wrapping quantity values.","triggerScenarios":"Quantity::from_mantissa_exponent(mantissa, exponent, precision) where scaling the mantissa to the target precision exceeds i128 — huge mantissa with large positive exponent, or an enormous precision gap requiring multiplication by 10^n beyond i128.","commonSituations":"Bad instrument definitions from venue configs (absurd step-size exponents); parsing CSV/JSON quantity fields with wrong units (e.g. wei-scale integers treated as whole coins); copy-pasted exponent conventions between venues.","solutions":["Correct the mantissa/exponent to the instrument's actual size/precision so the scaled value fits in i128.","Pre-validate: confirm |mantissa| * 10^(exponent - precision) < 2^127 before calling.","Normalize data at ingestion: convert to Decimal first, range-check, then construct Quantity.","Reject or clamp quantities exceeding the instrument's max quantity in your data pipeline."],"exampleFix":"// before\nlet qty = Quantity::from_mantissa_exponent(10_000_000_000_i64, 25, 8); // panics: i128 overflow\n// after\nlet qty = Quantity::from_mantissa_exponent(1_234_567_i64, -6, 8); // 1.234567 at precision 8","handlingStrategy":"validation","validationCode":"// Rust\nfn can_build_quantity(mantissa: i64, exponent: i8, precision: u8) -> bool {\n    let diff = i32::from(exponent) - i32::from(precision);\n    mantissa >= 0\n        && (mantissa.checked_ilog10().map(|d| d as i32).unwrap_or(0) + diff) <= 38 // i128 log10 bound\n}","typeGuard":"fn quantity_fits(value: Decimal, precision: u8) -> bool {\n    let scaled = value * Decimal::from(10_u32.pow(u32::from(precision)));\n    scaled >= Decimal::ZERO && scaled <= Decimal::from(i128::MAX)\n}","tryCatchPattern":null,"preventionTips":["Normalize venue quantity units (minimal units vs whole coins) before constructing Quantity.","Validate instrument step-size/precision definitions at load.","Keep exponents consistent with the instrument's declared precision.","Test with extreme mantissa/exponent pairs from real venue configs."],"tags":["rust","arithmetic-overflow","panic","quantity"],"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"}