{"record":{"id":"9a9c11d00b9ddb4a","repo":"nautechsystems/nautilus_trader","slug":"invalid-tick-range-tick-lower-tick-upper","errorCode":null,"errorMessage":"Invalid tick range: {tick_lower} >= {tick_upper}","messagePattern":"Invalid tick range: (.+?) >= (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_analysis/profiler.rs","lineNumber":1622,"sourceCode":"        // Safe to cast to u64: Since active_liquidity <= total_liquidity,\n        // the ratio is guaranteed to be <= PRECISION (1_000_000), which fits in u64\n        ratio.to::<u64>() as f64 / f64::from(PRECISION)\n    }\n\n    /// Validates tick range for position operations.\n    ///\n    /// Ensures ticks are properly ordered, aligned to tick spacing, and within\n    /// valid bounds. Used by all position-related operations.\n    ///\n    /// # Errors\n    ///\n    /// This function returns an error if:\n    /// - `tick_lower >= tick_upper` (invalid range).\n    /// - Ticks are not multiples of pool's tick spacing.\n    /// - Ticks are outside `MIN_TICK/MAX_TICK` bounds.\n    fn validate_ticks(&self, tick_lower: i32, tick_upper: i32) -> anyhow::Result<()> {\n        if tick_lower >= tick_upper {\n            anyhow::bail!(\"Invalid tick range: {tick_lower} >= {tick_upper}\")\n        }\n\n        if tick_lower % self.pool.tick_spacing.unwrap() as i32 != 0\n            || tick_upper % self.pool.tick_spacing.unwrap() as i32 != 0\n        {\n            anyhow::bail!(\n                \"Ticks {tick_lower} and {tick_upper} must be multiples of the tick spacing\"\n            )\n        }\n\n        if tick_lower < PoolTick::MIN_TICK || tick_upper > PoolTick::MAX_TICK {\n            anyhow::bail!(\"Invalid tick bounds for {tick_lower} and {tick_upper}\");\n        }\n        Ok(())\n    }\n\n    /// Updates all liquidity analytics.\n    fn update_liquidity_analytics(&mut self) {","sourceCodeStart":1604,"sourceCodeEnd":1640,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_analysis/profiler.rs#L1604-L1640","documentation":"validate_ticks enforces Uniswap-v3 position constraints: tick_lower must be strictly less than tick_upper, both must be multiples of the pool's tick spacing, and both within MIN_TICK/MAX_TICK. It bails immediately when tick_lower >= tick_upper since such a range defines no valid position. Used by both mint and burn processing.","triggerScenarios":"Calling process_mint/process_burn/execute_mint/execute_burn with tick_lower >= tick_upper — e.g. swapped arguments, decoded tick values from malformed events, or burns on positions that were never validated.","commonSituations":"Argument order mistakes when calling the API; event decoding bugs producing negative/garbage ticks; MIN_TICK==MAX_TICK style sentinel misuse; ticks decoded as unsigned then truncated.","solutions":["Swap or sort the tick arguments so tick_lower < tick_upper before calling","Validate the tick range (and spacing alignment) at your call site before invoking mint/burn","Check the event decoder: ticks should be i32 read from the correct log fields","Skip mint/burn events with invalid tick ranges as data errors, logging them for review"],"exampleFix":"// before\nprofiler.process_mint(owner, tick_upper, tick_lower, amount)?;\n// after\nlet (lower, upper) = (tick_lower.min(tick_upper), tick_lower.max(tick_upper));\nprofiler.process_mint(owner, lower, upper, amount)?;","handlingStrategy":"validation","validationCode":"anyhow::ensure!(tick_lower < tick_upper, \"invalid tick range\");\nanyhow::ensure!(tick_lower % spacing == 0 && tick_upper % spacing == 0, \"ticks off spacing\");","typeGuard":"fn valid_tick_range(lower: i32, upper: i32, spacing: i32) -> bool {\n    lower < upper && lower % spacing == 0 && upper % spacing == 0\n}","tryCatchPattern":"match profiler.process_mint(owner, lower, upper, amount) {\n    Err(e) if e.to_string().contains(\"Invalid tick range\") => { /* skip malformed event */ }\n    other => other?,\n}","preventionTips":["Order tick arguments (min, max) at every call site","Validate tick spacing alignment before mint/burn simulation","Check tick decoding (i32 from correct log fields)","Skip and log events with invalid tick ranges as data errors"],"tags":["rust","defi","uniswap-v3","ticks","validation"],"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"}