{"record":{"id":"9d57582512c7c25a","repo":"nautechsystems/nautilus_trader","slug":"price-limit-must-be-less-than-current-price-for-ze","errorCode":null,"errorMessage":"Price limit must be less than current price for zero_for_one swaps","messagePattern":"Price limit must be less than current price for zero_for_one swaps","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_analysis/profiler.rs","lineNumber":878,"sourceCode":"        zero_for_one: bool,\n    ) -> anyhow::Result<size_estimator::SizeForImpactResult> {\n        let config = size_estimator::EstimationConfig::default();\n        size_estimator::size_for_impact_bps_detailed(self, impact_bps, zero_for_one, &config)\n    }\n\n    /// Validates that the price limit is in the correct direction for the swap.\n    ///\n    /// # Errors\n    /// Returns error if price limit violates swap direction constraints.\n    fn validate_price_limit(\n        &self,\n        limit_price_sqrt: U160,\n        zero_for_one: bool,\n    ) -> anyhow::Result<()> {\n        if zero_for_one {\n            // Swapping token0 for token1: price must decrease\n            if limit_price_sqrt >= self.state.price_sqrt_ratio_x96 {\n                anyhow::bail!(\"Price limit must be less than current price for zero_for_one swaps\");\n            }\n        } else {\n            // Swapping token1 for token0: price must increase\n            if limit_price_sqrt <= self.state.price_sqrt_ratio_x96 {\n                anyhow::bail!(\n                    \"Price limit must be greater than current price for one_for_zero swaps\"\n                );\n            }\n        }\n\n        Ok(())\n    }\n\n    /// Processes a mint (liquidity add) event from historical data.\n    ///\n    /// Updates pool state when liquidity is added to a position, validates ticks,\n    /// and delegates to internal liquidity management methods.\n    ///","sourceCodeStart":860,"sourceCodeEnd":896,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_analysis/profiler.rs#L860-L896","documentation":"When quoting a zero_for_one swap (token0 -> token1), the pool price must move DOWN, so the caller-supplied sqrt price limit must be strictly below the current sqrt price. validate_price_limit bails if limit_price_sqrt >= current price_sqrt_ratio_x96, since such a limit would never be crossed and the swap simulation would be invalid.","triggerScenarios":"Calling quote_swap with sqrt_price_limit_x96 = Some(limit) where zero_for_one is true and limit >= current sqrt price — commonly passing MIN/MAX sentinel constants on the wrong side, or reusing a limit computed for the opposite direction.","commonSituations":"Using sqrt price limit constants meant for one_for_zero swaps in zero_for_one direction; passing the current price as the limit (no movement allowed); direction flags inverted when translating from amount-in semantics.","solutions":["Pass the correct sentinel: for zero_for_one use the minimum sqrt price limit (e.g. MIN_SQRT_RATIO), for one_for_zero the maximum","Compute the limit relative to the current price: ensure limit < state.price_sqrt_ratio_x96 for zero_for_one","Check the zero_for_one flag is not inverted at the call site","Pass None for sqrt_price_limit_x96 if no specific bound is required"],"exampleFix":"// before\nlet quote = profiler.quote_swap(amount, true, Some(current_sqrt_price))?;\n// after\nlet limit = MIN_SQRT_PRICE_X96; // must be below current price for zero_for_one\nlet quote = profiler.quote_swap(amount, true, Some(limit))?;","handlingStrategy":"validation","validationCode":"if zero_for_one {\n    anyhow::ensure!(limit < profiler.current_sqrt_price(), \"limit must be below current price\");\n}","typeGuard":"fn valid_zero_for_one_limit(limit: U160, current: U160) -> bool { limit < current }","tryCatchPattern":"match profiler.quote_swap(amount, true, Some(limit)) {\n    Ok(q) => q,\n    Err(e) if e.to_string().contains(\"must be less than current price\") => {\n        profiler.quote_swap(amount, true, Some(MIN_SQRT_PRICE_X96))?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Use the standard MIN/MAX sqrt-ratio sentinels unless a real bound is intended","Derive direction-specific limits from the current price","Double-check the zero_for_one flag matches the token direction","Prefer None when no limit constraint is needed"],"tags":["rust","defi","uniswap-v3","price-limit","swap-direction"],"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-14T00:17:10.932Z"}