{"record":{"id":"ea0e343f7e83a52b","repo":"nautechsystems/nautilus_trader","slug":"pool-manifest-address-is-invalid","errorCode":null,"errorMessage":"Pool manifest address is invalid","messagePattern":"Pool manifest address is invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/verification.rs","lineNumber":1377,"sourceCode":"        );\n        anyhow::ensure!(\n            !token.name.trim().is_empty()\n                && !token.symbol.trim().is_empty()\n                && matches!(token.asset_role.as_str(), \"base\" | \"quote\" | \"both\"),\n            \"Token manifest identity or asset role is invalid\"\n        );\n    }\n\n    for pool in &manifest.pools {\n        for address in [\n            &pool.address,\n            &pool.token0,\n            &pool.token1,\n            &pool.factory,\n            &pool.quote_contract,\n        ] {\n            let address = Address::from_str(address)\n                .map_err(|_| anyhow::anyhow!(\"Pool manifest address is invalid\"))?;\n            anyhow::ensure!(\n                contract_addresses.contains(&address),\n                \"Pool manifest references an unpinned contract\"\n            );\n        }\n        anyhow::ensure!(\n            pool.fee != 0 && pool.fee <= 1_000_000,\n            \"Pool fee is invalid\"\n        );\n    }\n    let mut call_edges = HashSet::new();\n    for edge in &manifest.call_edges {\n        anyhow::ensure!(\n            matches!(\n                edge.purpose.as_str(),\n                \"wrap\" | \"approve\" | \"swap_sell\" | \"swap_buy\"\n            ) && matches!(\n                edge.call_type.as_str(),","sourceCodeStart":1359,"sourceCodeEnd":1395,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/verification.rs#L1359-L1395","documentation":"Every manifest pool entry must contain valid 20-byte hex addresses for address, token0, token1, factory, and quote_contract. The validator parses each with Address::from_str and throws this error if any of the five fields is not parseable hex, so a single malformed field fails the whole pool entry.","triggerScenarios":"Running manifest verification when any pool field — the pool's own address, either token address, the factory address, or the quote contract address — is empty, wrong length, or non-hex (e.g. a pool ID/hash pasted into an address field, or an off-chain identifier).","commonSituations":"Pasting a Uniswap V3 pool's 32-byte pool key or slot0 hash instead of its 20-byte contract address; copying the wrong chain's pool address; truncated hex from CSV export; referencing a pool before its factory/quote contract addresses were filled in.","solutions":["Set every pool field to a valid 0x + 40-hex-char contract address, resolving each reference to its on-chain contract","Fix the specific field flagged by validating all five addresses (e.g. with cast or a small script) before re-running verification","Regenerate pool entries from deployment tooling, which derives token0/token1/factory/quote_contract from the actual deployment"],"exampleFix":"// before\n{\"address\": \"0x<32-byte pool key>\", \"token0\": \"0xabc...\", \"token1\": \"0xdef...\", \"factory\": \"\", \"quote_contract\": \"0xquote...\"}\n// after\n{\"address\": \"0x1234...20bytes\", \"token0\": \"0xabc...\", \"token1\": \"0xdef...\", \"factory\": \"0xfactory...\", \"quote_contract\": \"0xquote...\"}","handlingStrategy":"validation","validationCode":"fn pool_addresses_ok(pool: &PoolEntry) -> bool {\n    [&pool.address, &pool.token0, &pool.token1, &pool.factory, &pool.quote_contract]\n        .iter().all(|a| Address::from_str(a).is_ok())\n}\nassert!(manifest.pools.iter().all(pool_addresses_ok));","typeGuard":null,"tryCatchPattern":"match validate_manifest(&config) {\n    Err(e) if e.to_string().contains(\"Pool manifest address is invalid\") => {\n        eprintln!(\"fix the malformed address among address/token0/token1/factory/quote_contract: {e}\");\n    }\n    Err(e) => return Err(e),\n    Ok(v) => v,\n}","preventionTips":["Ensure address fields hold 20-byte contract addresses, never 32-byte pool keys or hashes","Derive pool token0/token1/factory from on-chain reads or deployment tooling","Validate all five pool address fields with a script before running verification"],"tags":["validation","hex-parsing","manifest"],"backgroundTag":"invalid-argument-format","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"}