nautechsystems/nautilus_trader · error
Missing fee in topic3 when parsing pool created event
Error message
Missing fee in topic3 when parsing pool created event
What it means
parse_pool_created_event_hypersync requires topic3 of the PoolCreated event because the fee uint24 is indexed there. When the hypersync log carries fewer than 4 topics, the library cannot recover the fee tier and bails rather than guessing a default.
Source
Thrown at crates/adapters/blockchain/src/exchanges/parsing/uniswap_v3/pool_created.rs:49
"783cca1c0412dd0d695e784568c96da2e9c22ff989357a2e8b1d9b2b4e6b7118";
/// Parses a pool creation event from a HyperSync log.
///
/// # Errors
///
/// Returns an error if the log parsing fails or if the event data is invalid.
pub fn parse_pool_created_event_hypersync(log: HypersyncLog) -> anyhow::Result<PoolCreatedEvent> {
validate_event_signature_hash("PoolCreatedEvent", POOL_CREATED_EVENT_SIGNATURE_HASH, &log)?;
let block_number = extract_block_number(&log)?;
let token = extract_address_from_topic(&log, 1, "token0")?;
let token1 = extract_address_from_topic(&log, 2, "token1")?;
let fee = if let Some(topic) = log.topics.get(3).and_then(|t| t.as_ref()) {
U256::from_be_slice(topic.as_ref()).as_limbs()[0] as u32
} else {
anyhow::bail!("Missing fee in topic3 when parsing pool created event");
};
if let Some(data) = log.data {
// Data contains: [tick_spacing (32 bytes), pool_address (32 bytes)]
let data_bytes = data.as_ref();
// Extract tick_spacing (first 32 bytes)
let tick_spacing_bytes: [u8; 32] = data_bytes[0..32].try_into()?;
let tick_spacing = u32::from_be_bytes(tick_spacing_bytes[28..32].try_into()?);
// Extract pool_address (next 32 bytes)
let pool_address_bytes: [u8; 32] = data_bytes[32..64].try_into()?;
let pool_address = Address::from_slice(&pool_address_bytes[12..32]);
Ok(PoolCreatedEvent::new(
block_number,
token,
token1,View on GitHub (pinned to 18893faf8b)
Solutions
- Filter hypersync queries by the exact PoolCreated topic0 and require 4 indexed topics
- Check topics.len() >= 4 in the caller before invoking the parser and skip non-matching logs
- Confirm the source contract is the canonical Uniswap V3 factory for the target chain
- If decoding a fork whose fee is not indexed, parse fee from the data section instead of topic3
Example fix
// before
let fee = if let Some(topic) = log.topics.get(3).and_then(|t| t.as_ref()) {
U256::from_be_slice(topic.as_ref()).as_limbs()[0] as u32
} else {
anyhow::bail!("Missing fee in topic3 when parsing pool created event");
};
// after
if log.topics.len() < 4 {
tracing::debug!("skipping log: not a canonical PoolCreated event (topics < 4)");
return Ok(None); // or continue
}
let fee = U256::from_be_slice(log.topics[3].as_ref()).as_limbs()[0] as u32; Defensive patterns
Strategy: validation
Validate before calling
fn has_pool_created_topics(log: &HypersyncLog) -> bool {
log.topics.len() >= 4 && log.topics[0].as_ref() == POOL_CREATED_TOPIC0
}
if !has_pool_created_topics(&log) { skip_or_log(); } Try / catch
match parse_pool_created_event_hypersync(&log, &factory) {
Ok(ev) => handle(ev),
Err(e) => { tracing::debug!(%e, "pool-created log skipped"); Ok(None) }
} Prevention
- Always include the exact PoolCreated topic0 in hypersync topic filters
- Require 4 indexed topics in the subscription
- Verify chain-specific factory addresses
- Treat topic3-fee presence as a V3-canonicality check
When it happens
Trigger: Calling parse_pool_created_event_hypersync with a log that has fewer than 4 topics — typically because the source address is not actually a Uniswap V3 factory, or the subscription filter matched a non-PoolCreated event signature.
Common situations: Wide hypersync queries (topic0 omitted or broad) that pull in unrelated factory events; decoding logs from a V2-style factory or a fork that emits PoolCreated with unindexed fee (fee in data instead of topic3).
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
- Missing tickLower in topic2 when parsing collect event
- Missing tickUpper in topic3 when parsing collect event
- Swap event data is too short
- Failed to decode swap event data: {e}
- Initialize event missing topics: expected 4, was {topics_len
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/8db83dba90fdec09.
Report an issue: GitHub.