logoAcademy

Dynamic Fee Configuration

Dynamically configure transaction fees on the Avalanche network.

Configuring Dynamic Fees​

You can configure the parameters of the dynamic fee algorithm on chain using the FeeConfigManager. In order to activate this feature, you will need to provide the FeeConfigManager in the genesis:

{
  "config": {
    "feeManagerConfig": {
      "blockTimestamp": 0,
      "adminAddresses": ["0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"]
    }
  }
}

The precompile implements the FeeManager interface which includes the same AllowList interface used by ContractNativeMinter, TxAllowList, etc.

The Stateful Precompile contract powering the FeeConfigManager adheres to the following Solidity interface at 0x0200000000000000000000000000000000000003 (you can load this interface and interact directly in Remix).

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IAllowList.sol";
 
interface IFeeManager is IAllowList {
  struct FeeConfig {
    uint256 gasLimit;
    uint256 targetBlockRate;
    uint256 minBaseFee;
    uint256 targetGas;
    uint256 baseFeeChangeDenominator;
    uint256 minBlockGasCost;
    uint256 maxBlockGasCost;
    uint256 blockGasCostStep;
  }
  event FeeConfigChanged(
    address indexed sender,
    FeeConfig oldFeeConfig,
    FeeConfig newFeeConfig
  );
 
  // Set fee config fields to contract storage
  function setFeeConfig(
    uint256 gasLimit,
    uint256 targetBlockRate,
    uint256 minBaseFee,
    uint256 targetGas,
    uint256 baseFeeChangeDenominator,
    uint256 minBlockGasCost,
    uint256 maxBlockGasCost,
    uint256 blockGasCostStep
  ) external;
 
  // Get fee config from the contract storage
  function getFeeConfig()
    external
    view
    returns (
      uint256 gasLimit,
      uint256 targetBlockRate,
      uint256 minBaseFee,
      uint256 targetGas,
      uint256 baseFeeChangeDenominator,
      uint256 minBlockGasCost,
      uint256 maxBlockGasCost,
      uint256 blockGasCostStep
    );
 
  // Get the last block number changed the fee config from the contract storage
  function getFeeConfigLastChangedAt()
    external
    view
    returns (uint256 blockNumber);
}

FeeConfigManager precompile uses IAllowList interface directly, meaning that it uses the same AllowList interface functions like readAllowList and setAdmin, setManager, setEnabled, setNone.

In addition to the AllowList interface, the FeeConfigManager adds the following capabilities:

  • getFeeConfig: retrieves the current dynamic fee config
  • getFeeConfigLastChangedAt: retrieves the timestamp of the last block where the fee config was updated
  • setFeeConfig: sets the dynamic fee config on chain (see here for details on the fee config parameters). This function can only be called by an Admin, Manager or Enabled address.
  • FeeConfigChanged: an event that is emitted when the fee config is updated. Topics include the sender, the old fee config, and the new fee config.

You can also get the fee configuration at a block with the eth_feeConfig RPC method.

Initial Fee Config Configuration​

It's possible to enable this precompile with an initial configuration to activate its effect on activation timestamp. This provides a way to define your fee structure to take effect at the activation.

To use the initial configuration, you need to specify the fee config in initialFeeConfig field in your genesis or upgrade file:

{
  "config": {
    "feeManagerConfig": {
      "blockTimestamp": 0,
      "adminAddresses": ["0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"],
      "initialFeeConfig": {
        "gasLimit": 15000000,
        "minBaseFee": 25000000000,
        "targetGas": 15000000,
        "baseFeeChangeDenominator": 36,
        "minBlockGasCost": 0,
        "maxBlockGasCost": 1000000,
        "targetBlockRate": 2,
        "blockGasCostStep": 200000
      }
    }
  }
}

This will set the fee config to the values specified in the initialFeeConfig field.

On this page