Docs
IntegrationsEVM

Canonical tokens

Register an existing ERC-20 with ITS, and deploy interchain tokens for it on other chains.

A canonical token is an existing ERC-20 on one chain, its home chain, registered with ITS. The token stays as it is: ITS locks it when it leaves the home chain and unlocks it when it comes back. On every other chain, ITS deploys an interchain token for it, with no minter.

For setup and the variables used below, see the EVM overview.

Register the token

On the home chain:

function registerCanonicalInterchainToken(address tokenAddress) external payable returns (bytes32 tokenId);

The call deploys a LOCK_UNLOCK token manager for the token, with no operator. It sends no message, so send no value with it. The token must have name(), symbol() and decimals(), or the call reverts.

TOKEN=<your token address>

cast send $FACTORY "registerCanonicalInterchainToken(address)" $TOKEN \
  --rpc-url $RPC --private-key $PK

TOKEN_ID=$(cast call $FACTORY "canonicalInterchainTokenId(address)(bytes32)" $TOKEN --rpc-url $RPC)

A token can be registered once, and anyone can register any token. Its token ID depends only on the token's address and the home chain.

For a token that takes a fee on transfer, register it as a custom token with a LOCK_UNLOCK_FEE token manager instead: canonical registration always uses LOCK_UNLOCK.

Deploy it to other chains

On the home chain:

function deployRemoteCanonicalInterchainToken(
    address originalTokenAddress,
    string calldata destinationChain,
    uint256 gasValue
) external payable returns (bytes32 tokenId);
cast send $FACTORY "deployRemoteCanonicalInterchainToken(address,string,uint256)" \
  $TOKEN binance $FEE --value $FEE \
  --rpc-url $RPC --private-key $PK

The call sends a message, so pay its gas. Anyone can call it, for any registered token. It deploys an interchain token with the token's name, symbol and decimals, and no minter, on the destination chain. The ITS Hub can lower the decimals on chains with a smaller maximum amount. Here's a remote deployment on Axelarscan.

Send it

To send the token out of its home chain, approve ITS first: ITS moves the tokens to the token manager with transferFrom.

cast send $TOKEN "approve(address,uint256)" $ITS 25000000000000000000 \
  --rpc-url $RPC --private-key $PK

Then call interchainTransfer on ITS; see Transfers. On other chains, the token is an interchain token, and needs no approval.

Next steps

  • Transfers: send the token between chains.
  • Flow limits: a canonical token has no operator, so only ITS can set its flow limits.
  • its-canonical-token: an example that registers a canonical token and sends it between EVM chains.

On this page