Lock & Unlock Connector Scheme
Create contract with name UTSConnectorLockUnlockShowcase
.
You need to import:
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "@entangle-labs/uts-contracts/contracts/ERC20/UTSBase";
UTSBase
is our main contract that should be inherited by any Token or Connector.
In this implementation we also used Ownable
, Pausable
and IERC20Metadata
contract UTSConnectorLockUnlockShowcase is UTSBase, Ownable {}
We are starting with defining contract and dependencies. As access control we are choosing Ownable
.
constructor(
address underlyingToken_,
address _router,
uint256[] memory _allowedChainIds,
ChainConfig[] memory _chainConfigs
) Ownable(msg.sender) {
__UTSBase_init(underlyingToken_, IERC20Metadata(underlyingToken_).decimals());
_setRouter(_router);
_setChainConfig(_allowedChainIds, _chainConfigs);
}
Then we need do define constructor. Since it is connector, we need underlyingToken_
(the token that will be bridged through UTS protocol). We need also 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.
After this step we need to override 3 functions: _mintTo
, _burnFrom
and _authorizeCall
.
function _authorizeCall() internal override onlyOwner() {}
function _burnFrom(
address spender,
address /* from */,
bytes memory /* to */,
uint256 amount,
uint256 /* dstChainId */,
bytes memory /* customPayload */
) internal override returns(uint256 bridgedAmount) {
IERC20(_underlyingToken).safeTransferFrom(spender, address(this), amount);
return amount;
}
function _mintTo(
address to,
uint256 amount,
bytes memory /* customPayload */,
Origin memory /* origin */
) internal override returns(uint256 receivedAmount) {
IERC20(_underlyingToken).safeTransfer(to, amount);
return amount;
}
So, here is very simple logic, in the outbounding bridge
transaction, we need to transfer tokens from spender
to connector address, in the inbounding redeem
transaction, we need to transfer tokens from connector to receiver to
address.
Also we will implement one more function: getter for underlying token decimals.
function underlyingDecimals() external view returns(uint8) {
return _decimals;
}
Also we need to use SafeERC20
library by OpenZeppelin.
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
using SafeERC20 for IERC20;
So, our contract is ready, now it can be deployed on networks and we can start bridging tokens between each chain.
Last updated
Was this helpful?