{"record":{"id":"e529924d6502eeb4","repo":"nautechsystems/nautilus_trader","slug":"restored-pool-instrument-id-references-factory","errorCode":null,"errorMessage":"Restored pool {instrument_id} references factory {}, expected registered factory {factory}","messagePattern":"Restored pool (.+?) references factory (.+?), expected registered factory (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":1098,"sourceCode":"        let fee = U24::try_from(\n            pool.fee\n                .ok_or_else(|| anyhow::anyhow!(\"Restored pool {instrument_id} has no fee\"))?,\n        )?;\n        let quote_token = pool.get_quote_token();\n        let quote_currency = Currency::new_checked(\n            &quote_token.symbol,\n            quote_token.decimals,\n            0,\n            &quote_token.name,\n            CurrencyType::Crypto,\n        )?;\n        let (token_in, token_out) = swap_token_pair(\n            order.order_side(),\n            pool.get_base_token().address,\n            quote_token.address,\n        )?;\n        let factory = self.uniswap_v3_factory()?;\n        anyhow::ensure!(\n            pool.dex.factory == factory,\n            \"Restored pool {instrument_id} references factory {}, expected registered factory {factory}\",\n            pool.dex.factory\n        );\n\n        Ok(SwapPlan {\n            order,\n            quote_currency,\n            pool,\n            instrument_id,\n            pool_address,\n            router: Address::from_str(&intent.transaction_to)?,\n            factory,\n            weth: self.weth_address,\n            token_in,\n            token_out,\n            fee,\n            amount_in,","sourceCodeStart":1080,"sourceCodeEnd":1116,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L1080-L1116","documentation":"restore_swap_plan checks that the restored pool's DEX factory address equals the Uniswap V3 factory registered with this execution client (self.uniswap_v3_factory()). A mismatch means the instrument resolves to a pool created by a different factory than the one this client is configured to interact with, so the swap plan is rejected. This prevents routing swaps through a pool the client's configured router/factory does not govern.","triggerScenarios":"reconcile_unresolved_execution or build_execution_verification_migration calls restore_swap_plan and pool.dex.factory differs from the configured uniswap_v3_factory address for intent.instrument_id. Occurs when the factory contract address in config changed between persisting and restoring, or the instrument was registered against a different DEX/factory (fork, deployment, another V3-like DEX).","commonSituations":"Changing the Uniswap V3 factory address in config (e.g. moving to a fork like Base deployment) while old intents reference the previous factory; registering instruments from multiple V3-fork DEXes but reconciling with a client pinned to one factory; pointing the node at a different network with different contract addresses.","solutions":["Restore the original factory configuration so the registered factory matches the pool's dex.factory recorded at persist time.","Re-register the instrument against the currently configured factory (or update the instrument's dex metadata) if the pool should migrate.","Resolve/cancel the stale intent before switching factories or networks, then re-issue the trade.","Verify chain/network config: a same-named instrument on a different chain will carry a different factory address."],"exampleFix":"// before\nfactory_address = \"0xDifferentFactory\"\n// after (factory that created the persisted pool)\nfactory_address = \"0xOriginalUniswapV3Factory\"","handlingStrategy":"validation","validationCode":"let factory = client.uniswap_v3_factory()?;\nlet pool = client.resolve_pool(&instrument_id)?;\nif pool.dex.factory != factory {\n    eprintln!(\"pool factory {} != configured factory {factory}; align factory config with the instrument's DEX\", pool.dex.factory);\n}","typeGuard":"fn factory_matches(pool: &Pool, configured_factory: Address) -> bool {\n    pool.dex.factory == configured_factory\n}","tryCatchPattern":null,"preventionTips":["Keep the Uniswap V3 factory address stable per environment; plan intent-draining before changing it","Register instruments only from DEXes matching the configured factory","Verify chain/network addresses when forking or migrating deployments","Resolve stale intents before switching factories"],"tags":["uniswap-v3","address-mismatch","factory","reconciliation"],"backgroundTag":"checksum-mismatch","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"}