# 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 |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.glacislabs.com/glacis-core/references/smart-contracts/glacistokenclient.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
