Skip to content

Commit

Permalink
feat: limit EVM max gas refund to 150% of used gas
Browse files Browse the repository at this point in the history
- Encourages more accurate gas estimation
- Previously, 100% of unused gas was refunded
  • Loading branch information
blindchaser committed Aug 29, 2024
1 parent 67b7bcc commit 4c82168
Showing 1 changed file with 21 additions and 13 deletions.
34 changes: 21 additions & 13 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,31 +471,39 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
}

func (st *StateTransition) refundGas(refundQuotient uint64) uint64 {
// Apply refund counter, capped to a refund quotient
refund := st.gasUsed() / refundQuotient
if refund > st.state.GetRefund() {
refund = st.state.GetRefund()
// Calculate state change refund
stateRefund := st.gasUsed() / refundQuotient
if stateRefund > st.state.GetRefund() {
stateRefund = st.state.GetRefund()
}

if st.evm.Config.Tracer != nil && st.evm.Config.Tracer.OnGasChange != nil && refund > 0 {
st.evm.Config.Tracer.OnGasChange(st.gasRemaining, st.gasRemaining+refund, tracing.GasChangeTxRefunds)
// Calculate the total refund (unused gas + state refund)
totalRefund := st.gasRemaining + stateRefund

// Calculate the maximum refund allowed (150% of gas used)
maxRefund := st.gasUsed()/2 + st.gasUsed()

// Ensure the refund does not exceed the maximum allowed
if totalRefund > maxRefund {
totalRefund = maxRefund
}

st.gasRemaining += refund
// Update gasRemaining
st.gasRemaining += stateRefund

// Return ETH for remaining gas, exchanged at the original rate.
remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gasRemaining), st.msg.GasPrice)
st.state.AddBalance(st.msg.From, remaining, tracing.BalanceIncreaseGasReturn)
// Return ETH for total refund, exchanged at the original rate.
totalRefundValue := new(big.Int).Mul(new(big.Int).SetUint64(totalRefund), st.msg.GasPrice)
st.state.AddBalance(st.msg.From, totalRefundValue, tracing.BalanceIncreaseGasReturn)

// Notify the tracer about the gas change
if st.evm.Config.Tracer != nil && st.evm.Config.Tracer.OnGasChange != nil && st.gasRemaining > 0 {
st.evm.Config.Tracer.OnGasChange(st.gasRemaining, 0, tracing.GasChangeTxLeftOverReturned)
}

// Also return remaining gas to the block gas counter so it is
// available for the next transaction.
// Update gas pool
st.gp.AddGas(st.gasRemaining)

return refund
return stateRefund
}

// gasUsed returns the amount of gas used up by the state transition.
Expand Down

0 comments on commit 4c82168

Please sign in to comment.