nautechsystems/nautilus_trader · error

Missing data in the pool created event log

Error message

Missing data in the pool created event log

What it means

parse_camelot_v3_pool_created_event_hypersync parses a HyperSync log for the Camelot V3 PoolCreated event and bails when required fields (e.g. decoded token0/token1/pool address components) are absent from the log. It fails closed rather than fabricating a PoolCreatedEvent with missing data.

Source

Thrown at crates/adapters/blockchain/src/exchanges/arbitrum/camelot_v3.rs:81

    let token1 = extract_address_from_topic(&log, 2, "token1")?;

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

        // Extract pool address (only 32 bytes)
        let pool_address = Address::from_slice(&data_bytes[12..32]);
        let pool_identifier = PoolIdentifier::Address(Ustr::from(&pool_address.to_string()));
        Ok(PoolCreatedEvent::new(
            block_number,
            token,
            token1,
            pool_address,
            pool_identifier,
            None,
            None,
        ))
    } else {
        anyhow::bail!("Missing data in the pool created event log")
    }
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Filter logs by the exact PoolCreated event topic0 before calling the parser
  2. Verify the HyperSync log contains all expected decoded fields (token0, token1, pool address)
  3. Re-fetch the log range — the partial log may be a transient hydration issue
  4. Confirm the Camelot V3 ABI/event signature used to build the parser matches the deployed contract

Example fix

// before: parse whatever arrives
for log in logs {
    let ev = dex.parse_pool_created_event_hypersync(log)?;
    ...
}
// after: pre-filter by topic
let pool_created_topic0 = camelot_v3_pool_created_topic();
for log in logs.iter().filter(|l| l.topics().first() == Some(&pool_created_topic0)) {
    let ev = dex.parse_pool_created_event_hypersync(log)?;
    ...
}
Defensive patterns

Strategy: type-guard

Validate before calling

let expected_topic0 = camelot_v3_pool_created_topic();
if log.topics().first() != Some(&expected_topic0) || log.data_missing_fields() {
    return Ok(None); // not a decodable PoolCreated log
}

Type guard

fn is_decodable_pool_created_log(log: &HypersyncLog, topic0: &B256) -> bool {
    log.topics().first() == Some(topic0)
        && log.token0().is_some()
        && log.token1().is_some()
        && log.pool_address().is_some()
}

Try / catch

match dex.parse_pool_created_event_hypersync(&log) {
    Ok(ev) => Some(ev),
    Err(e) if e.to_string().contains("Missing data") => {
        tracing::warn!("skipping partial PoolCreated log at block {}", log.block_number);
        None
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Feeding a HypersyncLog to the Camelot V3 pool-created parser when the log is not actually a PoolCreated event, the ABI topic doesn't match, or HyperSync returned a partial/undecoded log missing expected data fields.

Common situations: Broad topic filters that match non-PoolCreated logs; HyperSync schema/field-name changes for that event; indexing lag or partial log hydration; copying a parser for the wrong event signature.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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