nautechsystems/nautilus_trader · error · anyhow::Error

Cannot divide by zero

Error message

Cannot divide by zero

What it means

div_rounding_up received b == 0 while computing the ceiling of a÷b for U256 values modeled on Solidity's divRoundingUp; division by zero is mathematically undefined, so the helper bails before attempting the division.

Source

Thrown at crates/model/src/defi/tick_map/full_math.rs:183

        // Check if there's a remainder
        if a.mul_mod(b, denominator).is_zero() {
            Ok(result)
        } else if result == U256::MAX {
            anyhow::bail!("Result would overflow 256 bits")
        } else {
            Ok(result + U256::from(1))
        }
    }

    /// Calculates ceil(a÷b) with proper rounding up
    /// Equivalent to Solidity's divRoundingUp function
    ///
    /// # Errors
    ///
    /// Returns error if `b` is zero or if the rounded quotient would overflow `U256`.
    pub fn div_rounding_up(a: U256, b: U256) -> anyhow::Result<U256> {
        if b.is_zero() {
            anyhow::bail!("Cannot divide by zero");
        }

        let quotient = a / b;
        let remainder = a % b;

        // Add 1 if there's a remainder (equivalent to gt(mod(x, y), 0) in assembly)
        if remainder > U256::ZERO {
            // Check for overflow before incrementing
            if quotient == U256::MAX {
                anyhow::bail!("Result would overflow 256 bits");
            }
            Ok(quotient + U256::from(1))
        } else {
            Ok(quotient)
        }
    }

    /// Computes the integer square root of a 256-bit unsigned integer using the Babylonian method

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check that the denominator is nonzero before calling and fix the source of the zero value
  2. anyhow::ensure!(!b.is_zero(), ...) at the call site for a clear local error
  3. Add validation when loading pool/config parameters so zero denominators fail early

Example fix

// before
let q = div_rounding_up(a, liquidity)?;
// after
anyhow::ensure!(!liquidity.is_zero(), "liquidity must be > 0");
let q = div_rounding_up(a, liquidity)?;
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(!denominator.is_zero(), "denominator must be > 0");

Prevention

When it happens

Trigger: Calling div_rounding_up(a, U256::zero()) — e.g. a computed price, liquidity, or tick spacing that evaluated to zero from upstream data.

Common situations: Empty/uninitialized pool state feeding zero liquidity; config where a scaling factor defaults to 0; division by a value fetched from a bad RPC response.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/0ec1f4c911afa923. Report an issue: GitHub.