> For the complete documentation index, see [llms.txt](https://docs.glacislabs.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.glacislabs.com/glacis-core/references/smart-contracts/glacistokenclient.md).

# GlacisTokenClient

**The base of your cross-chain token transfer contracts.**

GlacisTokenClient is a smart contract base that can be used by developers to interact with token passing features that Glacis has to offer. By inheriting from GlacisTokenClient, a smart contract is able to send and receive messages and tokens across chains through the GlacisTokenMediator with specific security/availability features.\
You can discover the source smart contract [`GlacisTokenClient.sol`](https://github.com/glacislabs/v1-core/blob/main/contracts/client/GlacisTokenClient.sol) in this repository. There is also an `Ownable` variant, [`GlacisTokenClientOwnable.sol`](https://github.com/glacislabs/v1-core/blob/main/contracts/client/GlacisTokenClientOwnable.sol).

This contract inherits from GlacisClient extending its message passing capabilities with token passing features, it communicates with [`GlacisTokenMediator.sol`](https://github.com/glacislabs/v1-core/blob/main/contracts/mediators/GlacisTokenMediator.sol) to perform message and/or token routing actions through Glacis infrastructure.

These are the constructor arguments for GlacisTokenClient:

* The address for GlacisRouter
* The address for GlacisTokenMediator to create the underlying GlacisClient
* The default GMP quorum for this contract to effectively receive a message

```solidity
    constructor(
        address glacisTokenMediator_,
        address glacisRouter_,
        uint256 quorum
    ) GlacisClient(glacisRouter_, quorum) {
        GLACIS_TOKEN_ROUTER = glacisTokenMediator_;
    }
```

## The Route Function

GlacisTokenClient has multiple internal route functions that mirror the route functions that GlacisRouter provides, each which return a bytes32 message ID:

* \_sendMessageAndTokens\_\_abstract( uint256 chainId, address to, uint8 gmp, bytes memory payload, uint256 gasPayment, address token, uint256 tokenAmount ) internal returns (bytes32)

  ```
    Convenient method - Routes message and tokens to destination through GlacisTokenMediator using specified GMP without any additional feature
  ```
* \_sendMessageAndTokens\_\_redundant( uint256 chainId, address to, uint8\[] memory gmps, uint256\[] memory fees, bytes memory payload, uint256 gasPayment, address token, uint256 tokenAmount ) internal returns (bytes32)

  ```
    Convenient method - Routes message and tokens to destination through the specific GMP without any additional Glacis Features
  ```
* \_sendMessageAndTokens\_\_retriable( uint256 chainId, address to, uint8\[] memory gmps, uint256\[] memory fees, bytes memory payload, uint256 gasPayment, address token, uint256 tokenAmount ) internal returns (bytes32)

  ```
    Convenient method - Routes message and tokens to destination through GlacisTokenMediator using specified GMPs with redundancy feature
  ```
* \_sendMessageAndTokens( uint256 chainId, address to, bytes memory payload, uint8\[] memory gmps, uint256\[] memory fees, bool retriable, address token, uint256 tokenAmount, uint256 gasPayment ) internal returns (bytes32)

  ```
    Routes message and tokens to destination through GlacisTokenMediator using any feature
  ```

The following parameters are applicable to each of these route functions, similar to GlacisTokenMediator:

| Parameter Name                                | Parameter Description                                                                                                                                                                                                                                                             |
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **uint256** chainId                           | The Glacis chain ID of the blockchain that you wish to send a message and/or tokens to                                                                                                                                                                                            |
| **bytes32** to                                | The address of the destination contract that you are sending a message and/or tokens to                                                                                                                                                                                           |
| **bytes memory** payload                      | The payload of data (message) that you wish to send to the destination contract                                                                                                                                                                                                   |
| **address\[]** **memory** adapters            | An array of adapters to send the message over, such as an [Axelar](https://www.axelar.network/) adapter. Can be an address if you wish to use an adapter that Glacis does not use, otherwise it can be a [GMP ID](/glacis-core/references/supported-gmps.md) stored as an address |
| **address** adapter                           | A single adapter for the message to send over, used in lieu of the adapters parameter for conveniently defining a single GMP route                                                                                                                                                |
| **GlacisRouter.CrossChainGas\[] memory** fees | An array of fees that correspond to the amount provided to each adapter. This is a parallel array to the adapters parameter. Its rules are the same as in the [GlacisRouter](/glacis-core/references/smart-contracts/glacisrouter.md#crosschaingas)                               |
| **address** refundAddress                     | The address to which excess native currency is sent to if an adapter deems that the user overpaid                                                                                                                                                                                 |
| **bool** retryable                            | Whether to allow the message to be retried (stores owner of the message ID on-chain, slightly more gas expensive)                                                                                                                                                                 |
| **uint256** gasPayment                        | The amount of native currency to forward to the GlacisRouter to pay for cross-chain gas fees                                                                                                                                                                                      |
| **address** token                             | The address of the XERC20 token you wish to send to the destination contract                                                                                                                                                                                                      |
| **uint256** tokenAmount                       | The amount of XERC20 tokens you wish to send to the destination contract                                                                                                                                                                                                          |

Each of the routing functions returns a `bytes32`, which is the Glacis message ID for the routing. The more verbose route function also returns a `uint256` nonce.

## The Retry Route

An additional route is provided within GlacisTokenClient, which doesn't send a new message and/or tokens. Instead, it resends a previous message and tokens so long as it receives identical input.

* \_retrySendWithTokens( uint256 chainId, address to, uint8\[] memory gmps, uint256\[] memory fees, bytes memory payload, bytes32 messageId, uint256 nonce, uint256 gasPayment, address token, uint256 tokenAmount ) internal returns (bytes32)

Two additional parameters are required with this function:

| Parameter Name        | Parameter Description                                                                |
| --------------------- | ------------------------------------------------------------------------------------ |
| **bytes32** messageId | The Glacis message ID of the original message                                        |
| **uint256** nonce     | The nonce of the message, which can be retrieved in the original message's event log |

Keep in mind that in the GlacisTokenMediator, only the original sender can retry routes. If this internal function is exposed publicly, anyone can retry on your smart contract's behalf.

## The Receive Message Function

The GlacisTokenMediator will call the receiveMessageWithTokens function within your GlacisTokenClient whenever there is a message sent to your smart contract. You must override the following internal function to react to cross-chain messages:

* function \_receiveMessageWithTokens( uint8\[] memory fromGmpIds, uint256 fromChainId, address fromAddress, address toAddress, bytes memory payload, address token, uint256 tokenAmount ) internal virtual {}

The parameters involved with this function are:

| Parameter Name                     | Parameter Description                                                         |
| ---------------------------------- | ----------------------------------------------------------------------------- |
| **address\[] memory** fromAdapters | The adapters through which the messages were received                         |
| **uint256** fromChainId            | The Glacis chain ID of the message's source/origin                            |
| **bytes32** fromAddress            | The address of the message's source/origin                                    |
| **bytes memory** payload           | The generic bytes payload of the message, which can be decoded to your liking |
| **address** token                  | The token that was sent with the message                                      |
| **uint256** tokenAmount            | The amount of the token that was sent with this message                       |

## Adding Routes for Access Control

This operation is inherited so it is performed exactly as in [GlacisClient](https://github.com/glacislabs/v1-documentation/blob/main/docs/pages/References/Smart%20Contracts/GlacisClient/README.md#adding-routes-for-access-control)

## Setting Quorum

This operation is inherited so it is performed exactly as in [GlacisClient](https://github.com/glacislabs/v1-documentation/blob/main/docs/pages/References/Smart%20Contracts/GlacisClient/README.md#setting-quorum)

## Read-Only

These are some of the read-only functions in GlacisClient:

* GLACIS\_TOKEN\_ROUTER() returns(address) — returns the address set as the GlacisTokenMediator, which was set in the constructor
* isAllowedRoute(GlacisRoute memory accessRoute) returns(bool) — returns true if the provided route is available, false otherwise. Used by the GlacisRouter to verify access

## Errors

{% hint style="warning" %}
Glacis is not compatible with fee-on-transfer tokens.
{% endhint %}

GlacisTokenClient includes the following errors, which you might encounter:

| Error Name                                          | Error Description                                                                                       |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| GlacisTokenClient\_\_CanOnlyBeCalledByTokenRouter() | Occurs when an address that is not the GlacisTokenMediator attempts to call the receiveMessage function |
