nautechsystems/nautilus_trader · error
Contract address should be set in logs
Error message
Contract address should be set in logs
What it means
parse_swap_event_hypersync requires log.address to be present: it is the pool contract address converted into a PoolIdentifier for the SwapEvent. The parser asserts this with expect(), documented as a panic condition, because a Swap log without an emitting address is considered malformed input that the caller should have filtered.
Source
Thrown at crates/adapters/blockchain/src/exchanges/parsing/pancakeswap_v3/swap.rs:81
let sender = extract_address_from_topic(log, 1, "sender")?;
let recipient = extract_address_from_topic(log, 2, "recipient")?;
if let Some(data) = &log.data {
let data_bytes = data.as_ref();
if data_bytes.len() < 7 * 32 {
anyhow::bail!("Swap event data is too short");
}
let decoded = match <SwapEventData as SolType>::abi_decode(data_bytes) {
Ok(decoded) => decoded,
Err(e) => anyhow::bail!("Failed to decode swap 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(SwapEvent::new(
dex,
pool_identifier,
extract_block_number(log)?,
extract_transaction_hash(log)?,
extract_transaction_index(log)?,
extract_log_index(log)?,
sender,
recipient,
decoded.amount0,
decoded.amount1,
decoded.sqrt_price_x96,
decoded.liquidity,
decoded.tick.as_i32(),
))View on GitHub (pinned to 18893faf8b)
Solutions
- Include the address field in the Hypersync log query so all rows carry the emitting contract address.
- Filter logs with address None upstream (e.g. validate_event_signature_hash-style guard or a pre-check) before parsing.
- Convert the expect into an anyhow error return inside the parser for graceful handling.
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 swap 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 swap log without contract address");
return Ok(());
}
let event = parse_swap_event_hypersync(dex.clone(), &log)?; Type guard
fn has_address(log: &HypersyncLog) -> bool {
log.address.is_some()
} Try / catch
match parse_swap_event_hypersync(dex, &log) {
Ok(event) => handle(event),
Err(e) => log::error!("failed to parse swap log: {e:#}"),
}
// Note: missing address panics via expect(); pre-check log.address before calling. Prevention
- Select the address field in every Hypersync query used for swap ingestion.
- Filter address-less logs once, centrally, before dispatching to event parsers.
- Keep test fixtures for HypersyncLog complete (set address) so tests reflect real rows.
When it happens
Trigger: Calling parse_swap_event_hypersync with a HypersyncLog where address is None — Hypersync result rows lacking the address field, or test fixtures constructing logs without address, when topic/data otherwise match the Swap signature.
Common situations: Hypersync queries with projections excluding address; version drift in the Hypersync client/arrow schema dropping the field; handcrafted log fixtures in integration tests.
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/96327295528f101c.
Report an issue: GitHub.