Skip to main content
This guide shows how to send transactions that pay gas fees in ERC20 tokens instead of CELO. For background on how fee abstraction works, see the Overview.

Allowlisted Fee Currencies

The protocol maintains a governable allowlist of smart contract addresses that can be used as fee currencies. These contracts implement an extension of the ERC20 interface with additional functions for debiting and crediting transaction fees (see Adding Fee Currencies). To fetch the current allowlist, call getCurrencies() on the FeeCurrencyDirectory contract, or use celocli:

Adapters for Non-18-Decimal Tokens

Allowlisted addresses may be adapters rather than full ERC20 tokens. Adapters are used when a token has decimals other than 18 (e.g., USDC and USDT use 6 decimals). The Celo blockchain calculates gas pricing in 18 decimals, so adapters normalize the value.
  • For transfers: use the token address as usual.
  • For feeCurrency: use the adapter address.
  • For balanceOf: querying via the adapter returns the balance as if the token had 18 decimals — useful for checking whether an account can cover gas without converting units.
To get the underlying token address for an adapter, call adaptedToken() on the adapter contract. For more on gas pricing, see Gas Pricing.

Adapter Addresses

Mainnet

Celo Sepolia (Testnet)


Using Fee Abstraction with Celo CLI

Transfer 1 USDC using USDC as the fee currency via celocli:
When using USDC or USDT, use the adapter address (not the token address) as --gasCurrency. Both tokens use 6 decimals — pass --value in units of 10^6 (e.g. 1000000 = 1 USDT/USDC). Transfer 1 USDT using USDT as the fee currency:

Using Fee Abstraction with viem

We recommend viem, which has native support for the feeCurrency field. Ethers.js and web3.js do not currently support this field.

1. Estimate the Gas Fee

Before sending, estimate the transaction fee so the UI can reserve that amount and prevent users from trying to transfer more than their available balance.
The gas price returned from the RPC is always expressed in 18 decimals, regardless of the fee currency.
Use the adapter address (for USDC/USDT) or token address (for USDm, EURm, BRLm) as the feeCurrency value when estimating.

2. Prepare the Transaction

Set feeCurrency to the adapter address (USDC/USDT) or token address (USDm, EURm, BRLm). Use transaction type 123 (0x7b), which is CIP-64 compliant.

3. Send the Transaction

The example below transfers 1 USDC, subtracting the estimated fee from the transfer amount so the sender’s full balance is not over-spent.

If you have any questions, please reach out.