{"record":{"id":"417df1566f6ce2bb","repo":"nautechsystems/nautilus_trader","slug":"setfeeprotocol-event-data-is-too-short-417df1","errorCode":null,"errorMessage":"SetFeeProtocol event data is too short","messagePattern":"SetFeeProtocol event data is too short","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/exchanges/parsing/uniswap_v3/fee_protocol_update.rs","lineNumber":71,"sourceCode":"/// # Panics\n///\n/// Panics if the contract address is not set in the log.\npub fn parse_fee_protocol_update_event_hypersync(\n    dex: SharedDex,\n    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,","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/exchanges/parsing/uniswap_v3/fee_protocol_update.rs#L53-L89","documentation":"Thrown by parse_fee_protocol_update_event_hypersync when the hypersync log's data field is present but shorter than the 4 x 32 = 128 bytes required to hold the SetFeeProtocol event's four padded parameters (feeProtocol0Old, feeProtocol1Old, feeProtocol0New, feeProtocol1New). The library checks length before decoding to avoid a guaranteed decode failure.","triggerScenarios":"A hypersync log whose topic0 matches SetFeeProtocol arrives with data shorter than 128 bytes — e.g. empty data, truncated hex, or data from a different event with fewer parameters.","commonSituations":"Feeding logs filtered only by address rather than by event topic so unrelated events slip through; hypersync query returning partial data fields; malformed/custom test fixtures in tests like test_parse_fee_protocol_update_event_hypersync.","solutions":["Ensure the hypersync query filters on the SetFeeProtocol topic0 signature so only matching event logs are fetched.","Check that log.data is populated and its hex is >= 256 hex chars (128 bytes).","Confirm the log comes from a standard Uniswap V3 pool; a SetFeeProtocol variant with different parameter layout will fail.","Fix test/log fixtures so data contains four 32-byte words.","If the event genuinely emits fewer words, update SetFeeProtocolEventData to the actual ABI and adjust the length check."],"exampleFix":"// before\nif data_bytes.len() < 4 * 32 {\n    anyhow::bail!(\"SetFeeProtocol event data is too short\");\n}\n// after\nif data_bytes.len() != 4 * 32 {\n    anyhow::bail!(\"SetFeeProtocol event data must be exactly 128 bytes, got {}\", data_bytes.len());\n}","handlingStrategy":"validation","validationCode":"fn is_valid_set_fee_protocol_data(data: Option<&[u8]>) -> bool {\n    data.map(|d| d.len() == 4 * 32).unwrap_or(false)\n}","typeGuard":"fn has_set_fee_protocol_shape(log: &HypersyncLog) -> bool {\n    log.data\n        .as_ref()\n        .map(|d| d.len() >= 128)\n        .unwrap_or(false)\n}","tryCatchPattern":"match parse_fee_protocol_update_event_hypersync(dex, &log) {\n    Ok(event) => handle(event),\n    Err(e) if e.to_string().contains(\"SetFeeProtocol\") => {\n        tracing::warn!(\"skipping invalid SetFeeProtocol log: {e}\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Filter hypersync queries by the SetFeeProtocol topic0 so only well-formed event logs are returned","Always request the data field in the log selection","Validate data length == 128 bytes before calling the parser","Verify emitting addresses are standard Uniswap V3 pools"],"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"}