{"record":{"id":"b98b7b18dde63954","repo":"nautechsystems/nautilus_trader","slug":"token-pair-token-in-token-out-is-not-in-the","errorCode":null,"errorMessage":"Token pair {token_in} -> {token_out} is not in the `allowed_token_pairs` allowlist","messagePattern":"Token pair (.+?) -> (.+?) is not in the `allowed_token_pairs` allowlist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":1594,"sourceCode":"\n        let base_token = pool.get_base_token();\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) =\n            swap_token_pair(order.order_side(), base_token.address, quote_token.address)?;\n\n        if !self\n            .transaction_limits\n            .allowed_token_pairs\n            .contains(&(token_in, token_out))\n        {\n            anyhow::bail!(\n                \"Token pair {token_in} -> {token_out} is not in the `allowed_token_pairs` allowlist\"\n            );\n        }\n\n        let base_amount = quantity_to_raw_amount(order.quantity(), base_token.decimals)?;\n        if base_amount > U256::from(self.transaction_limits.max_order_amount) {\n            anyhow::bail!(\n                \"Order amount {base_amount} exceeds the configured `max_order_amount` {}\",\n                self.transaction_limits.max_order_amount\n            );\n        }\n\n        let slippage_bps = match cmd\n            .params\n            .as_ref()\n            .and_then(|params| params.get_u64(\"slippage_bps\"))\n        {\n            Some(value) => u32::try_from(value).map_err(|_| {","sourceCodeStart":1576,"sourceCodeEnd":1612,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/execution/client.rs#L1576-L1612","documentation":"The client enforces a configured `allowed_token_pairs` allowlist; submitting a swap whose (token_in, token_out) pair is not in that list is rejected as a safety control against trading unintended tokens. The pair is checked after resolving the pool and computing direction.","triggerScenarios":"submit_order for an instrument whose base/quote tokens are not both present in transaction_limits.allowed_token_pairs — e.g. trading a new pool that was never added to the allowlist config.","commonSituations":"Adding a new pool/instrument to the strategy but forgetting to update the allowlist; token address ordering mismatch (allowlist stores (tokenA,tokenB) but the order resolves to (tokenB,tokenA)); typos in token addresses in the config file.","solutions":["Add the exact (token_in, token_out) pair to `allowed_token_pairs` in the transaction_limits configuration.","Check address ordering — add the pair in the same direction the order resolves, or add both directions if either direction is tradable.","Verify the token addresses in the config match the on-chain token addresses (checksummed/lowercase consistently)."],"exampleFix":"// before\ntransaction_limits.allowed_token_pairs = vec![(usdc_addr, weth_addr)];\n// after\ntransaction_limits.allowed_token_pairs = vec![\n    (usdc_addr, weth_addr),\n    (weth_addr, usdc_addr), // allow the reverse direction too\n];","handlingStrategy":"validation","validationCode":"// Rust\nlet pair = (token_in_addr, token_out_addr);\nif !transaction_limits.allowed_token_pairs.contains(&pair) {\n    return Err(anyhow::anyhow!(\"pair {:?} not allowlisted\", pair));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep allowed_token_pairs in sync whenever instruments are added.","Add both directions of a pair if either is tradable.","Validate token addresses (checksum/case) against on-chain values during config load."],"tags":["blockchain","allowlist","risk-limit","configuration"],"backgroundTag":"invalid-config-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"}