{"record":{"id":"17703c24bd60b033","repo":"nautechsystems/nautilus_trader","slug":"price-limit-must-be-greater-than-current-price-for","errorCode":null,"errorMessage":"Price limit must be greater than current price for one_for_zero swaps","messagePattern":"Price limit must be greater than current price for one_for_zero swaps","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_analysis/profiler.rs","lineNumber":883,"sourceCode":"\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    ///\n    /// # Errors\n    ///\n    /// This function returns an error if:\n    /// - Pool is not initialized.\n    /// - Tick range is invalid or not properly spaced.","sourceCodeStart":865,"sourceCodeEnd":901,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_analysis/profiler.rs#L865-L901","documentation":"For one_for_zero swaps (token1 -> token0) the pool price must move UP, so the supplied sqrt price limit must be strictly greater than the current sqrt price. validate_price_limit bails if limit_price_sqrt <= current price_sqrt_ratio_x96, because the swap could never reach such a limit going in that direction.","triggerScenarios":"Calling quote_swap with sqrt_price_limit_x96 = Some(limit) where zero_for_one is false and limit <= current sqrt price — typically using the MIN sentinel instead of MAX, or a stale limit computed at an earlier price.","commonSituations":"Copying example code with the wrong sentinel constant; limits cached from a previous block before the price moved; inverted direction flags; passing current price as the limit.","solutions":["For one_for_zero swaps pass the maximum sqrt price sentinel (e.g. MAX_SQRT_RATIO) unless a tighter bound is intended","Validate limit > state.price_sqrt_ratio_x96 before calling, or recompute from the current price","Verify the zero_for_one flag matches the intended swap direction","Use None as the limit when any price movement is acceptable"],"exampleFix":"// before\nlet quote = profiler.quote_swap(amount, false, Some(current_sqrt_price))?;\n// after\nlet limit = MAX_SQRT_PRICE_X96; // must exceed current price for one_for_zero\nlet quote = profiler.quote_swap(amount, false, Some(limit))?;","handlingStrategy":"validation","validationCode":"if !zero_for_one {\n    anyhow::ensure!(limit > profiler.current_sqrt_price(), \"limit must be above current price\");\n}","typeGuard":"fn valid_one_for_zero_limit(limit: U160, current: U160) -> bool { limit > current }","tryCatchPattern":"match profiler.quote_swap(amount, false, Some(limit)) {\n    Ok(q) => q,\n    Err(e) if e.to_string().contains(\"must be greater than current price\") => {\n        profiler.quote_swap(amount, false, Some(MAX_SQRT_PRICE_X96))?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Use MAX_SQRT_RATIO sentinel for one_for_zero swaps","Recompute limits from the current price rather than caching them","Keep direction flags consistent across your quoting helpers","Pass None if the limit is not a real constraint"],"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"}