{"record":{"id":"ab9fdb65670a7b94","repo":"nautechsystems/nautilus_trader","slug":"pool-fee-should-be-initialized","errorCode":null,"errorMessage":"Pool fee should be initialized","messagePattern":"Pool fee should be initialized","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/defi/pool_analysis/profiler.rs","lineNumber":494,"sourceCode":"    /// # 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    ///\n    /// # Panics\n    ///\n    /// Panics if the pool fee has not been initialized.\n    pub fn simulate_swap_through_ticks(\n        &self,\n        amount_specified: I256,\n        zero_for_one: bool,\n        sqrt_price_limit_x96: U160,\n        traverse_empty_ranges: bool,\n    ) -> anyhow::Result<SwapQuote> {\n        let exact_input = amount_specified.is_positive();\n        let fee_tier = self.pool.fee.expect(\"Pool fee should be initialized\");\n\n        let mut current_sqrt_price = self.state.price_sqrt_ratio_x96;\n        let mut current_tick = self.state.current_tick;\n        let mut current_active_liquidity = self.tick_map.liquidity;\n        let mut amount_specified_remaining = amount_specified;\n        let mut amount_calculated = I256::ZERO;\n        let mut protocol_fee = U256::ZERO;\n        let mut lp_fee = U256::ZERO;\n        let mut crossed_ticks = Vec::new();\n\n        // Swapping cache variables\n        let fee_protocol = self.state.uniswap_v3_fee_protocol(zero_for_one);\n        let fee_protocol_basis_points = self.state.fee_protocol_basis_points(zero_for_one);\n\n        // Track current fee growth during swap\n        let mut current_fee_growth_global = if zero_for_one {\n            self.state.fee_growth_global_0\n        } else {","sourceCodeStart":476,"sourceCodeEnd":512,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/defi/pool_analysis/profiler.rs#L476-L512","documentation":"simulate_swap_through_ticks reads self.pool.fee to get the fee tier used in swap math; if the fee was never initialized on the pool, expect panics. The fee tier is essential for computing fees accrued within each swap step, so simulation cannot proceed without it.","triggerScenarios":"Calling simulate_swap_through_ticks (directly or via process_swap, execute_swap, quote_swap) on a profiler whose pool.fee is None — i.e. the pool's fee rate was not captured during topology initialization.","commonSituations":"Quoting swaps against a pool seeded from partial data; pools discovered via RPC where the fee() call failed silently; test fixtures building SharedPool without fee.","solutions":["Initialize pool.fee from the factory/pool fee() call or the mint/create event before running swap simulation.","Call check_if_initialized (or an equivalent guard) and return an error instead of proceeding when fee is None.","Validate pool completeness (fee, tick_spacing) at profiler construction so uninitialized pools fail early with a clear error."],"exampleFix":"// before\nlet fee_tier = self.pool.fee.expect(\"Pool fee should be initialized\");\n// after\nlet fee_tier = self.pool.fee.ok_or_else(|| anyhow::anyhow!(\n    \"pool {} fee not initialized; cannot simulate swap\", self.pool.address\n))?;","handlingStrategy":"validation","validationCode":"if self.pool.fee.is_none() { return Err(anyhow::anyhow!(\"pool fee not initialized\")); }","typeGuard":"fn fee_tier(pool: &SharedPool) -> Option<u32> { pool.fee }","tryCatchPattern":"match self.pool.fee { Some(f) => simulate_with(f), None => Err(anyhow!(\"fee missing\")), }","preventionTips":["Guarantee pool.fee is set by the topology loader before simulation.","Run a pre-flight check (fee and tick_spacing present) on every profiler used for quoting.","Persist fee with snapshots."],"tags":["rust","panic","defi","swap-simulation","initialization"],"backgroundTag":"missing-required-config-field","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"}