{"record":{"id":"f6fdab0f853e902c","repo":"nautechsystems/nautilus_trader","slug":"failed-to-decode-setfeeprotocol-event-data-e-f6fdab","errorCode":null,"errorMessage":"Failed to decode SetFeeProtocol event data: {e}","messagePattern":"Failed to decode SetFeeProtocol event data: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/exchanges/parsing/uniswap_v3/fee_protocol_update.rs","lineNumber":76,"sourceCode":"    log: &HypersyncLog,\n) -> anyhow::Result<FeeProtocolUpdateEvent> {\n    validate_event_signature_hash(\n        \"SetFeeProtocolEvent\",\n        FEE_PROTOCOL_UPDATE_EVENT_SIGNATURE_HASH,\n        log,\n    )?;\n\n    if let Some(data) = &log.data {\n        let data_bytes = data.as_ref();\n\n        // Validate the data contains 4 parameters of 32 bytes each\n        if data_bytes.len() < 4 * 32 {\n            anyhow::bail!(\"SetFeeProtocol event data is too short\");\n        }\n\n        let decoded = match <SetFeeProtocolEventData as SolType>::abi_decode(data_bytes) {\n            Ok(decoded) => decoded,\n            Err(e) => anyhow::bail!(\"Failed to decode SetFeeProtocol event data: {e}\"),\n        };\n\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\n        Ok(FeeProtocolUpdateEvent::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            u32::from(decoded.fee_protocol0_new),","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/exchanges/parsing/uniswap_v3/fee_protocol_update.rs#L58-L94","documentation":"Thrown by parse_fee_protocol_update_event_hypersync when the data is long enough (>=128 bytes) but alloy's SolType::abi_decode for SetFeeProtocolEventData still fails. This means the byte content does not decode into four uint8-ish parameters per the event ABI — wrong encoding, extra unaligned bytes, or wrong event type.","triggerScenarios":"abi_decode returns Err on a 128+ byte payload for a log whose topic matched SetFeeProtocol — e.g. data belongs to a different event, trailing bytes, or a provider returned a non-canonical encoding.","commonSituations":"Topic hash collision or alias filtering by signature with a different full signature; decoding logs from a fork/custom pool; corrupted or hand-built log data in tests (test_parse_fee_protocol_update_event_hypersync, test_hypersync_rpc_match).","solutions":["Log the underlying error {e} to see expected vs actual encoded sizes and fix the payload accordingly.","Verify data length is exactly 128 bytes; strip any trailing bytes before decoding.","Confirm the hypersync log filter matches the exact SetFeeProtocol event signature (name plus indexed parameter types).","Regenerate the SolStruct (SetFeeProtocolEventData) from the verified ABI to ensure parameter order/types are correct.","Cross-check with the RPC parser (parse_fee_protocol_update_event_rpc) on the same log to isolate hypersync-specific data issues."],"exampleFix":"// before\nErr(e) => anyhow::bail!(\"Failed to decode SetFeeProtocol event data: {e}\"),\n// after\nErr(e) => anyhow::bail!(\n    \"Failed to decode SetFeeProtocol event data (len={}): {e}\",\n    data_bytes.len()\n),","handlingStrategy":"validation","validationCode":"fn is_decodeable_set_fee_protocol(data: &[u8]) -> bool {\n    data.len() == 128\n        && <SetFeeProtocolEventData as SolType>::abi_decode(data).is_ok()\n}","typeGuard":null,"tryCatchPattern":"match parse_fee_protocol_update_event_hypersync(dex, &log) {\n    Ok(event) => handle(event),\n    Err(e) if e.to_string().contains(\"Failed to decode SetFeeProtocol\") => {\n        tracing::debug!(raw = ?log.data, \"undecodeable SetFeeProtocol data: {e}\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Use the full event signature (not a prefix) when building topic filters","Keep SetFeeProtocolEventData regenerated from the canonical pool ABI","Log the inner decode error to distinguish length vs content problems","Cross-validate hypersync parses against the RPC parser for the same logs"],"tags":["blockchain","uniswap-v3","hypersync","abi-decode"],"backgroundTag":"schema-validation-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}