{"record":{"id":"75ccf1d2e665d0ff","repo":"nautechsystems/nautilus_trader","slug":"missing-poolid-topic","errorCode":null,"errorMessage":"Missing poolId topic","messagePattern":"Missing poolId topic","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/exchanges/parsing/uniswap_v4/initialize.rs","lineNumber":101,"sourceCode":"    );\n\n    // Extract currency0 and currency1 from topics\n    // topics[0] = event signature\n    // topics[1] = poolId (bytes32)\n    // topics[2] = currency0 (indexed)\n    // topics[3] = currency1 (indexed)\n    let topics = &log.topics;\n    if topics.len() < 4 {\n        anyhow::bail!(\n            \"Initialize event missing topics: expected 4, was {}\",\n            topics.len()\n        );\n    }\n\n    // Extract Pool ID from topics[1] - this is the unique identifier for V4 pools\n    let pool_id_bytes = topics[1]\n        .as_ref()\n        .ok_or_else(|| anyhow::anyhow!(\"Missing poolId topic\"))?\n        .as_ref();\n    let pool_identifier = Ustr::from(&hex::encode_prefixed(pool_id_bytes));\n\n    let currency0 = Address::from_slice(\n        topics[2]\n            .as_ref()\n            .ok_or_else(|| anyhow::anyhow!(\"Missing currency0 topic\"))?\n            .as_ref()\n            .get(12..32)\n            .ok_or_else(|| anyhow::anyhow!(\"Invalid currency0 topic length\"))?,\n    );\n\n    let currency1 = Address::from_slice(\n        topics[3]\n            .as_ref()\n            .ok_or_else(|| anyhow::anyhow!(\"Missing currency1 topic\"))?\n            .as_ref()\n            .get(12..32)","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/exchanges/parsing/uniswap_v4/initialize.rs#L83-L119","documentation":"parse_initialize_event_hypersync for Uniswap V4 throws this when topics[1] is absent, since the Pool ID (the unique V4 pool identifier, e.g. the salt/poolId) lives in the second indexed topic. Unlike V3, V4 pools are identified by this ID rather than a pool address, so the parser cannot proceed without it. The error distinguishes a missing topic from a malformed one.","triggerScenarios":"Calling parse_initialize_event_hypersync (v4) with a log that has fewer than 2 topics or topics[1] = None — e.g. an Initialize-shaped topic0 emitted by a non-standard contract, or a log fixture built with only the event signature topic.","commonSituations":"Consuming logs from forked V4-like contracts with different topic layouts; hand-built test logs missing indexed parameters; provider payloads that drop optional/None topic slots; mixing V3 Initialize logs into the V4 parser.","solutions":["Verify the log is a genuine Uniswap V4 PoolManager Initialize event with 4 topics (signature, poolId, currency0, currency1).","Check topics.len() >= 2 and topics[1].is_some() before calling the parser and skip otherwise.","Ensure you are routing V3 logs to the v3 parser and V4 logs to the v4 parser — the signatures differ.","Fix test fixtures to include the poolId as an indexed topic."],"exampleFix":"// before\nlet event = parse_initialize_event_hypersync(&log)?;\n// after\nif log.topics.len() < 2 || log.topics[1].is_none() {\n    tracing::warn!(tx = ?log.transaction_hash, \"v4 Initialize log missing poolId topic; skipping\");\n    return Ok(None);\n}\nlet event = parse_initialize_event_hypersync(&log)?;","handlingStrategy":"validation","validationCode":"if log.topics.len() < 2 || log.topics[1].is_none() {\n    // skip: v4 Initialize requires poolId as topics[1]\n    return Ok(None);\n}","typeGuard":"fn has_pool_id_topic(log: &Log) -> bool {\n    log.topics.len() >= 2 && log.topics[1].is_some()\n}","tryCatchPattern":"match parse_initialize_event_hypersync(&log) {\n    Ok(event) => handle(event),\n    Err(e) if e.to_string().contains(\"Missing poolId topic\") => {\n    tracing::warn!(\"v4 initialize log without poolId; skipping\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Verify the log has 4 topics before routing to the v4 parser.","Do not feed V3 Initialize logs into the v4 parser.","Build test fixtures with poolId as an indexed topic.","Validate topic completeness at ingestion, not parse time."],"tags":["blockchain","uniswap-v4","log-parsing","hypersync"],"backgroundTag":"missing-required-argument","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"}