# CCIP v1.6.1 TokenAdminRegistry Contract API Reference
Source: https://docs.chain.link/ccip/api-reference/evm/v1.6.1/token-admin-registry

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

<Aside type="note" title="Integrate Chainlink CCIP v1.6.1 into your project">
  <Tabs sharedStore="ccip-v1-6-1-package" client:visible>
    <Fragment slot="tab.1">npm</Fragment>
    <Fragment slot="tab.2">yarn</Fragment>
    <Fragment slot="tab.3">foundry</Fragment>

    <Fragment slot="panel.1">
      If you use [NPM](https://www.npmjs.com/), install the [@chainlink/contracts-ccip NPM package](https://www.npmjs.com/package/@chainlink/contracts-ccip):

      ```shell
      npm install @chainlink/contracts-ccip@1.6.1
      ```
    </Fragment>

    <Fragment slot="panel.2">
      If you use [Yarn](https://yarnpkg.com/), install the [@chainlink/contracts-ccip NPM package](https://www.npmjs.com/package/@chainlink/contracts-ccip):

      ```shell
      yarn add @chainlink/contracts-ccip@1.6.1
      ```
    </Fragment>

    <Fragment slot="panel.3">
      If you use [Foundry](https://book.getfoundry.sh/), install the package:

      ```shell
      forge install smartcontractkit/chainlink-ccip@bbab0601244ce58e2ffac0dbc178a80aab1fa4a3
      ```
    </Fragment>
  </Tabs>
</Aside>

## TokenAdminRegistry

A contract that manages token pool configurations and administrator access for CCIP-enabled tokens.

[Git Source](https://github.com/smartcontractkit/chainlink-ccip/tree/contracts-ccip-v1.6.1/chains/evm/contracts/tokenAdminRegistry/TokenAdminRegistry.sol)

**Inherits:**

- [ITypeAndVersion](/ccip/api-reference/evm/v1.6.1/i-type-and-version)

> \*\*NOTE\*\*
>
>
>
> This contract provides self-service token registration and administration:
>
> - Manages token pool configurations
> - Handles administrator permissions through [`proposeAdministrator`](#proposeadministrator) and [`acceptAdminRole`](#acceptadminrole)
> - Supports registry modules for flexible registration via [`addRegistryModule`](#addregistrymodule)
> - Implements secure admin role transfers using [`transferAdminRole`](#transferadminrole)
> - Not upgradeable due to significant data storage
>
> Note: This contract is designed as a customer-facing interface and stores substantial data, making it non-upgradeable by design.

## Events

### AdministratorTransferred

```solidity
event AdministratorTransferred(address indexed token, address indexed newAdmin);
```

<Aside>Emitted when an administrator role transfer is completed via [`acceptAdminRole`](#acceptadminrole).</Aside>

**Parameters**

| Name       | Type      | Indexed | Description                           |
| ---------- | --------- | ------- | ------------------------------------- |
| `token`    | `address` | Yes     | The token whose administrator changed |
| `newAdmin` | `address` | Yes     | The address of the new administrator  |

### AdministratorTransferRequested

```solidity
event AdministratorTransferRequested(address indexed token, address indexed currentAdmin, address indexed newAdmin);
```

> \*\*NOTE\*\*
>
>
>
> Emitted when an administrator transfer is initiated via [`proposeAdministrator`](#proposeadministrator) or
> [`transferAdminRole`](#transferadminrole).

**Parameters**

| Name           | Type      | Indexed | Description                       |
| -------------- | --------- | ------- | --------------------------------- |
| `token`        | `address` | Yes     | The token for the transfer        |
| `currentAdmin` | `address` | Yes     | The current administrator address |
| `newAdmin`     | `address` | Yes     | The proposed new administrator    |

### PoolSet

```solidity
event PoolSet(address indexed token, address indexed previousPool, address indexed newPool);
```

<Aside>Emitted when a token pool address is updated via [`setPool`](#setpool).</Aside>

**Parameters**

| Name           | Type      | Indexed | Description                  |
| -------------- | --------- | ------- | ---------------------------- |
| `token`        | `address` | Yes     | The token whose pool changed |
| `previousPool` | `address` | Yes     | The previous pool address    |
| `newPool`      | `address` | Yes     | The new pool address         |

### RegistryModuleAdded

```solidity
event RegistryModuleAdded(address module);
```

<Aside>Emitted when a registry module is added via [`addRegistryModule`](#addregistrymodule).</Aside>

**Parameters**

| Name     | Type      | Indexed | Description               |
| -------- | --------- | ------- | ------------------------- |
| `module` | `address` | No      | The address of the module |

### RegistryModuleRemoved

```solidity
event RegistryModuleRemoved(address indexed module);
```

<Aside>Emitted when a registry module is removed via [`removeRegistryModule`](#removeregistrymodule).</Aside>

**Parameters**

| Name     | Type      | Indexed | Description               |
| -------- | --------- | ------- | ------------------------- |
| `module` | `address` | Yes     | The address of the module |

## Functions

### acceptAdminRole

Accepts the administrator role for a token.

```solidity
function acceptAdminRole(address localToken) external;
```

> \*\*NOTE\*\*
>
>
>
> Second step of the two-step administrator transfer process:
>
> - Only callable by the pending administrator
> - Clears the pending administrator after acceptance
> - Emits AdministratorTransferred event

**Parameters**

| Name         | Type      | Description                                |
| ------------ | --------- | ------------------------------------------ |
| `localToken` | `address` | The token to accept the administrator role |

### addRegistryModule

Adds a new registry module to the allowed modules list.

```solidity
function addRegistryModule(address module) external onlyOwner;
```

> \*\*NOTE\*\*
>
>
>
> Registry module management:
>
> - Only callable by contract owner
> - Emits RegistryModuleAdded event if module is added
> - No effect if module is already registered

**Parameters**

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `module` | `address` | The module to authorize |

### getAllConfiguredTokens

Returns a paginated list of configured tokens.

```solidity
function getAllConfiguredTokens(uint64 startIndex, uint64 maxCount) external view returns (address[] memory tokens);
```

> \*\*NOTE\*\*
>
>
>
> Pagination features:
>
> - Supports partial list retrieval to prevent RPC timeouts
> - Maintains consistent ordering
> - Returns empty array if startIndex is beyond list length
> - Automatically adjusts count if it exceeds available tokens

**Parameters**

| Name         | Type     | Description                                               |
| ------------ | -------- | --------------------------------------------------------- |
| `startIndex` | `uint64` | Starting position in the list (0 for beginning)           |
| `maxCount`   | `uint64` | Maximum tokens to retrieve (use type(uint64).max for all) |

**Returns**

| Type        | Description                        |
| ----------- | ---------------------------------- |
| `address[]` | List of configured token addresses |

### getPool

Returns the pool address for a specific token.

```solidity
function getPool(address token) external view returns (address);
```

> \*\*NOTE\*\*
>
>
>
> Returns address(0) if:
>
> - Token is not configured
> - Token is delisted from CCIP

**Parameters**

| Name    | Type      | Description        |
| ------- | --------- | ------------------ |
| `token` | `address` | The token to query |

**Returns**

| Type      | Description              |
| --------- | ------------------------ |
| `address` | The token's pool address |

### getPools

Returns pool addresses for multiple tokens.

```solidity
function getPools(address[] calldata tokens) external view returns (address[] memory);
```

> \*\*NOTE\*\*
>
>
>
> Batch query functionality:
>
> - Returns address(0) for unconfigured tokens
> - Maintains order corresponding to input array
> - Useful for efficient multi-token queries

**Parameters**

| Name     | Type        | Description     |
| -------- | ----------- | --------------- |
| `tokens` | `address[]` | Tokens to query |

**Returns**

| Type        | Description                           |
| ----------- | ------------------------------------- |
| `address[]` | Array of corresponding pool addresses |

### getTokenConfig

Returns the complete configuration for a token.

```solidity
function getTokenConfig(address token) external view returns (TokenConfig memory);
```

> \*\*NOTE\*\*
>
>
>
> Returns all token configuration data:
>
> - Current administrator
> - Pending administrator (if any)
> - Token pool address

**Parameters**

| Name    | Type      | Description    |
| ------- | --------- | -------------- |
| `token` | `address` | Token to query |

**Returns**

| Type          | Description                  |
| ------------- | ---------------------------- |
| `TokenConfig` | Complete token configuration |

### isAdministrator

Checks if an address is the administrator for a token.

```solidity
function isAdministrator(address localToken, address administrator) external view returns (bool);
```

> \*\*NOTE\*\*
>
>
>
> Permission verification helper:
>
> - Returns true only for current administrator
> - Does not consider pending administrators

**Parameters**

| Name            | Type      | Description       |
| --------------- | --------- | ----------------- |
| `localToken`    | `address` | Token to check    |
| `administrator` | `address` | Address to verify |

**Returns**

| Type   | Description                              |
| ------ | ---------------------------------------- |
| `bool` | True if address is current administrator |

### isRegistryModule

Checks if an address is an authorized registry module.

```solidity
function isRegistryModule(address module) public view returns (bool);
```

> \*\*NOTE\*\*
>
>
>
> Module verification helper:
>
> - Returns true for authorized modules
> - Used for permission checks in proposeAdministrator

**Parameters**

| Name     | Type      | Description       |
| -------- | --------- | ----------------- |
| `module` | `address` | Address to verify |

**Returns**

| Type   | Description                          |
| ------ | ------------------------------------ |
| `bool` | True if address is authorized module |

### proposeAdministrator

Proposes an initial administrator for a token.

```solidity
function proposeAdministrator(address localToken, address administrator) external;
```

> \*\*NOTE\*\*
>
>
>
> Initial administrator setup:
>
> - Only callable by registry modules (see [`isRegistryModule`](#isregistrymodule)) or owner
> - Cannot override existing administrator (reverts with [`AlreadyRegistered`](#alreadyregistered))
> - Initiates two-step transfer process requiring [`acceptAdminRole`](#acceptadminrole)
> - Adds token to configured tokens list
> - Emits [`AdministratorTransferRequested`](#administratortransferrequested) event

**Parameters**

| Name            | Type      | Description                    |
| --------------- | --------- | ------------------------------ |
| `localToken`    | `address` | Token to configure             |
| `administrator` | `address` | Proposed administrator address |

### removeRegistryModule

Removes a registry module from the allowed modules list.

```solidity
function removeRegistryModule(address module) external onlyOwner;
```

> \*\*NOTE\*\*
>
>
>
> Registry module management:
>
> - Only callable by contract owner
> - Emits RegistryModuleRemoved event if module is removed
> - No effect if module is not registered

**Parameters**

| Name     | Type      | Description          |
| -------- | --------- | -------------------- |
| `module` | `address` | The module to remove |

### setPool

Sets or updates the pool for a token.

```solidity
function setPool(address localToken, address pool) external onlyTokenAdmin(localToken);
```

> \*\*NOTE\*\*
>
>
>
> Pool configuration management:
>
> - Only callable by token administrator (reverts with [`OnlyAdministrator`](#onlyadministrator))
> - Can delist token by setting address(0)
> - Validates pool supports token (reverts with [`InvalidTokenPoolToken`](#invalidtokenpooltoken))
> - Emits [`PoolSet`](#poolset) event on changes

**Parameters**

| Name         | Type      | Description                       |
| ------------ | --------- | --------------------------------- |
| `localToken` | `address` | Token to configure                |
| `pool`       | `address` | New pool address (or 0 to delist) |

### transferAdminRole

Initiates transfer of administrator role.

```solidity
function transferAdminRole(address localToken, address newAdmin) external onlyTokenAdmin(localToken);
```

> \*\*NOTE\*\*
>
>
>
> First step of two-step administrator transfer:
>
> - Only callable by current administrator (reverts with [`OnlyAdministrator`](#onlyadministrator))
> - Can cancel pending transfer with address(0)
> - Requires [`acceptAdminRole`](#acceptadminrole) call to complete
> - Emits [`AdministratorTransferRequested`](#administratortransferrequested) event

**Parameters**

| Name         | Type      | Description                                              |
| ------------ | --------- | -------------------------------------------------------- |
| `localToken` | `address` | The token contract whose admin role is being transferred |
| `newAdmin`   | `address` | The proposed new administrator address (or 0 to cancel)  |

## Events

### AdministratorTransferRequested

```solidity
event AdministratorTransferRequested(address indexed token, address indexed currentAdmin, address indexed newAdmin);
```

> \*\*NOTE\*\*
>
>
>
> Emitted when an administrator transfer is initiated via [`transferAdminRole`](#transferadminrole) or canceled.

**Parameters**

| Name           | Type      | Indexed | Description                                              |
| -------------- | --------- | ------- | -------------------------------------------------------- |
| `token`        | `address` | Yes     | The token contract whose admin role is being transferred |
| `currentAdmin` | `address` | Yes     | The current administrator address                        |
| `newAdmin`     | `address` | Yes     | The proposed new administrator address                   |

### AdministratorTransferred

```solidity
event AdministratorTransferred(address indexed token, address indexed newAdmin);
```

<Aside>Emitted when an administrator transfer is completed via [`acceptAdminRole`](#acceptadminrole).</Aside>

**Parameters**

| Name       | Type      | Indexed | Description                                              |
| ---------- | --------- | ------- | -------------------------------------------------------- |
| `token`    | `address` | Yes     | The token contract whose admin role has been transferred |
| `newAdmin` | `address` | Yes     | The new administrator address                            |

### PoolSet

```solidity
event PoolSet(address indexed token, address indexed previousPool, address indexed newPool);
```

<Aside>Emitted when a token's pool configuration is changed via [`setPool`](#setpool).</Aside>

**Parameters**

| Name           | Type      | Indexed | Description                        |
| -------------- | --------- | ------- | ---------------------------------- |
| `token`        | `address` | Yes     | The token address being configured |
| `previousPool` | `address` | Yes     | The previous pool address          |
| `newPool`      | `address` | Yes     | The new pool address               |

### RegistryModuleAdded

```solidity
event RegistryModuleAdded(address module);
```

<Aside>Emitted when a new registry module is authorized.</Aside>

**Parameters**

| Name     | Type      | Indexed | Description                                |
| -------- | --------- | ------- | ------------------------------------------ |
| `module` | `address` | No      | The address of the newly authorized module |

### RegistryModuleRemoved

```solidity
event RegistryModuleRemoved(address indexed module);
```

<Aside>Emitted when a registry module is deauthorized.</Aside>

**Parameters**

| Name     | Type      | Indexed | Description                       |
| -------- | --------- | ------- | --------------------------------- |
| `module` | `address` | Yes     | The address of the removed module |

## Errors

### AddressZero

```solidity
error ZeroAddress();
```

<Aside>Thrown when attempting to use address(0) where not allowed.</Aside>

### AlreadyRegistered

```solidity
error AlreadyRegistered(address token);
```

<Aside>Thrown when attempting to register an administrator for a token that already has one.</Aside>

**Parameters**

| Name    | Type      | Description                                         |
| ------- | --------- | --------------------------------------------------- |
| `token` | `address` | The token address that already has an administrator |

### InvalidTokenPoolToken

```solidity
error InvalidTokenPoolToken(address token);
```

<Aside>Thrown when attempting to set a pool that doesn't support the token.</Aside>

**Parameters**

| Name    | Type      | Description                                         |
| ------- | --------- | --------------------------------------------------- |
| `token` | `address` | The token address that is not supported by the pool |

### OnlyAdministrator

```solidity
error OnlyAdministrator(address sender, address token);
```

<Aside>Thrown when a function restricted to the token administrator is called by another address.</Aside>

**Parameters**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `sender` | `address` | The unauthorized caller's address |
| `token`  | `address` | The token address being accessed  |

### OnlyPendingAdministrator

```solidity
error OnlyPendingAdministrator(address sender, address token);
```

<Aside>Thrown when acceptAdminRole is called by an address other than the pending administrator.</Aside>

**Parameters**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `sender` | `address` | The unauthorized caller's address |
| `token`  | `address` | The token address being accessed  |

### OnlyRegistryModuleOrOwner

```solidity
error OnlyRegistryModuleOrOwner(address sender);
```

<Aside>Thrown when a function restricted to registry modules or owner is called by another address.</Aside>

**Parameters**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `sender` | `address` | The unauthorized caller's address |

## Structs

### TokenConfig

Configuration data structure for each token.

```solidity
struct TokenConfig {
  address administrator;
  address pendingAdministrator;
  address tokenPool;
}
```

> \*\*NOTE\*\*
>
>
>
> Token configuration fields:
>
> - `administrator`: Current token administrator
> - `pendingAdministrator`: Address pending administrator role transfer
> - `tokenPool`: Associated token pool address (0 if delisted)

## State Variables

### s\_registryModules

```solidity
EnumerableSet.AddressSet internal s_registryModules;
```

<Aside>Set of authorized registry modules that can register administrators.</Aside>

### s\_tokenConfig

```solidity
mapping(address token => TokenConfig) internal s_tokenConfig;
```

<Aside>Stores configuration data for each token, including administrators and pool addresses.</Aside>

### s\_tokens

```solidity
EnumerableSet.AddressSet internal s_tokens;
```

<Aside>Set of all configured tokens for efficient enumeration.</Aside>

### typeAndVersion

```solidity
string public constant override typeAndVersion = "TokenAdminRegistry 1.5.0";
```

<Aside>Contract identifier that specifies the implementation version.</Aside>