nautechsystems/nautilus_trader · error
Contract address should be set in logs
Error message
Contract address should be set in logs
What it means
parse_burn_event_hypersync unwraps log.address with expect() because the emitting contract address identifies the Uniswap V3 pool for the BurnEvent. A Hypersync log without an address is treated as impossible for well-formed Burn logs, so the parser panics rather than returning a result; this panic is documented in the function's # Panics section.
Source
Thrown at crates/adapters/blockchain/src/exchanges/parsing/uniswap_v3/burn.rs:95
if let Some(data) = &log.data {
let data_bytes = data.as_ref();
// Validate if data contains 3 parameters of 32 bytes each
if data_bytes.len() < 3 * 32 {
anyhow::bail!("Burn event data is too short");
}
// Decode the data using the BurnEventData struct
let decoded = match <BurnEventData as SolType>::abi_decode(data_bytes) {
Ok(decoded) => decoded,
Err(e) => anyhow::bail!("Failed to decode burn event data: {e}"),
};
let pool_address = Address::from_slice(
log.address
.clone()
.expect("Contract address should be set in logs")
.as_ref(),
);
let pool_identifier = PoolIdentifier::Address(Ustr::from(&pool_address.to_string()));
Ok(BurnEvent::new(
dex,
pool_identifier,
extract_block_number(log)?,
extract_transaction_hash(log)?,
extract_transaction_index(log)?,
extract_log_index(log)?,
owner,
tick_lower,
tick_upper,
decoded.amount,
decoded.amount0,
decoded.amount1,
))
} else {View on GitHub (pinned to 18893faf8b)
Solutions
- Request the address field in the Hypersync log selection so every log row includes it.
- Pre-filter logs lacking an address before dispatching to event parsers.
- Change the parser to return anyhow::Result error via ok_or instead of panicking.
Example fix
// before
let pool_address = Address::from_slice(
log.address.clone().expect("Contract address should be set in logs").as_ref(),
);
// after
let raw_address = log.address.as_ref()
.ok_or_else(|| anyhow::anyhow!("missing contract address in burn log"))?;
let pool_address = Address::from_slice(raw_address.as_ref()); Defensive patterns
Strategy: validation
Validate before calling
if log.address.is_none() {
log::warn!("skipping burn log without contract address");
return Ok(());
}
let event = parse_burn_event_hypersync(dex.clone(), &log)?; Type guard
fn has_address(log: &HypersyncLog) -> bool {
log.address.is_some()
} Try / catch
match parse_burn_event_hypersync(dex, &log) {
Ok(event) => handle(event),
Err(e) => log::error!("failed to parse burn log: {e:#}"),
}
// Note: missing address panics via expect(); pre-check log.address before calling. Prevention
- Include address in Hypersync projections for burn event ingestion.
- Add a central address-presence check in the log-processing pipeline.
- Verify Hypersync client upgrades do not change log field nullability.
When it happens
Trigger: Passing a HypersyncLog with address == None to parse_burn_event_hypersync — typically from a Hypersync query that omitted the address column or a manually built log fixture.
Common situations: Query projection mistakes when collecting raw logs; Hypersync client upgrades changing field nullability; test harnesses constructing partial HypersyncLog values.
Related errors
- Contract address should be set in logs
- Contract address should be set in logs
- Contract address should be set in logs
- Contract address should be set in logs
- Contract address should be set in logs
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/99a541acbfb7a0b1.
Report an issue: GitHub.