nautechsystems/nautilus_trader · error
Swap event data is too short
Error message
Swap event data is too short
What it means
parse_swap_event_hypersync decodes a PancakeSwap V3 Swap log whose data section must carry 7 ABI words (Uniswap V3's 5 fields plus two appended protocolFees words). Before decoding, the function checks `data_bytes.len() < 7 * 32` and bails with 'Swap event data is too short' if the payload cannot hold all 7 words. This guards the ABI decoder and surfaces a common case: a log with a Uniswap V3-style (5-word) data payload being fed to the PancakeSwap parser.
Source
Thrown at crates/adapters/blockchain/src/exchanges/parsing/pancakeswap_v3/swap.rs:71
///
/// # Errors
///
/// Returns an error if the log parsing fails or if the event data is invalid.
///
/// # Panics
///
/// Panics if the contract address is not set in the log.
pub fn parse_swap_event_hypersync(dex: SharedDex, log: &HypersyncLog) -> anyhow::Result<SwapEvent> {
validate_event_signature_hash("SwapEvent", SWAP_EVENT_SIGNATURE_HASH, log)?;
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)?,View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the log is actually a PancakeSwap V3 Swap event: its topic0 must be 0x19b47279256b2a23a1665c810c8d55a1758940ee09377d4f8d26497a3577dc83 and data must be 0x + 448 hex chars (7 words); route Uniswap V3 topic0 (0xc42079f9...) to the Uniswap V3 parser instead
- Check the HyperSync query/response for truncation — re-fetch the log and confirm the full data field is returned
- Validate `log.data` length in your ingestion pipeline before calling parse_swap_event_hypersync and skip or quarantine logs shorter than 224 bytes
- If building fixtures/tests, base them on a real PancakeSwap V3 Swap log (7 data words) rather than a Uniswap V3 one
Example fix
// before: feeding a Uniswap V3 (5-word) data payload to the PancakeSwap parser
let log: HypersyncLog = serde_json::from_str(uniswap_style_log)?;
let event = parse_swap_event_hypersync(dex, &log)?; // bail: data too short
// after: route by topic0 to the correct parser
const PANCAKE_V3_SWAP_TOPIC: &str = "19b47279256b2a23a1665c810c8d55a1758940ee09377d4f8d26497a3577dc83";
const UNISWAP_V3_SWAP_TOPIC: &str = "c42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67";
let event = if log.topics[0].to_string().contains(PANCAKE_V3_SWAP_TOPIC) {
parse_swap_event_hypersync(pancake_dex, &log)?
} else if log.topics[0].to_string().contains(UNISWAP_V3_SWAP_TOPIC) {
parse_uniswap_v3_swap(dex, &log)?
} else { anyhow::bail!("unknown swap topic"); }; Defensive patterns
Strategy: validation
Validate before calling
const PANCAKE_V3_SWAP_TOPIC: &str = "19b47279256b2a23a1665c810c8d55a1758940ee09377d4f8d26497a3577dc83";
pub fn can_parse_pancake_swap(log: &HypersyncLog) -> bool {
let topic_ok = log.topics.first()
.and_then(|t| t.as_ref())
.map(|t| t.to_string().contains(PANCAKE_V3_SWAP_TOPIC))
.unwrap_or(false);
let data_ok = log.data.as_ref()
.map(|d| d.as_ref().len() >= 7 * 32)
.unwrap_or(false);
topic_ok && data_ok
} Type guard
fn is_full_pancake_swap_data(log: &HypersyncLog) -> bool {
log.data.as_ref().map(|d| d.as_ref().len() >= 224).unwrap_or(false)
} Try / catch
match parse_swap_event_hypersync(dex, &log) {
Ok(event) => store(event),
Err(e) if e.to_string().contains("too short") => {
tracing::warn!(tx = ?log.transaction_hash, "short swap data — likely Uniswap V3 log routed to PancakeSwap parser; skipping");
}
Err(e) => return Err(e),
} Prevention
- Dispatch log parsing on full topic0 hash, not event name — PancakeSwap V3 and Uniswap V3 Swap topics differ
- Check log.data length (>= 224 bytes for PancakeSwap V3 Swap) before parsing
- Base test fixtures on real PancakeSwap V3 logs with 7 data words, not Uniswap V3 ones
- Watch for HyperSync response truncation on large batch queries
When it happens
Trigger: Calling parse_swap_event_hypersync with a HypersyncLog whose topic0 matches the PancakeSwap V3 Swap signature hash (0x19b47279...) but whose `data` hex is shorter than 224 bytes (7 x 32 bytes) — e.g. a truncated 5-word Uniswap V3 layout, a partially fetched log, or corrupted data.
Common situations: Indexing BSC pools with a query that mixes Uniswap V3 and PancakeSwap V3 logs; copying a Uniswap V3 Swap log fixture into PancakeSwap test data; HyperSync responses truncated by size limits or network errors; manually constructing test logs with incomplete data fields.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- Failed to decode swap event data: {e}
- Missing tickLower in topic2 when parsing burn event
- Failed to decode initialize event data: {e}
- Missing data in the pool created event log
- HyperSync parsing of pool created event is not defined in th
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/945e98ddc3582bf2.
Report an issue: GitHub.