- January 27, 2026
OpenZeppelin Security
OpenZeppelin Security
Security Audits
-
Summary
Type: Layer 2 & Rollups
Timeline: From 2025-12-15 → To 2025-12-24
Languages: SolidityFindings
Total issues: 6 (5 resolved, 1 partially resolved)
Critical: 0 (0 resolved) · High: 0 (0 resolved) · Medium: 0 (0 resolved) · Low: 3 (3 resolved)Notes & Additional Information
3 notes raised (2 resolved, 1 partially resolved)
Scope
OpenZeppelin performed a diff audit of the taikoxyz/taiko-mono repository, comparing the BASE commit 5034456 with the HEAD commit 430b332. During the audit, the diff comparing the BASE commit 430b332 and HEAD commit 2ad7378 was also added to the scope. The files below are annotated with full (commit 430b332), diff 1 (5034456...430b332), and diff 2 (430b332...2ad7378) depending on when they were reviewed.
packages/protocol/contracts
├── layer1
│ ├── core
│ │ ├── iface
│ │ │ ├── IBondManager.sol (diff 2)
│ │ │ ├── ICodec.sol (diff 1 & 2)
│ │ │ ├── IForcedInclusionStore.sol (diff 1)
│ │ │ ├── IInbox.sol (diff 1 & 2)
│ │ │ └── IProverWhitelist.sol (full)
│ │ ├── impl
│ │ │ ├── Codec.sol (full)
│ │ │ ├── Inbox.sol (full & diff 2)
│ │ │ ├── ProverWhitelist.sol (full)
│ │ └── libs
│ │ ├── LibBonds.sol (diff 2)
│ │ ├── LibBlobs.sol (diff 1)
│ │ ├── LibForcedInclusion.sol (diff 1)
│ │ ├── LibHashOptimized.sol (diff 1)
│ │ ├── LibInboxSetup.sol (full & diff 2)
│ │ ├── LibPackUnpack.sol (diff 1)
│ │ ├── LibProposeInputCodec.sol (diff 1)
│ │ ├── LibProposedEventCodec.sol (diff 1)
│ │ ├── LibProveInputCodec.sol (diff 1)
│ │ └── LibTransitionCodec.sol (full)
│ ├── mainnet
│ │ └── MainnetInbox.sol (diff 1 & 2)
│ ├── preconf
│ │ └── impl
│ │ └── PreconfWhitelist.sol (diff 1)
│ └── verifiers
│ ├── IProofVerifier.sol (diff 1)
│ ├── LibPublicInput.sol (diff 1)
│ ├── Risc0Verifier.sol (diff 1)
│ ├── SP1Verifier.sol (diff 1)
│ ├── SgxVerifier.sol (diff 1)
│ └── compose
│ └── ComposeVerifier.sol (diff 1)
├── layer2
│ └── core
│ ├── Anchor.sol (diff 1 & 2)
│ ├── AnchorForkRouter.sol (diff 1)
│ ├── BondManager.sol (full)
│ ├── IBondManager.sol (diff 1)
│ └── IBondProcessor.sol (full)
└── shared
├── fork-router
│ └── ForkRouter.sol (diff 1)
└── signal
└── SignalService.sol (diff 1)
System Overview
The Taiko Shasta protocol is a "Based Rollup" architecture that leverages Ethereum (L1) for sequencing and data availability while executing state transitions on a Layer 2 (L2) network. The system is designed to be permissionless and decentralized, utilizing a multi-proof mechanism that combines Trusted Execution Environments (SGX) and Zero-Knowledge Proofs (ZK-SNARKs/STARKs) to verify L2 state transitions on L1.
L1 Core and Inbox
The Inbox contract serves as the central entry point for the protocol on Layer 1. It acts as the anchor for the L2 chain, managing the proposal of new blocks, the submission of validity proofs, and the finalization of the chain state.
- Block Proposal:
Inboxaccepts L2 block proposals, which include transaction data blobs. It enforces sequencing rules and interacts with thePreconfWhitelist(via theIProposerCheckerinterface) to validate authorized proposers during specific windows. - Proof Verification: The contract coordinates the verification of state transitions. It supports a modular verification architecture where different proof types (SGX, Risc0, SP1) are routed to their respective verifiers.
- Bond Management: Instead of a standalone manager,
InboxintegratesLibBondsto handle the economic security of the protocol. It manages Taiko Token (TKO) deposits, withdrawals, and the slashing of liveness bonds for provers who fail to submit proofs within the designated window. - Forced Inclusions: The system implements a censorship-resistance mechanism allowing users to force transaction inclusion directly via L1 if L2 proposers are unresponsive.
Inboxqueues these requests and enforces their processing.
Proof Verification Architecture
The verification layer is modular, allowing for flexible security configurations. It consists of specific verifier implementations and a composition layer.
ComposeVerifier: An abstract verifier that aggregates multiple sub-verifiers (e.g., requiring both an SGX proof and a ZK proof). It ensures that a state transition is considered valid only if all required sub-verifiers approve it.- Specific Verifiers:
SgxVerifier: Verifies signatures from attested SGX enclaves. It maintains a registry of valid instances and handles the expiration of attestations to prevent side-channel attacks.Risc0Verifier&SP1Verifier: These contracts verify ZK proofs generated by the RISC Zero and SP1 zkVMs, respectively. They validate that the execution trace matches the public inputs derived fromInbox's state.
L2 Anchor and Signal Service
On L2, the protocol maintains synchronization with L1 and facilitates cross-chain communication.
Anchor: This contract is responsible for anchoring L1 block data onto L2. It validates and stores L1 checkpoints (block hash, state root), providing the L2 chain with a trusted view of the L1 state. It utilizes a "Golden Touch" address to ensure that only protocol-authorized transactions can update the anchor state.SignalService: A general-purpose cross-chain messaging protocol. It allows contracts on one layer to "send signals" (store data) and prove on the other layer that a signal was sent. This underpins the bridge and other cross-chain applications.ForkRouter: A utility framework used to manage protocol upgrades. It routes calls between legacy and new implementations usingdelegatecall, allowing specific functionalities (like the Anchor) to be upgraded while preserving storage layout compatibility.
Preconfirmation Whitelist
The PreconfWhitelist contract acts as a gatekeeper for block proposers. It manages a set of active operators who are authorized to provide pre-confirmations. This contract determines who is allowed to propose blocks to the Inbox during the exclusive submission window, enabling a pre-confirmation layer before L1 sequencing.
Security Model and Trust Assumptions
The Taiko Shasta protocol relies on the security of the underlying Ethereum L1 for data availability and transaction ordering. The system's security model combines economic incentives (bonds) with cryptographic and hardware-based proofs to ensure state validity. While striving for decentralization, the current iteration relies on specific governance controls and trusted hardware assumptions.
The critical trust assumptions and security model components are as follows:
- L1 Security: The system assumes that Ethereum L1 is secure, censorship-resistant, and that its history is immutable. L1 is the ultimate source of truth for the canonical L2 chain.
- Governance and Privileged Roles:
- Owner/DAO: The protocol includes an
Ownerrole (the DAO) with the power to upgrade contracts and update verifier configurations (e.g., adding trusted SGX instances or ZK verification keys). - Prover Whitelist: If enabled, the system relies on a whitelist of authorized provers. There is a fallback mechanism to allow permissionless proving if the whitelisted provers colluding to censor or halt the chain.
- Preconf Operators: The entities managed by the
PreconfWhitelistare trusted to provide fair pre-confirmations and not to abuse their exclusive proposal windows.
- Owner/DAO: The protocol includes an
- Verifier and Circuit Correctness:
- Trusted Execution Environments (TEE): The
SgxVerifiercontract assumes that Intel SGX hardware is secure and that the remote attestation process is not compromised. It assumes the enclave code correctly implements the protocol rules. - Zero-Knowledge Circuits: The
Risc0VerifierandSP1Verifiercontracts assume that the underlying ZK circuits correctly constrain the state transition function and that the verifier contracts correctly implement the verifier logic for the respective proof systems.
- Trusted Execution Environments (TEE): The
- Economic Security:
- Bond Sufficiency: It is assumed that the
minBondandlivenessBondvalues are set sufficiently high to make spamming or griefing attacks economically irrational for proposers and provers. - Rational Actors: The protocol assumes that provers and proposers are rational actors motivated by profit (fees and rewards) and deterred by slashing penalties.
- Bond Sufficiency: It is assumed that the
- Data Availability: The system relies on Ethereum's EIP-4844 (blobs) for data availability. It is assumed that blob data is available for a sufficient period to allow provers to derive the chain state and generate proofs.
- Cross-Chain Integrity:
- The
Anchorcontract assumes the integrity of the data provided by the "Golden Touch" transaction, which is generated by the protocol's node software and enforced by the prover. - The
SignalServicerelies on the correctness of Merkle proofs to verify cross-chain messages, assuming that the root hash anchored on the destination chain is correct. Once again, this is enforced by the prover.
- The
Low Severity
Misleading documentation
Throughout the codebase, multiple instances of misleading documentation were identified. For instance, the Derivation.md description:
- incorrectly states that
isForcedInclusionshould befalsewhen discussing forced inclusion sources - still refers to the obsolete "bond instruction" concept. It correctly describes the L1 behavior, but it is listed as a subsection under "Metadata Validation and Computation"
- references a non-existent
ShastaAnchorcontract - omits the
parentProposalHashandendOfSubmissionWindowTimestampfields from its proposal-level metadata tables, despite these being present in the on-chainProposalstruct andProposedevent.
In addition, the Checkpoint struct fields are described as L2 data, but it is also used for L1 checkpoints.
Lastly, the minCheckpointDelay is described as less than a "finalization grace period", but it is configured to be larger than maxProofSubmissionDelay and it is not clear which other variable the grace period refers to. Any such requirement should be enforced when validating the configuration.
Consider updating the documentation accordingly.
Update: Resolved in pull request #21161.
Imprecise Error
The ProverWhitelistedAlready error suggests the owner is attempting to whitelist a whitelisted address. However, the error is also used when the owner attempts to remove an address that is not yet whitelisted.
Consider updating the ProverWhitelistedAlready error to account for both cases.
Update: Resolved in pull request #21162. The team stated:
Implemented 2 different errors.
Incorrect Storage Gap
The Anchor contract's state variables occupy 7 storage slots. However, the __gap variable only pads this to 48 (instead of the standard 50).
Consider increasing the gap variable accordingly.
Update: Resolved in pull request #21163. The team stated:
Updated the contract to use the remaining slots.
Notes & Additional Information
Code Simplification
The _getAvailableCapacity function is only ever used to check if there is any available capacity.
Consider replacing the _getAvailableCapacity function with an _isSpaceAvailable check that simply returns _ringBufferSize > _nextProposalId - _lastFinalizedProposalId.
Update: Resolved in pull request #21166.
Code Consistency
The forcedInclusionDelay field of the Inbox config struct is set to 384 instead of 384 seconds. This is inconsistent with how other duration fields are set.
For consistency, consider specifying the forced inclusion delay as 384 seconds instead of just 384.
Update: Resolved in pull request #21164. The team stated:
Used explicit seconds as a unit.
Naming Suggestions
Throughout the codebase, multiple opportunities for improve naming were identified:
lastProposalBlockIdcould be namedlastProposalL1BlockNumber.- Some fields in the
CoreStatestruct refer to proposal finalization. However, finalization is achieved with proving and is no longer an independent phase. Thus, the naming can be adjusted to "proven" or similar. PROPOSAL_MAX_BLOCKScould be renamed toDERIVATION_SOURCE_MAX_BLOCKin line with its actual usage.
Consider implementing the above renaming suggestions to improve code clarity and maintainability.
Update: Partially Resolved in pull request #21165. The Taiko team changed the wording of the documentation, while the code remains the same. The team stated:
Updated, but avoid doing ABI breaking changes.
Conclusion
This audit covered the Shasta protocol version of the Taiko Based Rollup in a 12-day engagement. Overall, the codebase appears to be in good shape and demonstrates a robust security posture. The findings are limited to low- and note-severity issues.
The Taiko team is commended for being very helpful and responsive throughout the engagement, providing clear insights into the system's design and architecture.
Appendix
Rollup Stages
L2Beat includes a set of criteria for classifying rollups into stages of maturity. The design of the system naturally satisfies all Stage 0 criteria.
With respect to the Stage 1 criteria, the Taiko team intends to:
- deploy the new inbox
- configure it with a working Verifier contract
- activate it
- transfer ownership to the
TaikoDAOController
Once this occurs, the only ways to make invalid L2 withdrawals will be to:
- maliciously upgrade the inbox contract, or
- change the verifier contract (or function image it verifies against).
This will require action from the TaikoDAOController contract, which meets all the Stage 1 requirements:
- 6 of 8 (75%) security council members are required to make an emergency proposal.
- Regular proposals will take effect 7 days after they are passed.
The codebase currently utilizes a prover whitelist. However, pull request #21146 introduces a permissionless fallback mechanism. Thus, if whitelisted provers fail to prove a block within the configured permissionlessProvingDelay (set to 72 hours), proving becomes open to anyone. This ensures that whitelisted provers cannot halt the chain indefinitely. Since this 3-day delay is strictly shorter than the 7-day governance timelock, users retain the ability to exit even in a censorship scenario, making the system compatible with Stage 1 requirements.
Issue Classification
OpenZeppelin classifies smart contract vulnerabilities on a 5-level scale:
- Critical
- High
- Medium
- Low
- Note/Information
Critical Severity
This classification is applied when the issue’s impact is catastrophic, threatening extensive damage to the client's reputation and/or causing severe financial loss to the client or users. The likelihood of exploitation can be high, warranting a swift response. Critical issues typically involve significant risks such as the permanent loss or locking of a large volume of users' sensitive assets or the failure of core system functionalities without viable mitigations. These issues demand immediate attention due to their potential to compromise system integrity or user trust significantly.
High Severity
These issues are characterized by the potential to substantially impact the client’s reputation and/or result in considerable financial losses. The likelihood of exploitation is significant, warranting a swift response. Such issues might include temporary loss or locking of a significant number of users' sensitive assets or disruptions to critical system functionalities, albeit with potential, yet limited, mitigations available. The emphasis is on the significant but not always catastrophic effects on system operation or asset security, necessitating prompt and effective remediation.
Medium Severity
Issues classified as being of medium severity can lead to a noticeable negative impact on the client's reputation and/or moderate financial losses. Such issues, if left unattended, have a moderate likelihood of being exploited or may cause unwanted side effects in the system. These issues are typically confined to a smaller subset of users' sensitive assets or might involve deviations from the specified system design that, while not directly financial in nature, compromise system integrity or user experience. The focus here is on issues that pose a real but contained risk, warranting timely attention to prevent escalation.
Low Severity
Low-severity issues are those that have a low impact on the client's operations and/or reputation. These issues may represent minor risks or inefficiencies to the client's specific business model. They are identified as areas for improvement that, while not urgent, could enhance the security and quality of the codebase if addressed.
Notes & Additional Information Severity
This category is reserved for issues that, despite having a minimal impact, are still important to resolve. Addressing these issues contributes to the overall security posture and code quality improvement but does not require immediate action. It reflects a commitment to maintaining high standards and continuous improvement, even in areas that do not pose immediate risks.
Ready to secure your code?