// Copyright 2021 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . package misc import ( "fmt" "math/big" "github.com/scroll-tech/go-ethereum/core/types" "github.com/scroll-tech/go-ethereum/params" ) // Protocol-enforced maximum L2 base fee. // We would only go above this if L1 base fee hits 2931 Gwei. const MaximumL2BaseFee = 10000000000 // L2 base fee formula constants and defaults. // l2BaseFee = (l1BaseFee * scalar) / PRECISION + overhead. // `scalar` accounts for finalization costs. `overhead` accounts for sequencing and proving costs. // we use 1e18 for precision to match the contract implementation. var ( BaseFeePrecision = new(big.Int).SetUint64(1e18) DefaultBaseFeeScalar = new(big.Int).SetUint64(34000000000000) DefaultBaseFeeOverhead = new(big.Int).SetUint64(15680000) ) // VerifyEip1559Header verifies some header attributes which were changed in EIP-1559, // - gas limit check // - basefee check func VerifyEip1559Header(config *params.ChainConfig, parent, header *types.Header) error { // Verify that the gas limit remains within allowed bounds if err := VerifyGaslimit(parent.GasLimit, header.GasLimit); err != nil { return err } // Verify the header is not malformed if header.BaseFee == nil { return fmt.Errorf("header is missing baseFee") } // note: we do not verify L2 base fee, the sequencer has the // right to set any base fee below the maximum. L2 base fee // is not subject to L2 consensus or zk verification. if header.BaseFee.Cmp(big.NewInt(MaximumL2BaseFee)) > 0 { return fmt.Errorf("invalid baseFee: have %s, maximum %d", header.BaseFee, MaximumL2BaseFee) } return nil } // CalcBaseFee calculates the basefee of the header. func CalcBaseFee(config *params.ChainConfig, parent *types.Header, parentL1BaseFee *big.Int) *big.Int { if config.Clique != nil && config.Clique.ShadowForkHeight != 0 && parent.Number.Uint64() >= config.Clique.ShadowForkHeight { return big.NewInt(10000000) // 0.01 Gwei } scalar := config.Scroll.BaseFeeScalar if scalar == nil { scalar = DefaultBaseFeeScalar } overhead := config.Scroll.BaseFeeOverhead if overhead == nil { overhead = DefaultBaseFeeOverhead } return calcBaseFee(scalar, overhead, parentL1BaseFee) } // MinBaseFee calculates the minimum L2 base fee based on the configured coefficients. func MinBaseFee(scalar, overhead *big.Int) *big.Int { return calcBaseFee(scalar, overhead, big.NewInt(0)) } func calcBaseFee(scalar, overhead, parentL1BaseFee *big.Int) *big.Int { baseFee := new(big.Int).Set(parentL1BaseFee) baseFee.Mul(baseFee, scalar) baseFee.Div(baseFee, BaseFeePrecision) baseFee.Add(baseFee, overhead) if baseFee.Cmp(big.NewInt(MaximumL2BaseFee)) > 0 { baseFee = big.NewInt(MaximumL2BaseFee) } return baseFee }