Repository navigation
docs(fees): document the post-Jovian base fee floor and FeeHandler splits on mainnet and Celo Sepolia - #2375
Conversation
GigaHierz
left a comment
There was a problem hiding this comment.
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
-
Medium ·
operate/specification/deployments.mdx:57(channelTimeoutrow)- 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.jsonhas"channelTimeout": 50, androllup.jsonhas"granite_time": 0, so Granite is active from genesis. The OP Granite spec (specs/protocol/granite/derivation.md) reducesCHANNEL_TIMEOUTfrom 300 to 50 as a protocol constant. Sorollup.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.jsonand Granite).
- Defect: the row still says 300 for Celo, but the file the PR used to correct the neighbouring rows says otherwise.
-
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_gasPriceof 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.
-
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%) andgetBurnFraction()= 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).
- 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
-
Low ·
operate/specification/transaction-fees.mdx:25and:31(headings),operate/specification/deployments.mdx:53-65(OPcolumn)- Defect: (a) the PR keeps
## Base Fee Floorand## FeeHandlercasing "so the anchor keeps working", but Mintlify slugs are lowercased and hyphenated, so## Base fee floorstill yields#base-fee-floor. AGENTS.md section 3 asks for sentence case on pages you are already editing. (b) TheOPcolumn 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.
- Defect: (a) the PR keeps
Verified good
- Floor on chain.
eth_getBlockByNumber lateston forno mainnet (block 79381384):extraData0x0100000190000000050000002e90edd000,baseFeePerGas200.0 gwei; decoded version 1, denominator 400, elasticity 5,minBaseFeebytes [9,17) = 200 gwei. Celo Sepolia block 37998153:...0000000ba43b7400= 50 gwei, base fee 50 gwei. Matches the OP Jovian exec-engine spec (minBaseFeeis a big-endianu64at byte offset[9, 17)); "bytes 9 to 16" in the page is the same range written inclusively. - L1 source.
SystemConfig.minBaseFee()at0x760a5f022c9940f4a074e0030be682f560d29818(Ethereum Sepolia) returns 50000000000; at0x89E31965D844a309231B1f17759Ccaf1b7c09861(Ethereum mainnet, read through drpc because publicnode did not resolve here) returns 200000000000. Both addresses matchtooling/contracts/l1-contracts.mdx. - Deployments facts. Block gas limit 30,000,000 observed; 30M / elasticity 5 = 6M target as listed.
sequencerWindowSize7200 andfinalizationPeriodSeconds604800 (7 days) matchconfig.json, androllup.jsonseq_window_sizeis 7200.config.jsonstill carries the 25 gweieip1559BaseFeeFloor, but Jovian is active on mainnet (jovian_time1774958788) and the header value is what governs, so dropping the row is right. - FeeHandler (Celo Mainnet). Registry
getAddressForString("FeeHandler")returns0xcD437749E43A154C07F3553504c68fBfD56B8778(matchestooling/contracts/core-contracts.mdx);getBurnFraction()0;getCarbonFraction()0;getTotalFractionOfOtherBeneficiariesAndCarbon()1e24;getOtherBeneficiariesAddresses()is the single address0x7A1E98FC9a008107DbD1f430a05Ace8cf6f3FE19;getOtherBeneficiariesInfo(...)returns (1e24, "cLabs", true);owner()equals the Registry'sGovernance(0xD533Ca259b330c7A88f74E000a3FaEa2d63B7972). "10^24 is 100%" is the Fixidity unit. All as the page states. - FeeCurrencyDirectory. Registry returns
0x15F344b9E6c3Cb6F0376A36A64928b13F62C6276(matches core-contracts);getCurrencies()on the old0x71FFbD48E34bdD5a87c3c683E866dc63b8B2a685reverts 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:83stays consistent. The L1-era "80% burn, 20% carbon" text appears nowhere else;smart-contract-updates-from-l1.mdxalready describes the multi-beneficiary FeeHandler. "Block period: 1 second" is untouched. - Links by hand:
/operate/specification/upgrades/jovian,/operate/specification/deployments,#base-fee-floorand/tooling/contracts/core-contracts#celo-mainnetall 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/2375is clean and a rebase needs no manual step. - #2368 (Build tab, not landed) renames
tooling/contracts/core-contractstobuild/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-runmint 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
left a comment
There was a problem hiding this comment.
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.
| | `sequencerWindowSize` | 7200 | 3600 | | ||
| | `channelTimeout` | 300 | 300 | | ||
| | `finalizationPeriodSeconds` | 12 | 12 | | ||
| | `finalizationPeriodSeconds` | 604800 | 12 | |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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.
|
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. |
|
Previewed in a local live deployment (
Each page returns 200 and renders the new text, with no horizontal overflow on phone, no broken images and 0 console errors. |
…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>
efedf53 to
c873b0f
Compare
|
Head is now
One question on Checks on this head:
#2368 has merged, so the two new links now point at |
GigaHierz
left a comment
There was a problem hiding this comment.
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
channelTimeoutleft 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.jsonhas"channelTimeout": 50; the OP Granite spec says "With Granite, theCHANNEL_TIMEOUTis reduced from 300 to 50 L1 Blocks";op-nodeChainSpec.ChannelTimeout(t)returns the Granite constant onceIsGranite(t); Celo'srollup.jsonhasgranite_time0.- "below 0.01 USD" claim after the floor rose: FIXED.
transaction-fees.mdx:27now 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. - Celo Sepolia FeeHandler split omitted: FIXED.
transaction-fees.mdx:33states burn 20% and carbon 80% with no other beneficiaries. On chain: SepoliagetBurnFraction()2e23,getCarbonFraction()8e23,getOtherBeneficiariesAddresses()empty; mainnet 0, 0, and the single address0x7A1E...FE19registered ascLabsat 1e24. ## Base Fee Floorheading case: FIXED. It is## Base fee floor, the rendered id is stillbase-fee-floor, and the#base-fee-floorlinks ontransaction-fees.mdx:12anddeployments.mdx:68still resolve. The two typos in that paragraph are fixed too.- OP column unverified: PARTLY FIXED.
sequencerWindowSize3600,finalizationPeriodSeconds604800 (OP's portalproofMaturityDelaySecondsreads 604800 on chain) andchannelTimeout50 are right. See findings 1 and 2 for the rest. - Links to
/tooling/contracts/core-contracts#celo-mainnet: FIXED.transaction-fees.mdx:33andnative-bridge.mdx:28now point at/build/tools/contracts/core-contracts#celo-mainnet; both render as links andid="celo-mainnet"exists on that page. No/tooling/link remains in any.mdx.
New findings
-
Medium ·
operate/specification/deployments.mdx:55and:66(maxSequencerDriftrow and the note under the table)- Defect: the new note says the table shows the value in force for
channelTimeout, but themaxSequencerDriftrow 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 makesmax_sequencer_drifta constant of 1800 seconds ("Constant Maximum Sequencer Drift"), andop-nodeChainSpec.MaxSequencerDrift(t)returns the 1800 constant once Fjord is active. Celo hasfjord_time0 inrollup.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 "
channelTimeoutandmaxSequencerDriftshow 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.
- Defect: the new note says the table shows the value in force for
-
Low ·
operate/specification/deployments.mdx:60-64(OP cells foreip1559*andgasPriceOracle*)- 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
SystemConfigon 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.
- 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
-
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.
- 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
-
Low · PR description (not a file)
- Defect: the body still describes the head before this commit: "
channelTimeoutis 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 Floorkeeps its heading", links to/tooling/contracts/core-contracts, "Branched offmainat50ed71d", 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).
- Defect: the body still describes the head before this commit: "
Verified good
- Floor on chain:
eth_getBlockByNumber lateston forno mainnet (block 79414760):extraData0x0100000190000000050000002e90edd000,baseFeePerGas200 gwei; decoded version 1, denominator 400, elasticity 5,minBaseFeeat 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_gasPriceis 202.5 gwei mainnet and 52.5 gwei Sepolia. - L1 source:
SystemConfig.minBaseFee()at0x89E31965D844a309231B1f17759Ccaf1b7c09861returns 200000000000 (Ethereum mainnet). - FeeHandler: Registry
getAddressForString("FeeHandler")returns0xcD437749E43A154C07F3553504c68fBfD56B8778on both networks ("same address" is true);getTotalFractionOfOtherBeneficiariesAndCarbon()1e24 on mainnet;getOtherBeneficiariesInfo(0x7A1E98FC9a008107DbD1f430a05Ace8cf6f3FE19)returns (1e24, "cLabs", true);owner()equals the Registry'sGovernanceon mainnet (0xD533Ca259b330c7A88f74E000a3FaEa2d63B7972) and on Sepolia (0x50d2f15CcF5E97999bDf9D6760d0208b00D14ad1), so "Celo governance sets" holds for both.10^24is 100% (Fixidity). - FeeCurrencyDirectory: Registry returns
0x15F344b9E6c3Cb6F0376A36A64928b13F62C6276on mainnet, matching the core contracts table;getCurrencies()on the old0x71FFbD48...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;
sequencerWindowSize7200 andfinalizationPeriodSeconds604800 matchconfig.jsonandrollup.json; the removedeip1559BaseFeeFloorrow (25 gwei inconfig.json) no longer governs becausejovian_time1774958788 has passed. - OP column values that are right:
sequencerWindowSize3600 (op.tomlseq_window_size),finalizationPeriodSeconds604800,channelTimeout50. - 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.mdxalready 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 (
## FeeHandleris 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-feesshows the canonical $0.01 sentence, "bytes 9 to 16" and the Sepolia split, with idsbase-fee-floorandfeehandler;deploymentsshows 200 and 50 Gwei and thechannelTimeoutnote;native-bridgehas the new link and no0x71FFbD48. - CI:
gh pr checks 2375lists GitGuardian and the three StepSecurity checks, all passing. The repository'smint broken-linksworkflow does not appear; it is most likely waiting for maintainer approval of the first-time-contributor run. Locallymint broken-links --check-redirectspasses 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) andgit merge-tree --write-tree origin/main refs/remotes/pr/2375is clean. GitHub reports it mergeable, with the merge stateBLOCKEDpending 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 underoperate/operators/*andoperate/notices/archive/*).
palango
left a comment
There was a problem hiding this comment.
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.
| | `sequencerWindowSize` | 3600 | 3600 | | ||
| | `channelTimeout` | 300 | 300 | | ||
| | `finalizationPeriodSeconds` | 12 | 12 | | ||
| | `maxSequencerDrift` | 2892 | 600 | |
There was a problem hiding this comment.
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.
| | `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. |
There was a problem hiding this comment.
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>
|
Head is now
Preview on this head with |
palango
left a comment
There was a problem hiding this comment.
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
left a comment
There was a problem hiding this comment.
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.
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.mdxlisted "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 JovianminBaseFeein every block header'sextraDataand in the L1SystemConfig. The page now lists those values and notes Sepolia differs only in the floor.eip1559BaseFeeFloor(no longer what sets the floor) and hadsequencerWindowSize3600,channelTimeout300 andfinalizationPeriodSeconds12 for Celo. The table now shows:sequencerWindowSize7200 andfinalizationPeriodSeconds604800 for Celo (published mainnet deploy config), andfinalizationPeriodSeconds604800 for OP.channelTimeout50 on both chains, andmaxSequencerDrift2892 for Celo and 1800 for OP: the values in force. Granite madechannelTimeouta protocol constant of 50 L1 blocks, and Fjord mademaxSequencerDrifta 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 foreip1559Denominator,eip1559DenominatorCanyon,eip1559Elasticity,gasPriceOracleBaseFeeScalarandgasPriceOracleBlobBaseFeeScalar. OP Mainnet can change these in itsSystemConfig, 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.eip1559BaseFeeFloorrow is removed, and one sentence under the table points to where the floor lives now.operate/specification/transaction-fees.mdxsaid the floor comes fromeip1559BaseFeeFloor. It now describesminBaseFee(L1SystemConfig, encoded inextraDatabytes 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-flooranchor 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.cLabsat 100%.learn/protocol/transactions/overview.mdxsaid 10% of fees go to carbon offsetting and 90% to network operations, andlearn/protocol/epoch-rewards/carbon-offsetting-fund.mdxsaid 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.mdxhardcoded theFeeCurrencyDirectoryas0x71FFbD48E34bdD5a87c3c683E866dc63b8B2a685. On mainnet that address reverts with "No Implementation set"; the Registry returns0x15F344b9E6c3Cb6F0376A36A64928b13F62C6276, 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
WETH" innative-bridge.mdxwas not re-verified and is unchanged.minBaseFeeand OP Mainnet'sSystemConfigvalues are governance- or owner-controlled and can change; the docs state current values and how to read them.Judgement calls
eip1559BaseFeeFloorrow was removed rather than kept with a caveat, since it no longer controls the floor.channelTimeoutandmaxSequencerDriftshow the values in force rather than the deploy-config values, with a note naming the overridden values.-instead of a snapshot of OP's current values, so this page does not have to track another chain's settings.cLabs) and does not print its address; the getters return it.## FeeHandlerkeeps 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-base7b8f97c2, #2368).mainhas moved since, with no overlapping files; GitHub reports the PR mergeable. Touches five files: the three underoperate/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
extraDatabaseFeePerGasgasLimit0x4bb25c3(79373763)0x0100000190000000050000002e90edd0000x2e90edd0000x1c9c3800x243b087(37990535)0x0100000190000000050000000ba43b74000xba43b74000x1c9c380Decoded per the OP Jovian exec-engine spec (version
u8at [0,1), denominatoru32at [1,5), elasticityu32at [5,9),minBaseFeeu64big-endian at [9,17)):01= 101= 100000190= 40000000190= 40000000005= 500000005= 50000002e90edd000= 200000000000 wei = 200 Gwei0000000ba43b7400= 50000000000 wei = 50 GweiBoth chains were at the floor (
baseFeePerGasequalsminBaseFee).gasLimit0x1c9c380= 30,000,000. Re-read on 2026-10-08: mainnet block 79552923 and Celo Sepolia block 38169693 return the sameextraDataand base fees.eth_gasPrice(same endpoints,{"jsonrpc":"2.0","id":1,"method":"eth_gasPrice","params":[]}): mainnet0x2f25f0c900= 202.5 Gwei, Celo Sepolia0xc393e6d00= 52.5 Gwei, both at or above the floor.2. Minimum base fee at its L1 source (
SystemConfig.minBaseFee(), selector0xa62611a2)eip1559Denominator()(0xd220a9e0) returns0x...0190(400) andeip1559Elasticity()(0xc9ff2d16) returns0x...05(5) on both. SystemConfig proxy addresses are from/build/tools/contracts/l1-contracts;l1_system_config_addressin the mainnetrollup.jsonmatches.3. OP Stack config
config.jsonkeys:"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 Sepoliaconfig.jsonis published (celo-sepolia/config.jsonreturns 404).Values in force:
channelTimeout: the OP Granite spec (specs/protocol/granite/derivation.md) reducesCHANNEL_TIMEOUTfrom 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_time1726070401 in the Superchain Registryop.toml).maxSequencerDrift: the OP Fjord spec (specs/protocol/fjord/derivation.md, "Constant Maximum Sequencer Drift") makes it a constant of 1800 seconds.celo-org/optimismat3357d43a(celo-rebase-18, the default branch),op-node/rollup/chain_spec.go:MaxSequencerDrift(t)returnsmaxSequencerDriftCelo = maxSequencerDriftFjord + 1092(2892) whenIsCel2(t)and Fjord is active, else 1800. Celo hascel2_time0 andfjord_time0; OP Mainnet's Fjord activated 2024-07-10 (fjord_time1720627201 inop.toml), and itsop.tomlmax_sequencer_driftof 600 is overridden.SystemConfig(0x229047fed2591dbec1eF1118d64F7aF3dB9EB290, theSystemConfigProxyin the Superchain Registryop.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"):Getters from
celo-monorepo/packages/protocol/contracts/common/FeeHandler.sol, called on0xcd437749e43a154c07f3553504c68fbfd56b8778on Celo Mainnet with the sameeth_callshape:getBurnFraction()0x2457380b0x00…00getCarbonFraction()0xfc0640070x00…00getTotalFractionOfOtherBeneficiariesAndCarbon()0x527e234d0x…d3c21bcecceda1000000FIXED1_UINT= 1e24)getOtherBeneficiariesAddresses()0xcbfcb68a0x…20 …01 …7a1e98fc9a008107dbd1f430a05ace8cf6f3fe19[0x7A1E98FC9a008107DbD1f430a05Ace8cf6f3FE19]getOtherBeneficiariesInfo(0x7A1E…FE19)0xe396f5630x…d3c21bcecceda1000000 …60 …01 …05 634c616273…(1e24, "cLabs", true)owner()0x8da5cb5b0x…d533ca259b330c7a88f74e000a3faea2d63b7972getAddressForString("Governance")Celo Sepolia's FeeHandler (same address, on
https://forno.celo-sepolia.celo-testnet.org) returnsgetBurnFraction()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
BaseFeeVaultpredeploy0x4200000000000000000000000000000000000019balance did not change. The increase is belowgasUsed * baseFeebecause fee-currency transactions pay their base fee in tokens.5. FeeCurrencyDirectory address
getCurrencies()on0x15F344b9…6276returns a 20-entry list. Celo Sepolia's Registry returns0x9212fb72ae65367a7c887ec4ad9be310bac611bf. Both match/build/tools/contracts/core-contracts.6. Links
npx -y mint@latest broken-linkson this machine (Windows) reports existing pages as broken, so the check compares this head withorigin/mainon 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 matchingid. No new external link other than the Superchain Registryop.toml(returns 200). CI's run on this PR is the authoritative check.7. Preview
mint devon 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-fundEach 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"andid="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
Checklist
mainlint/typecheck/testpass locally: n/a;mint broken-linksresult aboveClosesissue: noCloses.env.example/ examples / error strings updated: n/a🤖 Generated with Claude Code