nautechsystems/nautilus_trader · error

Cannot calculate execution price with zero amounts

Error message

Cannot calculate execution price with zero amounts

What it means

execution_price on SwapTradeInfo derives the swap's effective execution price from raw_swap_data.amount0/amount1 and token decimals. If either amount is zero the ratio is undefined, so the method bails instead of producing a zero or infinite price. This is a data-integrity guard against malformed or degenerate swap events.

Source

Thrown at crates/model/src/defi/data/swap_trade_info.rs:399

    /// ```text
    /// price_raw = (quote_amount * 10^base_decimals * 10^FIXED_PRECISION) / (base_amount * 10^quote_decimals)
    /// ```
    ///
    /// # Base/Quote Logic
    /// - When `is_inverted=false`: quote=token1, base=token0 → price = amount1/amount0
    /// - When `is_inverted=true`: quote=token0, base=token1 → price = amount0/amount1
    ///
    /// # Use Cases
    /// - Trade accounting and P&L calculation
    /// - Comparing quoted vs executed prices
    /// - Cost analysis (includes all fees and price impact)
    /// - Performance reporting
    fn execution_price(&self) -> anyhow::Result<Price> {
        let amount0 = self.raw_swap_data.amount0.unsigned_abs();
        let amount1 = self.raw_swap_data.amount1.unsigned_abs();

        if amount0.is_zero() || amount1.is_zero() {
            anyhow::bail!("Cannot calculate execution price with zero amounts");
        }

        // Determine base and quote amounts/decimals based on inversion
        let (quote_amount, base_amount, quote_decimals, base_decimals) = if self.is_inverted {
            // inverted: token0=quote, token1=base
            (amount0, amount1, self.token0.decimals, self.token1.decimals)
        } else {
            // not inverted: token0=base, token1=quote
            (amount1, amount0, self.token1.decimals, self.token0.decimals)
        };

        FullMath::check_decimal_exponent(base_decimals)?;
        FullMath::check_decimal_exponent(quote_decimals)?;

        let exponent =
            i16::from(base_decimals) + i16::from(FIXED_PRECISION) - i16::from(quote_decimals);
        let price_raw_u256 = if exponent >= 0 {
            let exponent = u8::try_from(exponent)

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check amount0 and amount1 are non-zero before calling execution_price and skip such swaps
  2. Filter out zero-amount swap events at ingestion/decoding time so they never reach analysis
  3. If the zero amount is legitimate, treat the swap as non-price-forming and exclude it from price statistics
  4. Re-verify the event decoding (decimals, signed fields) if amounts should not be zero

Example fix

// before
let price = swap.execution_price()?;
// after
if swap.raw_swap_data.amount0.unsigned_abs().is_zero()
    || swap.raw_swap_data.amount1.unsigned_abs().is_zero()
{
    return Ok(None); // no meaningful execution price
}
let price = swap.execution_price()?;
Defensive patterns

Strategy: validation

Validate before calling

let a0 = swap.raw_swap_data.amount0.unsigned_abs();
let a1 = swap.raw_swap_data.amount1.unsigned_abs();
if a0.is_zero() || a1.is_zero() { /* skip: no execution price */ }

Type guard

fn has_pricing_amounts(s: &SwapTradeInfo) -> bool {
    !s.raw_swap_data.amount0.unsigned_abs().is_zero()
        && !s.raw_swap_data.amount1.unsigned_abs().is_zero()
}

Try / catch

match swap.execution_price() {
    Ok(p) => Some(p),
    Err(e) if e.to_string().contains("zero amounts") => None,
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling execution_price on a SwapTradeInfo whose raw_swap_data.amount0 or amount1 is zero — e.g. zero-value swap events, truncated/mis-decoded event logs, or synthetic swaps with no amounts.

Common situations: Indexing real chain events where some swaps emit amount0=0 or amount1=0 (single-sided or minimum-liquidity artifacts); bad ABI decoding filling zeros; flash-swap callbacks with zero amounts.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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