nautechsystems/nautilus_trader · error

Missing currency1 topic

Error message

Missing currency1 topic

What it means

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.

Source

Thrown at crates/adapters/blockchain/src/exchanges/parsing/uniswap_v4/initialize.rs:117

    let pool_id_bytes = topics[1]
        .as_ref()
        .ok_or_else(|| anyhow::anyhow!("Missing poolId topic"))?
        .as_ref();
    let pool_identifier = Ustr::from(&hex::encode_prefixed(pool_id_bytes));

    let currency0 = Address::from_slice(
        topics[2]
            .as_ref()
            .ok_or_else(|| anyhow::anyhow!("Missing currency0 topic"))?
            .as_ref()
            .get(12..32)
            .ok_or_else(|| anyhow::anyhow!("Invalid currency0 topic length"))?,
    );

    let currency1 = Address::from_slice(
        topics[3]
            .as_ref()
            .ok_or_else(|| anyhow::anyhow!("Missing currency1 topic"))?
            .as_ref()
            .get(12..32)
            .ok_or_else(|| anyhow::anyhow!("Invalid currency1 topic length"))?,
    );

    if let Some(data) = log.data {
        let data_bytes = data.as_ref();

        // Validate minimum data length (5 fields × 32 bytes = 160 bytes)
        if data_bytes.len() < 160 {
            anyhow::bail!(
                "Initialize event data too short: expected at least 160 bytes, was {}",
                data_bytes.len()
            );
        }

        let decoded = <InitializeEventData as SolType>::abi_decode(data_bytes)
            .map_err(|e| anyhow::anyhow!("Failed to decode initialize event data: {e}"))?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the log actually matches the Uniswap V4 Initialize event signature (topic0 hash) before parsing; filter on the exact topic0 in the HyperSync query.
  2. Check that topics.len() >= 4 and topics[3].is_some() before calling the parser.
  3. Update the adapter to the current Uniswap V4 event ABI if the contract version changed.
  4. Log the offending log's topic0 and tx hash to identify the true event type.

Example fix

// before
let currency1 = Address::from_slice(topics[3].as_ref().ok_or_else(|| anyhow::anyhow!("Missing currency1 topic"))?.as_ref().get(12..32)?...);
// after
if topics.len() < 4 || topics[3].is_none() {
    tracing::warn!(topic0 = ?topics.first(), "log is not a Uniswap V4 Initialize event; skipping");
    return Ok(None); // or filter by exact event signature upstream
}
let currency1 = Address::from_slice(topics[3].as_ref().unwrap().as_ref().get(12..32)...);
Defensive patterns

Strategy: validation

Validate before calling

// call before parsing
fn has_initialize_topics(log: &HypersyncLog) -> bool {
    log.topics.len() >= 4 && log.topics[0].is_some() && log.topics[3].is_some()
}

Type guard

fn topic3_is_address(log: &HypersyncLog) -> bool {
    log.topics.get(3).and_then(|t| t.as_ref()).map(|t| t.as_ref().len() == 32).unwrap_or(false)
}

Try / catch

match parse_initialize_event_hypersync(&log) {
    Ok(event) => store(event),
    Err(e) if e.to_string().contains("Missing currency1 topic") => skip_log(&log, e),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/f6d6be22f8be1f22. Report an issue: GitHub.