{"record":{"id":"f6d6be22f8be1f22","repo":"nautechsystems/nautilus_trader","slug":"missing-currency1-topic","errorCode":null,"errorMessage":"Missing currency1 topic","messagePattern":"Missing currency1 topic","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/exchanges/parsing/uniswap_v4/initialize.rs","lineNumber":117,"sourceCode":"    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)\n        if data_bytes.len() < 160 {\n            anyhow::bail!(\n                \"Initialize event data too short: expected at least 160 bytes, was {}\",\n                data_bytes.len()\n            );\n        }\n\n        let decoded = <InitializeEventData as SolType>::abi_decode(data_bytes)\n            .map_err(|e| anyhow::anyhow!(\"Failed to decode initialize event data: {e}\"))?;","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/exchanges/parsing/uniswap_v4/initialize.rs#L99-L135","documentation":"This error is thrown by `parse_initialize_event_hypersync` when a Uniswap V4 `Initialize` event log fetched via HyperSync has no value at index 3 of its topic list. The Initialize event always emits 4 indexed topics (pool_id, currency0, currency1, hooks), so a missing third topic means the log is malformed or belongs to a different event. The parser refuses to guess and fails fast.","triggerScenarios":"Calling `parse_initialize_event_hypersync` with a `HypersyncLog` whose `topics` array has fewer than 4 entries, or where `topics[3]` is `None`. This happens when HyperSync returns a log whose signature doesn't actually match the Initialize event ABI, or a partially populated log.","commonSituations":"Querying HyperSync with a topic0 filter that also matches non-Initialize events due to a wrong/aliased event signature; a contract or chain variant that emits a differently shaped Initialize event; stale ABI definitions after a Uniswap V4 upgrade.","solutions":["Verify the log actually matches the Uniswap V4 Initialize event signature (topic0 hash) before parsing; filter on the exact topic0 in the HyperSync query.","Check that topics.len() >= 4 and topics[3].is_some() before calling the parser.","Update the adapter to the current Uniswap V4 event ABI if the contract version changed.","Log the offending log's topic0 and tx hash to identify the true event type."],"exampleFix":"// before\nlet currency1 = Address::from_slice(topics[3].as_ref().ok_or_else(|| anyhow::anyhow!(\"Missing currency1 topic\"))?.as_ref().get(12..32)?...);\n// after\nif topics.len() < 4 || topics[3].is_none() {\n    tracing::warn!(topic0 = ?topics.first(), \"log is not a Uniswap V4 Initialize event; skipping\");\n    return Ok(None); // or filter by exact event signature upstream\n}\nlet currency1 = Address::from_slice(topics[3].as_ref().unwrap().as_ref().get(12..32)...);","handlingStrategy":"validation","validationCode":"// call before parsing\nfn has_initialize_topics(log: &HypersyncLog) -> bool {\n    log.topics.len() >= 4 && log.topics[0].is_some() && log.topics[3].is_some()\n}","typeGuard":"fn topic3_is_address(log: &HypersyncLog) -> bool {\n    log.topics.get(3).and_then(|t| t.as_ref()).map(|t| t.as_ref().len() == 32).unwrap_or(false)\n}","tryCatchPattern":"match parse_initialize_event_hypersync(&log) {\n    Ok(event) => store(event),\n    Err(e) if e.to_string().contains(\"Missing currency1 topic\") => skip_log(&log, e),\n    Err(e) => return Err(e),\n}","preventionTips":["Filter HyperSync queries by the exact Initialize event topic0 signature","Validate topic count and presence before parsing each log","Keep ABI definitions in sync with the deployed Uniswap V4 contracts"],"tags":["blockchain","parsing","hypersync","event-decoding"],"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"}