From e91edd3c607ce1a18c036d1c1b2229c89346f36a Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Fri, 15 Jul 2022 04:32:54 -0500 Subject: [PATCH] core: prevent negative fee during RPC calls (#25214) During RPC calls such as eth_call and eth_estimateGas, st.evm.Config.NoBaseFee is set which allows the gas price to be below the base fee. This results the tip being negative, and balance being subtracted from the coinbase instead of added to it, which results in a potentially negative coinbase balance interestingly. This can't happen during normal chain processing as outside of RPC calls the gas price is required to be at least the base fee, as NoBaseFee is false. This change prevents this behavior by disabling fee payment when the fee is not set. Co-authored-by: lightclient@protonmail.com Co-authored-by: Felix Lange --- core/state_transition.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/core/state_transition.go b/core/state_transition.go index 3b5f81b16632..0946c0372e2f 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -344,7 +344,16 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { if rules.IsLondon { effectiveTip = cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee)) } - st.state.AddBalance(st.evm.Context.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveTip)) + + if st.evm.Config.NoBaseFee && st.gasFeeCap.Sign() == 0 && st.gasTipCap.Sign() == 0 { + // Skip fee payment when NoBaseFee is set and the fee fields + // are 0. This avoids a negative effectiveTip being applied to + // the coinbase when simulating calls. + } else { + fee := new(big.Int).SetUint64(st.gasUsed()) + fee.Mul(fee, effectiveTip) + st.state.AddBalance(st.evm.Context.Coinbase, fee) + } return &ExecutionResult{ UsedGas: st.gasUsed(),