From 681abb426beab4ce549a2d32b406adf1ca953f3a Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Tue, 21 Jul 2026 11:57:54 +0200 Subject: [PATCH 01/11] docs: migrate specs.celo.org content into a new Specs tab Converts the 16 mdBook pages from celo-org/specs to MDX under specs/, mirroring the old sidebar hierarchy in docs.json. Removes the external-link stub (infra-partners/specs) in favor of the real content and assigns /specs/ to the blockchain team in CODEOWNERS. --- .github/CODEOWNERS | 3 + docs.json | 50 ++- infra-partners/specs.mdx | 5 - specs/deployments.mdx | 64 +++ specs/eigenda.mdx | 11 + specs/fee-abstraction.mdx | 111 ++++++ specs/finality.mdx | 63 +++ specs/index.mdx | 31 ++ specs/l1-smart-contract-verification.mdx | 331 ++++++++++++++++ specs/l2-migration.mdx | 479 +++++++++++++++++++++++ specs/native-bridge.mdx | 27 ++ specs/smart-contract-updates-from-l1.mdx | 164 ++++++++ specs/token-duality.mdx | 29 ++ specs/transaction-fees.mdx | 35 ++ specs/transaction-types.mdx | 48 +++ specs/upgrades/ice-cream.mdx | 29 ++ specs/upgrades/isthmus.mdx | 53 +++ specs/upgrades/jello.mdx | 27 ++ specs/upgrades/jovian.mdx | 51 +++ 19 files changed, 1604 insertions(+), 7 deletions(-) delete mode 100644 infra-partners/specs.mdx create mode 100644 specs/deployments.mdx create mode 100644 specs/eigenda.mdx create mode 100644 specs/fee-abstraction.mdx create mode 100644 specs/finality.mdx create mode 100644 specs/index.mdx create mode 100644 specs/l1-smart-contract-verification.mdx create mode 100644 specs/l2-migration.mdx create mode 100644 specs/native-bridge.mdx create mode 100644 specs/smart-contract-updates-from-l1.mdx create mode 100644 specs/token-duality.mdx create mode 100644 specs/transaction-fees.mdx create mode 100644 specs/transaction-types.mdx create mode 100644 specs/upgrades/ice-cream.mdx create mode 100644 specs/upgrades/isthmus.mdx create mode 100644 specs/upgrades/jello.mdx create mode 100644 specs/upgrades/jovian.mdx diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 98c50a691..b2ddac298 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -21,6 +21,9 @@ # Legacy section - Blockchain team (L1 content) /legacy/ @celo-org/blockchain +# Specs section (was specs.celo.org) - Blockchain team +/specs/ @celo-org/blockchain + # Tooling section /tooling/ @celo-org/devrel diff --git a/docs.json b/docs.json index 5e08307e6..72518420b 100644 --- a/docs.json +++ b/docs.json @@ -453,10 +453,52 @@ "infra-partners/operators/configuration", "infra-partners/operators/network-config" ] + } + ] + }, + { + "tab": "Specs", + "groups": [ + { + "group": "Introduction", + "pages": [ + "specs/index" + ] }, { - "group": "Celo L2 Specs", - "pages": ["infra-partners/specs"] + "group": "Specs", + "pages": [ + { + "group": "Deployments", + "pages": [ + "specs/deployments", + "specs/l1-smart-contract-verification" + ] + }, + "specs/token-duality", + "specs/transaction-fees", + "specs/fee-abstraction", + "specs/transaction-types", + "specs/native-bridge", + "specs/eigenda", + "specs/finality", + { + "group": "Protocol Upgrades", + "pages": [ + "specs/upgrades/jovian", + "specs/upgrades/jello", + "specs/upgrades/ice-cream", + "specs/upgrades/isthmus", + { + "group": "L2 Migration", + "pages": [ + "specs/l2-migration", + "specs/smart-contract-updates-from-l1" + ] + } + ] + } + ] } ] }, @@ -664,6 +706,10 @@ "dark": "/images/CeloDocs_LogoDark.svg" }, "redirects": [ + { + "source": "/infra-partners/specs", + "destination": "/specs" + }, { "source": "/blog/2022/01/08/valora-wc-v1", "destination": "/" diff --git a/infra-partners/specs.mdx b/infra-partners/specs.mdx deleted file mode 100644 index 4b75dbe50..000000000 --- a/infra-partners/specs.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Celo L2 Specs -url: https://specs.celo.org/ -sidebarTitle: Specification ---- diff --git a/specs/deployments.mdx b/specs/deployments.mdx new file mode 100644 index 000000000..8263b39a1 --- /dev/null +++ b/specs/deployments.mdx @@ -0,0 +1,64 @@ +--- +title: "Deployments" +--- + +## Mainnet + +Celo Mainnet will be migrated to an L2 on March 26, 2025, around 3:00 AM UTC. The migration is scheduled for block *31056500*. For this L1 chain will be stopped at a block height of *31056499*. At this point the existing state will migrated to work with the L2 nodes. The migration process preserves the full L1 history while updating it to work with the Celo L2 stack. More technical details are available in the [migration docs](/specs/l2-migration). + +The Celo L2 network has the following chain properties: + +- Block period: 1 second +- Block gas limit: 30,000,000 gas +- Block gas target: 6,000,000 gas (see EIP-1559 elasticity multiplier) +- EIP-1559 elasticity multiplier: 5 +- EIP-1559 denominator: 400 +- EIP-1559 floor: 25 Gwei + +### Parameters + +- [ProxyOwner owner](https://mondo.celo.org/governance/cgp-171): [`0x4092A77bAF58fef0309452cEaCb09221e556E112`](https://app.safe.global/home?safe=eth:0x4092A77bAF58fef0309452cEaCb09221e556E112) +- Guardian address (can pause/unpause the bridge): `0x6E226fa22e5F19363d231D3FA048aaBa73CC1f47` + +### Contract addresses + +L1 and L2 contract addresses are listed in the documentation. + +- [L1 contracts](/tooling/contracts/l1-contracts#celo-mainnet) +- [Core contracts](/tooling/contracts/core-contracts#celo-mainnet) +- [Fee Abstraction contracts](/tooling/contracts/token-contracts#celo-mainnet) + +## Celo Sepolia testnet + +The Celo Sepolia testnet has the same chain properties as Celo Mainnet: + +- Block period: 1 second +- Block gas limit: 30,000,000 gas +- Block gas target: 6,000,000 gas (see EIP-1559 elasticity multiplier) +- EIP-1559 elasticity multiplier: 5 +- EIP-1559 denominator: 400 +- EIP-1559 floor: 25 Gwei + +### Contract addresses + +L1 and L2 contract addresses are listed in the documentation. + +- [L1 contracts](/tooling/contracts/l1-contracts#celo-sepolia-testnet) +- [Core contracts](/tooling/contracts/core-contracts#celo-sepolia-testnet) +- [Fee Abstraction contracts](/tooling/contracts/token-contracts#celo-sepolia-testnet) + +## OP stack config + +| Config | Celo | OP | +|-----------------------------------|-------------|--------| +| `maxSequencerDrift` | 2892 | 1800 | +| `sequencerWindowSize` | 3600 | 3600 | +| `channelTimeout` | 300 | 300 | +| `finalizationPeriodSeconds` | 12 | 12 | +| `enableGovernance` | `false` | `true` | +| `eip1559Denominator` | 400 | 50 | +| `eip1559DenominatorCanyon` | 400 | 250 | +| `eip1559Elasticity` | 5 | 6 | +| `eip1559BaseFeeFloor` | 25000000000 | - | +| `gasPriceOracleBaseFeeScalar` | 0 | 1368 | +| `gasPriceOracleBlobBaseFeeScalar` | 0 | 810949 | diff --git a/specs/eigenda.mdx b/specs/eigenda.mdx new file mode 100644 index 000000000..6808d3904 --- /dev/null +++ b/specs/eigenda.mdx @@ -0,0 +1,11 @@ +--- +title: "EigenDA" +--- + +In contrast to OP Mainnet sequencer which writes TX batches to Ethereum in the form of calldata or, more recently, EIP-4844 blobs to commit to the transactions included in the canonical L2 chain, Celo uses [EigenDA](https://docs.eigenlayer.xyz/eigenda/overview) as an alternative data availability layer in order to minimize the TX fees. EigenDA is a data availability store made by [EigenLabs](https://www.eigenlabs.org) and built on top of [EigenLayer](https://docs.eigenlayer.xyz/eigenlayer/overview/). With EigenDA, TX data is stored by EigenDA operators off-chain, only DA commitments used for verficiation and subsequent data retrieval are stored On Ethereum which significantly reduces DA costs and L2 TX fees. + +The integration is done in accordance with the [Optimism's Alt-DA spec](https://specs.optimism.io/experimental/alt-da.html) which contains a more in-depth description of this interface. + +## Testnet and Contract Addresses + +The Celo Sepolia testnet uses the [EigenDA Sepolia testnet](https://docs.eigencloud.xyz/products/eigenda/networks/sepolia). diff --git a/specs/fee-abstraction.mdx b/specs/fee-abstraction.mdx new file mode 100644 index 000000000..074dd2ce6 --- /dev/null +++ b/specs/fee-abstraction.mdx @@ -0,0 +1,111 @@ +--- +title: "Fee Abstraction: Paying Gas With ERC20 Tokens" +sidebarTitle: "Fee Abstraction" +--- + +Fee Abstraction is a Celo feature that allows users to send transactions without spending any native CELO tokens. Instead, ERC20 tokens are used to pay for the transaction's gas cost. + +## As a User + +### Sending Fee Abstraction Transactions + +To pay gas via Fee Abstraction, the gas token must be specified in a [CIP-64](https://github.com/celo-org/celo-proposals/blob/master/CIPs/cip-0064.md) transaction. This tx type has an additional `feeCurrency` field that specifies which token is used for the `maxFeePerGas` and `maxPriorityFeePerGas` fields. See [CIP-64](https://github.com/celo-org/celo-proposals/blob/master/CIPs/cip-0064.md) for details. + +Client library support is [described in docs.celo.org](/home/protocol/transactions/transaction-types#client-library-support). + +### JSON-RPC Changes + +To make it easier to reliably send Fee Abstraction transactions, the JSON-RPC interface has been extended in two ways: + +- `eth_estimateGas` takes an optional `feeCurrency` parameter to get Fee Abstraction specific gas estimates (the gas price for the fee token transfers depends on the token) +- `eth_gasPrice` and `eth_maxPriorityFeePerGas` take an optional `feeCurrency` parameter for getting CIP-64 gas prices. + +### The Fee Currency Directory + +Only tokens that have been registered in the `FeeCurrencyDirectory` contract using Celo's governance process can be used for Fee Abstraction. The directory entry shows that the token is trustworthy and contains additional information about the token: + +- The token address +- An oracle address, conforming to the [`IOracle`](https://github.com/celo-org/celo-monorepo/blob/2ace1d08b9da5d2618e945eef7663cc385917a2d/packages/protocol/contracts-0.8/common/interfaces/IOracle.sol) interface, to get the current exchange rate +- The amount of intrinsic gas for Fee Abstraction gas calculation (see ["Gas Calculation for Fee Abstraction Transactions"](#gas-calculation-for-fee-abstraction-transactions)) + +You can run the `getCurrencies()` method on the `FeeCurrencyDirectory` contract to get a list of all registered tokens and use `getExchangeRate(token address)` to fetch the current exchange rate for a token. The `IOracle` interface is only intended for parties providing Fee Abstraction tokens, not for users or client libraries. + +### Tokens using FeeCurrencyAdapter + +Tokens with a low number of `decimals` (USDC and USDT) would cause problems during the gas calculation, because the cost per gas can only be accurately given in fractions and not integers. To avoid this issue, the tokens are not directly added to the `FeeCurrencyDirectory`. Instead, a `FeeCurrencyAdapter` contracts wraps these tokens, calculates the costs per gas in a higher accuracy and only converts it back to the lower accuracy once the total gas costs for a transaction is determined. + +This only really impacts the user in a single way: Instead of using the USDC and USDT token addresses, you have to pass their `FeeCurrencyAdapter` addresses in the `feeCurrency` field for CIP-64 txs. + +## For Token Authors + +### Requirements for Registering a Fee Abstraction Token + +To become registered as a Fee Abstraction currency, the following requirements have to be met: + +- Implement the [IFeeCurrency interface](https://github.com/celo-org/fee-currency-example/blob/master/src/IFeeCurrency.sol) +- Ensure exchange rates are kept up to date in the oracle with the `IOracle` interface +- Pass a Celo governance vote for the `FeeCurrencyDirectory` addition + +The [fee-currency-example repository](https://github.com/celo-org/fee-currency-example) contains the interface description and an example Fee Abstraction token implementation with tests. + +### Tokens With Non-18 Decimals + +Tokens that do not use 18 decimal places (e.g. USDT with 6 decimals) cannot be registered directly in the `FeeCurrencyDirectory`. The low precision causes problems during gas price calculation, where the cost per gas can only be accurately represented as a fraction, not an integer with few decimal places. + +To support Fee Abstraction, the token deployer must deploy a [`FeeCurrencyAdapter`](https://github.com/celo-org/celo-monorepo/blob/874eeacf65c64de097c2d5c44a4d849961aeccfd/packages/protocol/contracts-0.8/stability/FeeCurrencyAdapter.sol) contract that wraps the token. The adapter performs gas cost calculations at higher precision (18 decimals) and only converts back to the token's native decimal precision when the total gas cost for a transaction has been determined. It is the adapter contract address, not the underlying token address, that gets registered in the `FeeCurrencyDirectory`. + +The `FeeCurrencyAdapter` contract has been [audited by Trail of Bits](https://github.com/celo-org/celo-monorepo/files/14377164/cLabs.Equivalent.Tokens.Review.-.Summary.Report.pdf) and was released as part of [Core Contracts v11](https://github.com/celo-org/celo-monorepo/releases/tag/core-contracts.v11). + +## Inside the Celo Blockchain + +### Exchange Rate Handling Inside the Blockchain Client + +Before each block, the blockchain client reads the list of all registered Fee Abstraction tokens from the `FeeCurrencyDirectory` and fetches the currency exchange rate for each of them. If the Oracle for a token reverts or returns invalid exchange rates (numerator or denominator are zero), the token is treated as if it was not registered. Token registrations and exchange rates stay the same within a block and are only updated before the next block. + +Transactions with unregistered `feeCurrency` values are not accepted into the tx pool and dropped from the pool if they have been previously accepted. The same is true if the `maxFeePerGas` falls below the current base fee. + +### Gas Calculation for Fee Abstraction Transactions + +Ethereum transactions pay a fixed fee of 21000 gas ("intrinsic gas") in addition to the cost for executing the transaction. This is meant to cover the operating expenses during tx processing outside the actual tx execution, like debiting the gas cost from the tx sender's account, refunding the unused gas or transferring the base fee and tip to the respective receivers. + +When using Fee Abstraction, the fees are transferred by executing functions on the respective token contract, which is computationally more expensive than native token transfers. The exact costs will vary by token and can change over time. Therefore, a token-specific intrinsic gas value is used for Fee Abstraction txs in addition to Ethereum's intrinsic gas. This value is stored in the `FeeCurrencyDirectory` contract and can be changed by Celo governance. It should be set to at least the maximum gas cost of executing all function calls for debiting and crediting fees for a single transaction. +Addresses warmed during the debit will keep their warm status for the execution of the main tx. + +If fetching the intrinsic gas for a token from the `FeeCurrencyDirectory` reverts, the token is treated as unregistered. Values exceeding `2^64-1` are capped at that value. + +### EIP-7623 Implementation and Intrinsic Gas Considerations + +Celo L2 implements [EIP-7623](https://eips.ethereum.org/EIPS/eip-7623) to mitigate transaction spam by enforcing a minimum gas cost floor for transactions with significant calldata. This floor is calculated as: + +``` +21_000 + TOTAL_COST_FLOOR_PER_TOKEN * tokens_in_calldata +``` + +The `21_000` value represents the **standard Ethereum intrinsic gas** and is used consistently across all transaction types for EIP-7623 floor calculations, regardless of whether the transaction uses Fee Abstraction or not. + +### Block Space Limits Per Fee Abstraction Token + +As described above, Celo allows users to pay for gas using ERC20 tokens. There is a governable list of accepted tokens. However, the Celo blockchain client starting with version 1.8.1 implements a protective mechanism that allows validators to control the percentage of available block space used by transactions paid with an alternative fee currency (other than CELO) more precisely. + +There are two new flags that control this behavior: + +1. `celo.feecurrency.limits` with a comma-separated `currency_address_hash=limit` mappings for currencies listed in the `FeeCurrencyDirectory` contract, where `limit` represents the maximal fraction of the block gas limit as a float point number available for the given fee currency. The addresses are not expected to be checksummed. + + For example, `0x765DE816845861e75A25fCA122bb6898B8B1282a=0.1,0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73=0.05,0xEd6961928066D3238134933ee9cDD510Ff157a6e=0`. + +1. `celo.feecurrency.default` - an overridable default value (initially set to `0.5`) for currencies not listed in the limits map, meaning that if not specified otherwise, a transaction with a given fee currency can take up to `50%` of the block space. CELO token doesn't have a limit. + +Based on historical data, the following default configuration is proposed: + +```bash +--celo.feecurrency.default=0.5 +--celo.feecurrency.limits="0x765DE816845861e75A25fCA122bb6898B8B1282a=0.9,0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73=0.5,0xe8537a3d056DA446677B9E9d6c5dB704EaAb4787=0.5" +``` + +It imposes the following limits: + +- cUSD up to 90% +- cEUR up to 50% +- cREAL up to 50% +- any other token except CELO - 50% +- CELO doesn't have a limit diff --git a/specs/finality.mdx b/specs/finality.mdx new file mode 100644 index 000000000..0991a8707 --- /dev/null +++ b/specs/finality.mdx @@ -0,0 +1,63 @@ +--- +title: "Finality" +--- + +## Overview + +The Celo L2 provides two layers of economic security — Celo-economic security and Ethereum-economic security. Celo-economic security is the security the L2 blockchain provides until data has been written to an L1 block and that block has been finalized. In order to provide reorg resistance at Celo-economic security in the L2 design, we need to address two sources of possible reorgs: + +1. Avoid discrepancies in what the sequencer shares over the p2p network and posts to the L1. +2. Avoid those caused by Ethereum reorgs. + +The first section below describes the standard OP Stack finality model and where reorgs can occur. The second section describes the modifications Celo L2 makes on top of the OP Stack to mitigate these reorgs. + +## Finality and Reorgs in Optimism (Baseline) + +Optimism L2 blocks have three levels of finality: + +- **Unsafe:** Blocks are shared by the sequencer over the p2p network and can be reorged with no penalty. +- **Safe:** Blocks are deterministically derived from inputs and L2 data posted to not-yet-finalized Ethereum blocks. These blocks are susceptible to Ethereum reorgs. +- **Finalized:** Blocks are derived from finalized blocks on Ethereum and can practically not be reorged without massive economic costs. This is Ethereum-economic security. + +Once an L2 block is finalized, it has the same security guarantees as the underlying L1 and is highly unlikely to be reorged. Therefore, our focus lies on avoiding reorgs at the unsafe and safe levels. + +**Unsafe head reorgs** could happen in the following scenarios: + +- The sequencer shares an unsafe block on the p2p network but misses the sequencing window to post the corresponding transaction data to Ethereum. As a result, there won't be valid block data for that height, and the unsafe head will reorg to use a generated empty block. +- The sequencer distributes an unsafe block on the p2p network but posts different transaction data for the same block height to Ethereum. The unsafe head will reorg to use the data on Ethereum. + +These cases are controlled by the sequencer. If the user trusts the sequencer and its actions, it can follow unsafe blocks. If not, it can completely avoid those by only following safe blocks. + +**Safe head reorgs** can occur in the following situations: + +- An L1 block is reorged, then the corresponding sequencing epoch's blocks will need to be updated to account for the changes in the L1 origin (specifically, deposit transactions). This situation can also cause an unsafe head reorg. +- If Ethereum reorgs such that transaction data posted either no longer exists or now falls outside of the sequencing window, then the corresponding (previously safe) L2 block will become an empty block. + +## Celo L2 Changes to the OP Stack + +The following describes modifications Celo L2 makes to the standard OP Stack derivation pipeline to achieve safe-head reorg resistance. In the standard OP Stack, the sequencer follows the unsafe L1 head, which leaves safe blocks susceptible to Ethereum reorgs. Celo L2 changes this behavior. + +### 1. Sequencer Uses Finalized L1 Origin + +Celo L2 configures the sequencer to follow only finalized blocks on Ethereum by enabling the `--sequencer.use-finalized` flag on the op-node. In the standard OP Stack, the sequencer follows the unsafe L1 head; by contrast, Celo L2 restricts the L1 origin to finalized blocks only. The L1 origin is still incremented in steps of one, so that all invariants relying on this behavior in the Optimism codebase are preserved. + +**Trade-off:** This increases the time for user-deposited and (native) bridging transactions to be included in the L2 from the standard ~4 blocks (48 seconds) to at least 2 Ethereum epochs (64 slots, ~12.8 minutes). + +### 2. Sequencer Stalling on L1 Finalization Lag + +If the Ethereum L1 fails to finalize blocks, the sequencer would continue to create unsafe L2 blocks without a finalized L1 origin to anchor to. To handle this, Celo L2 introduces a safeguard: the sequencer must stall and avoid producing blocks until L1 finalization catches up to below some threshold. + +### 3. Fast Finality via Espresso (In Progress) + +We are actively working with [Espresso](https://www.espressosys.com/) to provide 1–5 second finality backed by Espresso's economic security guarantees. This will allow Celo L2 users to receive fast confirmation of transactions with meaningful economic backing, significantly improving on the current trade-off between finality speed and reorg resistance. + +--- + +### Summary of Changes + +| Change | Standard OP Stack Behavior | Celo L2 Behavior | +|---|---|---| +| **L1 origin for sequencing** | Follows the unsafe L1 head | Follows only finalized L1 blocks (`--sequencer.use-finalized`) | +| **L1 finalization failure** | Sequencer continues producing blocks | Sequencer stalls until finalization catches up | +| **Deposit inclusion latency** | ~48 seconds (4 blocks) | ~12.8 minutes (2 epochs) | +| **Fast finality** | None | 1–5s finality via Espresso (in progress) | diff --git a/specs/index.mdx b/specs/index.mdx new file mode 100644 index 000000000..3bdbf7de1 --- /dev/null +++ b/specs/index.mdx @@ -0,0 +1,31 @@ +--- +title: "Celo L2 Specification" +sidebarTitle: "Introduction" +--- + +This document describes the differences between the Celo L2 implementation and [Optimism's](https://optimism.io) OP Stack, on which it is based. Refer to the [OP Stack specs](https://specs.optimism.io/) for details on the unmodified OP Stack. + +For more general information about the Celo blockchain visit the [Celo Docs](/home/celo). + +The [L1→L2 migration changes page](/specs/l2-migration) details the differences compared to the Celo L1 blockchain. The Celo L2 is a continuation of the L1 by using its state and providing a high level of compatibility with it. + +## Background + +Since May 2024, the Celo Community has decided to transition from an L1 blockchain to a L2 solution using the OP Stack. This move, detailed and [approved](https://mondo.celo.org/governance/cgp-133) in [CGP-133](https://github.com/celo-org/governance/blob/main/CGPs/cgp-0133.md), aims to enhance scalability, security, and interoperability with Ethereum. The proposal aligns with Celo's mission to create a more accessible and inclusive financial system. By leveraging the OP Stack, Celo L2 will retain the benefits of the existing ecosystem while integrating with Ethereum's robust infrastructure, fostering greater innovation and user engagement. + +## New Features + +- [Token duality](/specs/token-duality), access native tokens via ERC20 +- [Fee Abstraction](/specs/fee-abstraction), pay gas with ERC20 tokens + +## Technical Differences + +- New [transaction types](/specs/transaction-types) to support Fee Abstraction +- [One new precompile](/specs/token-duality#the-transfer-precompile) to support token duality +- [Changes to finality](/specs/finality) +- The `MaxCodeSize` for newly deployed contracts is increased from 24576 to 65536. + +## Deployments + +- [Mainnet](/specs/deployments#mainnet) +- [Celo Sepolia testnet](/specs/deployments#celo-sepolia-testnet) diff --git a/specs/l1-smart-contract-verification.mdx b/specs/l1-smart-contract-verification.mdx new file mode 100644 index 000000000..59c9898e9 --- /dev/null +++ b/specs/l1-smart-contract-verification.mdx @@ -0,0 +1,331 @@ +--- +title: "L1 Deploy Verification" +sidebarTitle: "L1 Contracts Verification" +--- + +This guide walks through verifying Celo L1 (Ethereum) smart contracts deployment. It contains steps to verify contracts in the `packages/contracts-bedrock` folder. L2 (Celo) contracts will be available after the [transition](https://x.com/cLabs/status/1900625559090328062). + +## 1. Prerequisites + +- **Foundry Installed:** Ensure you have Foundry installed and updated (via [foundryup](https://github.com/foundry-rs/foundry)). +- **JQ Installed:** jq cli tool for handling json files is required later. +- **API Key:** Obtain an Etherscan (or corresponding block explorer) API key. + +## 2. Verify Smart Contracts bytecode + +Check that on chain bytecode correspond to compiled bytecode from smart contract release. + +Smart contract release is: https://github.com/celo-org/optimism/releases/tag/celo-contracts.L1%2Fv1.8.0--1 + +Clone the `celo-org/optimism` repository and checkout release tag + +```bash + git clone https://github.com/celo-org/optimism + cd optimism + git checkout celo-contracts.L1/v1.8.0--1 +``` + +Enter the contract folder & compile contracts +Navigate to the Contracts Folder + +```bash + cd packages/contracts-bedrock + forge build +``` + +To verify contract, will compare onchain bytecode with compiled one using a script. + +For that, create `scripts/compare_bytecode.sh` with following content: + +```bash +#!/bin/bash +# Usage: ./compare_bytecode_ignore_immutables.sh + +if [ "$#" -lt 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +CONTRACT_ADDRESS=$1 +ARTIFACT_FILE=$2 + +# Fetch deployed bytecode from chain +DEPLOYED_BYTECODE=$(cast code "$CONTRACT_ADDRESS" --rpc-url https://eth.llamarpc.com | tr -d '\n') + +if [ -z "$DEPLOYED_BYTECODE" ]; then + echo "Error: Failed to fetch bytecode." + exit 1 +fi + +# Get local bytecode +LOCAL_BYTECODE=$(jq -r '.deployedBytecode.object' "$ARTIFACT_FILE" | tr -d '\n') + +if [ -z "$LOCAL_BYTECODE" ]; then + echo "Error: Failed to extract local bytecode." + exit 1 +fi + +# Special exception for SuperchainConfig version diff +if grep -q "SuperchainConfig" "$ARTIFACT_FILE"; then + # Replace metadata version "1.1.1-beta.1" with "1.1.0" since SuperchainConfig was deployed with version "1.1.0" instead of "1.1.1-beta.1" (no other changes) + LOCAL_BYTECODE=$(echo "$LOCAL_BYTECODE" | sed 's/600c81526020017f312e312e312d626574612e31/600581526020017f312e312e3000000000000000/g') +fi + +# Replace immutables with 0000 +IMMUTABLES=$(jq -c '.deployedBytecode.immutableReferences' "$ARTIFACT_FILE") + +replace_with_zeros() { + local BYTECODE=$1 + local START=$2 + local LENGTH=$3 + local PREFIX=${BYTECODE:0:START} + local SUFFIX=${BYTECODE:START+LENGTH} + local ZEROS=$(printf '%*s' "$LENGTH" '' | tr ' ' '0') + echo "$PREFIX$ZEROS$SUFFIX" +} + +if [ "$IMMUTABLES" != "null" ]; then + for entry in $(echo "$IMMUTABLES" | jq -c '.[] | .[]'); do + START=$(($(echo "$entry" | jq '.start * 2'))) + LENGTH=$(($(echo "$entry" | jq '.length * 2'))) + + DEPLOYED_BYTECODE=$(replace_with_zeros "$DEPLOYED_BYTECODE" "$((START + 2))" "$LENGTH") + done +fi + +# Now compare ignoring immutables and version diff +if [ "$DEPLOYED_BYTECODE" = "$LOCAL_BYTECODE" ]; then + echo "$ARTIFACT_FILE Success: Deployed bytecode matches local artifact (excluding immutables/version diff)." +else + echo "$ARTIFACT_FILE Mismatch: Bytecode differs beyond immutables/version diff." + echo "Deployed: $DEPLOYED_BYTECODE" + echo "Local: $LOCAL_BYTECODE" +fi + +``` + +And make sure can be executed: + +```bash +chmod +x scripts/compare_bytecode.sh +``` + +Then to verify each contract: + +```bash +./scripts/compare_bytecode.sh 0xde47b113e4157ed15fa46c5572562ac11146c5ea forge-artifacts/L1CrossDomainMessenger.sol/L1CrossDomainMessenger.json +./scripts/compare_bytecode.sh 0x783A434532Ee94667979213af1711505E8bFE374 forge-artifacts/ProxyAdmin.sol/ProxyAdmin.json +./scripts/compare_bytecode.sh 0x55093104b76FAA602F9d6c35A5FFF576bE78d753 forge-artifacts/AddressManager.sol/AddressManager.json +./scripts/compare_bytecode.sh 0x693cfd911523ccae1a14ade2501ae4a0a463b446 forge-artifacts/CeloSuperchainConfig.sol/CeloSuperchainConfig.json +./scripts/compare_bytecode.sh 0x64fe3f9201e6534d2d744c7c57d134e709131a6e forge-artifacts/CeloTokenL1.sol/CeloTokenL1.0.8.15.json +./scripts/compare_bytecode.sh 0xe8b013bee7bd603e2f0b4825638559d645a4c4cb forge-artifacts/DisputeGameFactory.sol/DisputeGameFactory.json +./scripts/compare_bytecode.sh 0xde47b113e4157ed15fa46c5572562ac11146c5ea forge-artifacts/L1CrossDomainMessenger.sol/L1CrossDomainMessenger.json +./scripts/compare_bytecode.sh 0xad5d111e961a5e451c8172034115bcc0551b6551 forge-artifacts/L1ERC721Bridge.sol/L1ERC721Bridge.json +./scripts/compare_bytecode.sh 0x5e21245e97A7BB4733f72c412DcdDCED1f408587 forge-artifacts/L1StandardBridge.sol/L1StandardBridge.json +./scripts/compare_bytecode.sh 0xff53e1a6885b5a90b24327e13b04b95e2b97bd6c forge-artifacts/ProtocolVersions.sol/ProtocolVersions.json +./scripts/compare_bytecode.sh 0x6322C2f2D6a4305Fc033754d486A5A067Ee5F9b1 forge-artifacts/StorageSetter.sol/StorageSetter.json +./scripts/compare_bytecode.sh 0x7b5a84f818b6fc3f079ee87c214f369062188d2a forge-artifacts/SystemConfig.sol/SystemConfig.json +./scripts/compare_bytecode.sh 0x53c165169401764778f780a69701385eb0ff19b7 forge-artifacts/SuperchainConfig.sol/SuperchainConfig.json +./scripts/compare_bytecode.sh 0xfaB0F466955D87e596Ca87E20c505bB6470D0DC4 forge-artifacts/PreimageOracle.sol/PreimageOracle.json +./scripts/compare_bytecode.sh 0x8A12E1754f729C0856E2E32D4821577f0B245bfA forge-artifacts/Mips.sol/Mips.json +./scripts/compare_bytecode.sh 0xDFBB69681F217aB3221E94AFCA4fEa51f5c6a779 forge-artifacts/DelayedWETH.sol/DelayedWETH.json +./scripts/compare_bytecode.sh 0x3Da872782f9fB696fD72Af2ec9313a56bDA6f06d forge-artifacts/OptimismPortal2.sol/OptimismPortal2.json +``` + +## 3. Verify Contract are correctly configured + +**Preliminary**. On a terminal set up RPC and Etherscan variables: + +```bash +export ETH_RPC_URL="https://mainnet.infura.io/v3/<>" +export ETHERSCAN_API_KEY="<>" +``` + +### 3.1 ProxyAdmin is owned by SystemOwnerSafe + +```bash +$ cast call 0x783A434532Ee94667979213af1711505E8bFE374 "owner() (address)" +0x4092A77bAF58fef0309452cEaCb09221e556E112 +``` + +This mean every proxy is indirectly owned by SystemOwnerSafe + +### 3.2 Check SystemConfigProxy is correctly configured + +SystemConfigProxy is `0x89E31965D844a309231B1f17759Ccaf1b7c09861` + +```bash +# Check its owned by SystemOwnerSafe +$ cast call 0x89E31965D844a309231B1f17759Ccaf1b7c09861 "owner() (address)" +0x4092A77bAF58fef0309452cEaCb09221e556E112 + +# Check all bridge addresses are correctly configured +$ cast call 0x89E31965D844a309231B1f17759Ccaf1b7c09861 "l1CrossDomainMessenger() (address)" +0x1AC1181fc4e4F877963680587AEAa2C90D7EbB95 +$ cast call 0x89E31965D844a309231B1f17759Ccaf1b7c09861 "l1ERC721Bridge() (address)" +0x3C519816C5BdC0a0199147594F83feD4F5847f13 +$ cast call 0x89E31965D844a309231B1f17759Ccaf1b7c09861 "l1StandardBridge() (address)" +0x9C4955b92F34148dbcfDCD82e9c9eCe5CF2badfe +$ cast call 0x89E31965D844a309231B1f17759Ccaf1b7c09861 "optimismPortal() (address)" +0xc5c5D157928BDBD2ACf6d0777626b6C75a9EAEDC #should match the optimismPortalProxy +``` + +### 3.3 Check SuperChainConfig correctly configured + +CeloSuperChainConfig is `0xa440975E5A6BB19Bc3Bee901d909BB24b0f43D33` + +```bash +#CeloSuperChainConfig managed by ProxyAdmin +$ cast call 0xa440975E5A6BB19Bc3Bee901d909BB24b0f43D33 "admin() (address)" +0x783A434532Ee94667979213af1711505E8bFE374 + +#CeloSuperChainConfig depends on OP SuperChainConfig +$ cast call 0xa440975E5A6BB19Bc3Bee901d909BB24b0f43D33 "superchainConfig() (address)" +0x95703e0982140D16f8ebA6d158FccEde42f04a4C + +#OP's SuperChainConfig managed by their ProxyAdmin +$ cast call 0x95703e0982140D16f8ebA6d158FccEde42f04a4C "admin() (address)" +0x543bA4AADBAb8f9025686Bd03993043599c6fB04 + +#Bridge is not paused +cast call 0xa440975E5A6BB19Bc3Bee901d909BB24b0f43D33 "paused() (bool)" +false + +#Guardian for SuperChain Bridge Status is a address controlled by cLabs +$ cast call 0xa440975E5A6BB19Bc3Bee901d909BB24b0f43D33 "guardian() (address)" +0x6E226fa22e5F19363d231D3FA048aaBa73CC1f47 +``` + +### 3.4 Bridge Contracts are correctly configured + +Bridge Contracts: + +- L1CrossDomainMessengerProxy `0x1AC1181fc4e4F877963680587AEAa2C90D7EbB95` +- L1ERC721BridgeProxy `0x3C519816C5BdC0a0199147594F83feD4F5847f13` +- L1StandardBridgeProxy `0x9C4955b92F34148dbcfDCD82e9c9eCe5CF2badfe` +- OptimismPortalProxy `0xc5c5D157928BDBD2ACf6d0777626b6C75a9EAEDC` +- OptimismPortal2 `0x3Da872782f9fB696fD72Af2ec9313a56bDA6f06d` + +Note: L1CrossDomainMessengerProxy is old kind of proxy that depends on AddressManager, it does not have an owner that can be queried. + +```bash +# Check L1ERC721BridgeProxy is owned by ProxyAdmin +$ cast call 0x3C519816C5BdC0a0199147594F83feD4F5847f13 "admin() (address)" +0x783A434532Ee94667979213af1711505E8bFE374 +# Check it uses the right SuperChainConfig +$ cast call 0x3C519816C5BdC0a0199147594F83feD4F5847f13 "superchainConfig() (address)" +0xa440975E5A6BB19Bc3Bee901d909BB24b0f43D33 + +# Check L1StandardBridgeProxy is owned by ProxyAdmin +# The L1StandardBridgeProxy uses a L1ChugSplashProxy +# To check the owner one must check the storage key 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 +$ cast storage 0x9C4955b92F34148dbcfDCD82e9c9eCe5CF2badfe 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 +0x000000000000000000000000783a434532ee94667979213af1711505e8bfe374 +$ cast parse-bytes32-address 0x000000000000000000000000783a434532ee94667979213af1711505e8bfe374 +0x783A434532Ee94667979213af1711505E8bFE374 + +# Check it uses the right SuperChainConfig +$ cast call 0x9C4955b92F34148dbcfDCD82e9c9eCe5CF2badfe "superchainConfig() (address)" +0xa440975E5A6BB19Bc3Bee901d909BB24b0f43D33 +# Check it uses the right SystemConfig +$ cast call 0x9C4955b92F34148dbcfDCD82e9c9eCe5CF2badfe "systemConfig() (address)" +0x89E31965D844a309231B1f17759Ccaf1b7c09861 + +# Check OptimismPortalProxy is managed by ProxyAdmin +$ cast call 0xc5c5D157928BDBD2ACf6d0777626b6C75a9EAEDC "admin() (address)" +0x783A434532Ee94667979213af1711505E8bFE374 +# Check it points to OptimismPortal2 +$ cast call 0xc5c5D157928BDBD2ACf6d0777626b6C75a9EAEDC "implementation() (address)" +0x3Da872782f9fB696fD72Af2ec9313a56bDA6f06d +# Check it has a 7 days delay window +$ cast call 0xc5c5D157928BDBD2ACf6d0777626b6C75a9EAEDC "proofMaturityDelaySeconds() (uint256)" +604800 +# Check it uses the right SuperChainConfig +$ cast call 0xc5c5D157928BDBD2ACf6d0777626b6C75a9EAEDC "superchainConfig() (address)" +0xa440975E5A6BB19Bc3Bee901d909BB24b0f43D33 +# Check it uses the right SystemConfig +$ cast call 0xc5c5D157928BDBD2ACf6d0777626b6C75a9EAEDC "systemConfig() (address)" +0x89E31965D844a309231B1f17759Ccaf1b7c09861 +# Check is has a cLabs Managed Account as guardian +$ cast call 0xc5c5D157928BDBD2ACf6d0777626b6C75a9EAEDC "guardian() (address)" +0x6E226fa22e5F19363d231D3FA048aaBa73CC1f47 +``` + +## 4 Verify CELO L1 Token is correctly deployed + +Start by checking on `SystemConfig` that customGasToken is enabled and pointing to CELO ERC20 + +```bash +# Check custom gas token is enabled +$ cast call 0x89E31965D844a309231B1f17759Ccaf1b7c09861 "isCustomGasToken() (bool)" +true +# Check ERC20 Address points to CELO with right number of decimals +cast call 0x89E31965D844a309231B1f17759Ccaf1b7c09861 "gasPayingToken() (address,uint8)" +0x057898f3C43F129a17517B9056D23851F124b19f +18 +# Check the symbol +cast call 0x89E31965D844a309231B1f17759Ccaf1b7c09861 "gasPayingTokenSymbol() (string)" +"CELO" +``` + +Check the ERC20 has correct ownership and all supply is locked on the bridge + +```bash +# CELO is implemented as a proxy managed by the ProxyAdmin +$ cast call 0x057898f3C43F129a17517B9056D23851F124b19f "admin() (address)" +0x783A434532Ee94667979213af1711505E8bFE374 + +# check the totalSupply is 1Billion +$ cast call 0x057898f3C43F129a17517B9056D23851F124b19f "totalSupply() (uint256)" +1000000000000000000000000000 [1e27] +# 1e27 / 1e18 = 1e9 = 1billion CELO +# check balance of OptimismPortalProxy to be total supply (only true before first withdrawal on Celo L2) +$ cast call 0x057898f3C43F129a17517B9056D23851F124b19f "balanceOf(address) (uint256)" 0xc5c5D157928BDBD2ACf6d0777626b6C75a9EAEDC +1000000000000000000000000000 [1e27] +``` + +## 5. Verifying SecurityCouncil Configuration + +Based on [this forum post](https://forum.celo.org/t/proposing-celo-l2s-security-council/10578), tied to [CGP-171](https://mondo.celo.org/governance/cgp-171); the security council is a 2/2 multisig whose members are a cLabsMultisig and "Celo Community Security Council" + +### 5.1 Verify the SystemOwnerSafe multisig + +During migration, this will be a 1/3 multisig, later becomes a 2/2. The third member is a cLabs managed account used during migraiton + +```bash +# Check members +$ cast call 0x4092A77bAF58fef0309452cEaCb09221e556E112 "getOwners()(address[])" +[0xC03172263409584f7860C25B6eB4985f0f6F4636, 0x9Eb44Da23433b5cAA1c87e35594D15FcEb08D34d, 0xbcA67eE5188efc419c42C91156EcC888b20664f3] + +# Check threshold +$ cast call 0x4092A77bAF58fef0309452cEaCb09221e556E112 "getThreshold()(uint256)" +1 +``` + +### 5.2 Verify the cLabs Multisig + +cLabs Multisig is a 6/8 multisig, and is a member of the SystemOwnerSafe multisig + +```bash +# Check members +$ cast call 0x9Eb44Da23433b5cAA1c87e35594D15FcEb08D34d "getOwners()(address[])" +[0x0Bd06B2b192BD9eC316f2880A0c296D9Bc3225e0, 0x21e595451bDD69a85cf946f37f5A6A356C3F875D, 0x09c0B069100F5d880a596605b94Cc9493D96e797, 0x326b764CEb4FE11e70af538D3CB997Bb2e16659d, 0x48139512241D32047760E7481eBf0b6BF3390f8F, 0x4D89adf3a4a71b25FB1a6D702Cf059CF5BebD02d, 0x8b4b85f78F799F8364198FFEd2266d3cb3EA0daE, 0xE0024dCadff414fCb0AAfBB475e92Ccc367E1A84] + +# Check threshold +$ cast call 0x9Eb44Da23433b5cAA1c87e35594D15FcEb08D34d "getThreshold()(uint256)" +6 +``` + +### 5.3 Verify the Celo Community Security Council + +Celo Community Security Council is a 6/8 multisig, and is a member of the SystemOwnerSafe multisig + +```bash +# Check members +$ cast call 0xC03172263409584f7860C25B6eB4985f0f6F4636 "getOwners()(address[])" +[0xB963047c5D875b7FE777339B1E6B61ac4df1f3e2, 0x6FDb3eA186981aA32DD8e7B782d95733Ca3c13A1, 0xd0cE4D055d04bDA69b20815A3F796019bB68c6Db, 0x148dfaC5dF51Ab1D7b02a3B53f1e2Da1F0A6B5Ca, 0x5f70938aA8d2fd91EE3959998E5DdaACFb6Ffb85, 0xD1C635987B6Aa287361d08C6461491Fa9df087f2, 0x2BE5E223E368E8c0f404a1f3Eb4eB09f99C8FaD8, 0xc3E966E79eF1aA4751221F55fB8A36589C24C0cA] + +# Check threshold +$ cast call 0xC03172263409584f7860C25B6eB4985f0f6F4636 "getThreshold()(uint256)" +6 +``` diff --git a/specs/l2-migration.mdx b/specs/l2-migration.mdx new file mode 100644 index 000000000..47c22ef6a --- /dev/null +++ b/specs/l2-migration.mdx @@ -0,0 +1,479 @@ +--- +title: "L1 to L2 Migration" +sidebarTitle: "L2 Migration" +--- + +The switch from the Celo L1 blockchain to the Celo L2 introduces a variety of changes, most of which are not visible to the majority of developers and even less to the end users. However, tool developers, infrastructure operators and some developers will have to take a few of these changes into account. This page contains all information to check if this is the case for you or not. + +## Changes for Contracts Developers + +- [Removed precompiles](/specs/smart-contract-updates-from-l1#precompiles-deprecation) (all except the `transfer` precompile) +- During the migration the following hardforks are enabled: + - [Berlin](https://github.com/ethereum/execution-specs/blob/mainnet/src/ethereum/forks/berlin/__init__.py) + - [London](https://github.com/ethereum/execution-specs/blob/mainnet/src/ethereum/forks/london/__init__.py) + - [Arrow Glacier](https://github.com/ethereum/execution-specs/blob/mainnet/src/ethereum/forks/arrow_glacier/__init__.py) + - [Gray Glacier](https://github.com/ethereum/execution-specs/blob/mainnet/src/ethereum/forks/gray_glacier/__init__.py) + - [Shanghai](https://github.com/ethereum/execution-specs/blob/mainnet/src/ethereum/forks/shanghai/__init__.py) + - [Cancun](https://github.com/ethereum/execution-specs/blob/mainnet/src/ethereum/forks/cancun/__init__.py) +- The following Optimism specific hardforks are enabled: + - [Canyon](https://specs.optimism.io/protocol/canyon/overview.html) + - [Delta](https://specs.optimism.io/protocol/delta/overview.html) + - [Ecotone](https://specs.optimism.io/protocol/ecotone/overview.html) + - [Fjord](https://specs.optimism.io/fjord/overview.html) + - Notably, this hardfork also enables the [`P256VERIFY`](https://specs.optimism.io/protocol/precompiles.html#p256verify) precompile, which performs signature verification for the secp256r1 elliptic curve. This curve has widespread adoption. It's used by Passkeys, Apple Secure Enclave and many other systems. + - [Granite](https://specs.optimism.io/protocol/granite/overview.html) + +### Precompile Deprecation and Epoch Management + +As part of Celo's transition to a L2 network, the following Celo precompiles, except the `Transfer` precompile, will be deprecated. + +- `FRACTION_MUL` +- `PROOF_OF_POSSESSION` +- `GET_VALIDATOR` +- `NUMBER_VALIDATORS` +- `EPOCH_SIZE` +- `BLOCK_NUMBER_FROM_HEADER` +- `HASH_HEADER` +- `GET_PARENT_SEAL_BITMAP` +- `GET_VERIFIED_SEAL_BITMAP` + +This means that the geth client is no longer responsible for processing epochs. Instead, processing of epochs, rewards distribution and storage of currently elected validators is now handled by the `EpochManager` contract. + +Any contract supporting the use of precompiles will now revert on Celo as a L2. This includes the `UsingPrecompiles` contract. More details [here](https://github.com/celo-org/celo-monorepo/blob/release/core-contracts/12/packages/protocol/contracts/common/UsingPrecompiles.sol) + +To keep costs of processing epochs low, only the following key functions (used for querying the current epoch or elected validators) have been ported over to the [EpochManager] contract. + +- `getEpochNumberOfBlock(uint256)` +- `getEpochNumber()` +- `validatorSignerAddressFromCurrentSet()` +- `numberValidatorsInCurrentSet()` + +Read more on new [epoch management and reward distribution](/specs/smart-contract-updates-from-l1#epochs-and-rewards) or [deprecated precompiles](/specs/smart-contract-updates-from-l1#precompiles-deprecation). + +### FeeCurrencyDirectory + +We introduced a new contract, `FeeCurrencyDirectory`, which is responsible for managing the fee currencies used in the Celo network. This contract is replacement for `FeeCurrencyWhitelist` and keeps track of ERC-20 tokens that can be used as gas currencies on Celo network with additional setup of intrinsic gas cost of transactions for these fee currencies. + +### FeeCurrencyWhitelist + +The `FeeCurrencyWhitelist` contract has been replaced by the `FeeCurrencyDirectory` contract. + +### Deactivated Random Contract + +The `Random` core contract has been deactivated. The [EIP-4399](https://eips.ethereum.org/EIPS/eip-4399) `PREVRANDAO` opcode provide some pseudo-randomness now. Please be aware of the limitations mentioned in the EIP, as well as the following OP Stack specific limitations: + +- The randao value is read from the L1, it is known a longer time in advance. +- Since multiple L2 blocks are derived from the same L1 block, the `PREVRANDAO` value will not change with every L2 block, but only with the L1 block. + +### Deactivated BlockchainParameters Contract + +The `BlockchainParameters` core contract has been deactivated. + +The `blockGasLimit` can now be found by querying the Optimism L1 `SystemConfig` contract and calling the `gasLimit()` getter. + +The `intrinsicGasForAlternativeFeeCurrency` can now be found by querying the [FeeCurrencyDirectory contract](https://github.com/celo-org/celo-monorepo/blob/master/packages/protocol/contracts-0.8/common/FeeCurrencyDirectory.sol) function `getCurrencyConfig(token).intrinsicGas`. + +### Updated Governance Hotfix + +The Governance Hotfix process has undergone several changes due to the absence of validators on L2, now using a multisig approach. Here’s a detailed explanation of these changes: + +#### Original Hotfix Process + +Previously, the hotfix process relied heavily on a set of validators: + +1. **Validator Approval**: A byzantine quorum of validators was needed to whitelist a hotfix. Validators had financial incentives to act in the network's best interest, ensuring that any approved hotfix had been vetted by a trustworthy group. +2. **Dynamic Validator Set**: The list of validators who approved the hotfix changed with each epoch. This dynamic nature made it difficult for validators to collude and approve a malicious hotfix. +3. **Epoch-Dependent**: If a hotfix was not executed within the same epoch it was approved, it needed to be reapproved by the new set of validators in the next epoch. +4. **Prepare Step**: The hotfix required a "prepare" step, ensuring that the current set of validators had approved the hotfix before it could be executed. + +#### Updated Hotfix Process + +Due to the absence of validators on L2, the process now incorporates a multisig approach: + +1. **Multisig Approval**: The new process requires the approval of an approver multisig, but now also includes the Security Council multisig. +2. **Fixed Signers**: Unlike the previous dynamic set of validators, the list of Security Council signers remains fixed. This change simplifies the approval process but also increases the risk of collusion among the fixed set of signers. +3. **Execution Time Limit**: If a hotfix is not executed within the specified `executionTimeLimit`, it must be reset and re-approved. This keeps the time constraint but no longer depends on epoch changes. +4. **Collusion Risk**: The fixed list of Security Council signers introduces a new risk factor. Without clear incentives for the signers to act in the network's best interest, there is a higher risk of collusion and the potential for malicious hotfixes being approved. + +## Changes for JSON-RPC Users + +### Removed Tx Types + +New transactions can't be submitted using the following transaction types, see also the [tx types page](/specs/transaction-types): + +- Celo legacy tx +- CIP-42 + +Information about existing transactions of these types can still be retrieved via RPC. + +### Block and Tx changes in RPC Responses + +To match the Ethereum and OP-Stack responses more closely, the RPC responses for historical blocks and transactions have been updated. +The following examples show the difference between the old (Celo L1) and the new (Celo L2) responses. + +#### Blocks + +##### Pre Gingerbread Block + +The new representation will lack the no longer needed `randomness` and `epochSnarkData` fields and gain `sha3Uncles`, `uncles`, `mixHash` and `nonce`. +The choice was taken to add `sha3Uncles`, `uncles`, `mixHash` and `nonce` even though they have zero values or are empty, in order to align better with the +ethereum block structure and increase compatibility with ethereum tooling. For example foundry's cast does not support fetching blocks that lack `sha3Uncles`. + +The `extraData` does not include the validator signatures ("Istanbul aggregated seal") anymore. That data has never been included when calculating the block hash, so removing it from the response makes it easier to reproduce the block hash. + +Note that the `size` will be different because of the missing `epochSnarkData` and `randomness` fields and also the underlying RLP datastructure in CeL2 differs from the RLP datastructure in Celo. + +```diff + { ++ "baseFeePerGas": "0x5f5e100", + "difficulty": "0x0", +- "epochSnarkData": null, +- "extraData": "0xd983010000846765746889676f312e31332e3130856c696e7578000000000000f8b6c0c080b841d97776193d6a3e3bf8319a47ac44e4489212e02a584035f58adb153e1da2a49215bdf6983d8b08c53e22dbe776fb489063eaf3a4e581d9c124b1745154ec875e01f78427da3f2fb01b4d9a10b3ff2c620b0b5dc4e3fbee3210c082012524fe8347e8369943ab5d68b43d1874af789493e974eb43bd47698180f7843fffffffb0aa91da2fe7d6b89d3e7c5f8d812c9e20f4dde29404975a5a4d68476c2cb0ff5500788d239a8729413c3adb43d9fb878180", ++ "extraData": "0xd983010000846765746889676f312e31332e3130856c696e7578000000000000f882c0c080b841d97776193d6a3e3bf8319a47ac44e4489212e02a584035f58adb153e1da2a49215bdf6983d8b08c53e22dbe776fb489063eaf3a4e581d9c124b1745154ec875e01c3808080f7843fffffffb0aa91da2fe7d6b89d3e7c5f8d812c9e20f4dde29404975a5a4d68476c2cb0ff5500788d239a8729413c3adb43d9fb878180", + "gasLimit": "0x989680", + "gasUsed": "0x9a972", + "hash": "0x4ef93291167de948057e6644016b4270aa922a04ae97f37ea471852cc13046e0", + "logsBloom": "0x00000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000010000000400000000000000000000000000000000100000000000000000000000000080000000008000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000080000000000000000000008000000000000001000000000000000000010000000000000000000080000000000000000000000000000000000000000000000", + "miner": "0xef0186b8eda17be7d1230eeb8389fa85e157e1fb", ++ "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", ++ "nonce": "0x0000000000000000", + "number": "0xb8d", + "parentHash": "0x48e4a4ba167e5b9a9af46b07882cac5d514b3d38bfec5f8f0cf09bc50c574876", +- "randomness": { +- "committed": "0x3654af1e4c47b230e06c37f3f49163f1ae3284b127d977bcadae6c8b809df86c", +- "revealed": "0xeec3298014c360628da382013379c53b58b339a89bb4c1437db7446250472f57" +- }, + "receiptsRoot": "0xffc520613572e5e655a13b5bb74a0dabcc4e5fc132cce6c193d1f9c419eb05f5", ++ "sha3Uncles": "0x0000000000000000000000000000000000000000000000000000000000000000", +- "size": "0xea0", ++ "size": "0xe26", + "stateRoot": "0x57f9dd4504d6142b099da5b0e7a8b1fc911af9293a48cdd0750111d7c19ed943", + "timestamp": "0x5ef3ab5e", + "totalDifficulty": "0xb8e", + "transactions": [ + "0xea2d6ace4848a91065f029f2cf403d6d3c4a3835ca3cb7e9f3c943f00cbfa759" + ], + "transactionsRoot": "0xbb3c1f1fe49abff6b98de7b3629fa1d94ad1fa01f2b0c85e22e4f69c419e5dfe", ++ "uncles": [] + } +``` + +##### Post Gingerbread, Pre CeL2 Block + +In this case, the new representation will lack the no longer needed `randomness` and `epochSnarkData` fields. + +The `extraData` does not include the validator signatures ("Istanbul aggregated seal") anymore. That data has never been included when calculating the block hash, so removing it from the response makes it easier to reproduce the block hash. + +Note that the `size` will be different because of the missing `epochSnarkData` and `randomness` fields and also the underlying RLP datastructure in CeL2 differs from the RLP datastructure in Celo. + +```diff + { + "baseFeePerGas": "0x12a05f200", + "difficulty": "0x0", +- "epochSnarkData": null, +- "extraData": "0xd983010804846765746889676f312e31392e3133856c696e7578000000000000f8b2c0c080b8412ba9e02862ac252968922b40998bf81ad3365573eb1022d6299fb4fc0556258d62369eaa1dbefa22537d78d1be4a75bdb182d7dd36d314ab13ac9933a3ae657b01f58202f9b0b125dcff9f90b02acffcd7a2a2c1b5855bcaea233aac4242659dbf217e23cd72a43626efc0f145191fdf298734c53f8080f58203ffb09fe8e166bcd22854dece60b93a2e59eb964778647fb5ba375386c9051f009b394aa46be3e039dbd78b9fa6e7e048d78080", ++ "extraData": "0xd983010804846765746889676f312e31392e3133856c696e7578000000000000f880c0c080b8412ba9e02862ac252968922b40998bf81ad3365573eb1022d6299fb4fc0556258d62369eaa1dbefa22537d78d1be4a75bdb182d7dd36d314ab13ac9933a3ae657b01c3808080f58203ffb09fe8e166bcd22854dece60b93a2e59eb964778647fb5ba375386c9051f009b394aa46be3e039dbd78b9fa6e7e048d78080", + "gasLimit": "0x2160ec0", + "gasUsed": "0x4468e", + "hash": "0x9374dd975e7a59cdf89e4fb1f6e75b168a5d5d95c2ce1c11209578a7561ef1bd", + "logsBloom": "0x00800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000040000000000000002000000000000000000000000000100000000000004000000000000000000000000000000000000000000000000008000000000000000400000000000000000000000000000000000400000000000000000000000000000000000000000000000000000800000000000000000008000000001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000", + "miner": "0xa910ffc6294e96c6a7cac175621d4b1991f53120", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "number": "0x186f055", + "parentHash": "0x6fd1b8122bbbdcab8ec82e44397929ab164584dce061d50f657d6f21962fd13a", +- "randomness": { +- "committed": "0xafb35e688710867bef9bf982ecff9cdbd9e8c19a687fa9bb2bdbb9341b79b237", +- "revealed": "0x6d6c35073bc7bee1f037c1f8225a4fbffbfdcf978c6af85c56f3e7b4a0ecf0f1" +- }, + "receiptsRoot": "0xf6193f8bea9c51a5ec6f65e644d3bc30df7414d08914b17f3543e0463aee4abb", + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", +- "size": "0x418", ++ "size": "0x3a0", + "stateRoot": "0x4ce545e412947838ab85b0e560b339cc4a903dc3b0364ee39d382c04a79c4df4", + "timestamp": "0x66babd40", + "totalDifficulty": "0x186f056", + "transactions": [ + "0xafb85e106fceea010ed9b1f9f50fbbdcfa4308f3a398aa4f31d35370e9cea300" + ], + "transactionsRoot": "0x392de6ef9cfb6047bad717b943c6397666c1cca2321c3d9fadd76ceaca0d1e57", + "uncles": [] + } +``` + +##### Post Cel2 Block + +Since the blocks after the migration are not available in a Celo L1 node, we can't show the diff between the response of a Celo L1 and a Celo L2 node. Instead, the following is a fictional diff between an L1 block right before the L2 migration and the same block if it was an L2 block instead. This illustrates the following changes for new blocks after the migration: + +- The `extraData` field is empty +- `mixHash` is used to provide pseudo-randomness for the `PREVRANDAO` opcode and is not empty anymore +- `parentBeaconBlockRoot` field added +- `totalDifficulty` removed +- `withdrawals` and `withdrawalsRoot` fields added + +Note that `withdrawals` will be empty for the foreseeable future, because there is no staking mechanism or beacon chain in the celo L2. + +```diff +{ + "baseFeePerGas": "0x5d21dba00", + "blobGasUsed": "0x0", + "difficulty": "0x0", + "excessBlobGas": "0x0", +- "extraData": "0xd983010804846765746889676f312e31392e3133856c696e7578000000000000f880c0c080b8412ba9e02862ac252968922b40998bf81ad3365573eb1022d6299fb4fc0556258d62369eaa1dbefa22537d78d1be4a75bdb182d7dd36d314ab13ac9933a3ae657b01c3808080f58203ffb09fe8e166bcd22854dece60b93a2e59eb964778647fb5ba375386c9051f009b394aa46be3e039dbd78b9fa6e7e048d78080", ++ "extraData": "0x", + "gasLimit": "0x1c9c380", + "gasUsed": "0xaaee", + "hash": "0xa2f404d653c22969acb3785db12df02604c2f6bc767f22b2c4ff8662f03ba305", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "miner": "0x4200000000000000000000000000000000000011", +- "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", ++ "mixHash": "0x08229a0e20d3896f829595d4e5c9eece4279ba7e45e38b492a3d99003c47c32b", + "nonce": "0x0000000000000000", + "number": "0x2549326", ++ "parentBeaconBlockRoot": "0x7606b339839b9ab700cfadc9cb0b105d33388f4f2755c2c7c7168af0c37a429f", + "parentHash": "0x914bda6eb9cb5866fa76607df3483d442f5d28d517245f592780aaf0ab2c6065", + "receiptsRoot": "0x766157eaef643639c1b76e03f157ffdd1ec6c7583ee2c85561916161ac964e3e", + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "size": "0x34c", + "stateRoot": "0x4723c7d986d7e7bb91818048b5ebcb64101db4395d9401d6a25901808ff33816", + "timestamp": "0x67b717df", +- "totalDifficulty": "0x186f056", + "transactions": [ + "0x246cb5812aab652a205e5d05145cdc8a5bbaa5d8e1eeae9fef43397c011666d9" + ], + "transactionsRoot": "0x8ef09de185b4ae02e2c42fe9b8dc1ff58fff9dffd91a8940197374005ccba057", + "uncles": [], ++ "withdrawals": [], ++ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" +} +``` + +#### Transactions + +See [this page](/home/protocol/transactions/transaction-types#summary) for a summary of transaction types in Celo. + +At genesis, type 0 transactions on Celo contained 3 extra fields compared to Ethereum. Those were `feeCurrency`, `gatewayFee` and `gatewayFeeRecipient`. These extra fields rendered Celo transactions incompatible with any existing Ethereum wallets. To mitigate this and allow use of existing ethereum wallets we extended the definition of type 0 transactions to support the original ethereum transaction format (i.e. without the 3 extra fields). + +Since it was valid for the celo type 0 transaction to not set the three extra fields in order to distinguish between the two forms of type 0 transaction an extra field (`ethCompatible`) was added to RPC API responses for type 0 transactions. + +Historically, we would return these 3 extra fields and `ethCompatible` on RPC API responses for all transaction types. But this was leading to some confusion since those fields were only relevant for some transaction types. + +In CeL2, we have updated the RPC API to omit the `feeCurrency`, `gatewayFee` and `gatewayFeeRecipient` fields when `ethCompatible` is true, meaning that ethereum compatible transactions should have no additional fields. + +In addition to the previous data, the CeL2 node will return `yParity` for all non 0 transaction types. + +##### Type 0 Eth Compatible + +```diff + { + "blockHash": "0x06613bb2a5c75748035e20c06c577669cd4d78f9a1d36ae79eb26ce72dda9c18", + "blockNumber": "0x16b8f4a", +- "ethCompatible": true, + "chainId": "0xaef3", + "from": "0x994532b8f186949d7217d7b843509c19e78b9584", + "gas": "0xa5c6", + "gasPrice": "0x2540be400", +- "gatewayFee": "0x0", + "hash": "0xe152376f4b2d3a81f3631cf5830fb820118de3cb3ef5ddb068978829c2712b08", + "input": "0x3798c7f2000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000066318fd2000000000000000000000000000000000000000000000000000000000160543a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000345555200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003f8e3083", + "nonce": "0x2b714", + "r": "0x1cbba1e5b0c6d9155a56f7f690d59ca46a7deab2bc6aefa4fe89542dbc779c5f", + "s": "0x66aff5220a9228352bee2a7ac07e9c723bc6bc00311d02338d15ed106b07a608", + "to": "0x3d00dea966314e47ac3d4acd2f00121351cec1c5", + "transactionIndex": "0x0", + "type": "0x0", + "v": "0x15e09", + "value": "0x0" + } + ``` + +##### Type 0 Not Eth Compatible With No Fee Currency And Gateway Fee Recipeint + +```diff + { + "blockHash": "0x11d497cf96f94c62db173e27a9aebe7db559d9675e58a9ac268c5c934bffe441", + "blockNumber": "0x16b8efc", + "chainId": "0xaef3", + "ethCompatible": false, + "from": "0x473a3be7c2a42452ed0b521614b3b76bc59d2d1d", + "gas": "0x8160d", + "gasPrice": "0x1bf08eb00", + "gatewayFee": "0x0", + "hash": "0x6ba6fb0f75a38112bada3a8d3e789d9a5fdce4ea11f35a7ef8b550bcc356d202", + "input": "0x80e50744000000000000000000000000874069fa1eb16d44d622f2e0ca25eea172369bc1000000000000000000000000000000000000000000009fc8476fe32ad9dd7cd0000000000000000000000000dd5cb02066fde415dda4f04ee53fbb652066afee0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x72ce1", + "r": "0x28ec2e7d544ad737ce7ee4c7d756f00335a764451b5036b44a5bd06cf50262af", + "s": "0x1d62168d50945e7457d74c095ccca0fbcafb6e5f86d30d1725fad089d1a4c435", + "to": "0xfdd8bd58115ffbf04e47411c1d228ecc45e93075", + "transactionIndex": "0x0", + "type": "0x0", + "v": "0x15e0a", + "value": "0x0" + } +``` + +##### Type 0 Not Eth Compatible With Fee Currency + +```diff + { + "blockHash": "0x3cd3ee79cd8e1a97e8979ee4d896256a5e369d6c7e3f66e631c8387f561bbbe8", + "blockNumber": "0x16b8ef1", + "chainId": "0xaef3", + "ethCompatible": false, + "feeCurrency": "0x874069fa1eb16d44d622f2e0ca25eea172369bc1", + "from": "0x0ac70692e0146522dd89dbf99831beaddcd57e8c", + "gas": "0x31e9e", + "gasPrice": "0x464abf343", + "gatewayFee": "0x0", + "hash": "0x86ba696a70eaf0f973313b0877f611f6500d9673eb51952a4a99c3200af0d249", + "input": "0xe1d6aceb000000000000000000000000e5f5363e31351c38ac82dbadead91fd5a7b08846000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x1", + "r": "0xb3fdfa10b8faaf1642e7e6e7c04f8e1d3051e61a4e79c4da1bb1f112e72607d2", + "s": "0x6114be273d1dcb45e485a8f7731666e3c36bfde385c8b47439c92b92d8ceb47f", + "to": "0x874069fa1eb16d44d622f2e0ca25eea172369bc1", + "transactionIndex": "0x0", + "type": "0x0", + "v": "0x15e09", + "value": "0x0" + } +``` + +##### Type 2 (dynamic fee transaction) + +```diff + { + "accessList": [], + "blockHash": "0x5b77a681e7ff2fc015e074ece54877c50a6ed1e093cc76aabb109846e4544420", + "blockNumber": "0x16b8f3f", + "chainId": "0xaef3", + "from": "0x48cc4c4133cbf40def64b95b002d4ee4d24df846", + "gas": "0x1ff04", + "gasPrice": "0x1a13b8600", +- "gatewayFee": "0x0", + "hash": "0x169500202b491733092159a496f535a9364f69d4059b9b26f39ea8896364ab26", + "input": "0xa87a20ce0000000000000000000000000000000000000000000000000000000000000068", + "maxFeePerGas": "0x1dcd65000", + "maxPriorityFeePerGas": "0x77359400", + "nonce": "0x6779", + "r": "0xe76c97eb3184a45d96563bfeca470e9c5f4410f6815a81e1df42ecc2f84d9f7c", + "s": "0x550fede7177a20024a76cc02dc5fbd6cdefa163ff861441cd9617afceee824", + "to": "0x4330b35a355c24ac8e544ade2d531050b5b9be7b", + "transactionIndex": "0x0", + "type": "0x2", + "v": "0x1", + "value": "0x0", + "yParity": "0x1" + } +``` + +##### Type 123 (Celo dynamic fee transaction v2) + +```diff + { + "accessList": [], + "blockHash": "0x9abe488547e2e3195dc6e69fbf7e378056f98b3608b69309ef99c358a825cf37", + "blockNumber": "0x16b8f03", + "chainId": "0xaef3", + "feeCurrency": "0x874069fa1eb16d44d622f2e0ca25eea172369bc1", + "from": "0x06502700eac7123676a7332ba2015dffba021af6", + "gas": "0x1ec78", + "gasPrice": null, +- "gatewayFee": "0x0", + "hash": "0xbe98d102295d6a5c7a26487a6ed7a5d2278cc30c2c8fb065f46bb78a6258090e", + "input": "0xe1d6aceb0000000000000000000000005fe1407f47b1310ff232a8d368b36099eff61604000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001cc4242484b6e2f42695479437171736a47646f6a686c687631456654617035786177577453447476412f784172695a6d7557774b6f6273735a6344356b4c414f7141436965737474516732616c4e7a6d68673866714f776a5651483761513273594968482b6f4d384669486364746768304e4f6a6e2b59365345306c434c62695a7a6a667143763277426878636834524634384d6639446530436a4e2b65704e4f52414431622f544d4d682b47424e4472736a3642724e43506f6c3432366375424f6273383578633378704938632f7144576c526f554d6c4456774c4370446a79505578746c2b4b515170415a70567a414a664d783867635257727a505936546644545554374b4b3954444979783461657558576a50765776442f46584b72414f546e6f394c3050427061582b7162734d3147394e2b39497274426133486476566f396b5744364454622f567767727752636d4b41656970416551346a6c415850556979376656623373324c5839655462626937654a2b514e616c78314d75522f4d38554f3178756547793330474c672b71695370434c4451626167314d74576565555645625269517a4b58484c6f4348704f357a4a6f4b2f5a50452b635558392f44354479513258557a453d0000000000000000000000000000000000000000", + "maxFeePerGas": "0x21b83c7d5", + "maxPriorityFeePerGas": "0x59eb4bf9", + "nonce": "0x1f9b", + "r": "0x68940dd91c0574638344927b53015752c78bc9cf67387f0d0c1f6d22559eeec3", + "s": "0x412aa02bd215cd0353dd1ffa1f99bbe2ee218e9e7ae3c5b462a568b705534f46", + "to": "0x874069fa1eb16d44d622f2e0ca25eea172369bc1", + "transactionIndex": "0x1", + "type": "0x7b", + "v": "0x1", + "value": "0x0", ++ "yParity": "0x1" + } +``` + +## State Changes during the Migration + +The migration is the process of converting the Celo L1 chain into an L2 based on Ethereum. +This migration involves different steps and requires the blockchain to shortly pause block production. + +During the migration the following things are done: + +- Historic blockchain data such as blocks, headers and transactions are transformed into a version readable by the updated execution client. During this process some data, such as data required for the Istanbul consensus algorithm, is removed as it is no longer required. +- OP Stack L2 contracts are deployed. +- The new Celo unreleased treasury core contract is initialized. + +### Historical data migration + +Celo started as a fork of `go-ethereum` but initially some significant changes to the structure of headers and blocks were made because it was operating with a Proof of Stake consensus mechanism. + +At the outset Celo blocks lacked the following fields that Ethereum blocks had: + +- `sha3Uncles` +- `uncles` +- `difficulty` +- `gasLimit` (the `gasLimit` was defined by a contract and so had to be retrieved from state) +- `mixHash` +- `nonce` + +Later in the [Espresso hardfork](https://github.com/celo-org/celo-proposals/blob/master/CIPs/cip-0041.md), dynamic fee transactions were introduced. Instead of relying on the `baseFeePerGas` field on the block header, the `baseFeePerGas` was also retrieved from state via a contract call similar to `gasLimit`. + +In the [Gingerbread hardfork](https://github.com/celo-org/celo-proposals/blob/master/CIPs/cip-0062.md) (block `21616000`) all the fields listed above plus `baseFeePerGas` were added to the internal block representation to bring future blocks into alignment with Ethereum. +A constant difficulty field of `0x0` was added to all pre-Gingerbread RPC API block responses. + +Celo added the following fields to block bodies: + +- `randomness` +- `epochSnarkData` + +As additions they do not damage compatibility at the RPC API level as API clients would generally ignore them. However, in the transition to L2 these fields are planned for removal because they will no longer be needed. + +In the transition to L2 as an attempt to improve the situation with RPC API compatibility for historical blocks, all post-Gingerbread fields will be returned for **all** blocks. +Both pre-Gingerbread and post-Gingerbread blocks retrieved from the L2 RPC API would look the same with the exception of `baseFeePerGas` which for now will not be returned for pre-Gingerbread blocks. + +#### L2 Block Structure + +Going forward, blocks occurring after the transition point will gain an extra field, `parentBeaconBlockRoot`, which will bring our block structure fully up to date with Ethereum’s block structure. + +As Ethereum evolves in the time before we make the transition to L2 we could end up with additional fields being added to the L2 Block Structure, and this document will be updated accordingly. + +### State migration + +The OP stack requires a number of contracts to be available on the L2. Those contracts have predefined addresses and cannot be deployed like normal contracts. Instead they are written to the state during the migration. + +As this process touches the blockchain state, it is important that it is transparent and can be verified by every node operator and user. Therefore, every node operator can do the migration locally and check the resulting state against Celo L2 state. + +#### OP predeploys + +The predeploys to be added to the state are supplied in form of an allocation file which contains a mapping of account addresses to their state. In the state migration tool this file is read and every account copied into the Celo L1 state. + +There's a number of checks to make sure this doesn't end up causing problems. + +- If an account to be written to the state already has a balance, this balance is added to the copied account balance. This makes sure the total amount of Celo doesn't change. +- If an account already contains code, it is checked that the code is the same. + +#### `CeloUnreleasedTreasury` set up + +The `CeloUnreleasedTreasury` is a new contract available on the migrated Celo L2. See [the spec](/specs/smart-contract-updates-from-l1#celo-minting) for more information. + +During the migration it needs to be setup with the remaining unminted Celo. + +This is done by first reading the total supply of Celo tokens at the time of the migration. This value is then subtracted from the max supply of Celo tokens, which is *1,000,000,000*. This difference is the remaining amount of tokens that gets set as the balance of the distribution schedule contract. + +## Other Changes + +### Validators + +Until Celo has decentralized sequencing, validators will no longer validate blocks, but instead operate community RPC nodes. +Refer to the [proposal](https://forum.celo.org/t/proposal-validator-engagement-during-the-transition-to-celo-l2/9700) in the context of [The Great Celo Halvening Temperature Check](https://mondo.celo.org/governance/cgp-164). + +### CIP-64 Receipts Now Contain the `baseFee` + +For the Celo L1, the `effectiveGasPrice` for CIP-64 txs is only available until the block state is pruned. Afterwards, the blockchain client is unable to get the `baseFee` for the relevant `feeCurrency`, which is required to calculate the `effectiveGasPrice`. To avoid this and make the `effectiveGasPrice` available permanently, the `baseFee` is [included as the last field in the RLP-encoded CIP-64 receipt](https://github.com/celo-org/op-geth/commit/6a1996f17b2ae22fcb3c24b82acbaffa1753f667) for CIP-64 txs submitted after the L2 migration. The EIP-2718 `ReceiptPayload` for this transaction type is now `rlp([status, cumulativeGasUsed, logsBloom, logs, baseFee])`. + +### CIP diff + +For a full list of changes by CIP, refer to the forum post: [Executed CIPs and Key Changes in Celo’s transition to L2](https://forum.celo.org/t/executed-cips-and-key-changes-in-celo-s-transition-to-l2/10664). diff --git a/specs/native-bridge.mdx b/specs/native-bridge.mdx new file mode 100644 index 000000000..609093ac5 --- /dev/null +++ b/specs/native-bridge.mdx @@ -0,0 +1,27 @@ +--- +title: "Native Bridge" +--- + +With the L2 migration, the Celo blockchain gained a native bridge to Ethereum based on [OP Stack's Standard Bridge](https://docs.optimism.io/app-developers/guides/bridging/standard-bridge). Specifically we use Custom Gas Token feature. This page describes the process of bridging assets between L1 and L2. + +The Celo token now exists in both L1 and L2 versions. The L1 version is a standard ERC20 token with a total supply of 1 billion, fully minted to the `OptimismPortal` smart contract, which is part of the bridge (this setup allows any Celo token holder on L2 to bridge their tokens to L1). The L2 version is the native token on the L2 Celo chain, preserving the balances from the Celo L1 chain. Tokens that have not yet been minted on the Celo L1 chain, such as tokens for Community Fund, are now minted to the `CeloDistributionSchedule`, which manages further distribution. + +## Bridging CELO from L1 to L2 + +To deposit ERC20 Celo tokens onto the chain, users should use the `OptimismPortalProxy.depositERC20Transaction` method. Before depositing tokens with `depositERC20Transaction`, users must first call `approve()` on the `OptimismPortal`. After the deposit is made, L1 tokens are bridged, and an equivalent amount of tokens is minted as native Celo tokens in the user's account on Layer 2 (L2). + +## Bridging CELO from L2 to L1 + +To withdraw Celo from the L2 chain, users should use the `L2ToL1MessagePasser.initiateWithdrawal` method. The process for proving and finalizing withdrawals is the [same](https://docs.optimism.io/op-stack/bridging/withdrawal-flow) as it is on OP chains that use ETH as the native token. + +## Bridging ETH + +Native ETH bridging is not supported for now since L1 bridge considers L1 Celo ERC20 as native token for Celo L2 and actively rejects any native ETH sent to the bridge. It is possible to bridge WETH (wrapped ETH) which behaves as standard ERC20 token both on L1 and L2. + +## Bridged ERC20 Tokens + +ERC20 tokens can be bridged the same way as in the unmodified OP Stack, see [Bridging ERC-20 Tokens to OP Mainnet With the Optimism SDK](https://docs.optimism.io/app-developers/tutorials/bridging/cross-dom-bridge-erc20) for a tutorial on this. + +## Using Bridged Tokens as Fee Abstraction + +The `OptimismMintableERC20` (used to represent ERC20 tokens from L1 on L2) supports the [`IFeeCurrency`](https://github.com/celo-org/fee-currency-example/blob/master/src/IFeeCurrency.sol) interface, which is a requirement to use them as a Fee Abstraction token. Before a new `OptimismMintableERC20` instance can actually be used as Fee Abstraction, it still has to be added to the `FeeCurrencyDirectory` (`0x71FFbD48E34bdD5a87c3c683E866dc63b8B2a685`) by Celo governance. This is currently only the case for `WETH`. diff --git a/specs/smart-contract-updates-from-l1.mdx b/specs/smart-contract-updates-from-l1.mdx new file mode 100644 index 000000000..9104cbe74 --- /dev/null +++ b/specs/smart-contract-updates-from-l1.mdx @@ -0,0 +1,164 @@ +--- +title: "Smart Contract Updates From L1" +sidebarTitle: "Contract Updates" +--- + +Smart contract changes that will be deployed to Celo before the transition can be seen in this diff: [https://github.com/celo-org/celo-monorepo/pull/11035/files](https://github.com/celo-org/celo-monorepo/pull/11035/files) + +## Epochs And rewards + +### Overview of rewards and epochs in L1 + +The Celo L1 produces a special block ("epoch block”) every 17280 blocks (approximately one day). This blocks includes "epoch transactions” that are triggered by the blockchain itself. + +During these epoch transactions, the protocol does: + +- Updates target voting yield +- Calculates validator rewards +- Update validators' scores +- Mints Celo: + - For validator rewards (then exchanged for cUSD using Mento) + - For voter rewards + - For CarbonOffsetting fund + - For Community Fund (Celo Governance) +- Distributing validator rewards to the validators, groups and delegator (in cUSD) +- Distributing voter rewards +- Running validator elections (the result is the addresses of the signers, then stored in the blockchain storage and accessed via a precompile) + +### Overview of rewards and epochs in L2 + +In the L2 "epoch blocks” no longer exist. There are no transactions triggered by the blockchain itself. Precompiles that were used to query epoch state are also not longer available. + +The concept for epochs still remains, but they are determined to be at least as long as "epoch duration” (targeted to be set as one day on mainnet), but there's no guaranteed limit of the maximal duration. The size of an epoch can no longer be deterministically calculated based on block numbers alone. + +The logic for processing epochs is now fully implemented in Solidity in the [EpochManager contract](https://github.com/celo-org/celo-monorepo/blob/release/core-contracts/12/packages/protocol/contracts-0.8/common/EpochManager.sol) introduced in Contract Release 12. cLabs is intended to run a bot to call the functions to trigger the epoch change and rewards distributions as soon as they are ready to do so, in a best-effort way. + +Epochs are now processed using multiple calls, as the gas consumption of the process involved uses is relatively high. + +Celo is no longer minted when processing the epoch, it is now transferred from the `CeloUnreleasedTreasury`. The contract `CeloUnreleasedTreasury` is allocated the full amount of unminted Celo at the time of the transition to L2. + +When "epoch duration" has elapsed since the current epoch started, the function `startNextEpochProcess` can be called. This function: + +1. Is permissionless, every EOA or contract can call it given that certain conditions are met: + 1. Enough time has elapsed after the beginning of the epoch. + 2. The epoch is not currently processing. +2. Updates target voting yield +3. Calculates epoch rewards (`EpochRewards.calculateTargetEpochRewards()`) +4. Allocates validator rewards: + 1. mints CELO and exchanges it to cUSD + 2. Sets an internal mapping with the allocation for each validator. Validators can later claim it calling `sendValidatorPayment` +5. Starts a block that prevents certain actions to be performed, notable lock Celo, unlock Celo and change validator locks. +6. Emits events: + 1. EpochRewards: `TargetVotingYieldUpdated(uint256 fraction)` + 2. CeloUnreleasedTreasury: `Released(address indexed to, uint256 amount)` + 3. cUSD: `Transfer(address indexed from, address indexed to, uint256 value)` + 4. EpochManager `EpochProcessingStarted(uint256 indexed epochNumber)` + +After `startNextEpochProcess` is called, the epoch can be fully finished by calling `finishNextEpochProcess` . This function: + +1. Is permissionless, every EOA or contract can call it given that certain conditions are met: + 1. `startNextEpochProcess` has been called before. +2. Distributes rewards to voters (Celo) +3. Elects validators (the result is stored as an array of accounts of the elected validators, signers are also stored for backwards compatibility purposes) +4. Unblocks all actions blocked in `startNextEpochProcess` . +5. Updates the Epoch state. +6. Emits events: + 1. Election: `EpochRewardsDistributedToVoters(address indexed group, uint256 value)` + 2. CeloUnreleasedTreasury: `Released(address indexed to, uint256 amount)` + 3. EpochManager: `EpochProcessingEnded(uint256 indexed epochNumber)` + +> In the unlikely case that `startNextEpochProcess` needs to use more gas than available in a block, the same result can be achieved using multiple calls to `processGroup` . + +### Scoring + +The rewards for a validator, its group and its voters were previously based on the score of the validator, and the downtime the validator. The score itsef was defined by the downtime the validator had over multiple epochs. + +The scoring is now managed by a contract called `ScoreManager`. This contract is a placeholder for a more complex implementation, meanwhile Governance and [a multisig](https://mondo.celo.org/governance/cgp-169) has the power to change the score of a validator. The score is now fully proportional to the rewards the validator and its voters will get at the end of the epoch. + +## Celo minting + +In the L1 Celo used to be minted using the well known `mint` function, that was using the `transfer` precompile under the hood. + +In the L2, the Celo in the L2 is a bridged token from the L1. At the moment of the transition the whole total supply of Celo (1 billion tokens) is allocated to the bridge contract in the L1. In the L2, all holders (contracts and EOAs) will remain with their balance in their account, but tokens that were previously unallocated in Celo as a L1 will now be allocated to a new contract called `CeloUnreleasedTreasury`. + +This comes with the implication that the `totalSuply()` function of the Celo Token (contract name `GoldToken`) will return 1 billion Celo after the L2 transition. + +This means that the Celo token is now an ERC20 on the Ethereum network, and the tokens available on the Celo chain are a bridged representation of the tokens in the L1. This is achieved by using the custom gas token functionality of the OP stack. + +## Governance Hotfix + +The hot fix mechanism has been changed from a consensus of validators to a security council multisig. The current setup will be available until the transition. + +## FeeCurrencyDirectory + +The contract `FeeCurrencyWhitelist` is now deprecated. Fee currencies are now stored in a new contract called `FeeCurrencyDirectory`. To add a new token to the directory, an address for an oracle needs to be provided, as well as the intrinsic gas for transactions paid with this token as fee. Changes can only be made by Celo Governance. + +The intrinsic gas is the amount of gas that it will be added to all transactions paying for fees with this token. It is meant to accurately represent the cost of the functions `debitGasFees`and `creditGasFees`, that were used to collect the fees involved while validating the transaction. + +## FeeHandler + +The [FeeHandler](https://github.com/celo-org/celo-proposals/blob/master/CIPs/cip-0052.md) was extended to support multiple beneficiaries. As it works in the L1 right now, only a carbon fund beneficiary and the burn fraction can be set. + +After Contract Release 12 is deployed, many beneficiaries can be set, and the burn fraction would be the reminding of all the allocations of the beneficiaries. + +## Slashing + +DowntimeSlasher and DoubleSigningSlasher will be deprecated after L2 transition, as the validators get replaced for RPC prividers. GovernanceSlasher will still be available and now supports removing members of a validator group and changing the slash multiplier. Governance slasher now supports to enable a multisig with the slasher role. + +## Deprecated contracts + +The following contracts have been deprecated: + +1. Attestations (withdraws still enabled). +2. FeeCurrencyWhitelist +3. GasPriceMinimum +4. BlockChainParameters +5. DowntimeSlasher +6. DoubleSigningSlasher +7. Random +8. UsingPrecompiles + +Deprecation means that they do not fulfill any purpose as a required primitive to run the chain. Deprecated contracts still remain on-chain, although their functions are supposed to revert with a [L2 check](https://github.com/celo-org/celo-monorepo/blob/release/core-contracts/12/packages/protocol/contracts-0.8/common/IsL2Check.sol). + +They still remain in the Celo Registry, but are scheduled for deletion after the L2 fully activates. + +Some functionality that was provided by precompiles (notably epoch number and elected validators) can be found in the EpochManager contract. + +Some contracts had function that exposed precompiles will begin to revert in L2, at least this contract still internally uses those functions. For more details, please refer to this [forum post](https://forum.celo.org/t/upcoming-changes-deprecation-of-celo-precompiles-and-usingprecompilescontract-functions-in-l2-migration/9421/2). + +### Deprecated Contract Methods with Replacements Table + +| Deprecated Contract Method | Replacement | +|--------|--------| +| BlockchainParams#getEpochNumberOfBlock | EpochManager#getEpochNumberOfBlock | +| BlockchainParams#getFirstBlockNumberForEpoch | EpochManager#getFirstBlockAtEpoch| +| FeeCurrencyWhitelist#getAddresses | FeeCurrencyDirectory#getAddresses | +| Election#getCurrentValidatorSigners | EpochManager#getElectedSigners | +| Election#getGroupEpochRewards | Election#getGroupEpochRewardsBasedOnScore | +| GovernanceSlasher#slash | GovernanceSlasher#slashL2 | +| Validators#registerValidator | Validators#registerValidatorNoBLS | + +## Precompiles deprecation + +On the L2, the `transfer` precompile is the only supported Celo-specific precompile. +Also, the `transfer` precompile can no longer mint Celo. There's an ongoing effort to push the transfer precompile upstream to the OP stack to guarantee full Superchain compatibility. + +All other Celo-specific precompiles are deprecated, so the L2 migration removes support for the following precompiles: + +- `fractionMulExp` +- `proofOfPossession` +- `getValidator` +- `numberValidators` +- `epochSize` +- `blockNumberFromHeader` +- `hashHeader` +- `getParentSealBitmap` +- `getVerifiedSealBitmap` + +## Transition + +Contracts for the L2 will be deployed before the transition, with Celo as L1. The contracts change behaviour automatically at the time of the transition. + +## Update March 24th 2025 + +Contract Release 12 has been [sucessfully deployed](https://mondo.celo.org/governance/cgp-166) to Celo Mainnet. diff --git a/specs/token-duality.mdx b/specs/token-duality.mdx new file mode 100644 index 000000000..d7b65f0d7 --- /dev/null +++ b/specs/token-duality.mdx @@ -0,0 +1,29 @@ +--- +title: "Token Duality" +--- + +## What is token duality? + +Token duality means that the CELO token is both the native currency of the Celo blockchain as well as an ERC20 compatible token. +This means CELO tokens can be moved both by doing a native transfer as well as ERC20 transfers and will show up in both in the native account balance and the ERC20 balance, no matter how they were transferred. In contrast to ETH/WETH, no token wrapping or unwrapping is necessary. + +## Implementation + +The native transfers and balances behave exactly as on Ethereum and are stored in the same way. The CELO contract reads native balances and triggers native transfers via its ERC20 interface. + +### Reading balances via ERC20 + +The ERC20 token does not store the balances in the contract storage, it uses the native balance as the source of truth. The `balanceOf` function just passes through the native balance. + +### Transfers via ERC20 + +Similarly, the ERC20 `transfer` and `transferFrom` functions do not change the contract storage, but initiate a native transfer instead. Since there is no way to trigger native transfers from within a contract in Ethereum, Celo adds a `transfer` precompile for this purpose. This precompile can only be called by the CELO token. + +### The `transfer` precompile + +The precompile directly manipulates the account balances in the EVM’s statedb. It checks the caller address to verify that it has been called by the CELO token. Since the [Jovian hardfork](/specs/upgrades/jovian), the `from` and `to` addresses get warmed (added to the access list) during precompil execution. Before Jovian, warmness stayed unchanged. + +Precompile address: `0xff - 2` == `253` +Parameters (abi-encoded): `address from, address to, uint256 value` +Gas costs: 9000 +No return value diff --git a/specs/transaction-fees.mdx b/specs/transaction-fees.mdx new file mode 100644 index 000000000..7532ae200 --- /dev/null +++ b/specs/transaction-fees.mdx @@ -0,0 +1,35 @@ +--- +title: "Transaction Fees" +--- + +## Overview + +While you can send transactions on Celo as you do on any Ethereum or OP-Stack chain, there are some key differences that are relevant if you want a deeper understanding: + +- **[Fee Abstraction](/specs/fee-abstraction)**, which allows users to pay for transaction fees in ERC20 tokens instead of CELO and is covered in its own chapter +- **[Zero L1 & Operator Fees](#zero-l1--operator-fees)**, meaning that the OP-Stack L1 & Operator fees are configured to always be zero, so that Celo chains don't incur any fees on top of the normal Ethereum transaction fees +- The **[base fee floor](#base-fee-floor)**, which sets a lower limit for a block's base fee +- The **[FeeHandler](#feehandler)** contract that decides what to do with the collected base fees + +## Zero L1 & Operator Fees + +OP-Stack supports charging transaction senders an [L1 data fee](https://docs.optimism.io/stack/transactions/fees#l1-data-fee), which is added on top of the normal transaction fees and can't be directly influenced or limited by the tx sender. The fee is meant to cover the cost of L1 transactions, especially for data availability. Since CELO uses EigenDA, the data availability costs are low and predictable, so that this mechanism is not needed. + +The L1 fees are configured to zero by setting the `gasPriceOracleBaseFeeScalar` and `gasPriceOracleBlobBaseFeeScalar` to zero, so that the L1 fee formula always returns zero. The `GasPriceOracle` will also correctly return zero as a result, so that you don't have to change your code if you are already relying on the `GasPriceOracle` due to supporting other OP-Stack chains. + +The [Isthmus](/specs/upgrades/isthmus) upgrade also introduces an [Operator fee](https://specs.optimism.io/protocol/isthmus/exec-engine.html#operatorfees), which is a configurable cost designed to price chain-specific resources such as Alt-DA storage or ZK proving. Celo disables this charge as well by setting both `operatorFeeScalar` and `operatorFeeConstant` to `0`. + +If you are coming from Ethereum, not having L1 data and operator fees is what you are used to, and you will feel right at home on Celo. + +## Base Fee Floor + +Celo follows the usual [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) rules to determine a block's base fee with on modification: The base fee can't fall below a certain limit, the base fee floor. This prevents the chain to be spammed with unimportant transactions that will make the chain state grow rapidly and make future scaling harder. The floor is set sufficiently low to still keep average transactions below 0.01 USD. + +The base fee floor is set in the `eip1559BaseFeeFloor` rollup configuration variable and is denominated in native CELO token. If Fee Abstraction is used to pay in other tokens, the base fee is converted to the token's value at the current exchange rate. + +## FeeHandler + +All base fees are sent to the FeeHandler contract, which is responsible for deciding what to eventually do with the fees. The final behavior for Celo L2 mainnet has not been confirmed yet (as of 2024-11-15). On Celo L1, the FeeHandler: + +- burns 80% of the fees (after converting non-CELO fees to CELO) +- sends 20% of the fees to carbon offsetting projects as part of the Ultragreen Money initiative. diff --git a/specs/transaction-types.mdx b/specs/transaction-types.mdx new file mode 100644 index 000000000..9f4f4c21c --- /dev/null +++ b/specs/transaction-types.mdx @@ -0,0 +1,48 @@ +--- +title: "Transaction Types On Celo L2" +sidebarTitle: "Transaction Types" +--- + +Different categories of transaction types are relevant to Celo. Some are inherited from Ethereum, others were added to support Celo's Fee Abstraction feature, and some older ones have been superseded and are no longer supported. When developing new applications, please use the tx types marked as "recommended" below. + +The [docs.celo.org page about tx types](/home/protocol/transactions/transaction-types) contains additional information on how to handle different tx types, their differences and tooling support. + +## Ethereum Compatible Tx Types + +To achieve its high level of Ethereum compatibility, Celo supports all Ethereum tx types relevant for an L2. The following transaction types can be used in exactly the same way as on Ethereum and don't require any changes to client libraries or other tooling. + +- [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) (recommended), type 2 +- [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930), type 1 +- [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702), type 4 (available post-Isthmus) +- Legacy Ethereum transaction as described in the [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf), type 0 + +The [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) tx type 3, which provides blobs for data availability on Ethereum, is not supported. + +## OP Stack Specific Tx Types + +OP Stack has deposited transactions, which are L2 transactions derived from L1 and included in an L2 block. Celo also utilizes this transaction type and introduces the following additional transaction type. + +- [Deposited transaction](https://specs.optimism.io/glossary.html#deposited-transaction), type 126 + +## Celo-Specific Tx Types + +The following tx type is an essential part of Celo's Fee Abstraction feature. For more details, read the CIP linked below, and the [Fee Abstraction section](/specs/fee-abstraction). + +- [CIP-64](https://github.com/celo-org/celo-proposals/blob/master/CIPs/cip-0064.md) (recommended), type 123 + +## Older, Unsupported Tx Types + +These tx types won't be accepted anymore, but transactions in blocks before the L2 migration can still contain transactions of these types. + +- [CIP-42](https://github.com/celo-org/celo-proposals/blob/master/CIPs/cip-0042.md), type 124 +- Legacy Celo transaction, type 0, but with different fields than the Ethereum legacy tx + +### Details on Celo Legacy Transactions + +For historic reasons, the Celo legacy txs are not prefixed with a tx type number, just like Ethereum legacy txs. To tell these two legacy tx types apart, you have to look at the tx content, which contains additional `feeCurrency`, `gatewayFeeRecipient`, and `gatewayFee` fields for Celo legacy txs: + +```text +RLP([nonce, gasPrice, gasLimit, feeCurrency, gatewayFeeRecipient, gatewayFee, recipient, amount, data, v, r, s]) +``` + +There is no CIP number for this tx type because it was included in version 1 of the Celo blockchain and CIPs only describe changes introduced after that point in time. diff --git a/specs/upgrades/ice-cream.mdx b/specs/upgrades/ice-cream.mdx new file mode 100644 index 000000000..7b6cb3ead --- /dev/null +++ b/specs/upgrades/ice-cream.mdx @@ -0,0 +1,29 @@ +--- +title: "Ice Cream Upgrade" +sidebarTitle: "Ice Cream" +--- + +## Overview + +The Ice Cream upgrade for the Celo network upgrades the DA layer to use EigenDA v2, also known as Blazar, to further innovate and strengthen the network’s data availability layer. + +Blazar represents a major architectural upgrade to the EigenDA protocol, introducing improved system throughput and stability, alongside new capabilities like permissionless DA payments and enhanced resource throttling. + +Most notably for Celo: + +- End-to-end confirmation latency is significantly reduced, moving from minutes to near real-time. Blazar’s design enables rollups to reference blocks in their own logic without waiting for L1 confirmations. +- System throughput and network stability are greatly improved through more efficient chunk distribution, optimized request routing, and horizontal scalability of DA nodes. Support for decentralized dispersal is unlocked by eliminating DDoS attack surfaces inherent in the original push-based mode. + +## Specifications + +After the Celo Ice Cream update, the Celo sequencer will use EigenDA v2 for distributing transaction data. Therefore, any node following the network must upgrade it's EigenDA proxy to a version compatible with EigenDA v2. For more details see the [Upgrade notice](/infra-partners/notices/archive/eigenda-v2-upgrade). + +## Upgrade Timelines + +The Ice Cream upgrade is scheduled for activation on the Mainnet, Alfajores, and Baklava, with the activation process for each network occurring independently. As this upgrade is activated on the sequencer, no detailed activation times can be given. + +| Network | Date & Time (UTC) | +| --------- | :----------------------: | +| Mainnet | Wed Sep 10 2025 15:00:00 | +| Alfajores | Wed Aug 20 2025 15:00:00 | +| Baklava | Wed Jul 30 2025 15:00:00 | diff --git a/specs/upgrades/isthmus.mdx b/specs/upgrades/isthmus.mdx new file mode 100644 index 000000000..b9202a5c6 --- /dev/null +++ b/specs/upgrades/isthmus.mdx @@ -0,0 +1,53 @@ +--- +title: "Isthmus Upgrade" +sidebarTitle: "Isthmus" +--- + +## Overview + +The Isthmus upgrade for the Celo network adopts features from the **Holocene** and **Isthmus** upgrades of Optimism, incorporating important improvements. + +This upgrade aligns Celo architecture closely with the Optimism ecosystem, bringing established and tested improvements to our network. + +## Specifications + +The Celo Isthmus upgrade brings in all consensus and execution changes from Optimism’s Holocene and Isthmus hardforks. For full technical details, see the Optimism specs linked below. + +- [Optimism's Holocene Upgrade Specifications](https://specs.optimism.io/protocol/holocene/overview.html) +- [Optimism's Isthmus Upgrade Specifications](https://specs.optimism.io/protocol/isthmus/overview.html) + +### Holocene Highlights + +- Upgraded derivation pipeline – A stricter, simpler derivation pipeline enhances the Fault Proof System's worst-case behaviour and compatibility. +- EIP-1559 configurability - The `SystemConfig` L1 contract lets operators adjust the elasticity and denominator parameters, so the gas target and gas limit can be tuned independently. + +### Isthmus Highlights + +Isthmus incorporates the execution-layer EIPs from Ethereum’s Prague upgrade, along with several Optimism-specific enhancements. + +#### Ethereum Prague's EIPs + +- [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702): Allows an EOA to function as a smart-contract wallet for a single transaction. +- [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537): Adds operations on BLS12-381 curve as a precompile. +- [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935): Introduces a system contract that stores the last 8,191 block hashes. +- [EIP-7623](https://eips.ethereum.org/EIPS/eip-7623): Increases the calldata gas cost, making calldata-intensive transactions more expensive. +- [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685): Extends the block header with a 32-byte `requests_hash` commitment for conveying execution-layer requests to the consensus layer. **In Celo, this field is always `sha256("")`.** + +> **Note:** Although **EIP-6110**, **EIP-7002**, and **EIP-7251** exist in the execution-layer codebase, they remain **disabled** in the Isthmus upgrade. + +#### Optimism-Specific Improvements + +- Updated `withdrawalsRoot`: The `withdrawalsRoot` in block header points to the storage root of `L2ToL1MessagePasser`, simplifying proof generation. +- Operator Fee: A flexible surcharge that can be tuned to cover chain-specific costs such as Alt-DA storage, ZK proving, or custom gas-token overhead. **In Celo, as with the L1 data fee, the Operator Fee is set to zero by setting `operatorFeeScalar` and `operatorFeeConstant` in `SystemConfig` contract to 0.** + +## Upgrade Timelines + +The Isthmus upgrade is scheduled for activation on the Mainnet, Alfajores, and Baklava, with the activation process for each network occurring independently. + +The table below shows the UNIX timestamp at which the Isthmus upgrade is set to activate for each network, the accompanying UTC date and time, and the approximate L2 block height. + +| Network | Unix Timestamp | Date & Time (UTC) | Block Height | +| --------- | :------------: | :----------------------: | -----------: | +| Mainnet | 1752073200 | Wed Jul 09 2025 15:00:00 | ~ 40,172,440 | +| Alfajores | 1750863600 | Wed Jun 25 2025 15:00:00 | ~ 49,908,280 | +| Baklava | 1749654000 | Wed Jun 11 2025 15:00:00 | ~ 37,881,140 | diff --git a/specs/upgrades/jello.mdx b/specs/upgrades/jello.mdx new file mode 100644 index 000000000..1c9ad9e8d --- /dev/null +++ b/specs/upgrades/jello.mdx @@ -0,0 +1,27 @@ +--- +title: "Jello Upgrade" +sidebarTitle: "Jello" +--- + +## Overview + +The Jello upgrade for the Celo network enables OP Succinct Lite, a production-ready, zero-knowledge-powered fault proof system built in collaboration with OP Labs and Succinct. + +## Specifications + +### L1 Contract changes + +The Jello upgrade included L1 contract changes. They have been been accepted by governance in [CGP-265](https://mondo.celo.org/governance/265) and executed by the Celo Security Council. + +### Execution Layer changes + +There's no execution layer changes in the Jello upgrade. + +## Upgrade Timelines + +The Jello upgrade activated on Mainnet and Celo Sepolia, with the activation process for each network occurring independently. + +| Network | Date & Time (UTC) | Upgrade transaction | +| ------------ | ------------------------- | ------------------- | +| Celo Sepolia | Wed, Nov 05 2025 11:16:00 |[`0x736deb757f4708eeafecc961f36e14f3711c1d9f944e45c933b666329743b31a`](https://eth-sepolia.blockscout.com/tx/0x736deb757f4708eeafecc961f36e14f3711c1d9f944e45c933b666329743b31a) | +| Mainnet | Wed, Dec 10 2025 10:24:22 |[`0x5fb3f2225dd2ba91efe941d4c9151df120ab06f6611b7b494bdecc96ff84c44b`](https://eth.blockscout.com/tx/0x5fb3f2225dd2ba91efe941d4c9151df120ab06f6611b7b494bdecc96ff84c44b) | diff --git a/specs/upgrades/jovian.mdx b/specs/upgrades/jovian.mdx new file mode 100644 index 000000000..8aed4383a --- /dev/null +++ b/specs/upgrades/jovian.mdx @@ -0,0 +1,51 @@ +--- +title: "Jovian Upgrade" +sidebarTitle: "Jovian" +--- + + +The Celo Jovian hardfork is still being worked on. This information is preliminary. + + +## Overview + +The Jovian upgrade for the Celo network adopts features from Optimism's Jovian hardfork, along with Celo-specific improvements to the transfer precompile and gas pricing mechanism. + +## Specifications + +The Celo Jovian upgrade brings in consensus and execution changes from Optimism's Jovian hardfork. For full technical details, see the Optimism documentation linked below. + +- [Optimism's Jovian Upgrade Notice](https://docs.optimism.io/notices/archive/upgrade-17) + +### Optimism Jovian Features + +- **Cannon Go 1.24 Support**: The on-chain fault proof virtual machine implementation is upgraded to support Go 1.24. +- **Configurable Minimum Base Fee**: Allows chain operators to specify a minimum base fee to shorten the length of priority fee auctions (disabled by default). +- **Data Availability Footprint Block Limit**: An in-protocol limit on estimated DA usage prevents spam and priority fee auctions. The `blobGasUsed` property now stores DA footprint values instead of remaining zero. **Celo does not make use of this feature.** + +### Celo-Specific Changes + +#### Transfer Precompile Address Warming + +The [transfer precompile](/specs/token-duality) now warms the `from` and `to` addresses during execution. This aligns with standard EVM behavior where address accesses during value transfers are warmed, ensuring correct gas accounting for subsequent operations on the same address. + +Related implementation: +- [op-geth #433](https://github.com/celo-org/op-geth/pull/433) +- [op-geth #435](https://github.com/celo-org/op-geth/pull/435) (tracing improvements) +- [celo-kona #115](https://github.com/celo-org/celo-kona/pull/115) + +#### Minimum Base Fee + +Celo transitions from its Celo-specific gas price floor mechanism to Optimism's Minimum Base Fee. This aligns Celo's gas pricing with the OP Stack standard while maintaining the ability to set a floor on transaction costs. + +Related implementation: +- [op-geth #445](https://github.com/celo-org/op-geth/pull/445) + +## Upgrade Timelines + +The Jovian upgrade is scheduled for activation on the Mainnet, Alfajores, and Baklava, with the activation process for each network occurring independently. + +| Network | Unix Timestamp | Date & Time (UTC) | Block Height | +| ------------ | -------------: | ----------------: | -----------: | +| Mainnet | TBD | Q1 2026 | TBD | +| Celo Sepolia | TBD | Q1 2026 | TBD | From 08d229d3f797084d3631d97846f96ef5bbe0071b Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Tue, 21 Jul 2026 11:58:03 +0200 Subject: [PATCH 02/11] docs: point specs.celo.org links at the migrated /specs pages Rewrites the 24 links in live sections to internal paths. The defunct core_contracts.html links now target /tooling/contracts/core-contracts. References in _deprecated/ are left untouched. --- build-on-celo/index.mdx | 2 +- build-on-celo/support.mdx | 2 +- .../community-rpc-nodes/penalties.mdx | 6 +++--- home/protocol/epoch-rewards/index.mdx | 2 +- .../notices/archive/celo-sepolia-launch.mdx | 2 +- infra-partners/notices/archive/jovian-upgrade.mdx | 2 +- legacy/faq.mdx | 14 +++++++------- legacy/overview.mdx | 2 +- legacy/transition/optimism/op-l2.mdx | 4 ++-- legacy/transition/whats-changed/l1-l2.mdx | 12 ++++++------ 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/build-on-celo/index.mdx b/build-on-celo/index.mdx index 0bb237423..55f90cc1a 100644 --- a/build-on-celo/index.mdx +++ b/build-on-celo/index.mdx @@ -69,7 +69,7 @@ Following a successful Baklava upgrade, the Celo L2 Mainnet officially went live ## Useful Links -* [Layer 2 Specification](https://specs.celo.org/root.html) +* [Layer 2 Specification](/specs) * [Node Operator Guide](/infra-partners/operators/overview) * [What's Changed?](/legacy/overview) * [Cel2 Code](https://github.com/celo-org/optimism) diff --git a/build-on-celo/support.mdx b/build-on-celo/support.mdx index 70bab861f..677c1eaa4 100644 --- a/build-on-celo/support.mdx +++ b/build-on-celo/support.mdx @@ -25,6 +25,6 @@ For the latest updates, sign up for the [DevDesk Mailing List](http ## Additional Resources -- [Celo specification](https://specs.celo.org/) +- [Celo specification](/specs) - [Transaction types on Celo](https://github.com/celo-org/txtypes) - [Celo Forum](https://forum.celo.org/) diff --git a/contribute-to-celo/community-rpc-nodes/penalties.mdx b/contribute-to-celo/community-rpc-nodes/penalties.mdx index 1ec4d375b..5e960629a 100644 --- a/contribute-to-celo/community-rpc-nodes/penalties.mdx +++ b/contribute-to-celo/community-rpc-nodes/penalties.mdx @@ -53,6 +53,6 @@ Providers with uptime below 20% for 7 days are slashed. ### References in the Specification -- [Overview of rewards and epochs in L2](https://specs.celo.org/smart_contract_updates_from_l1.html#overview-of-rewards-and-epochs-in-l2) -- [Scoring](https://specs.celo.org/smart_contract_updates_from_l1.html#scoring) -- [Slashing](https://specs.celo.org/smart_contract_updates_from_l1.html#slashing) \ No newline at end of file +- [Overview of rewards and epochs in L2](/specs/smart-contract-updates-from-l1#overview-of-rewards-and-epochs-in-l2) +- [Scoring](/specs/smart-contract-updates-from-l1#scoring) +- [Slashing](/specs/smart-contract-updates-from-l1#slashing) \ No newline at end of file diff --git a/home/protocol/epoch-rewards/index.mdx b/home/protocol/epoch-rewards/index.mdx index 1ba7e6b85..a54527e81 100644 --- a/home/protocol/epoch-rewards/index.mdx +++ b/home/protocol/epoch-rewards/index.mdx @@ -34,7 +34,7 @@ A total of **400 million CELO** will be released through epoch rewards over time For details on how epoch rewards worked when Celo was a Layer 1 blockchain, see [the historical epoch rewards section](/legacy/protocol/pos/epoch-rewards). -For technical changes since the L1 to L2 migration, refer to the [official specs](https://specs.celo.org/smart_contract_updates_from_l1.html#epochs-and-rewards). +For technical changes since the L1 to L2 migration, refer to the [official specs](/specs/smart-contract-updates-from-l1#epochs-and-rewards). ## Epoch Duration and Processing diff --git a/infra-partners/notices/archive/celo-sepolia-launch.mdx b/infra-partners/notices/archive/celo-sepolia-launch.mdx index dc3fd408b..b25a506fd 100644 --- a/infra-partners/notices/archive/celo-sepolia-launch.mdx +++ b/infra-partners/notices/archive/celo-sepolia-launch.mdx @@ -54,7 +54,7 @@ Since Celo Sepolia starts with a clean slate, there is no historical data or con - Chain ID: 11142220 - L1 Foundation: Ethereum Sepolia - EigenDA: v2 (Blazar) -- Contracts: [see the L1 and L2 contracts in the specification](https://specs.celo.org/core_contracts.html?#celo-sepolia-testnet) +- Contracts: [see the L1 and L2 contracts in the specification](/tooling/contracts/core-contracts#celo-sepolia-testnet) - RPC endpoint: [Celo Sepolia Forno](https://forno.celo-sepolia.celo-testnet.org) - Block explorer: [Blockscout](https://celo-sepolia.blockscout.com) - Faucets: diff --git a/infra-partners/notices/archive/jovian-upgrade.mdx b/infra-partners/notices/archive/jovian-upgrade.mdx index a8e8f689a..d550f8811 100644 --- a/infra-partners/notices/archive/jovian-upgrade.mdx +++ b/infra-partners/notices/archive/jovian-upgrade.mdx @@ -21,7 +21,7 @@ Key changes include: - **Transfer Precompile Address Warming**: The transfer precompile now warms `from` and `to` addresses during execution, aligning with standard EVM behavior and ensuring correct gas accounting for subsequent operations on the same address. - **Minimum Base Fee Transition**: Celo moves from its own gas price floor mechanism to Optimism's configurable Minimum Base Fee standard, maintaining a cost floor while aligning with OP Stack conventions. -For the full technical specification, see the [Jovian upgrade spec](https://specs.celo.org/upgrades/jovian.html). +For the full technical specification, see the [Jovian upgrade spec](/specs/upgrades/jovian). - **L1 Fusaka Upgrade**: Celo now includes improvements to handle the L1 Fusaka upgrade, leading to better compatibility with the Optimism stack. For more details see [OP Fusaka upgrade notice](https://docs.optimism.io/notices/archive/fusaka-notice). - **EigenDA upgrade**: The EigenDA proxy is upgraded to a recent version which improves the trustless integration and allows switching to the latest EigenDA protocol version. diff --git a/legacy/faq.mdx b/legacy/faq.mdx index 78dbc4fc6..9959d7f25 100644 --- a/legacy/faq.mdx +++ b/legacy/faq.mdx @@ -42,7 +42,7 @@ Yes, same as with Ethereum. -Have a look at the [changes from L1 to L2 in the specs](https://specs.celo.org/l2_migration.html#changes-for-json-rpc-users). +Have a look at the [changes from L1 to L2 in the specs](/specs/l2-migration#changes-for-json-rpc-users). @@ -61,20 +61,20 @@ There are multiple options. -[Governance](/home/protocol/governance/overview) remains a pillar of the Celo blockchain. The Validator Hotfix process has been adapted, see [Updated Governance Hotfix](https://specs.celo.org/l2_migration.html#updated-governance-hotfix) for the changes. +[Governance](/home/protocol/governance/overview) remains a pillar of the Celo blockchain. The Validator Hotfix process has been adapted, see [Updated Governance Hotfix](/specs/l2-migration#updated-governance-hotfix) for the changes. -* CELO token duality? Supported, see [Token Duality](https://specs.celo.org/token_duality.html). -* Fee currencies? Supported, see [Fee Abstraction](https://specs.celo.org/fee_abstraction.html). -* Epoch rewards? Epochs now work differently, but rewards stay, see [Epochs and Rewards](https://specs.celo.org/smart_contract_updates_from_l1.html#epochs-and-rewards). +* CELO token duality? Supported, see [Token Duality](/specs/token-duality). +* Fee currencies? Supported, see [Fee Abstraction](/specs/fee-abstraction). +* Epoch rewards? Epochs now work differently, but rewards stay, see [Epochs and Rewards](/specs/smart-contract-updates-from-l1#epochs-and-rewards). See [What's Changed Optimism -> Celo L2](/legacy/transition/optimism/op-l2). -Also see [Celo L2 Specification](https://specs.celo.org/root.html) for greater detail. +Also see [Celo L2 Specification](/specs) for greater detail. @@ -94,7 +94,7 @@ The gas limit per block is 30 million, so the maximum throughput is 30M gas/s. -See [What's Changed Celo L1 -> L2](/legacy/transition/whats-changed/l1-l2) and [L1 -> L2 Migration Changes](https://specs.celo.org/l2_migration.html) in the spec for greater detail. +See [What's Changed Celo L1 -> L2](/legacy/transition/whats-changed/l1-l2) and [L1 -> L2 Migration Changes](/specs/l2-migration) in the spec for greater detail. diff --git a/legacy/overview.mdx b/legacy/overview.mdx index e7b40fe36..b50aac774 100644 --- a/legacy/overview.mdx +++ b/legacy/overview.mdx @@ -33,4 +33,4 @@ The table below summarizes the technical changes involved in transitioning from | **Transactions** | — | Deprecated transactions include Type 0 with feeCurrency field and Type 124. | | **Finality** | One block finality, instantaneous once block is produced. | Finality depends on trust in sequencer, batcher, proposer, and eigenDA, or ultimately on Ethereum. | -For more detailed technical changes, see [Celo's L2 Migration Documentation](https://specs.celo.org/l2_migration.html). \ No newline at end of file +For more detailed technical changes, see [Celo's L2 Migration Documentation](/specs/l2-migration). \ No newline at end of file diff --git a/legacy/transition/optimism/op-l2.mdx b/legacy/transition/optimism/op-l2.mdx index 8b63d7118..73cc1d074 100644 --- a/legacy/transition/optimism/op-l2.mdx +++ b/legacy/transition/optimism/op-l2.mdx @@ -12,7 +12,7 @@ The native token is CELO as opposed to ETH. The native token is also an ERC20 to ## New transaction type -Type 123 (`0x7b`) transaction type allows paying for gas in currencies other than the native asset (CELO). It has an additional field `feeCurrency` which allows the sender to choose the gas currency. See [here](https://specs.celo.org/fee_abstraction.html) for details on using fee currencies. +Type 123 (`0x7b`) transaction type allows paying for gas in currencies other than the native asset (CELO). It has an additional field `feeCurrency` which allows the sender to choose the gas currency. See [here](/specs/fee-abstraction) for details on using fee currencies. The fee currencies available at Mainnet launch will be: @@ -25,7 +25,7 @@ The fee currencies available at Mainnet launch will be: - Celo Euro (cEUR) - Celo Brazilian Real (cREAL) -More details on supported transaction types [here](https://specs.celo.org/tx_types.html). +More details on supported transaction types [here](/specs/transaction-types). ## L1 fees diff --git a/legacy/transition/whats-changed/l1-l2.mdx b/legacy/transition/whats-changed/l1-l2.mdx index ec69c796c..ee5f4db17 100644 --- a/legacy/transition/whats-changed/l1-l2.mdx +++ b/legacy/transition/whats-changed/l1-l2.mdx @@ -13,7 +13,7 @@ Sending these transaction types is no longer be supported, however you can still - **Type 0 (`0x0`) _Celo_ legacy transaction**. These are type 0 transactions that had some combination of the following fields set ("feeCurrency", "gatewayFee", "gatewayFeeRecipient") and "ethCompatible" set to false. - **Type 124 (`0x7c`) Celo dynamic fee transaction**. -More details on supported transaction types [here](https://specs.celo.org/tx_types.html). +More details on supported transaction types [here](/specs/transaction-types). ## Native bridge to Ethereum @@ -34,15 +34,15 @@ The amount of rewards to be distributed has not been decided. However, rewards w ## Hardforks -See [here](https://specs.celo.org/l2_migration.html#changes-for-contracts-developers) for the list of hardforks that will be enabled in the first block of the L2. +See [here](/specs/l2-migration#changes-for-contracts-developers) for the list of hardforks that will be enabled in the first block of the L2. ## Precompiled contracts -All Celo specific precompiles have been removed except for the transfer precompile which supports Celo [token duality](https://specs.celo.org/token_duality.html) (the native asset CELO is also an ERC20 token) +All Celo specific precompiles have been removed except for the transfer precompile which supports Celo [token duality](/specs/token-duality) (the native asset CELO is also an ERC20 token) ## Randomness -The random contract has been removed. If randomness is needed then the PREVRANDAO opcode can be used. See [here](https://specs.celo.org/l2_migration.html#deactivated-random-contract) for more details. +The random contract has been removed. If randomness is needed then the PREVRANDAO opcode can be used. See [here](/specs/l2-migration#deactivated-random-contract) for more details. ## Blocks @@ -69,7 +69,7 @@ Note this results in a 300% increase in gas per second due to the shortened bloc Previously our implementation used a smart contract [(here)](https://github.com/celo-org/celo-monorepo/blob/faca88f6a48cc7c8e6104393e49ddf7c2d7d20e3/packages/protocol/contracts-0.8/common/GasPriceMinimum.sol#L162) to calculate the base fee which allowed for governable parameters. Now we use the standard EIP1559 algorithm with the parameter values being defined in the chain config. -For chain specific parameters see the [deployment information in the Celo specs](https://specs.celo.org/deployments.html). +For chain specific parameters see the [deployment information in the Celo specs](/specs/deployments). ## RPC API @@ -79,7 +79,7 @@ Old blocks, transactions, receipts and logs are still be accessible via the RPC In general the changes involve additional extra unset fields that have been added upstream but were not present on historical Celo L1 objects, and the removal of some unnecessarily set fields on Celo L1 objects. -For in depth details of what has changed see [here](https://specs.celo.org/l2_migration.html). +For in depth details of what has changed see [here](/specs/l2-migration). ### Block receipts From 46fd72ead34e3481af0163f1fcf6662b0d8d61c4 Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Tue, 21 Jul 2026 12:04:17 +0200 Subject: [PATCH 03/11] docs: fold Specs intro page into the main group Removes the one-page Introduction group that duplicated the page label in the sidebar. --- docs.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docs.json b/docs.json index 72518420b..26ebe5b97 100644 --- a/docs.json +++ b/docs.json @@ -459,15 +459,10 @@ { "tab": "Specs", "groups": [ - { - "group": "Introduction", - "pages": [ - "specs/index" - ] - }, { "group": "Specs", "pages": [ + "specs/index", { "group": "Deployments", "pages": [ From 0b23db0ab2f7ca2b76f25126e6c2874c7c95fbd5 Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Tue, 21 Jul 2026 12:06:37 +0200 Subject: [PATCH 04/11] docs: rename Specs sidebar group, promote Protocol Upgrades to section --- docs.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs.json b/docs.json index 26ebe5b97..4bb492fe2 100644 --- a/docs.json +++ b/docs.json @@ -460,7 +460,7 @@ "tab": "Specs", "groups": [ { - "group": "Specs", + "group": "Specification", "pages": [ "specs/index", { @@ -476,21 +476,21 @@ "specs/transaction-types", "specs/native-bridge", "specs/eigenda", - "specs/finality", + "specs/finality" + ] + }, + { + "group": "Protocol Upgrades", + "pages": [ + "specs/upgrades/jovian", + "specs/upgrades/jello", + "specs/upgrades/ice-cream", + "specs/upgrades/isthmus", { - "group": "Protocol Upgrades", + "group": "L2 Migration", "pages": [ - "specs/upgrades/jovian", - "specs/upgrades/jello", - "specs/upgrades/ice-cream", - "specs/upgrades/isthmus", - { - "group": "L2 Migration", - "pages": [ - "specs/l2-migration", - "specs/smart-contract-updates-from-l1" - ] - } + "specs/l2-migration", + "specs/smart-contract-updates-from-l1" ] } ] From ac6c52c19afe4906d0ccf3aa232c5561932d07c2 Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Tue, 21 Jul 2026 12:07:23 +0200 Subject: [PATCH 05/11] docs: drop redundant Celo Docs pointer from specs intro --- specs/index.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/specs/index.mdx b/specs/index.mdx index 3bdbf7de1..99090eb2d 100644 --- a/specs/index.mdx +++ b/specs/index.mdx @@ -5,8 +5,6 @@ sidebarTitle: "Introduction" This document describes the differences between the Celo L2 implementation and [Optimism's](https://optimism.io) OP Stack, on which it is based. Refer to the [OP Stack specs](https://specs.optimism.io/) for details on the unmodified OP Stack. -For more general information about the Celo blockchain visit the [Celo Docs](/home/celo). - The [L1→L2 migration changes page](/specs/l2-migration) details the differences compared to the Celo L1 blockchain. The Celo L2 is a continuation of the L1 by using its state and providing a high level of compatibility with it. ## Background From e33a5df1796d086e4958d3d2146c7d4141fa4011 Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Tue, 21 Jul 2026 12:09:12 +0200 Subject: [PATCH 06/11] docs: move specs redirect next to other infra-partners entries --- docs.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs.json b/docs.json index 4bb492fe2..337751a85 100644 --- a/docs.json +++ b/docs.json @@ -701,10 +701,6 @@ "dark": "/images/CeloDocs_LogoDark.svg" }, "redirects": [ - { - "source": "/infra-partners/specs", - "destination": "/specs" - }, { "source": "/blog/2022/01/08/valora-wc-v1", "destination": "/" @@ -2905,6 +2901,10 @@ "source": "/infra-partners/notices/l2-migration", "destination": "/infra-partners/notices/archive/l2-migration" }, + { + "source": "/infra-partners/specs", + "destination": "/specs" + }, { "source": "/cel2/operators/architecture", "destination": "/infra-partners/operators/architecture" From d4143490e18d5a43382dcbd0760ddb5d1f32e7b8 Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Tue, 21 Jul 2026 12:13:10 +0200 Subject: [PATCH 07/11] docs: fix dangling EpochManager reference link from spec source --- specs/l2-migration.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/l2-migration.mdx b/specs/l2-migration.mdx index 47c22ef6a..2bdaa0856 100644 --- a/specs/l2-migration.mdx +++ b/specs/l2-migration.mdx @@ -41,7 +41,7 @@ This means that the geth client is no longer responsible for processing epochs. Any contract supporting the use of precompiles will now revert on Celo as a L2. This includes the `UsingPrecompiles` contract. More details [here](https://github.com/celo-org/celo-monorepo/blob/release/core-contracts/12/packages/protocol/contracts/common/UsingPrecompiles.sol) -To keep costs of processing epochs low, only the following key functions (used for querying the current epoch or elected validators) have been ported over to the [EpochManager] contract. +To keep costs of processing epochs low, only the following key functions (used for querying the current epoch or elected validators) have been ported over to the `EpochManager` contract. - `getEpochNumberOfBlock(uint256)` - `getEpochNumber()` From 25a9f5f0ed78732874fe93f7590fe9222040bca3 Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Tue, 21 Jul 2026 12:16:54 +0200 Subject: [PATCH 08/11] docs: update stale wording in migrated spec pages The March 2025 L2 migration is described in past tense, the completed Ice Cream and Isthmus activations likewise, and the upcoming Jovian upgrade now targets Mainnet and Celo Sepolia as its own timeline table already says (Alfajores and Baklava are deprecated). --- specs/deployments.mdx | 2 +- specs/l1-smart-contract-verification.mdx | 2 +- specs/upgrades/ice-cream.mdx | 2 +- specs/upgrades/isthmus.mdx | 4 ++-- specs/upgrades/jovian.mdx | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/specs/deployments.mdx b/specs/deployments.mdx index 8263b39a1..190878b4d 100644 --- a/specs/deployments.mdx +++ b/specs/deployments.mdx @@ -4,7 +4,7 @@ title: "Deployments" ## Mainnet -Celo Mainnet will be migrated to an L2 on March 26, 2025, around 3:00 AM UTC. The migration is scheduled for block *31056500*. For this L1 chain will be stopped at a block height of *31056499*. At this point the existing state will migrated to work with the L2 nodes. The migration process preserves the full L1 history while updating it to work with the Celo L2 stack. More technical details are available in the [migration docs](/specs/l2-migration). +Celo Mainnet was migrated to an L2 on March 26, 2025, around 3:00 AM UTC, at block *31056500*. For this, the L1 chain was stopped at a block height of *31056499* and the existing state was migrated to work with the L2 nodes. The migration process preserved the full L1 history while updating it to work with the Celo L2 stack. More technical details are available in the [migration docs](/specs/l2-migration). The Celo L2 network has the following chain properties: diff --git a/specs/l1-smart-contract-verification.mdx b/specs/l1-smart-contract-verification.mdx index 59c9898e9..7bb4f5ba7 100644 --- a/specs/l1-smart-contract-verification.mdx +++ b/specs/l1-smart-contract-verification.mdx @@ -3,7 +3,7 @@ title: "L1 Deploy Verification" sidebarTitle: "L1 Contracts Verification" --- -This guide walks through verifying Celo L1 (Ethereum) smart contracts deployment. It contains steps to verify contracts in the `packages/contracts-bedrock` folder. L2 (Celo) contracts will be available after the [transition](https://x.com/cLabs/status/1900625559090328062). +This guide walks through verifying Celo L1 (Ethereum) smart contracts deployment. It contains steps to verify contracts in the `packages/contracts-bedrock` folder. L2 (Celo) contracts became available with the [transition](https://x.com/cLabs/status/1900625559090328062). ## 1. Prerequisites diff --git a/specs/upgrades/ice-cream.mdx b/specs/upgrades/ice-cream.mdx index 7b6cb3ead..81c9e6234 100644 --- a/specs/upgrades/ice-cream.mdx +++ b/specs/upgrades/ice-cream.mdx @@ -20,7 +20,7 @@ After the Celo Ice Cream update, the Celo sequencer will use EigenDA v2 for dist ## Upgrade Timelines -The Ice Cream upgrade is scheduled for activation on the Mainnet, Alfajores, and Baklava, with the activation process for each network occurring independently. As this upgrade is activated on the sequencer, no detailed activation times can be given. +The Ice Cream upgrade was activated on Mainnet, Alfajores, and Baklava, with the activation process for each network occurring independently. As this upgrade was activated on the sequencer, no detailed activation times can be given. | Network | Date & Time (UTC) | | --------- | :----------------------: | diff --git a/specs/upgrades/isthmus.mdx b/specs/upgrades/isthmus.mdx index b9202a5c6..d1e0a6724 100644 --- a/specs/upgrades/isthmus.mdx +++ b/specs/upgrades/isthmus.mdx @@ -42,9 +42,9 @@ Isthmus incorporates the execution-layer EIPs from Ethereum’s Prague upgrade, ## Upgrade Timelines -The Isthmus upgrade is scheduled for activation on the Mainnet, Alfajores, and Baklava, with the activation process for each network occurring independently. +The Isthmus upgrade was activated on Mainnet, Alfajores, and Baklava, with the activation process for each network occurring independently. -The table below shows the UNIX timestamp at which the Isthmus upgrade is set to activate for each network, the accompanying UTC date and time, and the approximate L2 block height. +The table below shows the UNIX timestamp at which the Isthmus upgrade activated for each network, the accompanying UTC date and time, and the approximate L2 block height. | Network | Unix Timestamp | Date & Time (UTC) | Block Height | | --------- | :------------: | :----------------------: | -----------: | diff --git a/specs/upgrades/jovian.mdx b/specs/upgrades/jovian.mdx index 8aed4383a..919fcb8cb 100644 --- a/specs/upgrades/jovian.mdx +++ b/specs/upgrades/jovian.mdx @@ -43,7 +43,7 @@ Related implementation: ## Upgrade Timelines -The Jovian upgrade is scheduled for activation on the Mainnet, Alfajores, and Baklava, with the activation process for each network occurring independently. +The Jovian upgrade is scheduled for activation on Mainnet and Celo Sepolia, with the activation process for each network occurring independently. | Network | Unix Timestamp | Date & Time (UTC) | Block Height | | ------------ | -------------: | ----------------: | -----------: | From d902b74b98199fbd7761c2e9bff03fac4f455ba6 Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Tue, 28 Jul 2026 15:45:15 +0200 Subject: [PATCH 09/11] docs: record Jovian activation times in the spec Jovian activated on Celo Sepolia and Mainnet in March 2026; the timestamps come from infra-partners/notices/archive/jovian-upgrade. Block heights are not published for this upgrade, so the column is dropped. --- specs/upgrades/jovian.mdx | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/specs/upgrades/jovian.mdx b/specs/upgrades/jovian.mdx index 919fcb8cb..047380805 100644 --- a/specs/upgrades/jovian.mdx +++ b/specs/upgrades/jovian.mdx @@ -3,10 +3,6 @@ title: "Jovian Upgrade" sidebarTitle: "Jovian" --- - -The Celo Jovian hardfork is still being worked on. This information is preliminary. - - ## Overview The Jovian upgrade for the Celo network adopts features from Optimism's Jovian hardfork, along with Celo-specific improvements to the transfer precompile and gas pricing mechanism. @@ -43,9 +39,11 @@ Related implementation: ## Upgrade Timelines -The Jovian upgrade is scheduled for activation on Mainnet and Celo Sepolia, with the activation process for each network occurring independently. +The Jovian upgrade was activated on Mainnet and Celo Sepolia, with the activation process for each network occurring independently. + +The table below shows the UNIX timestamp at which the Jovian upgrade activated for each network, along with the accompanying UTC date and time. -| Network | Unix Timestamp | Date & Time (UTC) | Block Height | -| ------------ | -------------: | ----------------: | -----------: | -| Mainnet | TBD | Q1 2026 | TBD | -| Celo Sepolia | TBD | Q1 2026 | TBD | +| Network | Unix Timestamp | Date & Time (UTC) | +| ------------ | :------------: | :-----------------------: | +| Celo Sepolia | 1773749037 | Tue, Mar 17 2026 12:03:57 | +| Mainnet | 1774958788 | Tue, Mar 31 2026 12:06:28 | From 98e2a67a338bcddd32457ff307b4df6acb43057d Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Tue, 28 Jul 2026 15:45:15 +0200 Subject: [PATCH 10/11] docs: use current CeloUnreleasedTreasury name in native bridge spec --- specs/native-bridge.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/native-bridge.mdx b/specs/native-bridge.mdx index 609093ac5..38ed88325 100644 --- a/specs/native-bridge.mdx +++ b/specs/native-bridge.mdx @@ -4,7 +4,7 @@ title: "Native Bridge" With the L2 migration, the Celo blockchain gained a native bridge to Ethereum based on [OP Stack's Standard Bridge](https://docs.optimism.io/app-developers/guides/bridging/standard-bridge). Specifically we use Custom Gas Token feature. This page describes the process of bridging assets between L1 and L2. -The Celo token now exists in both L1 and L2 versions. The L1 version is a standard ERC20 token with a total supply of 1 billion, fully minted to the `OptimismPortal` smart contract, which is part of the bridge (this setup allows any Celo token holder on L2 to bridge their tokens to L1). The L2 version is the native token on the L2 Celo chain, preserving the balances from the Celo L1 chain. Tokens that have not yet been minted on the Celo L1 chain, such as tokens for Community Fund, are now minted to the `CeloDistributionSchedule`, which manages further distribution. +The Celo token now exists in both L1 and L2 versions. The L1 version is a standard ERC20 token with a total supply of 1 billion, fully minted to the `OptimismPortal` smart contract, which is part of the bridge (this setup allows any Celo token holder on L2 to bridge their tokens to L1). The L2 version is the native token on the L2 Celo chain, preserving the balances from the Celo L1 chain. Tokens that have not yet been minted on the Celo L1 chain, such as tokens for Community Fund, are now minted to the `CeloUnreleasedTreasury`, which manages further distribution. ## Bridging CELO from L1 to L2 From efb05ec7aef396c2a452df630bfcba05f80b3d37 Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Tue, 28 Jul 2026 15:45:15 +0200 Subject: [PATCH 11/11] docs: describe completed L1 contract updates in past tense --- specs/smart-contract-updates-from-l1.mdx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/specs/smart-contract-updates-from-l1.mdx b/specs/smart-contract-updates-from-l1.mdx index 9104cbe74..b6b2e1121 100644 --- a/specs/smart-contract-updates-from-l1.mdx +++ b/specs/smart-contract-updates-from-l1.mdx @@ -3,7 +3,7 @@ title: "Smart Contract Updates From L1" sidebarTitle: "Contract Updates" --- -Smart contract changes that will be deployed to Celo before the transition can be seen in this diff: [https://github.com/celo-org/celo-monorepo/pull/11035/files](https://github.com/celo-org/celo-monorepo/pull/11035/files) +Smart contract changes that have been deployed to Celo before the transition can be seen in this diff: [https://github.com/celo-org/celo-monorepo/pull/11035/files](https://github.com/celo-org/celo-monorepo/pull/11035/files) ## Epochs And rewards @@ -31,7 +31,7 @@ In the L2 "epoch blocks” no longer exist. There are no transactions triggered The concept for epochs still remains, but they are determined to be at least as long as "epoch duration” (targeted to be set as one day on mainnet), but there's no guaranteed limit of the maximal duration. The size of an epoch can no longer be deterministically calculated based on block numbers alone. -The logic for processing epochs is now fully implemented in Solidity in the [EpochManager contract](https://github.com/celo-org/celo-monorepo/blob/release/core-contracts/12/packages/protocol/contracts-0.8/common/EpochManager.sol) introduced in Contract Release 12. cLabs is intended to run a bot to call the functions to trigger the epoch change and rewards distributions as soon as they are ready to do so, in a best-effort way. +The logic for processing epochs is now fully implemented in Solidity in the [EpochManager contract](https://github.com/celo-org/celo-monorepo/blob/release/core-contracts/12/packages/protocol/contracts-0.8/common/EpochManager.sol) introduced in Contract Release 12. cLabs runs a bot that calls the functions to trigger the epoch change and rewards distributions as soon as they are ready to be called, in a best-effort way. Epochs are now processed using multiple calls, as the gas consumption of the process involved uses is relatively high. @@ -87,7 +87,7 @@ This means that the Celo token is now an ERC20 on the Ethereum network, and the ## Governance Hotfix -The hot fix mechanism has been changed from a consensus of validators to a security council multisig. The current setup will be available until the transition. +The hot fix mechanism has been changed from a consensus of validators to a security council multisig. ## FeeCurrencyDirectory @@ -97,13 +97,13 @@ The intrinsic gas is the amount of gas that it will be added to all transactions ## FeeHandler -The [FeeHandler](https://github.com/celo-org/celo-proposals/blob/master/CIPs/cip-0052.md) was extended to support multiple beneficiaries. As it works in the L1 right now, only a carbon fund beneficiary and the burn fraction can be set. +The [FeeHandler](https://github.com/celo-org/celo-proposals/blob/master/CIPs/cip-0052.md) was extended to support multiple beneficiaries. On the L1, only a carbon fund beneficiary and the burn fraction could be set. -After Contract Release 12 is deployed, many beneficiaries can be set, and the burn fraction would be the reminding of all the allocations of the beneficiaries. +Since Contract Release 12, many beneficiaries can be set, and the burn fraction is the remainder of all the allocations of the beneficiaries. ## Slashing -DowntimeSlasher and DoubleSigningSlasher will be deprecated after L2 transition, as the validators get replaced for RPC prividers. GovernanceSlasher will still be available and now supports removing members of a validator group and changing the slash multiplier. Governance slasher now supports to enable a multisig with the slasher role. +DowntimeSlasher and DoubleSigningSlasher were deprecated with the L2 transition, as the validators were replaced by RPC providers. GovernanceSlasher remains available and now supports removing members of a validator group and changing the slash multiplier. Governance slasher now supports to enable a multisig with the slasher role. ## Deprecated contracts @@ -124,7 +124,7 @@ They still remain in the Celo Registry, but are scheduled for deletion after the Some functionality that was provided by precompiles (notably epoch number and elected validators) can be found in the EpochManager contract. -Some contracts had function that exposed precompiles will begin to revert in L2, at least this contract still internally uses those functions. For more details, please refer to this [forum post](https://forum.celo.org/t/upcoming-changes-deprecation-of-celo-precompiles-and-usingprecompilescontract-functions-in-l2-migration/9421/2). +Some contracts had functions that exposed precompiles; these revert on the L2, at least where the contract still internally uses those functions. For more details, please refer to this [forum post](https://forum.celo.org/t/upcoming-changes-deprecation-of-celo-precompiles-and-usingprecompilescontract-functions-in-l2-migration/9421/2). ### Deprecated Contract Methods with Replacements Table @@ -157,8 +157,8 @@ All other Celo-specific precompiles are deprecated, so the L2 migration removes ## Transition -Contracts for the L2 will be deployed before the transition, with Celo as L1. The contracts change behaviour automatically at the time of the transition. +Contracts for the L2 were deployed before the transition, while Celo was still an L1. The contracts changed behaviour automatically at the time of the transition. ## Update March 24th 2025 -Contract Release 12 has been [sucessfully deployed](https://mondo.celo.org/governance/cgp-166) to Celo Mainnet. +Contract Release 12 has been [successfully deployed](https://mondo.celo.org/governance/cgp-166) to Celo Mainnet.