Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build-on-celo/build-on-minipay/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Request CELO testnet tokens from the Celo [faucet](https://faucet.celo.org/celo-
## Helpful Tips to Make Your Mini App MiniPay Compatible

<Warning>
MiniPay uses Custom [Fee Abstraction](/tooling/overview/fee-abstraction) based
MiniPay uses Custom [Fee Abstraction](/build-on-celo/fee-abstraction/overview) based
transactions. We recommend using viem or wagmi as they provide native support
for fee currency.
</Warning>
Expand Down
2 changes: 1 addition & 1 deletion build-on-celo/build-with-ai/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,4 @@ await sendUSDCWithFeeAbstraction("0xRecipient...", parseUnits("1", 6));
| USDT | Mainnet | [`0x48065fbbe25f71c9282ddf5e1cd6d6a887483d5e`](https://celoscan.io/address/0x48065fbbe25f71c9282ddf5e1cd6d6a887483d5e) | [`0x0e2a3e05bc9a16f5292a6170456a710cb89c6f72`](https://celoscan.io/address/0x0e2a3e05bc9a16f5292a6170456a710cb89c6f72) |
| USDC | Sepolia | [`0x2F25deB3848C207fc8E0c34035B3Ba7fC157602B`](https://sepolia.celoscan.io/address/0x2f25deb3848c207fc8e0c34035b3ba7fc157602b) | [`0x4822e58de6f5e485eF90df51C41CE01721331dC0`](https://sepolia.celoscan.io/address/0x4822e58de6f5e485eF90df51C41CE01721331dC0) |

For the full guide — including gas estimation, CIP-64 transaction types, and CLI usage — see [Implementing Fee Abstraction](/tooling/overview/fee-abstraction).
For the full guide — including gas estimation, CIP-64 transaction types, and CLI usage — see [Fee Abstraction](/build-on-celo/fee-abstraction/using-fee-abstraction).
2 changes: 1 addition & 1 deletion build-on-celo/build-with-ai/x402.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -337,4 +337,4 @@ app.get("/articles/:id", async (req, res) => {

- [ERC-8004](/build-on-celo/build-with-ai/8004) - Trust layer for AI agents
- [Agent Skills](/build-on-celo/build-with-ai/agent-skills) - Modular agent capabilities
- [Fee Abstraction](/tooling/overview/fee-abstraction) - Pay gas with stablecoins on Celo
- [Fee Abstraction](/build-on-celo/fee-abstraction/overview) - Pay gas with stablecoins on Celo
151 changes: 151 additions & 0 deletions build-on-celo/fee-abstraction/add-fee-currency.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
---
title: Adding Fee Currencies
sidebarTitle: "Adding Fee Currencies"
og:description: How to implement and register a new ERC20 token as a fee currency on Celo
---

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](/build-on-celo/fee-abstraction/overview).

---

## The IFeeCurrency Interface

Fee currencies must implement the [IFeeCurrency](https://github.com/celo-org/fee-currency-example/blob/main/src/IFeeCurrency.sol) interface, which extends ERC20 with two additional functions used by the Celo blockchain to debit and credit gas fees.

When a [CIP-64](https://github.com/celo-org/celo-proposals/blob/master/CIPs/cip-0064.md) 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

```solidity
function debitGasFees(address from, uint256 value) external;
```

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):
```solidity
function creditGasFees(address[] calldata recipients, uint256[] calldata amounts) external;
```

- 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):
```solidity
function creditGasFees(
address refundRecipient,
address tipRecipient,
address _gatewayFeeRecipient,
address baseFeeRecipient,
uint256 refundAmount,
uint256 tipAmount,
uint256 _gatewayFeeAmount,
uint256 baseFeeAmount
) external;
```

- `_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](https://github.com/celo-org/fee-currency-example) shows a minimal fee currency token using OpenZeppelin's ERC20 with burn/mint mechanics for gas fee handling:

```solidity
pragma solidity ^0.8.13;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IFeeCurrency} from "./IFeeCurrency.sol";

contract FeeCurrency is ERC20, IFeeCurrency {
constructor(uint256 initialSupply) ERC20("ExampleFeeCurrency", "EFC") {
_mint(msg.sender, initialSupply);
}

modifier onlyVm() {
require(msg.sender == address(0), "Only VM can call");
_;
}

function debitGasFees(address from, uint256 value) external onlyVm {
_burn(from, value);
}

// New function signature
function creditGasFees(
address[] calldata recipients,
uint256[] calldata amounts
) public onlyVm {
require(
recipients.length == amounts.length,
"Recipients and amounts must be the same length."
);

for (uint256 i = 0; i < recipients.length; i++) {
_mint(recipients[i], amounts[i]);
}
}

// Legacy function signature for backwards compatibility
function creditGasFees(
address from,
address feeRecipient,
address, // gatewayFeeRecipient, unused
address communityFund,
uint256 refund,
uint256 tipTxFee,
uint256, // gatewayFee, unused
uint256 baseTxFee
) public onlyVm {
_mint(from, refund);
_mint(feeRecipient, tipTxFee);
_mint(communityFund, baseTxFee);
}
}
```

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](https://book.getfoundry.sh/) to test your fee currency implementation. The [fee-currency-example](https://github.com/celo-org/fee-currency-example) repository includes a test suite you can use as a starting point:

```bash
git clone https://github.com/celo-org/fee-currency-example.git
cd fee-currency-example
forge build
forge test
```

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**](/tooling/contracts/core-contracts) 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](/build-on-celo/fee-abstraction/overview#adapters-for-non-18-decimal-tokens) for details.
40 changes: 40 additions & 0 deletions build-on-celo/fee-abstraction/overview.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
title: Fee Abstraction
sidebarTitle: "Overview"
og:description: Pay gas fees using ERC20 tokens instead of the native CELO token
---

Fee abstraction is one of Celo's core protocol features. It allows users to pay gas fees in ERC20 tokens — like USDC, USDT, or Mento stablecoins — instead of needing to hold the native CELO token.

## Why Fee Abstraction Matters

On most EVM chains, users must hold the native token to pay for gas. This creates friction: a user who receives USDC on Celo can't send it anywhere without first acquiring CELO. Fee abstraction removes this barrier entirely.

With fee abstraction, a user holding only USDC can send transactions, interact with contracts, and pay gas — all in USDC. No bridging, no swaps, no extra steps. This is especially valuable for:

- **Onboarding new users** who receive stablecoins but don't know about gas tokens
- **Payment applications** where users transact in a single currency end-to-end
- **AI agents** that operate autonomously with a single token balance

## How It Works

Fee abstraction is built into the Celo protocol at the node level — it is not a paymaster or relayer. When a transaction includes a `feeCurrency` field, the Celo blockchain:

1. Calls `debitGasFees` on the fee currency contract to reserve the maximum gas cost
2. Executes the transaction normally
3. Calls `creditGasFees` to refund unused gas and distribute fees to block producers

This means fee abstraction works with any externally owned account (EOA). No smart contract wallets, no relayers, no extra infrastructure needed.

To use an alternate fee currency, set its token or adapter address as the `feeCurrency` property on the transaction object.

For implementation details, see [Using Fee Abstraction](/build-on-celo/fee-abstraction/using-fee-abstraction). To add a new fee currency to the protocol, see [Adding Fee Currencies](/build-on-celo/fee-abstraction/add-fee-currency).

---

## Related

- [Fee Abstraction for AI Agents](/build-on-celo/build-with-ai/overview#fee-abstraction-for-agents) — Using fee abstraction in autonomous agent backends
- [x402: Agent Payments](/build-on-celo/build-with-ai/x402) — HTTP-native stablecoin payments for agents
- [Using Fee Abstraction](/build-on-celo/fee-abstraction/using-fee-abstraction) — How to pay gas with alternate fee currencies in your transactions
- [Adding Fee Currencies](/build-on-celo/fee-abstraction/add-fee-currency) — How to implement and register a new fee currency
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
---
title: Implementing Fee Abstraction in Wallets
og:description: How to allow your wallet users to pay for gas fees using alternate fee currencies
sidebarTitle: "Fee Abstraction"
title: Using Fee Abstraction in Transactions
sidebarTitle: "Using Fee Abstraction"
og:description: How to pay gas fees using alternate fee currencies on Celo with viem and celocli
---

Celo allows users to pay gas fees in currencies other than the native CELO token. The list of accepted tokens is governed on-chain and maintained in [**FeeCurrencyDirectory.sol**](/contracts/core-contracts).

To use an alternate fee currency, set its token or adapter address as the `feeCurrency` property on the transaction object. This field is exclusive to Celo. Leaving it empty defaults to CELO. Note that transactions specifying a non-CELO fee currency cost approximately 50,000 additional gas.
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](/build-on-celo/fee-abstraction/overview).

---

## Allowlisted Fee Currencies

The protocol maintains a governable allowlist of smart contract addresses that implement an extension of the ERC20 interface, with additional functions for debiting and crediting transaction fees.
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](/build-on-celo/fee-abstraction/add-fee-currency)).

To fetch the current allowlist, call `getCurrencies()` on the `FeeCurrencyDirectory` contract, or use `celocli`:
```bash
# Celo Sepolia testnet
celocli network:whitelist --node celo-sepolia

# Celo mainnet
celocli network:whitelist --node https://forno.celo.org
celocli network:whitelist --node celo
```

---

## Adapters for Non-18-Decimal Tokens

After Contract Release 11, 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.
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.
Expand Down Expand Up @@ -196,13 +194,4 @@ async function send(amountInWei) {

---

---

## Related

- [Fee Abstraction for AI Agents](/build-on-celo/build-with-ai/overview#fee-abstraction-for-agents) — Using fee abstraction in autonomous agent backends
- [x402: Agent Payments](/build-on-celo/build-with-ai/x402) — HTTP-native stablecoin payments for agents

---

If you have any questions, please [reach out](https://github.com/celo-org/developer-tooling/discussions/categories/q-a).
2 changes: 1 addition & 1 deletion build-on-celo/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Whether you're building your first dApp or looking to integrate an existing prot

- **EVM Compatibile:** Celo is fully EVM-compatible, offering the same development experience as Ethereum with improved scalability and lower costs.
- **Fast Transactions:** After the migrations to an L2 Celo now has a **1-second block finality** compared to formerly 5 seconds.
- **Easy, Low-Cost Payments:** Celo's seamless payment infrastructure, including [Fee Abstraction](/developer/fee-abstraction), **sub-cent fees**, and **native stablecoins**, enables simple and affordable transactions.
- **Easy, Low-Cost Payments:** Celo's seamless payment infrastructure, including [Fee Abstraction](/build-on-celo/fee-abstraction/overview), **sub-cent fees**, and **native stablecoins**, enables simple and affordable transactions.
- **Global Reach:** Celo provides access to more than **8 million real-world users** with some dApps having more than **200,000 DAUs**.

## Getting Started
Expand Down
23 changes: 17 additions & 6 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@
"build-on-celo/build-with-local-stablecoin",
"build-on-celo/build-with-defi"
]
},
{
"group": "Fee Abstraction",
"pages": [
"build-on-celo/fee-abstraction/overview",
"build-on-celo/fee-abstraction/using-fee-abstraction",
"build-on-celo/fee-abstraction/add-fee-currency"
]
}
]
},
Expand All @@ -182,7 +190,6 @@
"pages": [
"tooling/overview/index",
"tooling/overview/faucet",
"tooling/overview/fee-abstraction",
"tooling/bridges/bridges",
"tooling/bridges/cross-chain-messaging",
"tooling/testnets/celo-sepolia/index"
Expand Down Expand Up @@ -678,7 +685,11 @@
},
{
"source": "/cel2/guides/fee-abstraction",
"destination": "/tooling/overview/fee-abstraction"
"destination": "/build-on-celo/fee-abstraction/overview"
},
{
"source": "/tooling/overview/fee-abstraction",
"destination": "/build-on-celo/fee-abstraction/overview"
},
{
"source": "/celo-codebase/protocol",
Expand Down Expand Up @@ -1726,7 +1737,7 @@
},
{
"source": "/developer/fee-currency",
"destination": "/tooling/overview/fee-abstraction"
"destination": "/build-on-celo/fee-abstraction/overview"
},
{
"source": "/developer/indexer",
Expand Down Expand Up @@ -2186,15 +2197,15 @@
},
{
"source": "/protocol/transaction/erc20-transaction-fees",
"destination": "/tooling/overview/fee-abstraction"
"destination": "/build-on-celo/fee-abstraction/overview"
},
{
"source": "/protocol/transaction/escrow",
"destination": "/home/protocol/escrow"
},
{
"source": "/protocol/transaction/gas-pricing",
"destination": "/tooling/overview/fee-abstraction"
"destination": "/build-on-celo/fee-abstraction/overview"
},
{
"source": "/protocol/transaction/native-currency",
Expand Down Expand Up @@ -2566,7 +2577,7 @@
},
{
"source": "/developer/fee-abstraction",
"destination": "/tooling/overview/fee-abstraction"
"destination": "/build-on-celo/fee-abstraction/overview"
},
{
"source": "/developer/launch-checklist",
Expand Down
2 changes: 1 addition & 1 deletion home/protocol/transactions/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ gas currencies incur approximately 50,000 additional gas units.
Celo allows paying gas fees in currencies other than the native currency. The tokens that can be
used to pay gas fees are controlled via governance and the list of tokens allowed is maintained in
FeeCurrencyDirectory.sol. Fee abstraction on Celo works with EOAs. No paymaster required! Learn all
about [fee abstraction](/developer/fee-abstraction).
about [fee abstraction](/build-on-celo/fee-abstraction/overview).

## Transaction Fee Allocation Post-L2 Transition

Expand Down
2 changes: 1 addition & 1 deletion home/wallets.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Overview of digital wallets available to send, spend, and earn Celo assets.

Celo is designed to work seamlessly with a range of wallets, each offering features to meet different user needs.

The [Celo Native Wallets](#celo-native-wallets) section provides an overview of wallets that are optimized for the Celo network. These wallets allow users to fully benefit from Celo’s native functionalities, such as [phone number mapping](/legacy/protocol/identity) and [fee abstraction](/developer/fee-abstraction).
The [Celo Native Wallets](#celo-native-wallets) section provides an overview of wallets that are optimized for the Celo network. These wallets allow users to fully benefit from Celo’s native functionalities, such as [phone number mapping](/legacy/protocol/identity) and [fee abstraction](/build-on-celo/fee-abstraction/overview).

The [Celo Compatible Wallets](#celo-compatible-wallets) section provides an overview of commonly used wallets wallets that support the Celo network.

Expand Down
4 changes: 2 additions & 2 deletions tooling/libraries-sdks/ethers/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ og:description: A minimal wrapper to make Ethers.JS compatible with the Celo net
---

<Warning>
When using Ethers.js on Celo, we suggest using the Celo Ethers.js Wrapper to make Ethers.JS compatible with the Celo network. This means being able to handle [fee abstraction](/developer/fee-abstraction) when opened in MiniPay/ Valora.
When using Ethers.js on Celo, we suggest using the Celo Ethers.js Wrapper to make Ethers.JS compatible with the Celo network. This means being able to handle [fee abstraction](/build-on-celo/fee-abstraction/overview) when opened in MiniPay/ Valora.

[Fee Abstraction](/developer/fee-abstraction) on Celo enables the use of stablecoins like cUSD, USDT and USDC as gas tokens.
[Fee Abstraction](/build-on-celo/fee-abstraction/overview) on Celo enables the use of stablecoins like cUSD, USDT and USDC as gas tokens.
</Warning>

## Celo Ethers.JS Wrapper
Expand Down
Loading
Loading