Token with Messages

Create contract with name UTSTokenWithLogicShowcase .

You need to import:

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@entangle-labs/uts-contracts/contracts/ERC20/UTSBase";

We start with defining the contract and the dependencies. For the access control we choose Ownable and also since it is UTS Token we need to import ERC20 implementation, here we are using one by openzeppelin.

UTSBase is our main contract that should be inherited by any Token or Connector.

In this implementation we also used Ownable and ERC20.

contract UTSTokenWithLogicShowcase is UTSBase, Ownable, ERC20 {}
constructor(
    address _router,  
    uint256[] memory _allowedChainIds,
    ChainConfig[] memory _chainConfigs
) Ownable(msg.sender) ERC20("UTS Token With Logic Showcase", "TWL") {
    __UTSBase_init(address(this), decimals());

    _setRouter(_router);
    _setChainConfig(_allowedChainIds, _chainConfigs);

    _mint(msg.sender, 1_000_000 * 10 ** decimals());
}

Then we need do define constructor. Since it is Token, we don't need a lot, just general UTS settings and ERC20 metadata.

We need setup _router address, that can be found here.

_allowedChainIds are simply whitelist of chain id's, where you are allowing to bridge tokens.

_chainConfigs is array of settings responsible for bridge settings. We described this config here.

In constructor we need to call __UTSBase_init function to initialize UTS Base contract. Also we need to set router and chain config.

Also we added mint function to premint some tokens for deployer address.

We can skip setting router and chain configs in constructor, but before starting bridging we need to do it with relevant public functions.

Also let's define some events to have a possibility to debug and track transactions and also some errors and library.

After this step we need to override 3 functions: _mintTo, _burnFrom and _authorizeCall. We need to do it, because this token is mint/burn, so, internal logic should be of main bridging function should be done via mint/burn of underlying token.

In this implementation, we use customPayload as an option to transfer tokens to multiple receivers in different amounts just by one transaction. To do that, we define rules for how the raw bytes passed in customPayload should be encoded. In the _burnFrom function, we burn the tokens from the token holder in the provided amount and implement basic validations of the customPayload, if it is provided.

Also, it is necessary to implement tokens minting to the receiver or multiple receivers in the _mintTo function. Both possible scenarios need to be handled depending on whether a meaningful customPayload was provided. In this case, the raw bytes should be decoded, and the corresponding token _amounts should be minted to _receivers.

So, our contract is ready, now it can be deployed on networks and we can start bridging tokens between each chain.

You can find full code here

Last updated

Was this helpful?