nautechsystems/nautilus_trader · error
Inverted price numerator exceeds U512 range
Error message
Inverted price numerator exceeds U512 range
What it means
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).
Source
Thrown at crates/model/src/defi/tick_map/sqrt_price_math.rs:423
})?;
let denominator =
price_square
.checked_mul(decimal_adjustment)
.ok_or_else(|| {
anyhow::anyhow!("Inverted price denominator exceeds U256 range")
})?;
FullMath::mul_div(numerator, U256::from(1), denominator)?
}
} else {
let price_square: U512 = sqrt_price.widening_mul(sqrt_price);
anyhow::ensure!(
!price_square.is_zero(),
"Cannot decode inverted price from zero sqrt_price_x96"
);
let numerator = U512::from(divisor_base)
.checked_mul(U512::from(decimal_adjustment))
.and_then(|value| value.checked_mul(U512::from(fixed_scalar)))
.ok_or_else(|| anyhow::anyhow!("Inverted price numerator exceeds U512 range"))?;
let quotient = numerator / price_square;
U256::checked_from_limbs_slice(quotient.as_limbs())
.ok_or_else(|| anyhow::anyhow!("Inverted price exceeds U256 range"))?
}
} else if decimal_diff >= 0 {
FullMath::mul_div_scaled(
sqrt_price,
sqrt_price,
divisor_base,
&[fixed_scalar, decimal_adjustment],
)?
} else {
FullMath::mul_div_scaled(sqrt_price, sqrt_price, divisor_base, &[fixed_scalar])?
/ decimal_adjustment
};
price_from_u256(price_raw)
}View on GitHub (pinned to 18893faf8b)
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.
Example fix
// before
let price = decode_sqrt_price_x96_to_price_tokens_adjusted(sqrt_price_x96, 0, token1_decimals, true)?;
// after
if i32::from(token1_decimals) - i32::from(token0_decimals) > 40 {
// decimal gap too large for inverted path; decode normal and invert downstream
return decode_sqrt_price_x96_to_price_tokens_adjusted(sqrt_price_x96, token0_decimals, token1_decimals, false);
}
let price = decode_sqrt_price_x96_to_price_tokens_adjusted(sqrt_price_x96, token0_decimals, token1_decimals, true)?; Defensive patterns
Strategy: validation
Validate before calling
fn inverted_numerator_fits(d0: u8, d1: u8, fixed_precision: u32) -> bool {
let gap = i64::from(d1) - i64::from(d0); // decimal_diff < 0 branch
gap >= 0 && (gap as u32) + fixed_precision + 192 < 512 / 3 // heuristic: 10^n fits U512 with margin
} Try / catch
match decode_sqrt_price_x96_to_price_tokens_adjusted(sp, d0, d1, true) {
Ok(p) => p,
Err(e) if e.to_string().contains("numerator exceeds U512") => {
// decimal gap too extreme; decode non-inverted instead
decode_sqrt_price_x96_to_price_tokens_adjusted(sp, d0, d1, false)
}
Err(e) => return Err(e),
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Misconfigured token decimals (e.g. passing 77+ or swapped decimal values) creating an absurd decimal_diff; tokens with extreme decimal counts on nonstandard chains.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Inverted price exceeds U256 range
- Cannot quote swap with zero amount
- Price limit must be less than current price for zero_for_one
- Price limit must be greater than current price for one_for_z
- No liquidity
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/2cbf6c2ef005825c.
Report an issue: GitHub.