# Manage Token Transfer Fees Using Hardhat
Source: https://docs.chain.link/ccip/evm/tutorials/cross-chain-tokens/set-transfer-fee-config-hardhat
Last Updated: 2026-05-05

> For the complete documentation index, see [llms.txt](/llms.txt).

## Guide Versions

- [Foundry](/ccip/evm/tutorials/cross-chain-tokens/set-transfer-fee-config-foundry)

- [Hardhat](/ccip/evm/tutorials/cross-chain-tokens/set-transfer-fee-config-hardhat)

CCIP 2.0 token pools let pool owners opt into **pool-level token transfer fee overrides** per destination lane. When an override is disabled, the [OnRamp](https://github.com/smartcontractkit/chainlink-ccip/tree/contracts-ccip-v2.0.0/chains/evm/contracts/onRamp/OnRamp.sol) falls back to [`FeeQuoter`](https://github.com/smartcontractkit/chainlink-ccip/tree/contracts-ccip-v2.0.0/chains/evm/contracts/FeeQuoter.sol) defaults for that lane. In this tutorial you will:

1. Review the current fee configuration for both configured lanes.
2. Optionally set a fee admin who can withdraw accrued fees.
3. Configure lane-specific flat fees, transfer fees, destination gas overhead, and destination bytes overhead.
4. Send a LINK-paid transfer and inspect accrued fees in the source token pool.
5. Withdraw accrued fee tokens.
6. Disable the fee configuration on both lanes to return to `FeeQuoter` defaults.

> **NOTE: Defaults apply unless you opt in**

## Before You Begin

## Tutorial

> **TIP: Prerequisites**
>
> This tutorial assumes you have already deployed tokens and token pools on both chains. If not, complete one of the two
> tutorials first:
>
> [Burn & Mint](/ccip/evm/tutorials/cross-chain-tokens/register-from-eoa-burn-mint-hardhat)
>
> [Lock & Mint](/ccip/evm/tutorials/cross-chain-tokens/register-from-eoa-lock-mint-hardhat)
>
> Use the token pool address for the chain you are configuring. In a Burn & Mint setup, both pools are&#x20;
> `BurnMintTokenPool` contracts. In a Lock & Mint setup, the source chain can use a&#x20;
> `LockReleaseTokenPool` backed by an `ERC20LockBox`, while the destination chain uses a&#x20;
> `BurnMintTokenPool`. This tutorial configures the token pool, not the lockbox.
>
> ```bash filename="Terminal"
> export ETHEREUM_SEPOLIA_TOKEN=0x...
> export ARBITRUM_SEPOLIA_TOKEN=0x...
>
> export ETHEREUM_SEPOLIA_TOKEN_POOL=0x...
> export ARBITRUM_SEPOLIA_TOKEN_POOL=0x...
> ```

> **CAUTION: Troubleshooting**
>
> **Owner revert:** confirm `KEYSTORE_NAME` is the owner of the source-chain token pool.
>
> **Fee admin withdrawal revert:** confirm the fee admin was set, the correct fee admin keystore is
> used, and the action is withdrawal rather than owner-only configuration.
>
> **Missing gas:** confirm the broadcaster has native gas on the source chain.
>
> **Missing LINK:** confirm the sender has source-chain LINK when using `--fee-token LINK`.
>
> **Missing lane:** confirm the pool lane was configured with `applyChainUpdates`.
>
> **Wrong lane or pool:** confirm `--network`, `--destchain`, and the source pool
> env var (or `--tokenpool`) match the intended source -> destination lane.
>
> **Invalid config:** confirm `--destgasoverhead` is not `0`,&#x20;
> `--destbytesoverhead` is at least `32`, and basis points values are below `10000`.
>
> **Fast-finality revert:** confirm the pool allows block-depth finality and the requested&#x20;
> `finality=<N>` is not below the pool minimum.
>
> **No accrued fees:** confirm `--feetokens` includes LINK and the source token, the send
> completed, native fee token was not used, and flat or basis points fee values are non-zero.

> **CAUTION: Educational Example Disclaimer**
>
> Please note, this page contains community examples only — these are not Chainlink products or services and are not
> supported or maintained by Chainlink. This code represents an example of using a Chainlink product or service, and is
> intended for demonstration and educational purposes only. It is provided "AS IS" and "AS AVAILABLE" without warranties
> of any kind, may not have been audited, and may omit checks or error handling. Each party intending to use this
> example code does so entirely at their own risk and must perform its own audits, security and code review, key
> management, and testing before any production deployment and ensure the operation and performance of such code matches
> expectations. Neither Chainlink Labs nor the Chainlink Foundation deploys, operates, monitors, maintains or endorses
> any deployment of this code. Note that this is not a Chainlink product, feature or service, and there are no
> commitments made with respect to the code, including compatibility with future Chainlink releases. You should not rely
> on this code without first conducting your own technical, engineering, and security review. This code is also outside
> the scope of any Chainlink bug bounty programs. Neither Chainlink Labs, the Chainlink Foundation, nor Chainlink node
> operators are responsible for outcomes due to errors in this example or how it is deployed or operated, or liable for
> any resulting claims or damages. Use of the Chainlink Network is subject to the Chainlink Foundation [Terms of
> Service](https://chain.link/terms), which provides important information and disclosures. By using this code, you
> acknowledge and agree to these terms.