Skip to content

docs(fees): document the post-Jovian base fee floor and FeeHandler splits on mainnet and Celo Sepolia - #2375

Merged
GigaHierz merged 3 commits into
celo-org:mainfrom
eddiemessiah:docs/fees-after-jovian
Oct 8, 2026
Merged

GigaHierz merged 3 commits into
celo-org:mainfrom
eddiemessiah:docs/fees-after-jovian

Conversation

@eddiemessiah

@eddiemessiah eddiemessiah commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

docs(fees): document the post-Jovian base fee floor and FeeHandler splits on mainnet and Celo Sepolia

The hole, and the fix

The fee pages predate the Jovian upgrade and still described the old mechanism, one page carried a contract address that no longer works, and two Learn pages stated a fee split the chain does not use.

  • operate/specification/deployments.mdx listed "EIP-1559 floor: 25 Gwei" for both networks and said Celo Sepolia has "the same chain properties" as mainnet. On chain, the minimum base fee is 200 Gwei on Celo Mainnet and 50 Gwei on Celo Sepolia, carried as Jovian minBaseFee in every block header's extraData and in the L1 SystemConfig. The page now lists those values and notes Sepolia differs only in the floor.
  • The same page's OP Stack config table listed eip1559BaseFeeFloor (no longer what sets the floor) and had sequencerWindowSize 3600, channelTimeout 300 and finalizationPeriodSeconds 12 for Celo. The table now shows:
    • sequencerWindowSize 7200 and finalizationPeriodSeconds 604800 for Celo (published mainnet deploy config), and finalizationPeriodSeconds 604800 for OP.
    • channelTimeout 50 on both chains, and maxSequencerDrift 2892 for Celo and 1800 for OP: the values in force. Granite made channelTimeout a protocol constant of 50 L1 blocks, and Fjord made maxSequencerDrift a constant of 1800 seconds, which Celo's op-node raises by 1092 seconds to 2892. A note under the table says so.
    • - in the OP column for eip1559Denominator, eip1559DenominatorCanyon, eip1559Elasticity, gasPriceOracleBaseFeeScalar and gasPriceOracleBlobBaseFeeScalar. OP Mainnet can change these in its SystemConfig, and the launch values the table carried are no longer what OP runs. One sentence points to OP Mainnet's entry in the Superchain Registry. Celo's values are unchanged.
    • The eip1559BaseFeeFloor row is removed, and one sentence under the table points to where the floor lives now.
  • operate/specification/transaction-fees.mdx said the floor comes from eip1559BaseFeeFloor. It now describes minBaseFee (L1 SystemConfig, encoded in extraData bytes 9 to 16), links the Jovian page, and links Deployments for the per-network values instead of restating them (AGENTS.md section 7). The heading is ## Base fee floor (the #base-fee-floor anchor is unchanged), the dollar claim uses the canonical wording "below $0.01 for a typical transaction" with no price restated, and two typos are fixed.
  • The FeeHandler section said the L2 behaviour was "not confirmed yet (as of 2024-11-15)" and described the L1 80% burn / 20% carbon split. It now states the split on each network, set by Celo governance (the FeeHandler owner is the Governance contract on both):
    • Celo Mainnet: burn fraction 0, carbon fraction 0, one other beneficiary registered as cLabs at 100%.
    • Celo Sepolia (same address): burn fraction 20%, carbon fraction 80%, no other beneficiaries.
    • It names the getters so a reader can check the split themselves.
  • learn/protocol/transactions/overview.mdx said 10% of fees go to carbon offsetting and 90% to network operations, and learn/protocol/epoch-rewards/carbon-offsetting-fund.mdx said the fund receives 10% of transaction fees. Both now say governance sets the split in the FeeHandler and link to /operate/specification/transaction-fees#feehandler, so the split is stated on one page. The two headings touched are in sentence case.
  • operate/specification/native-bridge.mdx hardcoded the FeeCurrencyDirectory as 0x71FFbD48E34bdD5a87c3c683E866dc63b8B2a685. On mainnet that address reverts with "No Implementation set"; the Registry returns 0x15F344b9E6c3Cb6F0376A36A64928b13F62C6276, which is already on the core contracts page. The address is replaced with a link to /build/tools/contracts/core-contracts#celo-mainnet.

What this does NOT do / residual risk

  • "This is currently only the case for WETH" in native-bridge.mdx was not re-verified and is unchanged.
  • The "0.1% of epoch rewards" line on the Carbon Offsetting Fund page was not re-verified and is unchanged.
  • Fee splits, minBaseFee and OP Mainnet's SystemConfig values are governance- or owner-controlled and can change; the docs state current values and how to read them.

Judgement calls

  • Floor values live on Deployments (the chain properties page); Transaction fees describes the mechanism and links there, so the number exists on one page. The fee split lives on Transaction fees, and the Learn pages link there.
  • The eip1559BaseFeeFloor row was removed rather than kept with a caveat, since it no longer controls the floor.
  • channelTimeout and maxSequencerDrift show the values in force rather than the deploy-config values, with a note naming the overridden values.
  • OP's mutable EIP-1559 and gas price oracle cells show - instead of a snapshot of OP's current values, so this page does not have to track another chain's settings.
  • The FeeHandler text names the mainnet beneficiary only by its on-chain registered name (cLabs) and does not print its address; the getters return it.
  • ## FeeHandler keeps its casing because it is the contract name.

Issues

Refs: none filed; found in a docs audit of the fee pages.

Stacking / conflicts

Based on current main (merge-base 7b8f97c2, #2368). main has moved since, with no overlapping files; GitHub reports the PR mergeable. Touches five files: the three under operate/specification/ and the two Learn pages above. No other open PR touches them.

Verification evidence

Reads on 2026-10-06, re-checked on 2026-10-08, against public endpoints.

1. Minimum base fee from block headers

curl -s -X POST -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockByNumber","params":["latest",false]}' \
  https://forno.celo.org
curl -s -X POST -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockByNumber","params":["latest",false]}' \
  https://forno.celo-sepolia.celo-testnet.org
Network Block extraData baseFeePerGas gasLimit
Celo Mainnet (42220) 0x4bb25c3 (79373763) 0x0100000190000000050000002e90edd000 0x2e90edd000 0x1c9c380
Celo Sepolia (11142220) 0x243b087 (37990535) 0x0100000190000000050000000ba43b7400 0xba43b7400 0x1c9c380

Decoded per the OP Jovian exec-engine spec (version u8 at [0,1), denominator u32 at [1,5), elasticity u32 at [5,9), minBaseFee u64 big-endian at [9,17)):

Field Mainnet Celo Sepolia
version 01 = 1 01 = 1
denominator 00000190 = 400 00000190 = 400
elasticity 00000005 = 5 00000005 = 5
minBaseFee 0000002e90edd000 = 200000000000 wei = 200 Gwei 0000000ba43b7400 = 50000000000 wei = 50 Gwei

Both chains were at the floor (baseFeePerGas equals minBaseFee). gasLimit 0x1c9c380 = 30,000,000. Re-read on 2026-10-08: mainnet block 79552923 and Celo Sepolia block 38169693 return the same extraData and base fees.

eth_gasPrice (same endpoints, {"jsonrpc":"2.0","id":1,"method":"eth_gasPrice","params":[]}): mainnet 0x2f25f0c900 = 202.5 Gwei, Celo Sepolia 0xc393e6d00 = 52.5 Gwei, both at or above the floor.

2. Minimum base fee at its L1 source (SystemConfig.minBaseFee(), selector 0xa62611a2)

# Ethereum mainnet, Celo Mainnet SystemConfigProxy
curl -s -X POST -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x89E31965D844a309231B1f17759Ccaf1b7c09861","data":"0xa62611a2"},"latest"]}' \
  https://ethereum-rpc.publicnode.com
# -> 0x0000000000000000000000000000000000000000000000000000002e90edd000  (200 Gwei)

# Ethereum Sepolia, Celo Sepolia SystemConfigProxy
curl -s -X POST -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x760a5f022c9940f4a074e0030be682f560d29818","data":"0xa62611a2"},"latest"]}' \
  https://ethereum-sepolia-rpc.publicnode.com
# -> 0x0000000000000000000000000000000000000000000000000000000ba43b7400  (50 Gwei)

eip1559Denominator() (0xd220a9e0) returns 0x...0190 (400) and eip1559Elasticity() (0xc9ff2d16) returns 0x...05 (5) on both. SystemConfig proxy addresses are from /build/tools/contracts/l1-contracts; l1_system_config_address in the mainnet rollup.json matches.

3. OP Stack config

curl -s https://storage.googleapis.com/cel2-rollup-files/celo/config.json
curl -s https://storage.googleapis.com/cel2-rollup-files/celo/rollup.json

config.json keys: "maxSequencerDrift": 2892, "sequencerWindowSize": 7200, "channelTimeout": 50, "finalizationPeriodSeconds": 604800, "enableGovernance": false, "eip1559Denominator": 400, "eip1559DenominatorCanyon": 400, "eip1559Elasticity": 5, "eip1559BaseFeeFloor": 25000000000, "gasPriceOracleBaseFeeScalar": 0, "gasPriceOracleBlobBaseFeeScalar": 0.

rollup.json: "seq_window_size": 7200, "channel_timeout": 300, "max_sequencer_drift": 2892, "cel2_time": 0, "fjord_time": 0, "granite_time": 0, "jovian_time": 1774958788. No Celo Sepolia config.json is published (celo-sepolia/config.json returns 404).

Values in force:

  • channelTimeout: the OP Granite spec (specs/protocol/granite/derivation.md) reduces CHANNEL_TIMEOUT from 300 to 50 L1 blocks as a protocol constant. Granite is active on Celo from genesis and on OP Mainnet since 2024-09-11 (granite_time 1726070401 in the Superchain Registry op.toml).
  • maxSequencerDrift: the OP Fjord spec (specs/protocol/fjord/derivation.md, "Constant Maximum Sequencer Drift") makes it a constant of 1800 seconds. celo-org/optimism at 3357d43a (celo-rebase-18, the default branch), op-node/rollup/chain_spec.go: MaxSequencerDrift(t) returns maxSequencerDriftCelo = maxSequencerDriftFjord + 1092 (2892) when IsCel2(t) and Fjord is active, else 1800. Celo has cel2_time 0 and fjord_time 0; OP Mainnet's Fjord activated 2024-07-10 (fjord_time 1720627201 in op.toml), and its op.toml max_sequencer_drift of 600 is overridden.
  • OP Mainnet SystemConfig (0x229047fed2591dbec1eF1118d64F7aF3dB9EB290, the SystemConfigProxy in the Superchain Registry op.toml), read on Ethereum mainnet block 26146882: basefeeScalar() 5227, blobbasefeeScalar() 1014213, eip1559Denominator() 250, eip1559Elasticity() 2. The launch values the table carried (1368, 810949, 50 / 250, 6) no longer apply, so those OP cells are -.

4. FeeHandler split

Registry lookup, getAddressForString("FeeHandler"):

curl -s -X POST -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x000000000000000000000000000000000000ce10","data":"0x853db3230000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a46656548616e646c657200000000000000000000000000000000000000000000"},"latest"]}' \
  https://forno.celo.org
# -> 0x000000000000000000000000cd437749e43a154c07f3553504c68fbfd56b8778

Getters from celo-monorepo/packages/protocol/contracts/common/FeeHandler.sol, called on 0xcd437749e43a154c07f3553504c68fbfd56b8778 on Celo Mainnet with the same eth_call shape:

Call Selector Raw result Decoded
getBurnFraction() 0x2457380b 0x00…00 0
getCarbonFraction() 0xfc064007 0x00…00 0
getTotalFractionOfOtherBeneficiariesAndCarbon() 0x527e234d 0x…d3c21bcecceda1000000 1e24 = 100% (Fixidity, FIXED1_UINT = 1e24)
getOtherBeneficiariesAddresses() 0xcbfcb68a 0x…20 …01 …7a1e98fc9a008107dbd1f430a05ace8cf6f3fe19 [0x7A1E98FC9a008107DbD1f430a05Ace8cf6f3FE19]
getOtherBeneficiariesInfo(0x7A1E…FE19) 0xe396f563 0x…d3c21bcecceda1000000 …60 …01 …05 634c616273… (1e24, "cLabs", true)
owner() 0x8da5cb5b 0x…d533ca259b330c7a88f74e000a3faea2d63b7972 equals Registry getAddressForString("Governance")

Celo Sepolia's FeeHandler (same address, on https://forno.celo-sepolia.celo-testnet.org) returns getBurnFraction() 0x…2a5a058fc295ed000000 (2e23 = 20%), getCarbonFraction() 0x…a968163f0a57b4000000 (8e23 = 80%), and no other beneficiaries. Both networks re-read on 2026-10-08 with the same results.

Base fees reach the FeeHandler: across mainnet blocks 79374030 to 79374032 the FeeHandler's CELO balance rose each block (by 0.5749, 0.0990, 0.0890 CELO), while the BaseFeeVault predeploy 0x4200000000000000000000000000000000000019 balance did not change. The increase is below gasUsed * baseFee because fee-currency transactions pay their base fee in tokens.

5. FeeCurrencyDirectory address

# Registry getAddressForString("FeeCurrencyDirectory")
curl -s -X POST -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x000000000000000000000000000000000000ce10","data":"0x853db3230000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001446656543757272656e63794469726563746f7279000000000000000000000000"},"latest"]}' \
  https://forno.celo.org
# -> 0x00000000000000000000000015f344b9e6c3cb6f0376a36a64928b13f62c6276

# getCurrencies() on the old address from native-bridge.mdx
curl -s -X POST -H 'Content-Type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x71FFbD48E34bdD5a87c3c683E866dc63b8B2a685","data":"0x61c661de"},"latest"]}' \
  https://forno.celo.org
# -> {"error":{"code":3,"message":"execution reverted: No Implementation set", ...}}

getCurrencies() on 0x15F344b9…6276 returns a 20-entry list. Celo Sepolia's Registry returns 0x9212fb72ae65367a7c887ec4ad9be310bac611bf. Both match /build/tools/contracts/core-contracts.

6. Links

npx -y mint@latest broken-links on this machine (Windows) reports existing pages as broken, so the check compares this head with origin/main on the same machine. The links this PR adds that the CLI lists are all to pages and anchors that exist: /operate/specification/upgrades/jovian, /operate/specification/deployments, /operate/specification/transaction-fees#base-fee-floor, /operate/specification/transaction-fees#feehandler (from both Learn pages) and /build/tools/contracts/core-contracts#celo-mainnet. Each target renders on the dev server with the matching id. No new external link other than the Superchain Registry op.toml (returns 200). CI's run on this PR is the authoritative check.

7. Preview

mint dev on this head, in the built-in browser at 1280x900 and 412x915:

  • /operate/specification/deployments
  • /operate/specification/transaction-fees
  • /learn/protocol/transactions/overview
  • /learn/protocol/epoch-rewards/carbon-offsetting-fund

Each page returns 200 and shows the new text (the drift note, - OP cells and the Superchain Registry link; the FeeHandler link on both Learn pages; id="feehandler" and id="base-fee-floor" on Transaction fees). The old 10% / 90% text is gone. At 412px no page scrolls horizontally (the config table scrolls inside its own container, as before). 0 console errors on all four pages at both widths.

Remaining ops steps

  • none

Checklist

  • Title is the commit message I want on main
  • Ships the test that fails on pre-fix code: n/a, docs only
  • Covers the seam: n/a, docs only
  • Error responses audited: n/a, docs only
  • Judgement calls / bundled product changes flagged above
  • lint / typecheck / test pass locally: n/a; mint broken-links result above
  • Re-read acceptance criteria of every Closes issue: no Closes
  • Development sidebar links match Closes/Refs above
  • README / runbook / .env.example / examples / error strings updated: n/a
  • Lockfile touched: n/a
  • Wallet/provider tree touched: n/a
  • UI touched: n/a
  • Money/security path: n/a
  • No secrets in the diff
  • Questions for the maintainer: none open

🤖 Generated with Claude Code

@eddiemessiah
eddiemessiah requested a review from a team as a code owner October 6, 2026 08:26
@eddiemessiah
eddiemessiah requested review from palango and seolaoh and removed request for a team October 6, 2026 08:26

@GigaHierz GigaHierz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

head efedf53 · local ref and API headRefOid match; merged into origin/main a12466b in a scratch checkout: clean, mint broken-links --check-redirects success, check-orphans.sh clean; three changed pages render on :3442 at 1280 and 412x915 with 0 console errors and no horizontal overflow; I reproduced every on-chain number (200/50 gwei floor, FeeHandler split, directory address)

Verdict: REQUEST-CHANGES

Thank you, this is a valuable fix: the old pages really did describe a mechanism that no longer exists, and I could reproduce your chain reads one by one. The remaining items are small: one table cell the PR's own source contradicts, one claim that now carries a number nobody rechecked, and two completeness points.

Findings

  1. Medium · operate/specification/deployments.mdx:57 (channelTimeout row)

    • Defect: the row still says 300 for Celo, but the file the PR used to correct the neighbouring rows says otherwise. https://storage.googleapis.com/cel2-rollup-files/celo/config.json has "channelTimeout": 50, and rollup.json has "granite_time": 0, so Granite is active from genesis. The OP Granite spec (specs/protocol/granite/derivation.md) reduces CHANNEL_TIMEOUT from 300 to 50 as a protocol constant. So rollup.json's 300 is the pre-Granite default and not the effective value; the two sources do not actually disagree about what is in force.
    • Failure scenario: an operator or agent configuring a derivation node or batcher copies 300 from a table this PR presents as corrected.
    • Fix shape: set the Celo cell to 50 (matches config.json and Granite).
  2. Medium · operate/specification/transaction-fees.mdx:27

    • Defect: "The floor is set sufficiently low to still keep average transactions below 0.01 USD" is untouched, but this PR moves the floor from 25 to 200 gwei (8x) and the body says it was not rechecked. It also differs from the canonical wording in AGENTS.md section 7 ("below $0.01 for a typical transaction").
    • My recomputation: a plain transfer is 21,000 gas x 200 gwei = 4.2e15 wei = 0.0042 CELO (eth_gasPrice of 202.5 gwei gives 0.00425 CELO). At the spot price I read today (about $0.1035 per CELO) that is about $0.00044, so the claim is true with a wide margin and holds while CELO stays under roughly $2.38. Correct, but price-dependent and unverified in the PR.
    • Failure scenario: a reader or agent comparing this page with the canonical fact sees two phrasings of one fact; if the floor is raised again nothing prompts a recheck of the dollar claim.
    • Fix shape: use the canonical phrase ("below $0.01 for a typical transaction") and do not restate a price.
  3. Low · operate/specification/transaction-fees.mdx:33 (FeeHandler paragraph)

    • Defect: the section gives the split for Celo Mainnet only, but the page covers both networks and the Celo Sepolia FeeHandler (same address) is configured differently. I read getCarbonFraction() = 8e23 (80%) and getBurnFraction() = 2e23 (20%) there.
    • Failure scenario: a developer testing on Celo Sepolia reads "burn and carbon are both 0, one beneficiary gets 100%" and finds the opposite on chain.
    • Fix shape: one sentence saying the Celo Sepolia split differs and is read with the same getters (stating the testnet values is fine too; they are true now).
  4. Low · operate/specification/transaction-fees.mdx:25 and :31 (headings), operate/specification/deployments.mdx:53-65 (OP column)

    • Defect: (a) the PR keeps ## Base Fee Floor and ## FeeHandler casing "so the anchor keeps working", but Mintlify slugs are lowercased and hyphenated, so ## Base fee floor still yields #base-fee-floor. AGENTS.md section 3 asks for sentence case on pages you are already editing. (b) The OP column of the config table was not re-verified (the body says so), yet the PR edits the table and leaves a column it cannot vouch for.
    • Fix shape: (a) retitle to ## Base fee floor; the anchor and the link on line 12 are unchanged. (b) Check the OP column against OP's published mainnet deploy config, or drop the column. While in the floor section, "with on modification" and "prevents the chain to be spammed" are pre-existing typos worth fixing.

Verified good

  • Floor on chain. eth_getBlockByNumber latest on forno mainnet (block 79381384): extraData 0x0100000190000000050000002e90edd000, baseFeePerGas 200.0 gwei; decoded version 1, denominator 400, elasticity 5, minBaseFee bytes [9,17) = 200 gwei. Celo Sepolia block 37998153: ...0000000ba43b7400 = 50 gwei, base fee 50 gwei. Matches the OP Jovian exec-engine spec (minBaseFee is a big-endian u64 at byte offset [9, 17)); "bytes 9 to 16" in the page is the same range written inclusively.
  • L1 source. SystemConfig.minBaseFee() at 0x760a5f022c9940f4a074e0030be682f560d29818 (Ethereum Sepolia) returns 50000000000; at 0x89E31965D844a309231B1f17759Ccaf1b7c09861 (Ethereum mainnet, read through drpc because publicnode did not resolve here) returns 200000000000. Both addresses match tooling/contracts/l1-contracts.mdx.
  • Deployments facts. Block gas limit 30,000,000 observed; 30M / elasticity 5 = 6M target as listed. sequencerWindowSize 7200 and finalizationPeriodSeconds 604800 (7 days) match config.json, and rollup.json seq_window_size is 7200. config.json still carries the 25 gwei eip1559BaseFeeFloor, but Jovian is active on mainnet (jovian_time 1774958788) and the header value is what governs, so dropping the row is right.
  • FeeHandler (Celo Mainnet). Registry getAddressForString("FeeHandler") returns 0xcD437749E43A154C07F3553504c68fBfD56B8778 (matches tooling/contracts/core-contracts.mdx); getBurnFraction() 0; getCarbonFraction() 0; getTotalFractionOfOtherBeneficiariesAndCarbon() 1e24; getOtherBeneficiariesAddresses() is the single address 0x7A1E98FC9a008107DbD1f430a05Ace8cf6f3FE19; getOtherBeneficiariesInfo(...) returns (1e24, "cLabs", true); owner() equals the Registry's Governance (0xD533Ca259b330c7A88f74E000a3FaEa2d63B7972). "10^24 is 100%" is the Fixidity unit. All as the page states.
  • FeeCurrencyDirectory. Registry returns 0x15F344b9E6c3Cb6F0376A36A64928b13F62C6276 (matches core-contracts); getCurrencies() on the old 0x71FFbD48E34bdD5a87c3c683E866dc63b8B2a685 reverts with "No Implementation set", and on the new address returns 20 entries, including WETH (0xD221812de1BD094f35587EE8E174B07B6167D9Af: symbol() WETH, bridge() 0x4200000000000000000000000000000000000010). Replacing the hardcoded address with a link to the one canonical table is the right shape (AGENTS section 7). I did not verify "only the case for WETH" across all 20 entries.
  • Consistency. No other page states a floor number (searches for 25 gwei, 25000000000 and minBaseFee hit only pages this PR edits plus the Jovian spec and notice). Those say Celo moves to the OP Minimum Base Fee, which agrees with this PR. operate/operators/faq.mdx:83 stays consistent. The L1-era "80% burn, 20% carbon" text appears nowhere else; smart-contract-updates-from-l1.mdx already describes the multi-beneficiary FeeHandler. "Block period: 1 second" is untouched.
  • Links by hand: /operate/specification/upgrades/jovian, /operate/specification/deployments, #base-fee-floor and /tooling/contracts/core-contracts#celo-mainnet all exist and render as links on the dev server.

What the PR got right

  • Fixing real, harmful errors: a dead contract address and an L1-era fee split that is not the L2 behaviour.
  • Keeping the number on one page (Deployments) and the mechanism on the other, as AGENTS section 7 asks, and naming the getters so readers can check the split themselves rather than trust the page.
  • Evidence quality: raw bytes, selectors, decode tables, and a balance-delta check showing base fees reach the FeeHandler and not the BaseFeeVault. Everything reproduced.
  • A candid residual-risk list, which pointed straight at findings 1 to 3.

Merge-order hazards

  • Behind main by 1 commit (Home to Learn rename, #2367). None of the three files moved, so git merge-tree --write-tree origin/main refs/remotes/pr/2375 is clean and a rebase needs no manual step.
  • #2368 (Build tab, not landed) renames tooling/contracts/core-contracts to build/tools/contracts/core-contracts. This PR adds two new inbound links to /tooling/contracts/core-contracts#celo-mainnet (transaction-fees FeeHandler paragraph, native-bridge). Redirects cover them, but whoever merges second should update them to the new path (AGENTS section 2, step 3) and re-run mint broken-links --check-redirects.
  • #2374 touches only the bridges pages: no conflict with this PR.

Checks run

mint broken-links --check-redirects: success on the merge with main (the Windows false positives described in the PR body do not reproduce). bash scripts/check-orphans.sh: no orphans. gh pr checks 2375: only GitGuardian and StepSecurity listed (pass); the repo's link-check workflow does not appear, most likely waiting for maintainer approval for an outside contributor.

@palango palango left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. I reran the chain reads, and the floor (200 gwei on mainnet and 50 gwei on Celo Sepolia, from the header extraData and SystemConfig.minBaseFee), the mainnet FeeHandler split and the new FeeCurrencyDirectory all check out. The extraData byte layout in transaction-fees.mdx matches what forno returns.

I agree with GigaHierz's points and won't repeat them all. One I'd settle rather than leave open: channelTimeout for Celo is 50. Granite is active from genesis (granite_time 0), and op-node ignores the rollup.json value once Granite is on. It returns the ChannelTimeoutGranite constant, which is 50 (op-node/rollup/chain_spec.go and op-node/params/constants.go). So config.json and the protocol agree, and the 300 in rollup.json only applies before Granite.

The OP column has a related problem that this PR makes more visible, and that's what I'd block on. OP's finalizationPeriodSeconds is 604800, not 12 (packages/contracts-bedrock/deploy-config/mainnet.json), and its effective channelTimeout is also 50. With the Celo cell fixed, the row now says OP finalizes in 12 seconds. Please either correct those OP cells or drop the OP column, since nobody has checked it against a source.

Comment thread operate/specification/deployments.mdx Outdated
| `sequencerWindowSize` | 7200 | 3600 |
| `channelTimeout` | 300 | 300 |
| `finalizationPeriodSeconds` | 12 | 12 |
| `finalizationPeriodSeconds` | 604800 | 12 |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OP's finalizationPeriodSeconds is 604800, not 12 (packages/contracts-bedrock/deploy-config/mainnet.json in ethereum-optimism/optimism). Next to Celo's corrected 604800, this row now reads as if OP finalizes in 12 seconds. The channelTimeout row above has the same issue: since Granite the effective value is 50 for both chains.

## 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:
All base fees are sent to the [FeeHandler](/tooling/contracts/core-contracts#celo-mainnet) contract, which decides what to do with the fees. Celo governance sets how the FeeHandler splits them between burning, carbon offsetting and other beneficiaries. On Celo Mainnet the burn fraction and the carbon fraction are both 0, and a single other beneficiary, registered under the name `cLabs`, receives 100% of the fees.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is right for mainnet, and I get the same values. Celo Sepolia's FeeHandler is set differently (burn 2e23, carbon 8e23, no other beneficiaries), so a sentence saying the testnet split differs would help testnet users.

@palango

palango commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Heads-up on merge order: #2368 moves tooling/ to build/tools/, and this PR adds two links to /tooling/contracts/core-contracts#celo-mainnet (native-bridge.mdx and transaction-fees.mdx). The /tooling/:slug* redirect keeps them working, but if #2368 lands first, please point them at /build/tools/contracts/core-contracts#celo-mainnet when you rebase. If this one lands first, #2368 will need to pick them up.

@eddiemessiah

Copy link
Copy Markdown
Contributor Author

Previewed in a local live deployment (mint dev, this branch merged with the other open docs fixes, no overlapping files) at desktop 1280px and phone 412px:

  • /operate/specification/deployments
  • /operate/specification/transaction-fees
  • /operate/specification/native-bridge

Each page returns 200 and renders the new text, with no horizontal overflow on phone, no broken images and 0 console errors.

eddiemessiah and others added 2 commits October 6, 2026 17:48
…ndler split

The fee pages still described the pre-Jovian eip1559BaseFeeFloor (25 Gwei) and a FeeHandler split that was 'not confirmed yet (as of 2024-11-15)'.

- deployments: minimum base fee is 200 Gwei on mainnet and 50 Gwei on Celo Sepolia (Jovian minBaseFee, read from block extraData and L1 SystemConfig); drop the eip1559BaseFeeFloor row; sequencerWindowSize 7200 and finalizationPeriodSeconds 604800 per the published mainnet deploy config.
- transaction-fees: describe the Jovian minBaseFee mechanism and link to deployments for values; replace the stale FeeHandler paragraph with the on-chain mainnet split (burn 0, carbon 0, one beneficiary 'cLabs' at 100%) and the getters to read it.
- native-bridge: replace the hardcoded FeeCurrencyDirectory address, which reverts with 'No Implementation set', with a link to the core contracts page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…plit and OP column

- deployments: channelTimeout 50 for Celo and OP (Granite constant), OP
  finalizationPeriodSeconds 604800 and maxSequencerDrift 600 from OP's
  mainnet deploy config, note on channelTimeout under the table
- transaction-fees: canonical fee wording, sentence-case heading, fix two
  typos, add the Celo Sepolia FeeHandler split
- point the two new core-contracts links at /build/tools after celo-org#2368

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@eddiemessiah
eddiemessiah force-pushed the docs/fees-after-jovian branch from efedf53 to c873b0f Compare October 6, 2026 18:13
@eddiemessiah

Copy link
Copy Markdown
Contributor Author

Head is now c873b0fd (rebased onto main at 7b8f97c2, pushed with --force-with-lease). Thanks both for the careful reads. Every point is addressed below.

Finding Status Where / new wording
GigaHierz 1, palango inline: channelTimeout Celo cell FIXED operate/specification/deployments.mdx:57 now 50 for Celo and OP. One sentence under the table (line 65): "channelTimeout shows the value in force: since the Granite upgrade it is a protocol constant of 50 L1 blocks on every OP Stack chain, and the deploy-config value of 300 no longer applies."
GigaHierz 2: price-dependent floor claim FIXED transaction-fees.mdx:27: "The floor is set low enough to keep fees below $0.01 for a typical transaction." No price stated.
GigaHierz 3, palango inline: Celo Sepolia FeeHandler FIXED transaction-fees.mdx:33, appended: "On Celo Sepolia the FeeHandler has the same address but a different split: the burn fraction is 20% and the carbon fraction is 80%, with no other beneficiaries, as returned by getBurnFraction() and getCarbonFraction()."
GigaHierz 4a: heading case and typos FIXED ## Base fee floor (line 25); the served page keeps id="base-fee-floor", so the link on line 12 is unchanged. ## FeeHandler stays, it is the contract name. Typos: "with one modification: the base fee can't fall below" and "prevents the chain from being spammed".
GigaHierz 4b, palango blocking: OP column FIXED Checked against packages/contracts-bedrock/deploy-config/mainnet.json in ethereum-optimism/optimism at commit 69bbccc2 (the last commit that carries the file; 9d88daf4, #18922, removed it from develop). Changed: finalizationPeriodSeconds 12 to 604800, channelTimeout 300 to 50 (Granite constant, params.ChannelTimeoutGranite in op-node), maxSequencerDrift 1800 to 600. Matched already: sequencerWindowSize 3600, enableGovernance true, eip1559Denominator 50, eip1559Elasticity 6, gasPriceOracleBaseFeeScalar 1368, gasPriceOracleBlobBaseFeeScalar 810949. eip1559DenominatorCanyon is not in that file; 250 is confirmed by superchain/configs/mainnet/op.toml in the superchain-registry (commit 3d974558).

One question on maxSequencerDrift. Since Fjord it is also a protocol constant (1800, maxSequencerDriftFjord in op-node), and Fjord is active on Celo from genesis (fjord_time 0) and on OP since July 2024. So the value in force is 1800 on both chains and the deploy-config values (2892 Celo, 600 OP) are overridden, the same situation as channelTimeout. I set the OP cell to the deploy-config value so it matches what the Celo cell shows. If you prefer the row to show the value in force, I will set both to 1800 and extend the note; say which.

Checks on this head:

  • git merge-tree --write-tree origin/main HEAD: clean. Behind by two (docs: rename the Home tab to Learn and move home/ to learn/ #2367, docs: merge Build on Celo and Tooling into one Build tab #2368), so this push was a rebase.
  • mint broken-links --check-redirects: on this Windows machine it reports 582 broken links in 123 files for this head and 575 in 122 for origin/main. The difference of 7 is exactly the 7 internal links this PR adds, each to a page that exists and is in docs.json navigation (the local false positive from the PR body; your run on the merge was clean). CI is authoritative.
  • bash scripts/check-orphans.sh: no orphan pages.
  • git grep for "Base Fee Floor", "below 0.01 USD" and "with on modification" under operate/: nothing.
  • mint dev --port 3474: /operate/specification/deployments, /operate/specification/transaction-fees and /operate/specification/native-bridge return 200. The served HTML has channelTimeout 50 | 50, finalizationPeriodSeconds 604800 | 604800, "typical transaction", id="base-fee-floor", the Celo Sepolia FeeHandler sentence and the /build/tools/... links. Loaded with Playwright at 1280x900 and 412x915: 200 on all three, no horizontal overflow, 0 console errors. Screenshots are saved locally; I can attach them if useful.

#2368 has merged, so the two new links now point at /build/tools/contracts/core-contracts#celo-mainnet (transaction-fees.mdx:33, native-bridge.mdx:28). No /tooling/ links remain under operate/.

@GigaHierz GigaHierz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

head c873b0f · local ref and API headRefOid match; PR merge-base is origin/main 7b8f97c (no merge needed), git merge-tree --write-tree clean; mint broken-links --check-redirects success, check-orphans.sh clean; three changed pages served from the PR on :3612; re-read on chain today: mainnet block 79414760 extraData 0x0100000190000000050000002e90edd000 (200 gwei, base fee 200 gwei), Celo Sepolia block 38031534 ...0ba43b7400 (50 gwei); FeeHandler splits both networks

Verdict: REQUEST-CHANGES

Thank you for the fast follow-up. The floor wording, the Sepolia split, the heading case, the channelTimeout row and the two links are all fixed, and every chain value on the pages still reproduces. What is left is one table row that the new channelTimeout note makes inconsistent, a stale OP cell group, one neighbouring page that now contradicts the FeeHandler text, and the PR description.

Status of earlier findings

  1. channelTimeout left at 300: FIXED. Both columns now say 50, and the note under the table explains it. Evidence: https://storage.googleapis.com/cel2-rollup-files/celo/config.json has "channelTimeout": 50; the OP Granite spec says "With Granite, the CHANNEL_TIMEOUT is reduced from 300 to 50 L1 Blocks"; op-node ChainSpec.ChannelTimeout(t) returns the Granite constant once IsGranite(t); Celo's rollup.json has granite_time 0.
  2. "below 0.01 USD" claim after the floor rose: FIXED. transaction-fees.mdx:27 now reads "set low enough to keep fees below $0.01 for a typical transaction", the canonical wording from AGENTS.md section 7, with no price restated. Recomputed anyway: 21,000 gas x 200 gwei = 4.2e15 wei = 0.0042 CELO; at the CELO price I read today (about $0.102) that is about $0.00043, and the claim holds until CELO is above roughly $2.38.
  3. Celo Sepolia FeeHandler split omitted: FIXED. transaction-fees.mdx:33 states burn 20% and carbon 80% with no other beneficiaries. On chain: Sepolia getBurnFraction() 2e23, getCarbonFraction() 8e23, getOtherBeneficiariesAddresses() empty; mainnet 0, 0, and the single address 0x7A1E...FE19 registered as cLabs at 1e24.
  4. ## Base Fee Floor heading case: FIXED. It is ## Base fee floor, the rendered id is still base-fee-floor, and the #base-fee-floor links on transaction-fees.mdx:12 and deployments.mdx:68 still resolve. The two typos in that paragraph are fixed too.
  5. OP column unverified: PARTLY FIXED. sequencerWindowSize 3600, finalizationPeriodSeconds 604800 (OP's portal proofMaturityDelaySeconds reads 604800 on chain) and channelTimeout 50 are right. See findings 1 and 2 for the rest.
  6. Links to /tooling/contracts/core-contracts#celo-mainnet: FIXED. transaction-fees.mdx:33 and native-bridge.mdx:28 now point at /build/tools/contracts/core-contracts#celo-mainnet; both render as links and id="celo-mainnet" exists on that page. No /tooling/ link remains in any .mdx.

New findings

  1. Medium · operate/specification/deployments.mdx:55 and :66 (maxSequencerDrift row and the note under the table)

    • Defect: the new note says the table shows the value in force for channelTimeout, but the maxSequencerDrift row shows deploy-config values that Fjord overrides, and the PR changed OP's cell from the in-force value to the deploy-config one. The OP Fjord spec makes max_sequencer_drift a constant of 1800 seconds ("Constant Maximum Sequencer Drift"), and op-node ChainSpec.MaxSequencerDrift(t) returns the 1800 constant once Fjord is active. Celo has fjord_time 0 in rollup.json (active from genesis) and OP Mainnet's Fjord activated in July 2024 (op.toml), so neither 2892 (Celo) nor 600 (OP) is in force; the old OP cell, 1800, was.
    • Failure scenario: an operator or agent tuning a batcher or sequencer reads that Celo allows a 2892-second drift and OP 600, when both chains enforce 1800.
    • Fix shape: set both cells to 1800 and extend the note to "channelTimeout and maxSequencerDrift show the values in force: Granite and Fjord made them protocol constants (50 L1 blocks, 1800 seconds), so the deploy-config values (300, and 2892 / 600) no longer apply". Or keep deploy-config values everywhere and drop the "in force" framing, but then do not change OP's drift cell.
  2. Low · operate/specification/deployments.mdx:60-64 (OP cells for eip1559* and gasPriceOracle*)

    • Defect: these OP values are launch-time settings that the chain owner has since changed, and the PR now presents the column as checked. Read today from OP Mainnet's SystemConfig on Ethereum (0x229047fed2591dbec1eF1118d64F7aF3dB9EB290): basefeeScalar() 5227, blobbasefeeScalar() 1014213, eip1559Denominator() 250, eip1559Elasticity() 2. The table says 1368, 810949, 50 / 250 and 6.
    • Failure scenario: someone compares Celo's zero scalars and 400/5 EIP-1559 settings with "OP" and copies 1368 or 6, which are not what OP runs now.
    • Fix shape: drop the mutable rows from the OP column (show - and keep the Celo values), or add one sentence that the OP column lists OP Mainnet's launch deploy config and link OP's published configuration for current values. AGENTS.md section 7 asks for one canonical page; OP's own config is the better home for OP's numbers.
  3. Low · learn/protocol/transactions/overview.mdx:37 (not in the diff)

    • Defect: "10% of transaction fees continue to support the carbon offset fund ... The remaining 90% ... are allocated to ... Data Availability ... Sequencer and Batcher Operations" contradicts the FeeHandler text this PR now makes precise. On Celo Mainnet getCarbonFraction() is 0 and one beneficiary receives 100% of the fees.
    • Failure scenario: a reader or agent that opens both pages gets a 10% carbon share from one and 0% from the other (AGENTS.md section 7, one fact one page: grep for the old value when you change a fact).
    • Fix shape: replace that bullet list with a sentence and a link to /operate/specification/transaction-fees#feehandler, or file a follow-up issue and link it from the PR body. A prose "could be a follow-up" does not resolve it.
  4. Low · PR description (not a file)

    • Defect: the body still describes the head before this commit: "channelTimeout is left at 300", "The 'OP' column ... was not re-verified", "The page describes mainnet only", "The 'below 0.01 USD' sentence ... was not re-checked", "## Base Fee Floor keeps its heading", links to /tooling/contracts/core-contracts, "Branched off main at 50ed71d", and the maintainer question about 50 versus 300.
    • Failure scenario: a maintainer deciding on the merge reads that the review items are still open.
    • Fix shape: rewrite those bullets to match the head, and update the title if it should mention the Sepolia split (the title becomes the squash commit; the repository uses a blank message body).

Verified good

  • Floor on chain: eth_getBlockByNumber latest on forno mainnet (block 79414760): extraData 0x0100000190000000050000002e90edd000, baseFeePerGas 200 gwei; decoded version 1, denominator 400, elasticity 5, minBaseFee at bytes [9,17) = 200 gwei. Celo Sepolia (block 38031534): ...0ba43b7400 = 50 gwei, base fee 50 gwei. "bytes 9 to 16" is the same range written inclusively. eth_gasPrice is 202.5 gwei mainnet and 52.5 gwei Sepolia.
  • L1 source: SystemConfig.minBaseFee() at 0x89E31965D844a309231B1f17759Ccaf1b7c09861 returns 200000000000 (Ethereum mainnet).
  • FeeHandler: Registry getAddressForString("FeeHandler") returns 0xcD437749E43A154C07F3553504c68fBfD56B8778 on both networks ("same address" is true); getTotalFractionOfOtherBeneficiariesAndCarbon() 1e24 on mainnet; getOtherBeneficiariesInfo(0x7A1E98FC9a008107DbD1f430a05Ace8cf6f3FE19) returns (1e24, "cLabs", true); owner() equals the Registry's Governance on mainnet (0xD533Ca259b330c7A88f74E000a3FaEa2d63B7972) and on Sepolia (0x50d2f15CcF5E97999bDf9D6760d0208b00D14ad1), so "Celo governance sets" holds for both. 10^24 is 100% (Fixidity).
  • FeeCurrencyDirectory: Registry returns 0x15F344b9E6c3Cb6F0376A36A64928b13F62C6276 on mainnet, matching the core contracts table; getCurrencies() on the old 0x71FFbD48... reverts "No Implementation set"; the new one returns 20 entries. Replacing the hardcoded address with a link to the canonical table is the right shape.
  • Deployments facts: block gas limit 30,000,000 on chain, so a 6,000,000 target at elasticity 5; sequencerWindowSize 7200 and finalizationPeriodSeconds 604800 match config.json and rollup.json; the removed eip1559BaseFeeFloor row (25 gwei in config.json) no longer governs because jovian_time 1774958788 has passed.
  • OP column values that are right: sequencerWindowSize 3600 (op.toml seq_window_size), finalizationPeriodSeconds 604800, channelTimeout 50.
  • Consistency: the only pages stating a floor number are the PR's own; the Jovian page and notice say Celo moves to OP's Minimum Base Fee, consistent with the PR. operate/specification/smart-contract-updates-from-l1.mdx already describes the multi-beneficiary FeeHandler. The "80% burn, 20% carbon" L1 text now appears only for Celo Sepolia, where it is true.
  • AGENTS.md: frontmatter untouched and valid; headings are sentence case (## FeeHandler is a contract name); no "recently"/"previously" phrasing added; no partner addresses; both new links are root-relative with no extension.
  • Rendered on :3612 from the PR: transaction-fees shows the canonical $0.01 sentence, "bytes 9 to 16" and the Sepolia split, with ids base-fee-floor and feehandler; deployments shows 200 and 50 Gwei and the channelTimeout note; native-bridge has the new link and no 0x71FFbD48.
  • CI: gh pr checks 2375 lists GitGuardian and the three StepSecurity checks, all passing. The repository's mint broken-links workflow does not appear; it is most likely waiting for maintainer approval of the first-time-contributor run. Locally mint broken-links --check-redirects passes on the head.

What the PR got right

  • Fixing real, harmful errors: a dead contract address and an L1-era fee split that is not what the L2 does.
  • The floor value lives on one page (Deployments) and the mechanism on the other, as AGENTS.md section 7 asks, and the getters are named so a reader can check the split instead of trusting the page.
  • The follow-up took the review literally and precisely: canonical wording, the testnet split, the heading, and the new paths, all with the evidence to back them.
  • A note under the table that explains why a deploy-config value no longer applies is the right idea. Finding 1 only asks to apply it to the one other row it covers.

Merge-order hazards

  • None. The PR is based directly on current main (7b8f97c) and git merge-tree --write-tree origin/main refs/remotes/pr/2375 is clean. GitHub reports it mergeable, with the merge state BLOCKED pending required checks and review.
  • #2374 touches only the bridge pages (build/tools/bridges/bridges.mdx, learn/bridged-tokens/bridges.mdx, learn/gas-fees.mdx); no shared files with this PR.
  • If finding 3 is fixed in this PR it touches learn/protocol/transactions/overview.mdx, which no other open PR from this contributor touches (#2376 and #2377 are under operate/operators/* and operate/notices/archive/*).

@palango palango left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick turnaround. channelTimeout, the OP finalization period, the Celo Sepolia FeeHandler split and the new links are all fixed, and the base fee floor still matches the chain on this head: 200 gwei on mainnet and 50 gwei on Celo Sepolia in the header extraData.

One thing I'd still block on is maxSequencerDrift. The OP cell was 1800, which is the value in force, and this commit changed it to 600 from the deploy config. Since Fjord the drift is a constant, so 600 no longer applies. Celo's 2892 is right, though, and not 1800 as suggested in the other review: celo-org/optimism's op-node has its own constant for Cel2 chains, maxSequencerDriftCelo = 1800 + 1092 = 2892 (op-node/rollup/chain_spec.go). So please set the OP cell back to 1800 and extend the note under the table to cover this row too. That also answers your question in the PR thread.

Smaller points, none blocking: the OP eip1559 and gas price oracle cells are OP's launch config and have changed since. A short note that the OP column shows launch values, or a dash in those cells, would be enough. learn/protocol/transactions/overview.mdx:37 and learn/protocol/epoch-rewards/carbon-offsetting-fund.mdx:17 still say 10% of fees go to carbon offsetting, which contradicts the FeeHandler section; a follow-up issue is fine for those. And please update the PR description, which still describes the first version.

Comment thread operate/specification/deployments.mdx Outdated
| `sequencerWindowSize` | 3600 | 3600 |
| `channelTimeout` | 300 | 300 |
| `finalizationPeriodSeconds` | 12 | 12 |
| `maxSequencerDrift` | 2892 | 600 |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since Fjord this is a protocol constant, so OP's deploy-config 600 isn't what runs; the value in force on OP is 1800, which this cell had before. Celo's 2892 is also the value in force: celo-org/optimism's op-node returns maxSequencerDriftCelo (1800 + 1092) for Cel2 chains (op-node/rollup/chain_spec.go). Please set this back to 1800.

Comment thread operate/specification/deployments.mdx Outdated
| `gasPriceOracleBaseFeeScalar` | 0 | 1368 |
| `gasPriceOracleBlobBaseFeeScalar` | 0 | 810949 |

`channelTimeout` shows the value in force: since the Granite upgrade it is a protocol constant of 50 L1 blocks on every OP Stack chain, and the deploy-config value of 300 no longer applies.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this note cover maxSequencerDrift as well? Something like: since Fjord it is a constant of 1800 seconds, and 2892 on Celo, whose op-node adds 1092 seconds on top.

…onstant, OP mutable rows, learn fee split)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@eddiemessiah
eddiemessiah requested a review from a team as a code owner October 8, 2026 10:01
@eddiemessiah eddiemessiah changed the title docs(fees): document the post-Jovian base fee floor and current FeeHandler split docs(fees): document the post-Jovian base fee floor and FeeHandler splits on mainnet and Celo Sepolia Oct 8, 2026
@eddiemessiah

Copy link
Copy Markdown
Contributor Author

Head is now d2e2cbd2 (fast-forward on top of c873b0fd). Thanks both. Point by point:

  1. maxSequencerDrift and the note under the table: FIXED. OP is back to 1800 and the note now covers both rows: "channelTimeout and maxSequencerDrift show the values in force. The Granite and Fjord upgrades made them protocol constants: 50 L1 blocks for channelTimeout, and 1800 seconds for maxSequencerDrift, which Celo's op-node raises by 1092 seconds to 2892 because the sequencer waits for L1 finality." Celo stays at 2892, following @palango: celo-org/optimism at 3357d43a (celo-rebase-18), op-node/rollup/chain_spec.go, MaxSequencerDrift(t) returns maxSequencerDriftCelo = maxSequencerDriftFjord + 1092 when IsCel2(t), and Celo's rollup.json has cel2_time 0 and fjord_time 0. OP's Fjord time is 1720627201 in the Superchain Registry op.toml.

  2. Stale OP eip1559* and gasPriceOracle* cells: FIXED. Those five OP cells are now -, and one sentence says OP Mainnet can change them in its SystemConfig, with a link to OP Mainnet's entry in the Superchain Registry. Celo's values are unchanged. I re-read OP's SystemConfig 0x229047fe…B290 (Ethereum block 26146882) and got the same values you did: 5227, 1014213, 250, 2.

  3. 10% carbon / 90% bullets in learn/protocol/transactions/overview.mdx: FIXED. The section is now one sentence: "Celo governance sets how the FeeHandler splits collected fees; see Transaction fees for the current split." The 10% line on learn/protocol/epoch-rewards/carbon-offsetting-fund.mdx:17 (which @palango flagged) is the same fact, so it now links to the same section. A repo-wide search finds no other fee-split percentages.

  4. PR description: FIXED. Rewritten to match this head. It drops the stale residual-risk items and the 50-vs-300 question, uses the /build/tools/... paths, covers the Celo Sepolia split and the Learn pages, and adds the preview evidence. The title now mentions both networks' FeeHandler splits.

Preview on this head with mint dev, at 1280px and 412px: Deployments, Transaction fees, and both Learn pages return 200 with the new text, have no page-level horizontal overflow and show 0 console errors. The #feehandler and #base-fee-floor anchors resolve.

@palango palango left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this addresses everything from my last two reviews. maxSequencerDrift is back to 1800 for OP and the note now covers it; I checked the 2892 and the finality reason against chain_spec.go in celo-org/optimism. The dashes in the OP column with the Superchain Registry link are a good way to handle the values OP can change, and it's good that the Learn pages got fixed here rather than in a follow-up. The FeeHandler splits still match what's on chain. mint broken-links passes locally on this head. The repo's Documentation Validation workflow hasn't run on the PR yet, so a maintainer needs to approve that run before this can merge.

@GigaHierz GigaHierz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed the current head: the findings from the earlier review are resolved, the diff merges cleanly into current main, and the changed claims still check out.

@GigaHierz
GigaHierz merged commit 69759c4 into celo-org:main Oct 8, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants