Call for Research Proposals — up to $50,000. Deadline June 1, 2026.Apply now

ACP-283: Dynamic Minimum Gas Price

Details for Avalanche Community Proposal 283: Dynamic Minimum Gas Price

ACP283
TitleDynamic Minimum Gas Price
Author(s)Stephen Buttolph (@StephenButtolph), Martin Eckardt (@martineckardt)
StatusProposed Discussion
TrackStandards

Abstract

Proposes making the minimum gas price parameter on the C-Chain dynamically adjustable via validator voting, using the same mechanism established by ACP-176 (gas target) and ACP-226 (minimum block delay).

Currently, ACP-176 sets the minimum gas price to 1 wei, allowing spam transactions to flood the chain at near-zero cost during low-activity periods. This has been exploited by protocols such as XEN, which performs proof-of-work mining on-chain when gas prices are negligible, causing unnecessary state growth and validator resource consumption. The current defense relies on wallets artificially inflating gas prices via failing transactions — a stopgap measure costing the community several AVAX per day.

This ACP applies the proven validator voting pattern from ACP-176 and ACP-226 to the minimum gas price. Validators express their preferred minimum gas price via node configuration, and the network converges on the median preference weighted by stake. The dynamic minimum gas price acts as a true floor: during low-activity periods the floor binds, while during congestion the existing ACP-176 fee mechanism dominates unchanged. This requires no future upgrades for parameter adjustments and allows the network to organically respond to changing spam conditions.

Motivation

ACP-176 introduced a dynamic fee mechanism for the C-Chain, setting the minimum gas price MM to 1 wei — the smallest possible denomination of the native EVM asset. The rationale was that the dynamic fee mechanism would raise prices under load, making a near-zero floor acceptable for price discovery.

In practice, the lowest observed C-Chain gas prices have been on the order of 10510^5 wei (~0.0001 nAVAX), cheap enough that spam protocols like XEN remain profitable, with their own demand keeping ACP-176's price discovery from pushing prices even lower.

The validator voting mechanism for adjusting network parameters has already been proven twice on the Avalanche network:

  1. ACP-176: Validators dynamically adjust the target gas consumption rate TT
  2. ACP-226: Validators dynamically adjust the minimum block delay time

This ACP applies the same proven pattern to the minimum gas price. The benefits are:

  • No future upgrades required: Future adjustments to the minimum gas price do not require coordinated network upgrades
  • Stake-weighted convergence: The effective value converges on the median preference weighted by validator stake
  • Decentralized governance: Each validator independently sets their preference based on local assessment of network conditions

Pre-ACP-176, the C-Chain gas price was approximately 25 nAVAX. Even a minimum gas price floor of 0.01 nAVAX — 2,500x below this baseline — would be entirely invisible to normal users while making spam economically infeasible.

Specification

Block Header Changes

A single new field is added to block headers: minimumGasPriceExponent, represented as a uint64.

The value of minimumGasPriceExponent MAY be updated in each block, similar to the gas target exponent introduced in ACP-176. The mechanism is specified below.

Dynamic minimum gas price mechanism

The effective minimum gas price MM, in wei, is defined as:

M=eqDM = e^{\dfrac{q}{D}}

Where:

  • qq is a non-negative integer carried in the minimumGasPriceExponent header field, initialized to qinitialq_{initial} at activation.
  • DD is a fixed conversion constant.

Both qinitialq_{initial} and DD are specified in Activation Parameters.

After the execution of transactions in block bb, the value of qq can be increased or decreased by up to QQ. It MUST be the case that ΔqQ\left|\Delta q\right| \leq Q, or block bb is considered invalid. The amount by which qq changes after executing block bb is specified by the block builder.

Block builders (i.e., validators) MAY set their desired value for MM in their configuration via the min-price-target setting (specified in wei). Their desired value for qq is then calculated locally as:

qdesired=Dln(Mdesired)q_{desired} = \left\lceil D \cdot \ln(M_{desired}) \right\rceil

Since qdesiredq_{desired} is only used locally, it is safe for implementations to approximate the value of ln(Mdesired)\ln(M_{desired}) and round the resulting value to the nearest integer. Alternatively, client implementations MAY choose to use binary search to find the closest integer solution.

If a validator does not set min-price-target, the validator SHOULD default to the previous block's value of qq. This matches the abstention default of ACP-176 and ACP-226.

When building a block, builders calculate their next preferred value for qq based on the network's current value (q_current) according to the same procedure used in ACP-176 and ACP-226:

# Calculates a node's new desired value for q for a given block
def calc_next_q(q_current: int, q_desired: int, max_change: int) -> int:
    if q_desired > q_current:
        return q_current + min(q_desired - q_current, max_change)
    else:
        return q_current - min(q_current - q_desired, max_change)

As qq is updated after the execution of transactions within the block, MM is also updated such that M=eq/DM = e^{q/D} at all times. The change to qq in block bb takes effect for the floor used when validating and building block b+1b+1; it does not affect the gas price of transactions included in block bb itself.

Allowing block builders to adjust the minimum gas price in blocks that they produce makes it such that the effective value should converge over time to the point where 50% of the voting stake weight wants it increased and 50% of the voting stake weight wants it decreased, because the number of blocks each validator produces is proportional to their stake weight.

Compatibility with ACP-176

ACP-176 defines the per-block gas price as P=Mex/KP = M \cdot e^{x/K}, where MM is a static minimum, xx is the gas price excess, and KK is the gas price update factor. Making MM dynamic without changing the structure of this formula would require rebalancing xx on every floor change to keep PP continuous. This is workable when MM changes rarely but breaks down once MM may oscillate every block.

To support oscillating MM values, the price formula is changed to:

P=max(M,exK)P = \max\left(M, e^{\dfrac{x}{K}}\right)

The max\max enforces the floor directly: PP is never below MM, even when integer rounding of ex/Ke^{x/K} produces a value just under MM (see the bias-low case below). When M=1M = 1 wei (the value at activation), ex/K1e^{x/K} \geq 1 always, so the max\max is a no-op and the formula reduces to ACP-176's P=Mex/KP = M \cdot e^{x/K}.

The state variable xx is additionally subject to a ratchet constraint:

xxfloorx \geq x_{floor}

where xfloorx_{floor} is derived from MM via binary search over price()\text{price}(\cdot), the integer-rounded forward price function used elsewhere in block validation.

Let x=min{x:price(x)M}x^* = \min\{x : \text{price}(x) \geq M\}:

  • If price(x)=M\text{price}(x^*) = M, xfloor=xx_{floor} = x^*.
  • If price(x)>M\text{price}(x^*) > M (the integer-rounded price function cannot represent MM exactly), xfloor=x1x_{floor} = x^* - 1, the largest integer where price(xfloor)<M\text{price}(x_{floor}) < M.

The second case biases toward the lower price when MM is not exactly representable by price()\text{price}(\cdot), keeping the floor enforcement consistent with prices the implementation actually produces. Implementations MUST use this binary-search procedure rather than evaluating the closed-form qK/D\left\lceil q \cdot K / D \right\rceil, which may diverge from price()\text{price}(\cdot).

After updating qq for the new block, the block-execution rule is:

  1. If the current x<xfloorx < x_{floor}, set xxfloorx \leftarrow x_{floor}.
  2. Otherwise, leave xx unchanged.

In particular, xx is never reduced as a consequence of a floor change. A decrease in qq relaxes the constraint but does not modify xx.

Activation Parameters

The only value this ACP specifies is BlocksToDouble; the remaining values are either derived from it or set implicitly.

Parameters

ParameterDescriptionValue
BlocksToDoublemax-change blocks required to halve or double MM3,6003{,}600

BlocksToDouble expresses the number of consecutive maximum-change blocks required to halve or double MM under sustained voting pressure, from which QQ is mechanically derived. A value of 3,6003{,}600 corresponds to roughly one hour at one-second block times, the current C-Chain block rate.

Constants

ConstantDescriptionValue
DDexponential-update conversion constant415,828,534,307,635,077415{,}828{,}534{,}307{,}635{,}077
QQper-block max Δq\left\|\Delta q\right\|80,063,993,375,47580{,}063{,}993{,}375{,}475
qinitialq_{initial}initial value of minimumGasPriceExponent00

DD is fully determined by the type constraint. The allowed range of MM is [1,264)[1, 2^{64}) wei (the full uint64 range), realized when qq ranges over [0,264)[0, 2^{64}).

Setting Mmax=qmax=2641M_{max} = q_{max} = 2^{64}-1 and solving for DD:

Mmax=eqmax/Dln(Mmax)=qmaxDD=qmaxln(Mmax)=2641ln(2641)\begin{align} M_{max} &= e^{q_{max}/D} \\ \ln(M_{max}) &= \dfrac{q_{max}}{D} \\ D &= \left\lfloor \dfrac{q_{max}}{\ln(M_{max})} \right\rfloor \\ &= \left\lfloor \dfrac{2^{64}-1}{\ln(2^{64}-1)} \right\rfloor \end{align}

QQ is derived from DD and BlocksToDouble:

Q=Dln(2)BlocksToDoubleQ = \left\lfloor \dfrac{D \cdot \ln(2)}{\text{BlocksToDouble}} \right\rfloor

qinitial=0q_{initial} = 0 means the effective minimum gas price at activation is M=e0=1M = e^0 = 1 wei, identical to the pre-activation value. Activation introduces the mechanism but does not change any user-visible parameter; subsequent movement of the floor requires explicit validator votes.

Choosing min-price-target

This new mechanism allows for validators to specify their desired minimum gas price (MdesiredM_{desired}) in their configuration via the min-price-target setting (specified in wei), and the value that they set impacts the effective minimum gas price of the network over time. When choosing what value makes sense for them, validators should consider:

  • The cost of spam during low-activity periods (the floor primarily binds when there is limited organic demand to drive the ACP-176 base fee).
  • The risk of pricing out legitimate users.
  • The trajectory of organic gas prices.

While Avalanche Network Clients MAY suggest reference values, each validator chooses min-price-target independently. The default behavior SHOULD be to abstain.

Backwards Compatibility

The changes proposed in this ACP require a network upgrade in order to take effect. Prior to its activation, the current minimum gas price of 1 wei continues to apply. Its activation should have minimal compatibility effects:

  • Transaction formats: Unchanged. Wallets and transaction signing are not impacted.
  • User fees: Activation does not change the effective minimum gas price — the initial value remains 1 wei, identical to the pre-activation behavior. The mechanism enables future increases, which validators must explicitly vote for.
  • Tooling: Any tooling parsing the RLP block bytes will need to update.
  • Gas price estimation APIs: eth_gasPrice and related APIs will need to respect the new dynamic minimum gas price floor.

Reference Implementation

This section will be updated with a tagged release once a complete reference implementation has been merged.

Security Considerations

This ACP changes the minimum gas price from a static constant to a dynamically-adjusted parameter governed by validator voting. Several security aspects should be considered:

Validators setting the minimum gas price too high: The exponential mechanism bounds how quickly the minimum gas price can change per block. With BlocksToDouble = 3,600 (approximately one hour at one-second block times), the floor cannot halve or double in less than that many consecutive maximum-change blocks, giving the community time to detect and respond to concerning changes. There is no policy ceiling on the floor; the implicit ceiling at M=2641M = 2^{64}-1 wei is an artifact of the uint64 representation of qq, not a design choice. Validators are also economically incentivized not to price out users, as doing so reduces network utility and the value of their staked AVAX.

Validators setting the minimum gas price too low: The same bounded adjustment speed applies in the downward direction, providing significant time for detection and response.

Comparison to existing approaches: The minimum gas price adjustment mechanism has the same structure as the proven gas target adjustment (ACP-176) and minimum block delay adjustment (ACP-226), providing confidence in its security properties. Compared to Base's approach of administrator-set static floors, the validator voting mechanism achieves the same spam deterrence in a decentralized manner.

Copyright and related rights waived via CC0.

Is this guide helpful?