nautechsystems/nautilus_trader · error
div_rounding_up failed
Error message
div_rounding_up failed
What it means
In the fallback path of get_next_sqrt_price_from_amount0_rounding_up, div_rounding_up(numerator, fallback_denominator) computes the next price as divRoundingUp(numerator1, numerator1/sqrtPX96 + amount). The expect panics when the division fails — i.e. fallback_denominator is zero, which happens when numerator/sqrt_price_x96 + amount wraps or evaluates to zero due to extreme inputs.
Source
Thrown at crates/model/src/defi/tick_map/sqrt_price_math.rs:116
let numerator = U256::from(liquidity) << 96;
let sqrt_price_x96 = U256::from(sqrt_price_x96);
let product = amount * sqrt_price_x96;
if add {
if product / amount == sqrt_price_x96 {
let denominator = numerator + product;
if denominator >= numerator {
// always fit to 160bits
let result = FullMath::mul_div_rounding_up(numerator, sqrt_price_x96, denominator)
.expect("mul_div_rounding_up failed");
return U160::from(result);
}
}
// Fallback: divRoundingUp(numerator1, (numerator1 / sqrtPX96).add(amount))
let fallback_denominator = (numerator / sqrt_price_x96) + amount;
let result = FullMath::div_rounding_up(numerator, fallback_denominator)
.expect("div_rounding_up failed");
// Check if result fits in U160
assert!(result <= U256::from(U160::MAX), "Result overflows U160");
U160::from(result)
} else {
// require((product = amount * sqrtPX96) / amount == sqrtPX96 && numerator1 > product);
assert!(
(product / amount) == sqrt_price_x96 && numerator > product,
"Invalid conditions for amount0 removal: overflow or underflow detected"
);
let denominator = numerator - product;
let result = FullMath::mul_div_rounding_up(numerator, sqrt_price_x96, denominator)
.expect("mul_div_rounding_up failed");
U160::from(result)
}
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Clamp swap amounts so the computed next price remains within valid bounds before invoking the function.
- Propagate the failure as an error instead of expect, letting swap simulation reject the quote.
- Pre-check fallback_denominator != 0 (and no U256 addition overflow) with checked_add.
Example fix
// before
let result = FullMath::div_rounding_up(numerator, fallback_denominator)
.expect("div_rounding_up failed");
// after
let result = FullMath::div_rounding_up(numerator, fallback_denominator)
.ok_or_else(|| anyhow::anyhow!("fallback next-sqrt-price division failed (zero denominator)"))?; Defensive patterns
Strategy: validation
Validate before calling
let fallback_denominator = (numerator / sqrt_price_x96).checked_add(amount)
.filter(|d| !d.is_zero())
.ok_or_else(|| anyhow!("degenerate fallback denominator"))?; Type guard
fn fallback_div_safe(numerator: U256, sqrt_price_x96: U160, amount: U256) -> bool {
(numerator / U256::from(sqrt_price_x96)).checked_add(amount).map_or(false, |d| !d.is_zero())
} Try / catch
match FullMath::div_rounding_up(numerator, fallback_denominator) {
Some(r) => U160::from(r),
None => return Err(anyhow!("fallback division failed")),
} Prevention
- Use checked_add when forming the fallback denominator.
- Bound input amounts before entering the overflow-safe fallback.
- Keep simulation errors recoverable rather than panicking.
When it happens
Trigger: Calling get_next_sqrt_price_from_input/output with amount0 values where (numerator / sqrt_price_x96) + amount overflows U256 or yields zero, typically with maximum-size amounts or degenerate sqrt_price_x96 values reaching this branch.
Common situations: Simulating swaps with amounts near U256::MAX; fuzz tests probing the overflow-safe fallback; pools with malformed sqrt prices making numerator/sqrtPX96 huge.
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
- mul_div overflow
- mul_div_rounding_up failed
- Liquidity addition overflow: x={current}, y={y}, delta={delt
- Cannot decode inverted price from zero sqrt_price_x96
- Contract address should be set in logs
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/9855afdad72e2148.
Report an issue: GitHub.