# Set Token Pool rate limits using Hardhat
Source: https://docs.chain.link/ccip/tutorials/evm/cross-chain-tokens/update-rate-limiters-hardhat
Last Updated: 2025-10-22


<PageTabs
  pages={[
  {
    name: "Hardhat",
    url: "/ccip/tutorials/evm/cross-chain-tokens/update-rate-limiters-hardhat",
    icon: "/images/tutorial-icons/hardhat-icn.png",
  },
  {
    name: "Foundry",
    url: "/ccip/tutorials/evm/cross-chain-tokens/update-rate-limiters-foundry",
    icon: "/images/tutorial-icons/foundry-icn.png",
  },
]}
/>

This tutorial will guide you through the process of updating the rate limiter settings for outbound and inbound transfers in your deployed token pools using [Hardhat](https://hardhat.org/). You will first review existing rate limiter settings and then update them.

## Prerequisites

- **Tokens and pools deployed**: Ensure that you have tokens and token pools already deployed on both networks you plan to use. If not, refer to one of the following tutorials:
  - [Register from an EOA (Burn & Mint)](/ccip/tutorials/evm/cross-chain-tokens/register-from-eoa-burn-mint-hardhat)
  - [Register from an EOA (Lock & Mint)](/ccip/tutorials/evm/cross-chain-tokens/register-from-eoa-lock-mint-hardhat)

- **Admin access**: Ensure you have the necessary privileges to call the [setChainRateLimiterConfig](/ccip/api-reference/evm/v1.6.1/token-pool#setchainratelimiterconfig) function for your token pools.

## Before You Begin

1. Make sure you have Node.js v22.10.0 or above installed. If not, **install Node.js v22.10.0**:

   [Download Node.js v22.10.0](https://nodejs.org/en/download/) if you don't have it installed. Optionally, you can use the [nvm package](https://www.npmjs.com/package/nvm) to switch between Node.js versions:

   ```bash
   nvm use 22
   ```

   Verify that the correct version of Node.js is installed:

   ```bash
   node -v
   ```

   Example output:

   ```bash
   $ node -v
   v22.15.0
   ```

> **CAUTION: Why Node.js v22?**
>
> Since the [migration](https://hardhat.org/migrate-from-hardhat2) to Hardhat 3.x, Node.js v22.10.0 or above is
> [required for compatibility](https://hardhat.org/migrate-from-hardhat2#before-starting-the-migration). Using an
> older version may lead to unexpected issues during development.

1. **Clone the repository and navigate to the project directory:**

   ```bash
   git clone https://github.com/smartcontractkit/smart-contract-examples.git
   cd smart-contract-examples/ccip/cct/hardhat
   ```

2. **Install dependencies for the project:**

   ```bash
   npm install
   ```

3. **Compile the project:**

   ```bash
   npm run compile
   ```

4. **Encrypt your environment variables for higher security:**\
   The project uses [@chainlink/env-enc](https://www.npmjs.com/package/@chainlink/env-enc) to encrypt your environment variables at rest. Follow the steps below to configure your environment securely:
   1. Set an encryption password for your environment variables:

      ```bash
      npx env-enc set-pw
      ```

   2. Set up a `.env.enc` file with the necessary variables for Avalanche Fuji and Ethereum Sepolia testnets. Use the following command to add the variables:

      ```bash
      npx env-enc set
      ```

      Variables to configure:

      - AVALANCHE\_FUJI\_RPC\_URL: A URL for the *Avalanche Fuji* testnet. You can get a personal
        endpoint from services like [Alchemy](https://www.alchemy.com/) or [Infura](https://www.infura.io/).
      - ETHEREUM\_SEPOLIA\_RPC\_URL: A URL for the *Ethereum Sepolia* testnet. You can get a
        personal endpoint from services like [Alchemy](https://www.alchemy.com/) or [Infura](https://www.infura.io/).
      - PRIVATE\_KEY: The private key for your testnet wallet. If you use MetaMask, you can
        follow this
        [guide](https://support.metamask.io/managing-my-wallet/secret-recovery-phrase-and-private-keys/how-to-export-an-accounts-private-key/)
        to export your private key. **Note:** This key is required for signing transactions like token transfers.

5. **Fund your EOA with native gas tokens**:\
   Make sure your EOA has enough native gas tokens on Avalanche Fuji to cover transaction fees. You can use the [Chainlink faucets](https://faucets.chain.link/) to get testnet tokens.

> **NOTE: Using Different Networks**
>
> This tutorial uses Avalanche Fuji and Ethereum Sepolia by default. To test with other CCIP-supported networks, see
> [Add CCIP Networks for Cross-Chain Token
> Tutorials](/ccip/tutorials/evm/cross-chain-tokens/configure-additional-networks-hardhat).

## Tutorial

> **NOTE: Explore the Code**
>
> All Hardhat tasks used in this tutorial are located in the `tasks/` directory of the repository. Each task is
> thoroughly commented and directly linked to a key step in the tutorial, making the code self-explanatory. Read the
> code and comments to gain a deeper understanding of the process or explore the implementation details.

### Review current rate limiter settings

Use the `getCurrentRateLimits` task to fetch the current rate limiter states for a specific chain from a token pool. This task provides detailed information about both inbound and outbound rate limits, including:

- Whether rate limiting is enabled
- The maximum capacity (bucket size)
- The refill rate (tokens per second)
- Current token amount in the bucket
- Last update timestamp

Below is an explanation of the parameters used:

| Parameter     | Description                                                                              | Default | Required |
| ------------- | ---------------------------------------------------------------------------------------- | ------- | -------- |
| `pooladdress` | The address of the token pool to query.                                                  | N/A     | Yes      |
| `remotechain` | The remote blockchain to check rate limits for (e.g., `ethereumSepolia` for Fuji pool).  | N/A     | Yes      |
| `network`     | The blockchain on which to execute the query (e.g., `avalancheFuji`, `ethereumSepolia`). | N/A     | Yes      |

1. **Get rate limiter settings for the token pool on Avalanche Fuji**:

   ```bash
   npx hardhat getCurrentRateLimits \
     --pooladdress 0x5e8b0e5EAC57d73E7b93d85b8eA3fcaDa282868A \
     --remotechain ethereumSepolia \
     --network avalancheFuji
   ```

   Example output:

   ```bash
   ✅ Tasks loaded from /tasks/index.ts
   2025-10-22T01:18:02.669Z info: 📊 Fetching rate limiter states for pool 0x5e8b0e5EAC57d73E7b93d85b8eA3fcaDa282868A on avalancheFuji...
   2025-10-22T01:18:02.670Z info:    Remote chain: ethereumSepolia
   2025-10-22T01:18:02.670Z info:    Remote chain selector: 16015286601757825753
   2025-10-22T01:18:04.702Z info:
   === Rate Limiter States for ethereumSepolia ===
   2025-10-22T01:18:04.702Z info: Pool Address: 0x5e8b0e5EAC57d73E7b93d85b8eA3fcaDa282868A
   2025-10-22T01:18:04.702Z info: Chain Selector: 16015286601757825753
   2025-10-22T01:18:04.702Z info:
   📤 Outbound Rate Limiter:
   2025-10-22T01:18:04.702Z info:   Enabled:       false
   2025-10-22T01:18:04.702Z info:   Capacity:      0
   2025-10-22T01:18:04.702Z info:   Rate:          0
   2025-10-22T01:18:04.702Z info:   Tokens:        0
   2025-10-22T01:18:04.702Z info:   Last Updated:  1761095882
   2025-10-22T01:18:04.702Z info:
   📥 Inbound Rate Limiter:
   2025-10-22T01:18:04.702Z info:   Enabled:       false
   2025-10-22T01:18:04.702Z info:   Capacity:      0
   2025-10-22T01:18:04.703Z info:   Rate:          0
   2025-10-22T01:18:04.703Z info:   Tokens:        0
   2025-10-22T01:18:04.703Z info:   Last Updated:  1761095882
   2025-10-22T01:18:04.703Z info:
   ✅ Rate limiters fetched successfully
   ```

2. **Get rate limiter settings for the token pool on Ethereum Sepolia**:

   ```bash
   npx hardhat getCurrentRateLimits \
     --pooladdress 0xA29878301cA30a4639C33cD7EC8061E4265E1a5D \
     --remotechain avalancheFuji \
     --network ethereumSepolia
   ```

   Example output:

   ```bash
   ✅ Tasks loaded from /tasks/index.ts
   2025-10-22T01:21:05.698Z info: 📊 Fetching rate limiter states for pool 0xA29878301cA30a4639C33cD7EC8061E4265E1a5D on ethereumSepolia...
   2025-10-22T01:21:05.699Z info:    Remote chain: avalancheFuji
   2025-10-22T01:21:05.699Z info:    Remote chain selector: 14767482510784806043
   2025-10-22T01:21:08.160Z info:
   === Rate Limiter States for avalancheFuji ===
   2025-10-22T01:21:08.161Z info: Pool Address: 0xA29878301cA30a4639C33cD7EC8061E4265E1a5D
   2025-10-22T01:21:08.161Z info: Chain Selector: 14767482510784806043
   2025-10-22T01:21:08.161Z info:
   📤 Outbound Rate Limiter:
   2025-10-22T01:21:08.161Z info:   Enabled:       false
   2025-10-22T01:21:08.161Z info:   Capacity:      0
   2025-10-22T01:21:08.161Z info:   Rate:          0
   2025-10-22T01:21:08.161Z info:   Tokens:        0
   2025-10-22T01:21:08.161Z info:   Last Updated:  1761096060
   2025-10-22T01:21:08.161Z info:
   📥 Inbound Rate Limiter:
   2025-10-22T01:21:08.161Z info:   Enabled:       false
   2025-10-22T01:21:08.161Z info:   Capacity:      0
   2025-10-22T01:21:08.161Z info:   Rate:          0
   2025-10-22T01:21:08.161Z info:   Tokens:        0
   2025-10-22T01:21:08.161Z info:   Last Updated:  1761096060
   2025-10-22T01:21:08.161Z info:
   ✅ Rate limiters fetched successfully
   ```

> **NOTE: Rate Limiters Disabled**
>
> As you can see from both outputs above, rate limiters are currently disabled (`Enabled: false`) for both pools, with
> capacity and rate set to 0. This means there are currently no restrictions on token transfers. In the next section,
> you will learn how to enable and configure these rate limiters to control token flow between chains.

### Update rate limiter settings

Use the `updateRateLimiters` task to update the rate limiter configurations for an existing chain connection in your token pool. This task specifically interacts with the [`setChainRateLimiterConfig`](/ccip/api-reference/evm/v1.6.1/token-pool#setchainratelimiterconfig) function of the `TokenPool` contract, allowing you to adjust the rate limits without altering other configurations like remote pool addresses.

The `updateRateLimiters` task allows you to:

- Enable or disable rate limiting for outbound or inbound transfers or both.
- Set the capacity and rate for the rate limiters, controlling the flow of tokens.
- Target a specific remote chain, updating rate limits for that chain only.

Below is an explanation of the parameters used during the rate limiter update process:

| Parameter                   | Description                                                                                                                                               | Default | Required |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -------- |
| `pooladdress`               | The address of the token pool being configured.                                                                                                           | N/A     | Yes      |
| `remotechain`               | The remote blockchain to which this pool is linked. Examples include `avalancheFuji`, `ethereumSepolia`, `baseSepolia`, and `arbitrumSepolia`.            | N/A     | Yes      |
| `ratelimiter`               | Specifies which rate limiters to update: `inbound`, `outbound`, or `both`.                                                                                | `both`  | No       |
| `outboundratelimitenabled`  | Flag to enable outbound rate limits for cross-chain transfers. Pass this flag to enable, omit to disable.                                                 | `false` | No       |
| `outboundratelimitcapacity` | The maximum number of tokens allowed in the bucket for outbound transfers (in wei). **Note:** Applicable if outbound rate limits are enabled.             | `0`     | No       |
| `outboundratelimitrate`     | The number of tokens per second that the bucket is refilled for outbound transfers (in wei). **Note:** Applicable if outbound rate limits are enabled.    | `0`     | No       |
| `inboundratelimitenabled`   | Flag to enable inbound rate limits for cross-chain transfers. Pass this flag to enable, omit to disable.                                                  | `false` | No       |
| `inboundratelimitcapacity`  | The maximum number of tokens allowed in the bucket for inbound transfers (in wei). **Note:** Applicable if inbound rate limits are enabled.               | `0`     | No       |
| `inboundratelimitrate`      | The number of tokens per second that the bucket is refilled for inbound transfers (in wei). **Note:** Applicable if inbound rate limits are enabled.      | `0`     | No       |
| `network`                   | The blockchain network where the local token pool is deployed. Examples include `avalancheFuji`, `ethereumSepolia`, `baseSepolia`, and `arbitrumSepolia`. | N/A     | Yes      |

**Command syntax**:

```bash
npx hardhat updateRateLimiters \
  --pooladdress <POOL_ADDRESS> \
  --remotechain <REMOTE_CHAIN> \
  --ratelimiter <inbound/outbound/both> \
  --outboundratelimitenabled \
  --outboundratelimitcapacity <OUTBOUND_CAPACITY> \
  --outboundratelimitrate <OUTBOUND_RATE> \
  --inboundratelimitenabled \
  --inboundratelimitcapacity <INBOUND_CAPACITY> \
  --inboundratelimitrate <INBOUND_RATE> \
  --network <NETWORK_NAME>
```

**Example command**:

Suppose you want to enable inbound and outbound rate limits for your token pool on Avalanche Fuji to control the number of tokens received or sent from/to Ethereum Sepolia. We will use an existing token pool that interacts with an ERC20 token with 18 decimals:

- **Token Pool on Avalanche Fuji**:
  - **Outbound Rate Limiter**:
    - **Enabled**: `true`
    - **Capacity**: `10000000000000000000` wei (equivalent to 10 tokens, based on 18 decimals)
    - **Rate**: `100000000000000000` wei (equivalent to 0.1 token per second, based on 18 decimals)
    - **Note**:
      - `Capacity / Rate = 10 / 0.1 = 100 seconds`
      - It takes **100 seconds** to replenish the bucket from 0 to full capacity.

  - **Inbound Rate Limiter**:
    - **Enabled**: `true`
    - **Capacity**: `20000000000000000000` wei (equivalent to 20 tokens, based on 18 decimals)
    - **Rate**: `100000000000000000` wei (equivalent to 0.1 tokens per second, based on 18 decimals)
    - **Note**:
      - `Capacity / Rate = 20 / 0.1 = 200 seconds`
      - It takes **200 seconds** to replenish the bucket from 0 to full capacity.

- **Token Pool on Ethereum Sepolia**: Rate limits are the same as the Avalanche Fuji pool, but the inbound and outbound settings are swapped.
  - **Outbound Rate Limiter**:
    - **Enabled**: `true`
    - **Capacity**: `20000000000000000000` wei
    - **Rate**: `100000000000000000` wei
  - **Inbound Rate Limiter**:
    - **Enabled**: `true`
    - **Capacity**: `10000000000000000000` wei
    - **Rate**: `100000000000000000` wei

1. **Update rate limiter settings for the token pool on Avalanche Fuji**: Replace `<POOL_ADDRESS>` with your token pool address.

   ```bash
   npx hardhat updateRateLimiters \
     --pooladdress <POOL_ADDRESS> \
     --remotechain ethereumSepolia \
     --ratelimiter both \
     --outboundratelimitenabled true \
     --outboundratelimitcapacity 10000000000000000000 \
     --outboundratelimitrate 100000000000000000 \
     --inboundratelimitenabled true \
     --inboundratelimitcapacity 20000000000000000000 \
     --inboundratelimitrate 100000000000000000 \
     --network avalancheFuji
   ```

   Expected output:

   ```bash
   $ npx hardhat updateRateLimiters \
     --pooladdress 0x5e8b0e5EAC57d73E7b93d85b8eA3fcaDa282868A \
     --remotechain ethereumSepolia \
     --ratelimiter both \
     --outboundratelimitenabled true \
     --outboundratelimitcapacity 10000000000000000000 \
     --outboundratelimitrate 100000000000000000 \
     --inboundratelimitenabled true \
     --inboundratelimitcapacity 20000000000000000000 \
     --inboundratelimitrate 100000000000000000 \
     --network avalancheFuji

   ✅ Tasks loaded from /tasks/index.ts
   2025-10-22T01:43:31.678Z info: ⚙️  Updating rate limiters for pool 0x5e8b0e5EAC57d73E7b93d85b8eA3fcaDa282868A on avalancheFuji...
   2025-10-22T01:43:31.680Z info:    Remote chain: ethereumSepolia
   2025-10-22T01:43:31.680Z info:    Remote chain selector: 16015286601757825753
   2025-10-22T01:43:31.680Z info:    Updating: both limiters
   2025-10-22T01:43:32.354Z info:    ✅ Remote chain is supported by the pool
   2025-10-22T01:43:32.630Z info:    ✅ Caller is the pool owner
   2025-10-22T01:43:32.901Z info:
   📊 Current Rate Limiters for pool 0x5e8b0e5EAC57d73E7b93d85b8eA3fcaDa282868A
   2025-10-22T01:43:32.901Z info:    Outbound → enabled=false, cap=0, rate=0
   2025-10-22T01:43:32.901Z info:    Inbound  → enabled=false, cap=0, rate=0
   2025-10-22T01:43:32.901Z info:
   ========== Preparing Update ==========
   2025-10-22T01:43:32.902Z info:    New Outbound → enabled=true, cap=10000000000000000000, rate=100000000000000000
   2025-10-22T01:43:32.902Z info:    New Inbound  → enabled=true, cap=20000000000000000000, rate=100000000000000000
   2025-10-22T01:43:32.902Z info:
   ⚡ Updating both limiters...
   2025-10-22T01:43:34.982Z info: ⏳ Rate limiter update tx: 0x2489f68073c72d96a7801bd046a23a23fad40f15d27c9d052a18697f2092336d
   2025-10-22T01:43:34.982Z info:    Waiting for 2 confirmation(s)...
   2025-10-22T01:43:44.017Z info: ✅ Rate limiters updated successfully
   2025-10-22T01:43:44.017Z info:    Transaction: 0x2489f68073c72d96a7801bd046a23a23fad40f15d27c9d052a18697f2092336d
   ```

2. **Update rate limiter settings for the token pool on Ethereum Sepolia**: Replace `<POOL_ADDRESS>` with your token pool address.

   ```bash
   npx hardhat updateRateLimiters \
     --pooladdress <POOL_ADDRESS> \
     --remotechain avalancheFuji \
     --ratelimiter both \
     --outboundratelimitenabled true \
     --outboundratelimitcapacity 20000000000000000000 \
     --outboundratelimitrate 100000000000000000 \
     --inboundratelimitenabled true \
     --inboundratelimitcapacity 10000000000000000000 \
     --inboundratelimitrate 100000000000000000 \
     --network ethereumSepolia
   ```

   Expected output:

   ```bash
   $ npx hardhat updateRateLimiters \
     --pooladdress 0xA29878301cA30a4639C33cD7EC8061E4265E1a5D \
     --remotechain avalancheFuji \
     --ratelimiter both \
     --outboundratelimitenabled true \
     --outboundratelimitcapacity 20000000000000000000 \
     --outboundratelimitrate 100000000000000000 \
     --inboundratelimitenabled true \
     --inboundratelimitcapacity 10000000000000000000 \
     --inboundratelimitrate 100000000000000000 \
     --network ethereumSepolia

   ✅ Tasks loaded from /tasks/index.ts
   2025-10-22T01:45:28.727Z info: ⚙️  Updating rate limiters for pool 0xA29878301cA30a4639C33cD7EC8061E4265E1a5D on ethereumSepolia...
   2025-10-22T01:45:28.730Z info:    Remote chain: avalancheFuji
   2025-10-22T01:45:28.731Z info:    Remote chain selector: 14767482510784806043
   2025-10-22T01:45:28.731Z info:    Updating: both limiters
   2025-10-22T01:45:29.327Z info:    ✅ Remote chain is supported by the pool
   2025-10-22T01:45:29.624Z info:    ✅ Caller is the pool owner
   2025-10-22T01:45:29.903Z info:
   📊 Current Rate Limiters for pool 0xA29878301cA30a4639C33cD7EC8061E4265E1a5D
   2025-10-22T01:45:29.903Z info:    Outbound → enabled=false, cap=0, rate=0
   2025-10-22T01:45:29.904Z info:    Inbound  → enabled=false, cap=0, rate=0
   2025-10-22T01:45:29.905Z info:
   ========== Preparing Update ==========
   2025-10-22T01:45:29.905Z info:    New Outbound → enabled=true, cap=20000000000000000000, rate=100000000000000000
   2025-10-22T01:45:29.905Z info:    New Inbound  → enabled=true, cap=10000000000000000000, rate=100000000000000000
   2025-10-22T01:45:29.905Z info:
   ⚡ Updating both limiters...
   2025-10-22T01:45:31.847Z info: ⏳ Rate limiter update tx: 0x1e3862484d4bcb7ca4aba6a8723ec6c90ad9fe223e337363c14ed99822842bb5
   2025-10-22T01:45:31.847Z info:    Waiting for 3 confirmation(s)...
   2025-10-22T01:46:03.375Z info: ✅ Rate limiters updated successfully
   2025-10-22T01:46:03.376Z info:    Transaction: 0x1e3862484d4bcb7ca4aba6a8723ec6c90ad9fe223e337363c14ed99822842bb5
   ```

### Verify the new rate limiter settings

After applying the new rate limiter settings, verify that they have been updated correctly.

- Use the `getCurrentRateLimits` task to verify the updated settings:

1. **Verify the updated rate limiter settings for the token pool on Avalanche Fuji**:

   ```bash
   npx hardhat getCurrentRateLimits \
     --pooladdress <POOL_ADDRESS> \
     --remotechain ethereumSepolia \
     --network avalancheFuji
   ```

   Example output:

   ```bash
   $ npx hardhat getCurrentRateLimits \
     --pooladdress 0x5e8b0e5EAC57d73E7b93d85b8eA3fcaDa282868A \
     --remotechain ethereumSepolia \
     --network avalancheFuji

   ✅ Tasks loaded from /tasks/index.ts
   2025-10-22T02:22:43.555Z info: 📊 Fetching rate limiter states for pool 0x5e8b0e5EAC57d73E7b93d85b8eA3fcaDa282868A on avalancheFuji...
   2025-10-22T02:22:43.556Z info:    Remote chain: ethereumSepolia
   2025-10-22T02:22:43.556Z info:    Remote chain selector: 16015286601757825753
   2025-10-22T02:22:45.445Z info:
   === Rate Limiter States for ethereumSepolia ===
   2025-10-22T02:22:45.445Z info: Pool Address: 0x5e8b0e5EAC57d73E7b93d85b8eA3fcaDa282868A
   2025-10-22T02:22:45.445Z info: Chain Selector: 16015286601757825753
   2025-10-22T02:22:45.445Z info:
   📤 Outbound Rate Limiter:
   2025-10-22T02:22:45.445Z info:   Enabled:       true
   2025-10-22T02:22:45.445Z info:   Capacity:      10000000000000000000
   2025-10-22T02:22:45.446Z info:   Rate:          100000000000000000
   2025-10-22T02:22:45.446Z info:   Tokens:        10000000000000000000
   2025-10-22T02:22:45.447Z info:   Last Updated:  1761099755
   2025-10-22T02:22:45.447Z info:
   📥 Inbound Rate Limiter:
   2025-10-22T02:22:45.447Z info:   Enabled:       true
   2025-10-22T02:22:45.447Z info:   Capacity:      20000000000000000000
   2025-10-22T02:22:45.447Z info:   Rate:          100000000000000000
   2025-10-22T02:22:45.447Z info:   Tokens:        20000000000000000000
   2025-10-22T02:22:45.447Z info:   Last Updated:  1761099755
   2025-10-22T02:22:45.447Z info:
   ✅ Rate limiters fetched successfully
   ```

2. **Verify the updated rate limiter settings for the token pool on Ethereum Sepolia**:

   ```bash
   npx hardhat getCurrentRateLimits \
     --pooladdress <POOL_ADDRESS> \
     --remotechain avalancheFuji \
     --network ethereumSepolia
   ```

   Example output:

   ```bash
   $ npx hardhat getCurrentRateLimits \
     --pooladdress 0xA29878301cA30a4639C33cD7EC8061E4265E1a5D \
     --remotechain avalancheFuji \
     --network ethereumSepolia

   ✅ Tasks loaded from /tasks/index.ts
   2025-10-22T02:23:57.094Z info: 📊 Fetching rate limiter states for pool 0xA29878301cA30a4639C33cD7EC8061E4265E1a5D on ethereumSepolia...
   2025-10-22T02:23:57.095Z info:    Remote chain: avalancheFuji
   2025-10-22T02:23:57.095Z info:    Remote chain selector: 14767482510784806043
   2025-10-22T02:23:59.253Z info:
   === Rate Limiter States for avalancheFuji ===
   2025-10-22T02:23:59.253Z info: Pool Address: 0xA29878301cA30a4639C33cD7EC8061E4265E1a5D
   2025-10-22T02:23:59.253Z info: Chain Selector: 14767482510784806043
   2025-10-22T02:23:59.254Z info:
   📤 Outbound Rate Limiter:
   2025-10-22T02:23:59.254Z info:   Enabled:       true
   2025-10-22T02:23:59.254Z info:   Capacity:      20000000000000000000
   2025-10-22T02:23:59.254Z info:   Rate:          100000000000000000
   2025-10-22T02:23:59.255Z info:   Tokens:        20000000000000000000
   2025-10-22T02:23:59.255Z info:   Last Updated:  1761099828
   2025-10-22T02:23:59.255Z info:
   📥 Inbound Rate Limiter:
   2025-10-22T02:23:59.255Z info:   Enabled:       true
   2025-10-22T02:23:59.255Z info:   Capacity:      10000000000000000000
   2025-10-22T02:23:59.255Z info:   Rate:          100000000000000000
   2025-10-22T02:23:59.255Z info:   Tokens:        10000000000000000000
   2025-10-22T02:23:59.255Z info:   Last Updated:  1761099828
   2025-10-22T02:23:59.255Z info:
   ✅ Rate limiters fetched successfully
   ```

### Test the rate limiter settings

To verify the rate limiter settings, initiate a cross-chain transfer between the token pools on Avalanche Fuji and Ethereum Sepolia. The rate limiter configuration will control the flow of tokens between these pools.

**Note**: Ensure that your externally owned account (EOA) has a sufficient balance of ERC20 tokens on Avalanche Fuji to complete the transfer.

In the example below, we use a token pool at address `0x5e8b0e5EAC57d73E7b93d85b8eA3fcaDa282868A` on Avalanche Fuji, which has burn and mint privileges for the token at address `0xb613B55897F07eAF430bF9a509498e55487305Ea`. We will transfer this token from Avalanche Fuji to Ethereum Sepolia. For your own test, substitute these addresses with the token pool and token addresses that you have deployed.

1. **Test Capacity**: Because the outbound capacity set is `1000000000000000000000` , let's transfer `1000000000000000000001` tokens from Avalanche Fuji to Ethereum Sepolia. This transfer should fail because the capacity is less than the number of tokens being transferred.

   Command:

   ```bash
   npx hardhat transferTokens --tokenaddress <TOKEN_ADDRESS> --amount 1000000000000000000001 --destinationchain ethereumSepolia --receiveraddress <RECEIVER_ADDRESS> --network avalancheFuji
   ```

   Expected output:

   ```bash
   $ npx hardhat transferTokens --tokenaddress 0xb613B55897F07eAF430bF9a509498e55487305Ea --amount 1000000000000000000001 --destinationchain ethereumSepolia --receiveraddress 0x27d7A69C878F9c8f51f4e53703abCE9bAcd2D9bf --network avalancheFuji

   ✅ Tasks loaded from /tasks/index.ts
   2025-10-22T03:53:06.293Z info: 🚀 Transferring 1000000000000000000001 tokens via CCIP from avalancheFuji to ethereumSepolia...
   2025-10-22T03:53:06.297Z info:    Token: 0xb613B55897F07eAF430bF9a509498e55487305Ea
   2025-10-22T03:53:06.297Z info:    Receiver: 0x27d7A69C878F9c8f51f4e53703abCE9bAcd2D9bf
   2025-10-22T03:53:06.297Z info:    Fee token: LINK
   2025-10-22T03:53:07.247Z info: 💰 Estimated fees: 12758132149667117
   2025-10-22T03:53:07.502Z info: Approving 1000000000000000000001 tokens for router 0xF694E193200268f9a4868e4Aa017A0118C9a8177
   2025-10-22T03:53:09.453Z info:    Waiting for 2 confirmation(s)...
   2025-10-22T03:53:23.404Z info: Approving 12758132149667117 LINK to router
   2025-10-22T03:53:24.672Z info:    Waiting for 2 confirmation(s)...
   2025-10-22T03:53:33.834Z info: 💰 Estimated CCIP fees: 12758132149667117
   2025-10-22T03:53:33.834Z info: Simulating CCIP message...
   2025-10-22T03:53:35.890Z error: ❌ Simulation failed
   2025-10-22T03:53:35.893Z error: ❌ TokenMaxCapacityExceeded (from RateLimiter)
   2025-10-22T03:53:35.893Z error:    Args:
   2025-10-22T03:53:35.893Z error:      [0]: 10000000000000000000
   2025-10-22T03:53:35.893Z error:      [1]: 1000000000000000000001
   2025-10-22T03:53:35.893Z error:      [2]: "0xb613B55897F07eAF430bF9a509498e55487305Ea"
   ```

   Notice in the logs that the transfer failed because the capacity was exceeded: `TokenMaxCapacityExceeded`.

2. **Test Rate**: Now, let's transfer `10000000000000000000` tokens from Avalanche Fuji to Ethereum Sepolia, which will empty the bucket. After this transfer, we will attempt to transfer another `10000000000000000000` tokens. This transfer will fail because it takes 100 seconds to replenish the bucket.
   1. **First transfer** (Successful):

      Command:

      ```bash
      npx hardhat transferTokens --tokenaddress <TOKEN_ADDRESS> --amount 10000000000000000000 --destinationchain ethereumSepolia --receiveraddress <RECEIVER_ADDRESS> --network avalancheFuji
      ```

      Expected output:

      ```bash
      $ npx hardhat transferTokens --tokenaddress 0xb613B55897F07eAF430bF9a509498e55487305Ea --amount 10000000000000000000 --destinationchain ethereumSepolia --receiveraddress 0x27d7A69C878F9c8f51f4e53703abCE9bAcd2D9bf --network avalancheFuji

      ✅ Tasks loaded from /tasks/index.ts
      2025-10-22T04:01:11.893Z info: 🚀 Transferring 10000000000000000000 tokens via CCIP from avalancheFuji to ethereumSepolia...
      2025-10-22T04:01:11.894Z info:    Token: 0xb613B55897F07eAF430bF9a509498e55487305Ea
      2025-10-22T04:01:11.895Z info:    Receiver: 0x27d7A69C878F9c8f51f4e53703abCE9bAcd2D9bf
      2025-10-22T04:01:11.895Z info:    Fee token: LINK
      2025-10-22T04:01:12.809Z info: 💰 Estimated fees: 12757807740510307
      2025-10-22T04:01:13.059Z info: Approving 10000000000000000000 tokens for router 0xF694E193200268f9a4868e4Aa017A0118C9a8177
      2025-10-22T04:01:15.068Z info:    Waiting for 2 confirmation(s)...
      2025-10-22T04:01:20.458Z info: Approving 12757807740510307 LINK to router
      2025-10-22T04:01:21.705Z info:    Waiting for 2 confirmation(s)...
      2025-10-22T04:01:26.687Z info: 💰 Estimated CCIP fees: 12757807740510307
      2025-10-22T04:01:26.687Z info: Simulating CCIP message...
      2025-10-22T04:01:26.936Z info: Sending CCIP message...
      2025-10-22T04:01:28.186Z info: ⏳ CCIP message tx: 0xb52fbc15e2aa90e35bd0d56073ce60c6b92626ac66ba219e1403927dfd31cfab
      2025-10-22T04:01:28.186Z info:    Waiting for 2 confirmation(s)...
      2025-10-22T04:01:32.924Z info: ✅ CCIP message sent successfully
      2025-10-22T04:01:32.924Z info:    Transaction: 0xb52fbc15e2aa90e35bd0d56073ce60c6b92626ac66ba219e1403927dfd31cfab
      2025-10-22T04:01:32.924Z info:    Check status: https://ccip.chain.link/tx/0xb52fbc15e2aa90e35bd0d56073ce60c6b92626ac66ba219e1403927dfd31cfab
      2025-10-22T04:01:32.924Z info: 📋 Transfer Summary:
      2025-10-22T04:01:32.924Z info:    Token: 0xb613B55897F07eAF430bF9a509498e55487305Ea
      2025-10-22T04:01:32.925Z info:    Amount: 10000000000000000000
      2025-10-22T04:01:32.925Z info:    From: avalancheFuji
      2025-10-22T04:01:32.925Z info:    To: ethereumSepolia
      2025-10-22T04:01:32.925Z info:    Receiver: 0x27d7A69C878F9c8f51f4e53703abCE9bAcd2D9bf
      2025-10-22T04:01:32.925Z info:    Fee paid in: LINK
      ```

   2. **Second transfer** (Failed):

      Command:

      ```bash
      npx hardhat transferTokens --tokenaddress <TOKEN_ADDRESS> --amount 10000000000000000000 --destinationchain ethereumSepolia --receiveraddress <RECEIVER_ADDRESS> --network avalancheFuji
      ```

      Expected output:

      ```bash
      $ npx hardhat transferTokens --tokenaddress 0xb613B55897F07eAF430bF9a509498e55487305Ea --amount 10000000000000000000 --destinationchain ethereumSepolia --receiveraddress 0x27d7A69C878F9c8f51f4e53703abCE9bAcd2D9bf --network avalancheFuji

      ✅ Tasks loaded from /tasks/index.ts
      2025-10-22T04:02:15.242Z info: 🚀 Transferring 10000000000000000000 tokens via CCIP from avalancheFuji to ethereumSepolia...
      2025-10-22T04:02:15.244Z info:    Token: 0xb613B55897F07eAF430bF9a509498e55487305Ea
      2025-10-22T04:02:15.245Z info:    Receiver: 0x27d7A69C878F9c8f51f4e53703abCE9bAcd2D9bf
      2025-10-22T04:02:15.245Z info:    Fee token: LINK
      2025-10-22T04:02:16.183Z info: 💰 Estimated fees: 12757807740510307
      2025-10-22T04:02:16.436Z info: Approving 10000000000000000000 tokens for router 0xF694E193200268f9a4868e4Aa017A0118C9a8177
      2025-10-22T04:02:18.432Z info:    Waiting for 2 confirmation(s)...
      2025-10-22T04:02:32.919Z info: Approving 12757807740510307 LINK to router
      2025-10-22T04:02:34.144Z info:    Waiting for 2 confirmation(s)...
      2025-10-22T04:02:43.114Z info: 💰 Estimated CCIP fees: 12757807740510307
      2025-10-22T04:02:43.114Z info: Simulating CCIP message...
      2025-10-22T04:02:45.169Z error: ❌ Simulation failed
      2025-10-22T04:02:45.175Z error: ❌ TokenRateLimitReached (from RateLimiter)
      2025-10-22T04:02:45.175Z error:    Args:
      2025-10-22T04:02:45.175Z error:      [0]: 30
      2025-10-22T04:02:45.176Z error:      [1]: 7000000000000000000
      2025-10-22T04:02:45.176Z error:      [2]: "0xb613B55897F07eAF430bF9a509498e55487305Ea"
      ```

      Notice in the logs that the transfer failed because the rate limit was exceeded: `TokenRateLimitReached`.

> **CAUTION: Educational Example Disclaimer**
>
> This page includes an educational example to use a Chainlink system, product, or service and is provided to
> demonstrate how to interact with Chainlink's systems, products, and services to integrate them into your own. This
> template is provided "AS IS" and "AS AVAILABLE" without warranties of any kind, it has not been audited, and it may be
> missing key checks or error handling to make the usage of the system, product or service more clear. Do not use the
> code in this example in a production environment without completing your own audits and application of best practices.
> Neither Chainlink Labs, the Chainlink Foundation, nor Chainlink node operators are responsible for unintended outputs
> that are generated due to errors in code.