Commit 4f2e1063 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #1266 from ethereum-optimism/fix/prevent-too-low-fees

l2geth: prevent too low of fees from getting through
parents fc297257 735ef774
---
'@eth-optimism/l2geth': patch
---
Fix a bug in the fee logic that allowed for fees that were too low to get through
......@@ -3,6 +3,7 @@ package fees
import (
"errors"
"fmt"
"math"
"math/big"
"github.com/ethereum/go-ethereum/common"
......@@ -115,7 +116,7 @@ func PaysEnough(opts *PaysEnoughOpts) error {
return fmt.Errorf("%w: no expected fee", errMissingInput)
}
fee := opts.ExpectedFee
fee := new(big.Int).Set(opts.ExpectedFee)
// Allow for a downward buffer to protect against L1 gas price volatility
if opts.ThresholdDown != nil {
fee = mulByFloat(fee, opts.ThresholdDown)
......@@ -129,7 +130,7 @@ func PaysEnough(opts *PaysEnoughOpts) error {
if opts.ThresholdUp != nil {
// overpaying = user fee - expected fee
overpaying := new(big.Int).Sub(opts.UserFee, opts.ExpectedFee)
threshold := mulByFloat(overpaying, opts.ThresholdUp)
threshold := mulByFloat(opts.ExpectedFee, opts.ThresholdUp)
// if overpaying > threshold, return error
if overpaying.Cmp(threshold) == 1 {
return ErrFeeTooHigh
......@@ -140,9 +141,10 @@ func PaysEnough(opts *PaysEnoughOpts) error {
func mulByFloat(num *big.Int, float *big.Float) *big.Int {
n := new(big.Float).SetUint64(num.Uint64())
n = n.Mul(n, float)
value, _ := float.Uint64()
return new(big.Int).SetUint64(value)
product := n.Mul(n, float)
pfloat, _ := product.Float64()
rounded := math.Ceil(pfloat)
return new(big.Int).SetUint64(uint64(rounded))
}
// calculateL1GasLimit computes the L1 gasLimit based on the calldata and
......
......@@ -157,13 +157,40 @@ func TestPaysEnough(t *testing.T) {
},
"fee-threshold-up": {
opts: &PaysEnoughOpts{
UserFee: common.Big3,
UserFee: common.Big256,
ExpectedFee: common.Big1,
ThresholdUp: new(big.Float).SetFloat64(1.5),
ThresholdDown: nil,
},
err: ErrFeeTooHigh,
},
"fee-too-low-high": {
opts: &PaysEnoughOpts{
UserFee: new(big.Int).SetUint64(10_000),
ExpectedFee: new(big.Int).SetUint64(1),
ThresholdUp: new(big.Float).SetFloat64(3),
ThresholdDown: new(big.Float).SetFloat64(0.8),
},
err: ErrFeeTooHigh,
},
"fee-too-low-down": {
opts: &PaysEnoughOpts{
UserFee: new(big.Int).SetUint64(1),
ExpectedFee: new(big.Int).SetUint64(10_000),
ThresholdUp: new(big.Float).SetFloat64(3),
ThresholdDown: new(big.Float).SetFloat64(0.8),
},
err: ErrFeeTooLow,
},
"fee-too-low-down-2": {
opts: &PaysEnoughOpts{
UserFee: new(big.Int).SetUint64(0),
ExpectedFee: new(big.Int).SetUint64(10_000),
ThresholdUp: new(big.Float).SetFloat64(3),
ThresholdDown: new(big.Float).SetFloat64(0.8),
},
err: ErrFeeTooLow,
},
}
for name, tt := range tests {
......
......@@ -858,9 +858,6 @@ func (s *SyncService) verifyFee(tx *types.Transaction) error {
// Only count the calldata here as the overhead of the fully encoded
// RLP transaction is handled inside of EncodeL2GasLimit
expectedTxGasLimit := fees.EncodeTxGasLimit(tx.Data(), l1GasPrice, l2GasLimit, l2GasPrice)
if err != nil {
return err
}
// This should only happen if the unscaled transaction fee is greater than 18.44 ETH
if !expectedTxGasLimit.IsUint64() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment