> ## Documentation Index
> Fetch the complete documentation index at: https://docs.celo.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Transaction Fees

> How transaction fees work on Celo, including the differences from Ethereum and the OP Stack

## Overview

While you can send transactions on Celo as you do on any Ethereum or OP-Stack chain, there are some key differences that are relevant if you want a deeper understanding:

* **[Fee Abstraction](/operate/specification/fee-abstraction)**, which allows users to pay for transaction fees in ERC20 tokens instead of CELO and is covered in its own chapter
* **[Zero L1 & Operator Fees](#zero-l1--operator-fees)**, meaning that the OP-Stack L1 & Operator fees are configured to always be zero, so that Celo chains don't incur any fees on top of the normal Ethereum transaction fees
* The **[base fee floor](#base-fee-floor)**, which sets a lower limit for a block's base fee
* The **[FeeHandler](#feehandler)** contract that decides what to do with the collected base fees

## Zero L1 & Operator Fees

OP-Stack supports charging transaction senders an [L1 data fee](https://docs.optimism.io/stack/transactions/fees#l1-data-fee), which is added on top of the normal transaction fees and can't be directly influenced or limited by the tx sender. The fee is meant to cover the cost of L1 transactions, especially for data availability. Since CELO uses EigenDA, the data availability costs are low and predictable, so that this mechanism is not needed.

The L1 fees are configured to zero by setting the `gasPriceOracleBaseFeeScalar` and `gasPriceOracleBlobBaseFeeScalar` to zero, so that the L1 fee formula always returns zero. The `GasPriceOracle` will also correctly return zero as a result, so that you don't have to change your code if you are already relying on the `GasPriceOracle` due to supporting other OP-Stack chains.

The [Isthmus](/operate/specification/upgrades/isthmus) upgrade also introduces an [Operator fee](https://specs.optimism.io/protocol/isthmus/exec-engine.html#operatorfees), which is a configurable cost designed to price chain-specific resources such as Alt-DA storage or ZK proving. Celo disables this charge as well by setting both `operatorFeeScalar` and `operatorFeeConstant` to `0`.

If you are coming from Ethereum, not having L1 data and operator fees is what you are used to, and you will feel right at home on Celo.

## Base fee floor

Celo follows the usual [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) rules to determine a block's base fee with one modification: the base fee can't fall below a certain limit, the base fee floor. This prevents the chain from being spammed with unimportant transactions that will make the chain state grow rapidly and make future scaling harder. The floor is set low enough to keep fees below \$0.01 for a typical transaction.

The base fee floor is the `minBaseFee` value introduced by the [Jovian upgrade](/operate/specification/upgrades/jovian). It is set in the L1 `SystemConfig` contract and encoded in the `extraData` field of every L2 block header, next to the EIP-1559 denominator and elasticity: bytes 9 to 16 hold the floor in wei as a big-endian `u64`. The current value for each network is listed on [Deployments](/operate/specification/deployments). The floor is denominated in native CELO token. If Fee Abstraction is used to pay in other tokens, the base fee is converted to the token's value at the current exchange rate.

## FeeHandler

All base fees are sent to the [FeeHandler](/build/tools/contracts/core-contracts#celo-mainnet) contract, which decides what to do with the fees. Celo governance sets how the FeeHandler splits them between burning, carbon offsetting and other beneficiaries. On Celo Mainnet the burn fraction and the carbon fraction are both 0, and a single other beneficiary, registered under the name `cLabs`, receives 100% of the fees. On Celo Sepolia the FeeHandler has the same address but a different split: the burn fraction is 20% and the carbon fraction is 80%, with no other beneficiaries, as returned by `getBurnFraction()` and `getCarbonFraction()`.

To read the current split, call `getBurnFraction()`, `getCarbonFraction()`, `getOtherBeneficiariesAddresses()` and `getOtherBeneficiariesInfo(address)` on the FeeHandler. Fractions are fixed-point values where `10^24` is 100%.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.