{"record":{"id":"0234c440b51e788f","repo":"nautechsystems/nautilus_trader","slug":"cannot-quote-swap-with-zero-amount","errorCode":null,"errorMessage":"Cannot quote swap with zero amount","messagePattern":"Cannot quote swap with zero amount","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_analysis/profiler.rs","lineNumber":749,"sourceCode":"    /// - Fee breakdown (LP fees and protocol fees)\n    /// - List of crossed ticks with state snapshots\n    ///\n    /// # Errors\n    ///\n    /// Returns error if:\n    /// - Pool fee is not configured\n    /// - Fee growth arithmetic overflows when scaling by liquidity\n    /// - Swap step calculations fail\n    pub fn quote_swap(\n        &self,\n        amount_specified: I256,\n        zero_for_one: bool,\n        sqrt_price_limit_x96: Option<U160>,\n    ) -> anyhow::Result<SwapQuote> {\n        self.check_if_initialized(PoolEventKind::Swap)?;\n\n        if amount_specified.is_zero() {\n            anyhow::bail!(\"Cannot quote swap with zero amount\");\n        }\n\n        if let Some(price_limit) = sqrt_price_limit_x96 {\n            self.validate_price_limit(price_limit, zero_for_one)?;\n        }\n\n        let limit = sqrt_price_limit_x96.unwrap_or_else(|| {\n            if zero_for_one {\n                MIN_SQRT_RATIO + U160::from(1)\n            } else {\n                MAX_SQRT_RATIO - U160::from(1)\n            }\n        });\n\n        self.simulate_swap_through_ticks(amount_specified, zero_for_one, limit, false)\n    }\n\n    /// Simulates an exact input swap (know input amount, calculate output amount).","sourceCodeStart":731,"sourceCodeEnd":767,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_analysis/profiler.rs#L731-L767","documentation":"PoolProfiler::quote_swap simulates a Uniswap-v3-style swap; it rejects a zero amount_specified up front because a zero-amount swap has no defined path or resulting price. The pool must also be initialized (check_if_initialized) before quoting. Callers like swap_exact_in/swap_exact_out and sqrt-price traversal helpers all funnel through this guard.","triggerScenarios":"Calling quote_swap (directly or via swap_exact_in/swap_exact_out/swap_to_lower_sqrt_price/swap_to_higher_sqrt_price) with amount_specified == 0, or quoting on a pool profiler that was never initialized with a swap/liquidity snapshot.","commonSituations":"Computers replaying pools with no trade volume passing zero amounts; a loop that processes empty deltas; building quotes from user input where 0 wasn't validated; uninitialized profiler used before mint events loaded.","solutions":["Skip zero-amount quotes: check amount_specified.is_zero() before calling and return a neutral/default quote instead","Clamp or filter upstream so amounts fed into quote_swap are strictly positive","Ensure the profiler is initialized for the pool before quoting (check_if_initialized passes)","Review the caller producing the amount — a zero usually indicates a missing or mis-decoded input"],"exampleFix":"// before\nlet quote = profiler.quote_swap(amount, zero_for_one, None)?;\n// after\nif amount.is_zero() {\n    return Ok(None); // nothing to quote\n}\nlet quote = profiler.quote_swap(amount, zero_for_one, None)?;","handlingStrategy":"validation","validationCode":"if amount_specified.is_zero() {\n    return Ok(None); // nothing to quote\n}\nif !profiler.is_initialized(PoolEventKind::Swap) {\n    return Ok(None);\n}","typeGuard":"fn quotable(profiler: &PoolProfiler, amount: U256) -> bool {\n    !amount.is_zero() && profiler.is_initialized(PoolEventKind::Swap)\n}","tryCatchPattern":"match profiler.quote_swap(amount, zero_for_one, limit) {\n    Ok(q) => Some(q),\n    Err(e) if e.to_string().contains(\"zero amount\") => None,\n    Err(e) => return Err(e),\n}","preventionTips":["Skip zero-amount deltas before simulating swaps","Initialize the profiler from a swap/liquidity snapshot before quoting","Clamp user- or data-supplied amounts to a positive minimum","Log skipped zero-amount quotes for data-quality review"],"tags":["rust","defi","uniswap-v3","zero-amount","quote"],"backgroundTag":"invalid-argument-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}