{"record":{"id":"1794cdd48507a690","repo":"nautechsystems/nautilus_trader","slug":"missing-currency0-topic","errorCode":null,"errorMessage":"Missing currency0 topic","messagePattern":"Missing currency0 topic","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/exchanges/parsing/uniswap_v4/initialize.rs","lineNumber":108,"sourceCode":"    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)\n            .ok_or_else(|| anyhow::anyhow!(\"Invalid currency1 topic length\"))?,\n    );\n\n    if let Some(data) = log.data {\n        let data_bytes = data.as_ref();\n\n        // Validate minimum data length (5 fields × 32 bytes = 160 bytes)","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/exchanges/parsing/uniswap_v4/initialize.rs#L90-L126","documentation":"parse_initialize_event_hypersync for Uniswap V4 throws this when topics[2] is absent, since currency0 (the first token address) is stored as an indexed topic on the V4 Initialize event. Without currency0 the pool's currency pair cannot be constructed and the event is unusable. The library fails fast instead of emitting a pool with a missing currency.","triggerScenarios":"Calling parse_initialize_event_hypersync (v4) with a log that has fewer than 3 topics or topics[2] = None — typically a malformed/non-standard Initialize log or an incomplete test fixture.","commonSituations":"Forked V4 contracts omitting indexed currency parameters; hand-built test logs with only signature and poolId topics; provider payloads delivering null topic slots; routing V3 Initialize logs (different topic count/layout) into the V4 parser.","solutions":["Confirm the log has 4 topics: signature, poolId, currency0, currency1 (canonical V4 Initialize).","Guard topics.len() >= 3 && topics[2].is_some() before parsing and skip/skip-log otherwise.","Verify V3 logs are not being fed to the V4 parser.","Correct test fixtures to include both currency topics."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if log.topics.len() < 3 || log.topics[2].is_none() {\n    // skip: v4 Initialize requires currency0 as topics[2]\n    return Ok(None);\n}","typeGuard":"fn has_currency0_topic(log: &Log) -> bool {\n    log.topics.len() >= 3 && log.topics[2].is_some()\n}","tryCatchPattern":"match parse_initialize_event_hypersync(&log) {\n    Ok(event) => handle(event),\n    Err(e) if e.to_string().contains(\"Missing currency0 topic\") => {\n        tracing::warn!(\"v4 initialize log without currency0; skipping\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Check topics count and presence of topics[2]/topics[3] before parsing.","Confirm the emitting contract is the canonical V4 PoolManager.","Avoid hand-built fixtures omitting indexed currency topics.","Validate log shape at the ingestion boundary."],"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"}