nautechsystems/nautilus_trader · error
Invalid currency0 topic length
Error message
Invalid currency0 topic length
What it means
parse_initialize_event_hypersync for Uniswap V4 throws this when topics[2] exists but is shorter than 32 bytes, so slicing the low 20 bytes (12..32) that hold the 160-bit currency0 address fails. Ethereum topics are fixed 32-byte words; a shorter value means the payload is malformed. The library checks the slice instead of panicking on an out-of-range index.
Source
Thrown at crates/adapters/blockchain/src/exchanges/parsing/uniswap_v4/initialize.rs:111
"Initialize event missing topics: expected 4, was {}",
topics.len()
);
}
// Extract Pool ID from topics[1] - this is the unique identifier for V4 pools
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 {}",View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure topics are represented as fixed 32-byte words; left-pad the currency0 address with zeros before parsing.
- Check the log source/provider is not truncating topics (compare against the raw transaction receipt).
- Validate topic byte length (>= 32) before calling the parser and reject/short-circuit malformed logs.
- Fix test fixtures to use full 32-byte topic values (e.g. 0x000...<20-byte address>).
Example fix
// before let topic = hex::decode(short_hex)?; // e.g. 20 bytes // after let mut topic = [0u8; 32]; topic[12..].copy_from_slice(&hex::decode(addr_hex)?); // left-pad to 32 bytes let event = parse_initialize_event_hypersync(&log)?;
Defensive patterns
Strategy: validation
Validate before calling
fn topic_is_word(t: &Option<FixedBytes<32>>) -> bool {
t.as_ref().map(|b| b.len() == 32).unwrap_or(false)
}
// require topic_is_word(&log.topics[2]) before parsing Type guard
fn is_full_word_topic(topic: &Option<FixedBytes<32>>) -> bool {
topic.as_ref().is_some_and(|t| t.len() == 32)
} Try / catch
match parse_initialize_event_hypersync(&log) {
Ok(event) => handle(event),
Err(e) if e.to_string().contains("Invalid currency0 topic length") => {
tracing::warn!("short currency0 topic; skipping log");
}
Err(e) => return Err(e),
} Prevention
- Ensure topics are always fixed 32-byte words (left-pad addresses).
- Avoid serializers/clients that strip leading zero bytes from topics.
- Compare parsed topics against raw receipt data to detect truncation.
- Use full-width hex in test fixtures (0x + 64 chars).
When it happens
Trigger: Calling parse_initialize_event_hypersync (v4) with a log whose topics[2] contains fewer than 32 bytes — e.g. a provider returning a stripped/truncated topic, a hand-built fixture with a short byte array, or a binary serializer dropping leading zero bytes.
Common situations: Custom RPC/indexer clients that trim topics instead of left-padding addresses to 32 bytes; fixtures built from hex strings parsed without padding; forked contracts emitting non-standard topic widths.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Missing poolId topic
- Missing currency0 topic
- Missing data in burn event log
- Missing data in collect event log
- Missing data in initialize event log
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b7cd49c7ea23ca8c.
Report an issue: GitHub.