{"record":{"id":"4467250d8caae6a1","repo":"nautechsystems/nautilus_trader","slug":"failed-to-decode-swap-event-data-e-446725","errorCode":null,"errorMessage":"Failed to decode swap event data: {e}","messagePattern":"Failed to decode swap event data: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/exchanges/parsing/uniswap_v3/swap.rs","lineNumber":74,"sourceCode":"/// Panics if the contract address is not set in the log.\npub fn parse_swap_event_hypersync(dex: SharedDex, log: &HypersyncLog) -> anyhow::Result<SwapEvent> {\n    validate_event_signature_hash(\"SwapEvent\", SWAP_EVENT_SIGNATURE_HASH, log)?;\n\n    let sender = extract_address_from_topic(log, 1, \"sender\")?;\n    let recipient = extract_address_from_topic(log, 2, \"recipient\")?;\n\n    if let Some(data) = &log.data {\n        let data_bytes = data.as_ref();\n\n        // Validate if data contains 5 parameters of 32 bytes each\n        if data_bytes.len() < 5 * 32 {\n            anyhow::bail!(\"Swap event data is too short\");\n        }\n\n        // Decode the data using the SwapEventData struct\n        let decoded = match <SwapEventData as SolType>::abi_decode(data_bytes) {\n            Ok(decoded) => decoded,\n            Err(e) => anyhow::bail!(\"Failed to decode swap event data: {e}\"),\n        };\n        let _ = decoded.amount0;\n        let pool_address = Address::from_slice(\n            log.address\n                .clone()\n                .expect(\"Contract address should be set in logs\")\n                .as_ref(),\n        );\n        let pool_identifier = PoolIdentifier::Address(Ustr::from(&pool_address.to_string()));\n        Ok(SwapEvent::new(\n            dex,\n            pool_identifier,\n            extract_block_number(log)?,\n            extract_transaction_hash(log)?,\n            extract_transaction_index(log)?,\n            extract_log_index(log)?,\n            sender,\n            recipient,","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/exchanges/parsing/uniswap_v3/swap.rs#L56-L92","documentation":"The same hypersync swap parser failed at the ABI decode stage: the data passed the 160-byte pre-check but <SwapEventData as SolType>::abi_decode rejected it. The inner alloy decoding error is embedded so developers can see the exact word/type mismatch.","triggerScenarios":"Data is >= 160 bytes but the word layout does not match SwapEventData — extra leading bytes, non-canonical padding, or a fork contract with a modified Swap schema.","commonSituations":"Decoding logs from a modified Uniswap fork; provider returning hex with wrong encoding (odd-length hex, non-hex chars); decoding events from unrelated contracts that share a partial topic0.","solutions":["Print the failing data hex and compare word-by-word against the canonical V3 Swap layout (amount0, amount1, sqrtPriceX96, liquidity, tick)","Confirm the log's topic0 equals the canonical V3 Swap signature hash","Validate the hex payload decodes cleanly (even length, valid hex) before ABI decoding","Regenerate SwapEventData bindings if the target contract is a fork with an altered event","Treat undecodable logs as skip-and-log instead of failing block ingestion"],"exampleFix":"// before\nlet decoded = match <SwapEventData as SolType>::abi_decode(data_bytes) {\n    Ok(d) => d,\n    Err(e) => anyhow::bail!(\"Failed to decode swap event data: {e}\"),\n};\n// after\nlet decoded = match <SwapEventData as SolType>::abi_decode(data_bytes) {\n    Ok(d) => d,\n    Err(e) => {\n        tracing::warn!(%e, \"undecodable swap log skipped\");\n        return Ok(None);\n    }\n};","handlingStrategy":"try-catch","validationCode":"if log.topic0 != SWAP_V3_TOPIC0 || data_bytes.len() < 160 { skip(); }\n// additionally validate hex payload:\nif data_hex.len() % 2 != 0 { skip(); }","typeGuard":null,"tryCatchPattern":"match parse_swap_event_hypersync(&dex, &log) {\n    Ok(ev) => handle(ev),\n    Err(e) => { tracing::warn!(%e, data = %hex, \"undecodable swap log skipped\"); Ok(None) }\n}","preventionTips":["Diff failing payloads word-by-word against the canonical Swap layout","Verify topic0 before decoding","Regenerate bindings for forked contracts","Make undecodable logs non-fatal in ingestion loops"],"tags":["blockchain","abi-decode","uniswap-v3","event-parsing"],"backgroundTag":"json-decode-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}