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
- Check amount0 and amount1 are non-zero before calling execution_price and skip such swaps
- Filter out zero-amount swap events at ingestion/decoding time so they never reach analysis
- If the zero amount is legitimate, treat the swap as non-price-forming and exclude it from price statistics
- 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
- Filter zero-amount swap events at decoding time
- Treat single-sided/zero-value swaps as non-price-forming
- Audit ABI decoding so amounts aren't silently zero
- Skip rather than propagate when the price metric is optional
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
- Cannot calculate price impact, the spot price before is not
- Cannot calculate slippage, the spot price before is not set
- Cannot quote swap with zero amount
- Price overflow: {price_raw} exceeds maximum valid raw price
- Router allowance {allowance} is below the swap amount {} for
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/83fc2296699ee7bb.
Report an issue: GitHub.