{
"architectureImage": "celo",
"dataAvailability": [
{
"name": "Data is posted to EigenDA",
"description": "Transactions roots are posted onchain and the full data is posted on EigenDA. The sequencer is publishing data to EigenDA v2. The DACert Verifier is used to verify attestations from the EigenDA operator set that the data is indeed available. If EigenDA becomes unavailable, the sequencer falls back to Ethereum.",
"risks": [
{
"category": "Funds can be lost if",
"text": "the sequencer posts an unavailable transaction root.",
"isCritical": true
},
{
"category": "Funds can be lost if",
"text": "the data is not available on the external provider.",
"isCritical": true
}
],
"references": [
{
"title": "EigenDA Docs - Overview",
"url": "https://docs.eigenda.xyz/overview"
},
{
"title": "Derivation: Batch submission - OP Mainnet specs",
"url": "https://github.com/ethereum-optimism/specs/blob/main/specs/protocol/derivation.md#batch-submission"
},
{
"title": "BatchInbox - address",
"url": "https://etherscan.io/address/0xff00000000000000000000000000000000042220#code"
},
{
"title": "OptimismPortal2.sol - source code, depositTransaction function",
"url": "https://etherscan.io/address/0x2c431080Fc733E259654f3b91E39468d9A85Ac9b#code"
}
]
}
],
"exitMechanisms": [
{
"name": "Regular exits",
"description": "The user initiates the withdrawal by submitting a regular transaction on this chain. When a state root containing such transaction is settled, the funds become available for withdrawal on L1 after 3d 12h. Withdrawal inclusion can be proven before state root settlement, but a 7d period has to pass before it becomes actionable. The process of state root settlement takes a challenge period of at least 3d 12h to complete. Finally the user submits an L1 transaction to claim the funds. This transaction requires a merkle proof.",
"risks": [],
"references": [
{
"title": "OptimismPortal2.sol - Etherscan source code, proveWithdrawalTransaction function",
"url": "https://etherscan.io/address/0x2c431080Fc733E259654f3b91E39468d9A85Ac9b#code"
},
{
"title": "OptimismPortal2.sol - Etherscan source code, finalizeWithdrawalTransaction function",
"url": "https://etherscan.io/address/0x2c431080Fc733E259654f3b91E39468d9A85Ac9b#code"
}
]
},
{
"name": "Forced messaging",
"description": "If the user experiences censorship from the operator with regular L2->L1 messaging they can submit their messages directly on L1. The system is then obliged to service this request or halt all messages, including forced withdrawals from L1 and regular messages initiated on L2. Once the force operation is submitted and if the request is serviced, the operation follows the flow of a regular message.",
"risks": [],
"references": [
{
"title": "Forced withdrawal from an OP Stack blockchain",
"url": "https://docs.optimism.io/stack/transactions/forced-transaction"
}
]
}
],
"forceTransactions": {
"name": "Users can force any transaction",
"description": "Because the state of the system is based on transactions submitted on the underlying host chain and anyone can submit their transactions there it allows the users to circumvent censorship by interacting with the smart contract on the host chain directly.",
"risks": [],
"references": [
{
"title": "Sequencing Window - OP Mainnet Specs",
"url": "https://github.com/ethereum-optimism/optimism/blob/51eeb76efeb32b3df3e978f311188aa29f5e3e94/specs/glossary.md#sequencing-window"
},
{
"title": "OptimismPortal2.sol - source code, depositTransaction function",
"url": "https://etherscan.io/address/0x2c431080Fc733E259654f3b91E39468d9A85Ac9b#code"
}
]
},
"operator": {
"name": "The system has a centralized operator",
"description": "The operator is the only entity that can propose blocks. A live and trustworthy operator is vital to the health of the system.",
"risks": [
{
"category": "MEV can be extracted if",
"text": "the operator exploits their centralized position and frontruns user transactions."
}
],
"references": []
},
"otherConsiderations": [
{
"name": "EVM compatible smart contracts are supported",
"description": "OP stack chains are pursuing the EVM Equivalence model. No changes to smart contracts are required regardless of the language they are written in, i.e. anything deployed on L1 can be deployed on L2.",
"risks": [],
"references": [
{
"title": "Introducing EVM Equivalence",
"url": "https://medium.com/ethereum-optimism/introducing-evm-equivalence-5c2021deb306"
}
]
}
],
"stateValidation": {
"categories": [
{
"title": "Fraud proofs",
"description": "State roots are proposed by whitelisted proposers who create dispute games via the DisputeGameFactory by posting a bond of 0.01 ETH. Once created, the game enters a challenge period of 3d 12h during which whitelisted challengers can dispute the proposal by posting a bond of 0.01 ETH. If challenged, anyone can submit a ZK proof to prove the correct state within the proving period of 1d. After the challenge period passes without a successful challenge, or after a valid proof is submitted, anyone can resolve the game and finalize the state root.",
"references": [
{
"url": "https://succinctlabs.github.io/op-succinct/fault_proofs/fault_proof_architecture.html",
"title": "OP Succinct Lite architecture"
},
{
"url": "https://docs.celo.org/home/protocol/challengers",
"title": "Celo Challengers"
}
],
"risks": [
{
"category": "Funds can be stolen if",
"text": "the validity proof cryptography is broken or implemented incorrectly."
},
{
"category": "Funds can be stolen if",
"text": "no whitelisted challenger disputes an invalid state root before the challenge window expires.",
"isCritical": true
},
{
"category": "Funds can be stolen if",
"text": "the proposer routes proof verification through a malicious or faulty verifier."
},
{
"category": "Funds can be frozen if",
"text": "the permissioned proposer fails to publish state roots to the L1."
}
]
}
]
},
"upgradesAndGovernance": {
"content": "Celo's L1 contracts are upgradable by a `ProxyAdmin` owned by the 2/2 `CeloProxyAdminOwner`, a nested Safe whose two signers are the 6/8 `Celo Security Council` and the 6/8 `Celo cLabs Multisig`. Both halves must approve, and there is no delay on upgrades. The shared `SuperchainConfig` is the exception: it remains under the 2/2 `SuperchainProxyAdminOwner` controlled by the Optimism Foundation and the Optimism Security Council, outside Celo's control.\n\nPause powers sit apart from the upgrade path. The `CeloSuperchainConfig` guardian, which can pause Celo withdrawals, is the `Celo cLabs Multisig` acting alone; the shared `SuperchainConfig` guardian, which can pause the whole Superchain including Celo, resolves to the Optimism Security Council. The `Celo Security Council` holds no pause power at all. `Celo cLabs Multisig` also owns `SystemConfig` and the OP Succinct `AccessManager` on its own, so it sets the sequencer, gas configuration and the proposer and challenger allowlists without Council approval.",
"governanceInfo": {
"securityCouncil": {
"Composition": "**6/8** community Security Council, nested as one of two signers in the 2/2 `CeloProxyAdminOwner` alongside the 6/8 `Celo cLabs Multisig`. An L1 upgrade therefore needs 12 signatures across two bodies, and neither side can move alone — the stated design goal is a non-cLabs quorum-blocking group. The policy explicitly permits nested multisigs, and one of the 8 Council seats is itself a 2/3 Safe, so a single seat can be held by a group rather than a person.",
"Members public": "**Named, not mapped** — the [docs](https://docs.celo.org/home/protocol/security-council) name 8 members (L2Beat, Hyperlane, Valora, Mento, Nitya Subramanian, Kris Kaczor, Tim Moreton, Aaron Boyd) without addresses, and the [founding proposal](https://forum.celo.org/t/proposing-celo-l2s-security-council/10578) lists 8 signer addresses \"in no particular order\", so no member can be tied to a signer. Membership is mostly Celo-ecosystem projects, and cLabs sits on the other half of the 2/2 rather than inside the Council.",
"Charter": "**No charter** — the [docs page](https://docs.celo.org/home/protocol/security-council) is explicitly a work in progress restating the [founding forum proposal](https://forum.celo.org/t/proposing-celo-l2s-security-council/10578), which deferred term lengths to \"a later date\" and never defined renewal, removal or rotation. Review feedback on that thread flagged missing emergency protocols, timezone coverage, compensation and reporting cadence; none have since been published. The Council does follow the Optimism multisig security policy.",
"Can bypass DAO?": "**Entirely** — every L1 upgrade runs on the 2/2 `CeloProxyAdminOwner` with no CELO vote at any step. cLabs goes further and acts alone outside the 2/2: it owns `SystemConfig` (sequencer and gas configuration), owns the OP Succinct `AccessManager` gating the 2 proposers and 6 challengers, and is the `CeloSuperchainConfig` guardian able to pause Celo withdrawals by itself.",
"DAO can override SC?": "**No — the Council administers itself.** Seats are changed by the Council Safe calling itself, so 6 of the 8 sitting members decide who joins or leaves. CELO governance ratified the inaugural cohort by vote but holds no standing power, because the `Governance` contract reaches Celo core contracts and the Community Fund rather than the Ethereum-side rollup contracts."
},
"upgrades": {
"Normal upgrade path": "A task is published in the public [celo-superchain-ops](https://github.com/celo-org/celo-superchain-ops) repo → **6/8 Security Council approval** → **6/8 cLabs approval** → execution through the 2/2 `CeloProxyAdminOwner`. Task files carry a nonce per signing layer, including a `grand_child` entry for the nested Safe inside the Council. No timelock at any step.",
"Emergency upgrade path": "**No separate path** — the normal path executes as soon as both halves have signed, so there is no lower emergency threshold. The fast levers are pauses, and neither belongs to the Security Council: the 6/8 `Celo cLabs Multisig` is the `CeloSuperchainConfig` guardian and can pause Celo withdrawals alone, while the shared `SuperchainConfig` guardian resolves to the 10/13 `Optimism Security Council`, which can pause the whole Superchain including Celo without any Celo party consenting. Pauses lapse after 3mo 1d. Celo can reassign its own guardian but cannot remove Optimism's, since the shared config is upgradable only by the 2/2 `SuperchainProxyAdminOwner`.",
"Exit window": "**None** — nothing separates the second approval from the upgrade taking effect, so users get no notice and cannot withdraw ahead of an unwanted change. Routine changes run through the same gate: rotating the OP Succinct verification keys is a `DisputeGameFactory.setImplementation` call and needs the full 2/2.",
"Proof-system levers": "Beyond upgrades, whoever controls the proof system controls withdrawals. `AccessManager` is cLabs-owned and currently allowlists 2 proposers and 6 challengers (5 independent plus one cLabs). A game can be challenged for 3d 12h, and if no proposal lands for 14d the system falls back to permissionless proposing."
},
"tokenGovernance": {
"Governance token": "`CELO` — 1,000,000,000 total supply. Voting weight comes from Locked CELO, not raw balance. Governance is native to the Celo chain and predates the L2 migration.",
"Voting venue": "The onchain `Governance` contract on Celo, with proposals raised as CGPs and discussed on the [Celo forum](https://forum.celo.org). Ethereum-side rollup contracts are not reachable from it.",
"Proposal threshold": "**10,000 CELO deposit** to queue a proposal. Queued proposals expire after 4 weeks, and only the 3 most-upvoted are promoted to a vote each day.",
"Quorum": "Participation must clear a moving baseline — currently ~23% of Locked CELO, scaled by a 0.5 quorum factor to roughly **12%**, with a 5% floor. The baseline is an exponential moving average of past turnout, so quorum drifts with participation rather than being fixed.",
"Execution model": "**7d referendum → 3d execution window.** A 3/14 approver multisig must approve before execution, after which anyone can execute. Scope is the limiting factor: this path governs Celo's L2 core contracts and the Community Fund, while every L1 rollup contract sits behind the 2/2 `CeloProxyAdminOwner` instead."
}
}
}
}