Skip to main content
Any ERC20 token can become a fee currency on Celo by implementing the IFeeCurrency interface and being added to the on-chain allowlist through governance. This guide explains the interface requirements and walks through an example implementation. For background on how fee abstraction works, see the Overview.

The IFeeCurrency Interface

Fee currencies must implement the IFeeCurrency interface, which extends ERC20 with two additional functions used by the Celo blockchain to debit and credit gas fees. When a CIP-64 transaction is executed:
  1. Before execution — the blockchain calls debitGasFees to reserve the maximum gas the transaction can spend
  2. After execution — the blockchain calls creditGasFees to refund unused gas and distribute fees to the appropriate recipients

debitGasFees

Called before transaction execution to reserve the maximum gas amount.
  • Must deduct value from from’s balance
  • Must revert if msg.sender is not address(0) (only the VM may call this)

creditGasFees

There are two versions of creditGasFees. Both should be implemented for compatibility. New signature (used once all fee currencies have migrated):
  • Must credit each recipient the corresponding amount
  • Must revert if msg.sender is not address(0)
  • Must revert if recipients and amounts have different lengths
Legacy signature (for backwards compatibility):
  • _gatewayFeeRecipient and _gatewayFeeAmount are deprecated and will always be zero
  • Must revert if msg.sender is not address(0)

Example Implementation

The following example from celo-org/fee-currency-example shows a minimal fee currency token using OpenZeppelin’s ERC20 with burn/mint mechanics for gas fee handling:
This implementation uses _burn in debitGasFees and _mint in creditGasFees to handle the gas fee lifecycle. The onlyVm modifier ensures only the blockchain itself (via address(0)) can call these functions.

Testing

Use Foundry to test your fee currency implementation. The fee-currency-example repository includes a test suite you can use as a starting point:
Key things to test:
  • debitGasFees correctly reduces the sender’s balance
  • debitGasFees reverts when called by any address other than address(0)
  • Both creditGasFees signatures correctly credit all recipients
  • creditGasFees reverts when called by any address other than address(0)
  • The total debited amount equals the total credited amount across a transaction lifecycle

Registering a Fee Currency

Once your token implements IFeeCurrency, it must be added to the on-chain allowlist in FeeCurrencyDirectory.sol through a governance proposal. The governance process ensures that fee currencies meet the necessary requirements for network stability. If your token uses decimals other than 18, you will also need to deploy an adapter contract. See Adapters for Non-18-Decimal Tokens for details.