{"record":{"id":"2cbf6c2ef005825c","repo":"nautechsystems/nautilus_trader","slug":"inverted-price-numerator-exceeds-u512-range","errorCode":null,"errorMessage":"Inverted price numerator exceeds U512 range","messagePattern":"Inverted price numerator exceeds U512 range","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/tick_map/sqrt_price_math.rs","lineNumber":423,"sourceCode":"                    })?;\n                let denominator =\n                    price_square\n                        .checked_mul(decimal_adjustment)\n                        .ok_or_else(|| {\n                            anyhow::anyhow!(\"Inverted price denominator exceeds U256 range\")\n                        })?;\n                FullMath::mul_div(numerator, U256::from(1), denominator)?\n            }\n        } else {\n            let price_square: U512 = sqrt_price.widening_mul(sqrt_price);\n            anyhow::ensure!(\n                !price_square.is_zero(),\n                \"Cannot decode inverted price from zero sqrt_price_x96\"\n            );\n            let numerator = U512::from(divisor_base)\n                .checked_mul(U512::from(decimal_adjustment))\n                .and_then(|value| value.checked_mul(U512::from(fixed_scalar)))\n                .ok_or_else(|| anyhow::anyhow!(\"Inverted price numerator exceeds U512 range\"))?;\n            let quotient = numerator / price_square;\n            U256::checked_from_limbs_slice(quotient.as_limbs())\n                .ok_or_else(|| anyhow::anyhow!(\"Inverted price exceeds U256 range\"))?\n        }\n    } else if decimal_diff >= 0 {\n        FullMath::mul_div_scaled(\n            sqrt_price,\n            sqrt_price,\n            divisor_base,\n            &[fixed_scalar, decimal_adjustment],\n        )?\n    } else {\n        FullMath::mul_div_scaled(sqrt_price, sqrt_price, divisor_base, &[fixed_scalar])?\n            / decimal_adjustment\n    };\n\n    price_from_u256(price_raw)\n}","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/tick_map/sqrt_price_math.rs#L405-L441","documentation":"In the inverted branch where token0_decimals < token1_decimals, the numerator is divisor_base (2^192) * decimal_adjustment * fixed_scalar computed in U512. This error is thrown when that triple product exceeds U512 range, which can only happen with extreme token decimal differences (decimal_adjustment is astronomically large).","triggerScenarios":"Calling decode_sqrt_price_x96_to_price_tokens_adjusted with invert=true, token0_decimals << token1_decimals (a large negative decimal_diff), so decimal_adjustment * 2^192 * 10^FIXED_PRECISION overflows U512.","commonSituations":"Misconfigured token decimals (e.g. passing 77+ or swapped decimal values) creating an absurd decimal_diff; tokens with extreme decimal counts on nonstandard chains.","solutions":["Verify token0_decimals and token1_decimals are correct and within DECIMAL_EXPONENT_MAX; swapped values are the usual cause.","Reduce the decimal gap by decoding the non-inverted orientation and inverting at a higher level.","Catch the error and treat the price as unrepresentable for this token pair."],"exampleFix":"// before\nlet price = decode_sqrt_price_x96_to_price_tokens_adjusted(sqrt_price_x96, 0, token1_decimals, true)?;\n// after\nif i32::from(token1_decimals) - i32::from(token0_decimals) > 40 {\n    // decimal gap too large for inverted path; decode normal and invert downstream\n    return decode_sqrt_price_x96_to_price_tokens_adjusted(sqrt_price_x96, token0_decimals, token1_decimals, false);\n}\nlet price = decode_sqrt_price_x96_to_price_tokens_adjusted(sqrt_price_x96, token0_decimals, token1_decimals, true)?;","handlingStrategy":"validation","validationCode":"fn inverted_numerator_fits(d0: u8, d1: u8, fixed_precision: u32) -> bool {\n    let gap = i64::from(d1) - i64::from(d0); // decimal_diff < 0 branch\n    gap >= 0 && (gap as u32) + fixed_precision + 192 < 512 / 3 // heuristic: 10^n fits U512 with margin\n}","typeGuard":null,"tryCatchPattern":"match decode_sqrt_price_x96_to_price_tokens_adjusted(sp, d0, d1, true) {\n    Ok(p) => p,\n    Err(e) if e.to_string().contains(\"numerator exceeds U512\") => {\n        // decimal gap too extreme; decode non-inverted instead\n        decode_sqrt_price_x96_to_price_tokens_adjusted(sp, d0, d1, false)\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Reject decimal gaps beyond DECIMAL_EXPONENT_MAX margins up front","Verify decimals from the token contract, not user config","Fall back to the non-inverted U256 path when decimal_diff is extreme"],"tags":["rust","overflow","defi","uniswap-v3"],"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"}