Incident Report: Chain ID Validation Bypass

Date: December 15, 2025
Status: Resolved
Funds at risk: None. No user funds were at risk. The issue has been mitigated on Celo Mainnet.

Summary

On December 15, a community researcher (s7v7nislands) reported a transaction on Celo Mainnet with a mismatched chain ID. We confirmed the report and took immediate steps to mitigate the issue. Within hours, an updated transaction proxy was deployed to the sequencer, blocking any further transactions of this type.

Investigation revealed that the bug was only introduced during the Celo L2 migration and did not exist in the previous L1 implementation. A fix for the bug was already included in our development branch and was scheduled for inclusion in the upcoming Jovian hardfork.

Note: If you discover a potential security issue on Celo, please follow the responsible disclosure process at celo.org/security.

Timeline

All times are UTC, December 15, 2025.

Time Event
04:14 Bug reported via GitHub issue tracker
11:31 Report confirmed and reproduced internally
18:37 Updated transaction proxy deployed with chain ID validation; issue fully mitigated

Root Cause

The Bug

The accessListTxFuncs.sender function, introduced in commit 862f6ebbe (“Handle access list txs at espresso hardfork”) on February 11, 2025, incorrectly used the transaction’s self-reported chain ID (tx.ChainId()) rather than the node’s configured chain ID (signerChainID) when constructing the signer:

// Before (incorrect)
return NewEIP2930Signer(tx.ChainId()).Sender(tx)

// After (correct)
return NewEIP2930Signer(signerChainID).Sender(tx)

This effectively bypassed chain ID validation in EIP2930Signer.Sender(), because the signer was initialized using the transaction’s own reported chain ID rather than the node’s configured chain ID.

Impact

The bug allowed EIP-2930 (access list) transactions with an incorrect chain ID to be accepted on Celo Mainnet. In theory, this could enable cross-chain replay attacks. In practice, the risk was very low. EIP-2930 transactions are rarely used, and exploiting the bug would require finding a transaction from another chain with the same nonce that does not revert on Celo and produces a result beneficial to the attacker.

One transaction with a wrong chain ID was included on Celo Mainnet. It was not used to gain or steal funds. It has been whitelisted in our node software to prevent syncing errors during block re-execution (see op-geth#454).

Resolution

The immediate mitigation (transaction proxy filtering) was deployed on December 15. The underlying code fix is included in the Jovian hardfork release and has also been deployed to the sequencer.

3 Likes