{"record":{"id":"73c5c63b8533abb4","repo":"linera-io/linera-protocol","slug":"event-topic-does-not-match-depositinitiated-signat","errorCode":null,"errorMessage":"event topic does not match DepositInitiated signature","messagePattern":"event topic does not match DepositInitiated signature","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-bridge/src/proof/mod.rs","lineNumber":431,"sourceCode":"    }\n\n    Ok(logs)\n}\n\n/// Parses a `DepositInitiated` event from a receipt log.\n///\n/// Verifies that `topic[0]` matches the event signature, that the log was emitted by\n/// the `expected_emitter` (bridge contract address), and ABI-decodes the data fields.\n/// The `depositor` field is indexed (stored in `topics[1]`); all other parameters are\n/// non-indexed and encoded in the log data.\npub fn parse_deposit_event(log: &ReceiptLog, expected_emitter: Address) -> Result<DepositEvent> {\n    ensure!(\n        log.address == expected_emitter,\n        \"log emitter {:?} does not match expected bridge contract {:?}\",\n        log.address,\n        expected_emitter\n    );\n    ensure!(\n        log.topics.first() == Some(&deposit_event_signature()),\n        \"event topic does not match DepositInitiated signature\"\n    );\n    ensure!(\n        log.topics.len() == 2,\n        \"expected exactly 2 topics (signature + indexed depositor), got {}\",\n        log.topics.len()\n    );\n    ensure!(\n        log.data.len() == 224,\n        \"expected 224 bytes of event data (7 x 32), got {}\",\n        log.data.len()\n    );\n\n    // Indexed `depositor` is in topics[1], left-padded to 32 bytes.\n    let depositor_topic = log.topics[1];\n    ensure!(\n        depositor_topic.as_slice()[..12] == [0u8; 12],","sourceCodeStart":413,"sourceCodeEnd":449,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-bridge/src/proof/mod.rs#L413-L449","documentation":"parse_deposit_event requires topics[0] to equal keccak256 of the DepositInitiated(uint256,bytes32,bytes32,bytes32,address,address,uint256,uint256) signature (deposit_event_signature()). Any log whose first topic is a different event signature — including similarly named events from the real contract — is rejected. This prevents confusing other bridge events (withdrawals, finalizations) with deposits.","triggerScenarios":"Feeding every log of the bridge contract into parse_deposit_event: a WithdrawalInitiated or DepositFinalized event also has the bridge as emitter but a different topic0; signature mismatch after the ABI changed (field added/removed) between contract versions.","commonSituations":"Scanner not filtering by topic0 at the RPC level; contract upgrade altering the event signature while the indexer still hashes the old ABI; fixtures copied from a different event of the same contract.","solutions":["Filter at query time by topic0: eth_getLogs(topics=[deposit_event_signature()]) so only DepositInitiated logs arrive","After a contract upgrade, regenerate the signature from the new ABI and redeploy/align the indexer","Verify with cast sig-event 'DepositInitiated(...)' that your expected signature matches the on-chain topic"],"exampleFix":"// before\nlet sig = keccak256(\"Deposit(uint256,address,uint256)\"); // old/short ABI\n\n// after\n// keccak256(\"DepositInitiated(uint256,bytes32,bytes32,bytes32,address,address,uint256,uint256)\")\nlet sig = deposit_event_signature();\nlet logs = rpc.get_logs(address = BRIDGE, topics = [sig]);","handlingStrategy":"validation","validationCode":"// Only offer logs whose topic0 is the DepositInitiated signature\nlet sig = deposit_event_signature();\nif log.topics.first() != Some(&sig) {\n    return Ok(None); // different event from the same contract\n}\nlet event = parse_deposit_event(log, bridge_address)?;","typeGuard":null,"tryCatchPattern":"match parse_deposit_event(&log, bridge_address) {\n    Ok(ev) => Some(ev),\n    Err(e) if e.to_string().contains(\"topic does not match DepositInitiated\") => {\n        tracing::debug!(\"skipping non-deposit event from bridge contract\"); None\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Subscribe with topics=[deposit_event_signature()] so non-deposit events never reach the parser","After contract upgrades, recompute the topic0 from the new ABI and update the indexer","Verify expected vs on-chain topic0 with cast keccak/cast sig-event during integration"],"tags":["ethereum","bridge","event-log","abi","signature-mismatch","rust"],"backgroundTag":"event-signature-mismatch","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}