ETH Price: $3,683.65 (+0.33%)
Gas: 5.99 Gwei
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

TokenTracker

CeDeFiAi (CDFi) (@$0.1077)

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Approve215266242025-01-01 2:27:116 days ago1735698431IN
CeDeFiAi: CDFi Token
0 ETH0.000190583.88929564
Approve215041532024-12-28 23:10:119 days ago1735427411IN
CeDeFiAi: CDFi Token
0 ETH0.000312096.3302093
Approve213782182024-12-11 8:56:4726 days ago1733907407IN
CeDeFiAi: CDFi Token
0 ETH0.0007451715.11428197
Approve213725152024-12-10 13:51:2327 days ago1733838683IN
CeDeFiAi: CDFi Token
0 ETH0.0008744317.73594946
Approve213468072024-12-06 23:42:3531 days ago1733528555IN
CeDeFiAi: CDFi Token
0 ETH0.0008805817.88245692
Approve213319682024-12-04 21:57:2333 days ago1733349443IN
CeDeFiAi: CDFi Token
0 ETH0.001775136.00390664
Approve213052652024-12-01 4:27:2337 days ago1733027243IN
CeDeFiAi: CDFi Token
0 ETH0.000216158
Approve212895542024-11-28 23:43:5939 days ago1732837439IN
CeDeFiAi: CDFi Token
0 ETH0.000368427.51665785
Transfer212894602024-11-28 23:24:5939 days ago1732836299IN
CeDeFiAi: CDFi Token
0 ETH0.000384087.75594671
Approve212893012024-11-28 22:52:4739 days ago1732834367IN
CeDeFiAi: CDFi Token
0 ETH0.000371247.5723444
Transfer212685982024-11-26 1:19:5942 days ago1732583999IN
CeDeFiAi: CDFi Token
0 ETH0.000451359.11220818
Transfer212282182024-11-20 10:01:1147 days ago1732096871IN
CeDeFiAi: CDFi Token
0 ETH0.0006271712.65870831
Approve211277192024-11-06 9:28:5961 days ago1730885339IN
CeDeFiAi: CDFi Token
0 ETH0.0007500715.30673341
Approve211219552024-11-05 14:10:1162 days ago1730815811IN
CeDeFiAi: CDFi Token
0 ETH0.0006432413.04673307
Approve211135672024-11-04 10:04:1163 days ago1730714651IN
CeDeFiAi: CDFi Token
0 ETH0.000186253.78244427
Transfer211135152024-11-04 9:53:4763 days ago1730714027IN
CeDeFiAi: CDFi Token
0 ETH0.00022924.62736882
Approve209522642024-10-12 21:40:2386 days ago1728769223IN
CeDeFiAi: CDFi Token
0 ETH0.00042578.63445021
Approve209493532024-10-12 11:54:2386 days ago1728734063IN
CeDeFiAi: CDFi Token
0 ETH0.0004958110.06873378
Approve209359752024-10-10 15:01:5988 days ago1728572519IN
CeDeFiAi: CDFi Token
0 ETH0.001541531.30410263
Interchain Trans...208876502024-10-03 21:24:4795 days ago1727990687IN
CeDeFiAi: CDFi Token
0.00026552 ETH0.000725475.49226539
Approve208149652024-09-23 18:06:23105 days ago1727114783IN
CeDeFiAi: CDFi Token
0 ETH0.000909718.47373059
Transfer208149612024-09-23 18:05:35105 days ago1727114735IN
CeDeFiAi: CDFi Token
0 ETH0.0009856619.90398557
Approve208149532024-09-23 18:03:59105 days ago1727114639IN
CeDeFiAi: CDFi Token
0 ETH0.0009408419.10616939
Approve207331452024-09-12 7:48:47116 days ago1726127327IN
CeDeFiAi: CDFi Token
0 ETH0.000150833.0631641
Approve207137952024-09-09 14:57:11119 days ago1725893831IN
CeDeFiAi: CDFi Token
0 ETH0.000412748.41665361
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
208876502024-10-03 21:24:4795 days ago1727990687
CeDeFiAi: CDFi Token
0.00026552 ETH
206464342024-08-31 5:22:23128 days ago1725081743
CeDeFiAi: CDFi Token
0.00023452 ETH
204737482024-08-07 2:36:11153 days ago1722998171
CeDeFiAi: CDFi Token
0.00021682 ETH
201748642024-06-26 9:07:59194 days ago1719392879
CeDeFiAi: CDFi Token
0.00018548 ETH
201243072024-06-19 7:30:47201 days ago1718782247
CeDeFiAi: CDFi Token
0.00019086 ETH
199357482024-05-23 23:05:35228 days ago1716505535
CeDeFiAi: CDFi Token
0.00019231 ETH
199354612024-05-23 22:07:47228 days ago1716502067
CeDeFiAi: CDFi Token
0.0001905 ETH
199351762024-05-23 21:10:23228 days ago1716498623
CeDeFiAi: CDFi Token
0.00012915 ETH
199266962024-05-22 16:45:11229 days ago1716396311
CeDeFiAi: CDFi Token
0.00020653 ETH
199264372024-05-22 15:53:11229 days ago1716393191
CeDeFiAi: CDFi Token
0.00007619 ETH
199137252024-05-20 21:11:11231 days ago1716239471
CeDeFiAi: CDFi Token
0.00021556 ETH
199117712024-05-20 14:35:47231 days ago1716215747
CeDeFiAi: CDFi Token
0.00008947 ETH
198202402024-05-07 19:21:11244 days ago1715109671
CeDeFiAi: CDFi Token
0.00026303 ETH
198180432024-05-07 11:59:11244 days ago1715083151
CeDeFiAi: CDFi Token
0.00026278 ETH
198144132024-05-06 23:46:59245 days ago1715039219
CeDeFiAi: CDFi Token
0.00010925 ETH
198144062024-05-06 23:45:23245 days ago1715039123
CeDeFiAi: CDFi Token
0.00026158 ETH
198143892024-05-06 23:41:59245 days ago1715038919
CeDeFiAi: CDFi Token
0.00010789 ETH
198143822024-05-06 23:40:35245 days ago1715038835
CeDeFiAi: CDFi Token
0.00038803 ETH
197998562024-05-04 22:55:23247 days ago1714863323
CeDeFiAi: CDFi Token
0.00010627 ETH
197916992024-05-03 19:33:23248 days ago1714764803
CeDeFiAi: CDFi Token
0.00025965 ETH
197623122024-04-29 16:59:11252 days ago1714409951
CeDeFiAi: CDFi Token
0.00024392 ETH
197429582024-04-27 0:00:35255 days ago1714176035
CeDeFiAi: CDFi Token
0.0002448 ETH
197407302024-04-26 16:31:11255 days ago1714149071
CeDeFiAi: CDFi Token
0.00024586 ETH
197406002024-04-26 16:04:59255 days ago1714147499
CeDeFiAi: CDFi Token
0.00024579 ETH
197391422024-04-26 11:10:11255 days ago1714129811
CeDeFiAi: CDFi Token
0.00024696 ETH
View All Internal Transactions
Loading...
Loading

Minimal Proxy Contract for 0x7f9f70da4af54671a6abac58e705b5634cac8819

Contract Name:
InterchainToken

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 1000 runs

Other Settings:
london EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 17 : InterchainToken.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { AddressBytes } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressBytes.sol';

import { IInterchainToken } from '../interfaces/IInterchainToken.sol';

import { InterchainTokenStandard } from './InterchainTokenStandard.sol';
import { ERC20 } from './ERC20.sol';
import { ERC20Permit } from './ERC20Permit.sol';
import { Minter } from '../utils/Minter.sol';

/**
 * @title InterchainToken
 * @notice This contract implements an interchain token which extends InterchainToken functionality.
 * @dev This contract also inherits Minter and Implementation logic.
 */
contract InterchainToken is InterchainTokenStandard, ERC20, ERC20Permit, Minter, IInterchainToken {
    using AddressBytes for bytes;

    string public name;
    string public symbol;
    uint8 public decimals;
    bytes32 internal tokenId;
    address internal immutable interchainTokenService_;

    // bytes32(uint256(keccak256('interchain-token-initialized')) - 1);
    bytes32 internal constant INITIALIZED_SLOT = 0xc778385ecb3e8cecb82223fa1f343ec6865b2d64c65b0c15c7e8aef225d9e214;

    /**
     * @notice Constructs the InterchainToken contract.
     * @dev Makes the implementation act as if it has been setup already to disallow calls to init() (even though that would not achieve anything really).
     */
    constructor(address interchainTokenServiceAddress) {
        _initialize();

        if (interchainTokenServiceAddress == address(0)) revert InterchainTokenServiceAddressZero();

        interchainTokenService_ = interchainTokenServiceAddress;
    }

    /**
     * @notice Returns true if the contract has been setup.
     * @return initialized True if the contract has been setup, false otherwise.
     */
    function _isInitialized() internal view returns (bool initialized) {
        assembly {
            initialized := sload(INITIALIZED_SLOT)
        }
    }

    /**
     * @notice Sets initialized to true, to allow only a single init.
     */
    function _initialize() internal {
        assembly {
            sstore(INITIALIZED_SLOT, true)
        }
    }

    /**
     * @notice Returns the interchain token service
     * @return address The interchain token service contract
     */
    function interchainTokenService() public view override(InterchainTokenStandard, IInterchainToken) returns (address) {
        return interchainTokenService_;
    }

    /**
     * @notice Returns the tokenId for this token.
     * @return bytes32 The token manager contract.
     */
    function interchainTokenId() public view override(InterchainTokenStandard, IInterchainToken) returns (bytes32) {
        return tokenId;
    }

    /**
     * @notice Setup function to initialize contract parameters.
     * @param tokenId_ The tokenId of the token.
     * @param minter The address of the token minter.
     * @param tokenName The name of the token.
     * @param tokenSymbol The symbopl of the token.
     * @param tokenDecimals The decimals of the token.
     */
    function init(bytes32 tokenId_, address minter, string calldata tokenName, string calldata tokenSymbol, uint8 tokenDecimals) external {
        if (_isInitialized()) revert AlreadyInitialized();

        _initialize();

        if (tokenId_ == bytes32(0)) revert TokenIdZero();
        if (bytes(tokenName).length == 0) revert TokenNameEmpty();
        if (bytes(tokenSymbol).length == 0) revert TokenSymbolEmpty();

        name = tokenName;
        symbol = tokenSymbol;
        decimals = tokenDecimals;
        tokenId = tokenId_;

        /**
         * @dev Set the token service as a minter to allow it to mint and burn tokens.
         * Also add the provided address as a minter. If `address(0)` was provided,
         * add it as a minter to allow anyone to easily check that no custom minter was set.
         */
        _addMinter(interchainTokenService_);
        _addMinter(minter);

        _setNameHash(tokenName);
    }

    /**
     * @notice Function to mint new tokens.
     * @dev Can only be called by the minter address.
     * @param account The address that will receive the minted tokens.
     * @param amount The amount of tokens to mint.
     */
    function mint(address account, uint256 amount) external onlyRole(uint8(Roles.MINTER)) {
        _mint(account, amount);
    }

    /**
     * @notice Function to burn tokens.
     * @dev Can only be called by the minter address.
     * @param account The address that will have its tokens burnt.
     * @param amount The amount of tokens to burn.
     */
    function burn(address account, uint256 amount) external onlyRole(uint8(Roles.MINTER)) {
        _burn(account, amount);
    }

    /**
     * @notice A method to be overwritten that will decrease the allowance of the `spender` from `sender` by `amount`.
     * @dev Needs to be overwritten. This provides flexibility for the choice of ERC20 implementation used. Must revert if allowance is not sufficient.
     */
    function _spendAllowance(address sender, address spender, uint256 amount) internal override {
        uint256 _allowance = allowance[sender][spender];

        if (_allowance != UINT256_MAX) {
            _approve(sender, spender, _allowance - amount);
        }
    }
}

File 2 of 17 : IERC20Permit.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;

interface IERC20Permit {
    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function nonces(address account) external view returns (uint256);

    function permit(
        address issuer,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
}

File 3 of 17 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    error InvalidAccount();

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 4 of 17 : IRolesBase.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title IRolesBase Interface
 * @notice IRolesBase is an interface that abstracts the implementation of a
 * contract with role control internal functions.
 */
interface IRolesBase {
    error MissingRole(address account, uint8 role);
    error MissingAllRoles(address account, uint256 accountRoles);
    error MissingAnyOfRoles(address account, uint256 accountRoles);

    error InvalidProposedRoles(address fromAccount, address toAccount, uint256 accountRoles);

    event RolesProposed(address indexed fromAccount, address indexed toAccount, uint256 accountRoles);
    event RolesAdded(address indexed account, uint256 accountRoles);
    event RolesRemoved(address indexed account, uint256 accountRoles);

    /**
     * @notice Checks if an account has a role.
     * @param account The address to check
     * @param role The role to check
     * @return True if the account has the role, false otherwise
     */
    function hasRole(address account, uint8 role) external view returns (bool);
}

File 5 of 17 : AddressBytes.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title AddressBytesUtils
 * @dev This library provides utility functions to convert between `address` and `bytes`.
 */
library AddressBytes {
    error InvalidBytesLength(bytes bytesAddress);

    /**
     * @dev Converts a bytes address to an address type.
     * @param bytesAddress The bytes representation of an address
     * @return addr The converted address
     */
    function toAddress(bytes memory bytesAddress) internal pure returns (address addr) {
        if (bytesAddress.length != 20) revert InvalidBytesLength(bytesAddress);

        assembly {
            addr := mload(add(bytesAddress, 20))
        }
    }

    /**
     * @dev Converts an address to bytes.
     * @param addr The address to be converted
     * @return bytesAddress The bytes representation of the address
     */
    function toBytes(address addr) internal pure returns (bytes memory bytesAddress) {
        bytesAddress = new bytes(20);
        // we can test if using a single 32 byte variable that is the address with the length together and using one mstore would be slightly cheaper.
        assembly {
            mstore(add(bytesAddress, 20), addr)
            mstore(bytesAddress, 20)
        }
    }
}

File 6 of 17 : RolesBase.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IRolesBase } from '../interfaces/IRolesBase.sol';

/**
 * @title RolesBase
 * @notice A contract module which provides a set if internal functions
 * for implementing role control features.
 */
contract RolesBase is IRolesBase {
    bytes32 internal constant ROLES_PREFIX = keccak256('roles');
    bytes32 internal constant PROPOSE_ROLES_PREFIX = keccak256('propose-roles');

    /**
     * @notice Modifier that throws an error if called by any account missing the role.
     */
    modifier onlyRole(uint8 role) {
        if (!_hasRole(_getRoles(msg.sender), role)) revert MissingRole(msg.sender, role);

        _;
    }

    /**
     * @notice Modifier that throws an error if called by an account without all the roles.
     */
    modifier withEveryRole(uint8[] memory roles) {
        uint256 accountRoles = _toAccountRoles(roles);
        if (!_hasAllTheRoles(_getRoles(msg.sender), accountRoles)) revert MissingAllRoles(msg.sender, accountRoles);

        _;
    }

    /**
     * @notice Modifier that throws an error if called by an account without any of the roles.
     */
    modifier withAnyRole(uint8[] memory roles) {
        uint256 accountRoles = _toAccountRoles(roles);
        if (!_hasAnyOfRoles(_getRoles(msg.sender), accountRoles)) revert MissingAnyOfRoles(msg.sender, accountRoles);

        _;
    }

    /**
     * @notice Checks if an account has a role.
     * @param account The address to check
     * @param role The role to check
     * @return True if the account has the role, false otherwise
     */
    function hasRole(address account, uint8 role) public view returns (bool) {
        return _hasRole(_getRoles(account), role);
    }

    /**
     * @notice Internal function to convert an array of roles to a uint256.
     * @param roles The roles to convert
     * @return accountRoles The roles in uint256 format
     */
    function _toAccountRoles(uint8[] memory roles) internal pure returns (uint256) {
        uint256 length = roles.length;
        uint256 accountRoles;

        for (uint256 i = 0; i < length; ++i) {
            accountRoles |= (1 << roles[i]);
        }

        return accountRoles;
    }

    /**
     * @notice Internal function to get the key of the roles mapping.
     * @param account The address to get the key for
     * @return key The key of the roles mapping
     */
    function _rolesKey(address account) internal view virtual returns (bytes32 key) {
        return keccak256(abi.encodePacked(ROLES_PREFIX, account));
    }

    /**
     * @notice Internal function to get the roles of an account.
     * @param account The address to get the roles for
     * @return accountRoles The roles of the account in uint256 format
     */
    function _getRoles(address account) internal view returns (uint256 accountRoles) {
        bytes32 key = _rolesKey(account);
        assembly {
            accountRoles := sload(key)
        }
    }

    /**
     * @notice Internal function to set the roles of an account.
     * @param account The address to set the roles for
     * @param accountRoles The roles to set
     */
    function _setRoles(address account, uint256 accountRoles) private {
        bytes32 key = _rolesKey(account);
        assembly {
            sstore(key, accountRoles)
        }
    }

    /**
     * @notice Internal function to get the key of the proposed roles mapping.
     * @param fromAccount The address of the current role
     * @param toAccount The address of the pending role
     * @return key The key of the proposed roles mapping
     */
    function _proposalKey(address fromAccount, address toAccount) internal view virtual returns (bytes32 key) {
        return keccak256(abi.encodePacked(PROPOSE_ROLES_PREFIX, fromAccount, toAccount));
    }

    /**
     * @notice Internal function to get the proposed roles of an account.
     * @param fromAccount The address of the current role
     * @param toAccount The address of the pending role
     * @return proposedRoles_ The proposed roles of the account in uint256 format
     */
    function _getProposedRoles(address fromAccount, address toAccount) internal view returns (uint256 proposedRoles_) {
        bytes32 key = _proposalKey(fromAccount, toAccount);
        assembly {
            proposedRoles_ := sload(key)
        }
    }

    /**
     * @notice Internal function to set the proposed roles of an account.
     * @param fromAccount The address of the current role
     * @param toAccount The address of the pending role
     * @param proposedRoles_ The proposed roles to set in uint256 format
     */
    function _setProposedRoles(
        address fromAccount,
        address toAccount,
        uint256 proposedRoles_
    ) private {
        bytes32 key = _proposalKey(fromAccount, toAccount);
        assembly {
            sstore(key, proposedRoles_)
        }
    }

    /**
     * @notice Internal function to add a role to an account.
     * @dev emits a RolesAdded event.
     * @param account The address to add the role to
     * @param role The role to add
     */
    function _addRole(address account, uint8 role) internal {
        _addAccountRoles(account, 1 << role);
    }

    /**
     * @notice Internal function to add roles to an account.
     * @dev emits a RolesAdded event.
     * @dev Called in the constructor to set the initial roles.
     * @param account The address to add roles to
     * @param roles The roles to add
     */
    function _addRoles(address account, uint8[] memory roles) internal {
        _addAccountRoles(account, _toAccountRoles(roles));
    }

    /**
     * @notice Internal function to add roles to an account.
     * @dev emits a RolesAdded event.
     * @dev Called in the constructor to set the initial roles.
     * @param account The address to add roles to
     * @param accountRoles The roles to add
     */
    function _addAccountRoles(address account, uint256 accountRoles) internal {
        uint256 newAccountRoles = _getRoles(account) | accountRoles;

        _setRoles(account, newAccountRoles);

        emit RolesAdded(account, accountRoles);
    }

    /**
     * @notice Internal function to remove a role from an account.
     * @dev emits a RolesRemoved event.
     * @param account The address to remove the role from
     * @param role The role to remove
     */
    function _removeRole(address account, uint8 role) internal {
        _removeAccountRoles(account, 1 << role);
    }

    /**
     * @notice Internal function to remove roles from an account.
     * @dev emits a RolesRemoved event.
     * @param account The address to remove roles from
     * @param roles The roles to remove
     */
    function _removeRoles(address account, uint8[] memory roles) internal {
        _removeAccountRoles(account, _toAccountRoles(roles));
    }

    /**
     * @notice Internal function to remove roles from an account.
     * @dev emits a RolesRemoved event.
     * @param account The address to remove roles from
     * @param accountRoles The roles to remove
     */
    function _removeAccountRoles(address account, uint256 accountRoles) internal {
        uint256 newAccountRoles = _getRoles(account) & ~accountRoles;

        _setRoles(account, newAccountRoles);

        emit RolesRemoved(account, accountRoles);
    }

    /**
     * @notice Internal function to check if an account has a role.
     * @param accountRoles The roles of the account in uint256 format
     * @param role The role to check
     * @return True if the account has the role, false otherwise
     */
    function _hasRole(uint256 accountRoles, uint8 role) internal pure returns (bool) {
        return accountRoles & (1 << role) != 0;
    }

    /**
     * @notice Internal function to check if an account has all the roles.
     * @param hasAccountRoles The roles of the account in uint256 format
     * @param mustHaveAccountRoles The roles the account must have
     * @return True if the account has all the roles, false otherwise
     */
    function _hasAllTheRoles(uint256 hasAccountRoles, uint256 mustHaveAccountRoles) internal pure returns (bool) {
        return (hasAccountRoles & mustHaveAccountRoles) == mustHaveAccountRoles;
    }

    /**
     * @notice Internal function to check if an account has any of the roles.
     * @param hasAccountRoles The roles of the account in uint256 format
     * @param mustHaveAnyAccountRoles The roles to check in uint256 format
     * @return True if the account has any of the roles, false otherwise
     */
    function _hasAnyOfRoles(uint256 hasAccountRoles, uint256 mustHaveAnyAccountRoles) internal pure returns (bool) {
        return (hasAccountRoles & mustHaveAnyAccountRoles) != 0;
    }

    /**
     * @notice Internal function to propose to transfer roles of message sender to a new account.
     * @dev Original account must have all the proposed roles.
     * @dev Emits a RolesProposed event.
     * @dev Roles are not transferred until the new role accepts the role transfer.
     * @param fromAccount The address of the current roles
     * @param toAccount The address to transfer roles to
     * @param role The role to transfer
     */
    function _proposeRole(
        address fromAccount,
        address toAccount,
        uint8 role
    ) internal {
        _proposeAccountRoles(fromAccount, toAccount, 1 << role);
    }

    /**
     * @notice Internal function to propose to transfer roles of message sender to a new account.
     * @dev Original account must have all the proposed roles.
     * @dev Emits a RolesProposed event.
     * @dev Roles are not transferred until the new role accepts the role transfer.
     * @param fromAccount The address of the current roles
     * @param toAccount The address to transfer roles to
     * @param roles The roles to transfer
     */
    function _proposeRoles(
        address fromAccount,
        address toAccount,
        uint8[] memory roles
    ) internal {
        _proposeAccountRoles(fromAccount, toAccount, _toAccountRoles(roles));
    }

    /**
     * @notice Internal function to propose to transfer roles of message sender to a new account.
     * @dev Original account must have all the proposed roles.
     * @dev Emits a RolesProposed event.
     * @dev Roles are not transferred until the new role accepts the role transfer.
     * @param fromAccount The address of the current roles
     * @param toAccount The address to transfer roles to
     * @param accountRoles The account roles to transfer
     */
    function _proposeAccountRoles(
        address fromAccount,
        address toAccount,
        uint256 accountRoles
    ) internal {
        if (!_hasAllTheRoles(_getRoles(fromAccount), accountRoles)) revert MissingAllRoles(fromAccount, accountRoles);

        _setProposedRoles(fromAccount, toAccount, accountRoles);

        emit RolesProposed(fromAccount, toAccount, accountRoles);
    }

    /**
     * @notice Internal function to accept roles transferred from another account.
     * @dev Pending account needs to pass all the proposed roles.
     * @dev Emits RolesRemoved and RolesAdded events.
     * @param fromAccount The address of the current role
     * @param role The role to accept
     */
    function _acceptRole(
        address fromAccount,
        address toAccount,
        uint8 role
    ) internal virtual {
        _acceptAccountRoles(fromAccount, toAccount, 1 << role);
    }

    /**
     * @notice Internal function to accept roles transferred from another account.
     * @dev Pending account needs to pass all the proposed roles.
     * @dev Emits RolesRemoved and RolesAdded events.
     * @param fromAccount The address of the current role
     * @param roles The roles to accept
     */
    function _acceptRoles(
        address fromAccount,
        address toAccount,
        uint8[] memory roles
    ) internal virtual {
        _acceptAccountRoles(fromAccount, toAccount, _toAccountRoles(roles));
    }

    /**
     * @notice Internal function to accept roles transferred from another account.
     * @dev Pending account needs to pass all the proposed roles.
     * @dev Emits RolesRemoved and RolesAdded events.
     * @param fromAccount The address of the current role
     * @param accountRoles The account roles to accept
     */
    function _acceptAccountRoles(
        address fromAccount,
        address toAccount,
        uint256 accountRoles
    ) internal virtual {
        if (_getProposedRoles(fromAccount, toAccount) != accountRoles) {
            revert InvalidProposedRoles(fromAccount, toAccount, accountRoles);
        }

        _setProposedRoles(fromAccount, toAccount, 0);
        _transferAccountRoles(fromAccount, toAccount, accountRoles);
    }

    /**
     * @notice Internal function to transfer roles from one account to another.
     * @dev Original account must have all the proposed roles.
     * @param fromAccount The address of the current role
     * @param toAccount The address to transfer role to
     * @param role The role to transfer
     */
    function _transferRole(
        address fromAccount,
        address toAccount,
        uint8 role
    ) internal {
        _transferAccountRoles(fromAccount, toAccount, 1 << role);
    }

    /**
     * @notice Internal function to transfer roles from one account to another.
     * @dev Original account must have all the proposed roles.
     * @param fromAccount The address of the current role
     * @param toAccount The address to transfer role to
     * @param roles The roles to transfer
     */
    function _transferRoles(
        address fromAccount,
        address toAccount,
        uint8[] memory roles
    ) internal {
        _transferAccountRoles(fromAccount, toAccount, _toAccountRoles(roles));
    }

    /**
     * @notice Internal function to transfer roles from one account to another.
     * @dev Original account must have all the proposed roles.
     * @param fromAccount The address of the current role
     * @param toAccount The address to transfer role to
     * @param accountRoles The account roles to transfer
     */
    function _transferAccountRoles(
        address fromAccount,
        address toAccount,
        uint256 accountRoles
    ) internal {
        if (!_hasAllTheRoles(_getRoles(fromAccount), accountRoles)) revert MissingAllRoles(fromAccount, accountRoles);

        _removeAccountRoles(fromAccount, accountRoles);
        _addAccountRoles(toAccount, accountRoles);
    }
}

File 7 of 17 : ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is IERC20 {
    mapping(address => uint256) public override balanceOf;

    mapping(address => mapping(address => uint256)) public override allowance;

    uint256 public override totalSupply;
    uint256 internal constant UINT256_MAX = type(uint256).max;

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) external virtual override returns (bool) {
        _transfer(msg.sender, recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) external virtual override returns (bool) {
        _approve(msg.sender, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external virtual override returns (bool) {
        uint256 _allowance = allowance[sender][msg.sender];

        if (_allowance != UINT256_MAX) {
            _approve(sender, msg.sender, _allowance - amount);
        }

        _transfer(sender, recipient, amount);

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool) {
        _approve(msg.sender, spender, allowance[msg.sender][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool) {
        _approve(msg.sender, spender, allowance[msg.sender][spender] - subtractedValue);
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        if (sender == address(0) || recipient == address(0)) revert InvalidAccount();

        balanceOf[sender] -= amount;
        balanceOf[recipient] += amount;
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        if (account == address(0)) revert InvalidAccount();

        totalSupply += amount;
        balanceOf[account] += amount;
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        if (account == address(0)) revert InvalidAccount();

        balanceOf[account] -= amount;
        totalSupply -= amount;
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        if (owner == address(0) || spender == address(0)) revert InvalidAccount();

        allowance[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }
}

File 8 of 17 : ERC20Permit.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';
import { IERC20Permit } from '@axelar-network/axelar-cgp-solidity/contracts/interfaces/IERC20Permit.sol';

import { ERC20 } from './ERC20.sol';

/**
 * @title ERC20Permit Contract
 * @dev Extension of ERC20 to include permit functionality (EIP-2612).
 * Allows for approval of ERC20 tokens by signature rather than transaction.
 */
abstract contract ERC20Permit is IERC20, IERC20Permit, ERC20 {
    error PermitExpired();
    error InvalidS();
    error InvalidV();
    error InvalidSignature();

    /**
     * @dev Represents hash of the EIP-712 Domain Separator.
     */
    bytes32 public nameHash;

    string private constant EIP191_PREFIX_FOR_EIP712_STRUCTURED_DATA = '\x19\x01';

    // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')
    bytes32 private constant DOMAIN_TYPE_SIGNATURE_HASH = bytes32(0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f);

    // keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)')
    bytes32 private constant PERMIT_SIGNATURE_HASH = bytes32(0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9);

    /**
     * @dev Mapping of nonces for each address.
     */
    mapping(address => uint256) public nonces;

    /**
     * @notice Internal function to set the token name hash
     * @param name The token name
     */
    function _setNameHash(string memory name) internal {
        nameHash = keccak256(bytes(name));
    }

    /**
     * @notice Calculates the domain separator.
     * @dev This is not cached because chainid can change on chain forks.
     */
    // solhint-disable func-name-mixedcase
    // slither-disable-next-line naming-convention
    function DOMAIN_SEPARATOR() public view returns (bytes32) {
        return keccak256(abi.encode(DOMAIN_TYPE_SIGNATURE_HASH, nameHash, keccak256(bytes('1')), block.chainid, address(this)));
    }

    // solhint-enable func-name-mixedcase

    /**
     * @notice Permit the designated spender to spend the holder's tokens
     * @dev The permit function is used to allow a holder to designate a spender
     * to spend tokens on their behalf via a signed message.
     * @param issuer The address of the token holder
     * @param spender The address of the designated spender
     * @param value The number of tokens to be spent
     * @param deadline The time at which the permission to spend expires
     * @param v The recovery id of the signature
     * @param r Half of the ECDSA signature pair
     * @param s Half of the ECDSA signature pair
     */
    function permit(address issuer, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external {
        if (block.timestamp > deadline) revert PermitExpired();

        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) revert InvalidS();

        if (v != 27 && v != 28) revert InvalidV();

        bytes32 digest = keccak256(
            abi.encodePacked(
                EIP191_PREFIX_FOR_EIP712_STRUCTURED_DATA,
                DOMAIN_SEPARATOR(),
                keccak256(abi.encode(PERMIT_SIGNATURE_HASH, issuer, spender, value, nonces[issuer]++, deadline))
            )
        );

        address recoveredAddress = ecrecover(digest, v, r, s);

        if (recoveredAddress != issuer) revert InvalidSignature();

        // _approve will revert if issuer is address(0x0)
        _approve(issuer, spender, value);
    }
}

File 9 of 17 : InterchainTokenStandard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IInterchainTokenStandard } from '../interfaces/IInterchainTokenStandard.sol';
import { ITransmitInterchainToken } from '../interfaces/ITransmitInterchainToken.sol';

/**
 * @title An example implementation of the IInterchainTokenStandard.
 * @notice The is an abstract contract that needs to be extended with an ERC20 implementation. See `InterchainToken` for an example implementation.
 */
abstract contract InterchainTokenStandard is IInterchainTokenStandard {
    /**
     * @notice Getter for the tokenId used for this token.
     * @dev Needs to be overwritten.
     * @return tokenId_ The tokenId that this token is registerred under.
     */
    function interchainTokenId() public view virtual returns (bytes32 tokenId_);

    /**
     * @notice Getter for the interchain token service.
     * @dev Needs to be overwritten.
     * @return service The address of the interchain token service.
     */
    function interchainTokenService() public view virtual returns (address service);

    /**
     * @notice Implementation of the interchainTransfer method
     * @dev We chose to either pass `metadata` as raw data on a remote contract call, or if no data is passed, just do a transfer.
     * A different implementation could use metadata to specify a function to invoke, or for other purposes as well.
     * @param destinationChain The destination chain identifier.
     * @param recipient The bytes representation of the address of the recipient.
     * @param amount The amount of token to be transferred.
     * @param metadata Either empty, just to facilitate an interchain transfer, or the data to be passed for an interchain contract call with transfer
     * as per semantics defined by the token service.
     */
    function interchainTransfer(
        string calldata destinationChain,
        bytes calldata recipient,
        uint256 amount,
        bytes calldata metadata
    ) external payable {
        address sender = msg.sender;

        _beforeInterchainTransfer(msg.sender, destinationChain, recipient, amount, metadata);

        ITransmitInterchainToken(interchainTokenService()).transmitInterchainTransfer{ value: msg.value }(
            interchainTokenId(),
            sender,
            destinationChain,
            recipient,
            amount,
            metadata
        );
    }

    /**
     * @notice Implementation of the interchainTransferFrom method
     * @dev We chose to either pass `metadata` as raw data on a remote contract call, or, if no data is passed, just do a transfer.
     * A different implementation could use metadata to specify a function to invoke, or for other purposes as well.
     * @param sender The sender of the tokens. They need to have approved `msg.sender` before this is called.
     * @param destinationChain The string representation of the destination chain.
     * @param recipient The bytes representation of the address of the recipient.
     * @param amount The amount of token to be transferred.
     * @param metadata Either empty, just to facilitate an interchain transfer, or the data to be passed to an interchain contract call and transfer.
     */
    function interchainTransferFrom(
        address sender,
        string calldata destinationChain,
        bytes calldata recipient,
        uint256 amount,
        bytes calldata metadata
    ) external payable {
        _spendAllowance(sender, msg.sender, amount);

        _beforeInterchainTransfer(sender, destinationChain, recipient, amount, metadata);

        ITransmitInterchainToken(interchainTokenService()).transmitInterchainTransfer{ value: msg.value }(
            interchainTokenId(),
            sender,
            destinationChain,
            recipient,
            amount,
            metadata
        );
    }

    /**
     * @notice A method to be overwritten that will be called before an interchain transfer. One can approve the tokenManager here if needed,
     * to allow users for a 1-call transfer in case of a lock-unlock token manager.
     * @param from The sender of the tokens. They need to have approved `msg.sender` before this is called.
     * @param destinationChain The string representation of the destination chain.
     * @param destinationAddress The bytes representation of the address of the recipient.
     * @param amount The amount of token to be transferred.
     * @param metadata Either empty, just to facilitate an interchain transfer, or the data to be passed to an interchain contract call and transfer.
     */
    function _beforeInterchainTransfer(
        address from,
        string calldata destinationChain,
        bytes calldata destinationAddress,
        uint256 amount,
        bytes calldata metadata
    ) internal virtual {}

    /**
     * @notice A method to be overwritten that will decrease the allowance of the `spender` from `sender` by `amount`.
     * @dev Needs to be overwritten. This provides flexibility for the choice of ERC20 implementation used. Must revert if allowance is not sufficient.
     */
    function _spendAllowance(address sender, address spender, uint256 amount) internal virtual;
}

File 10 of 17 : IERC20MintableBurnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title IERC20MintableBurnable Interface
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20MintableBurnable {
    /**
     * @notice Function to mint new tokens.
     * @dev Can only be called by the minter address.
     * @param to The address that will receive the minted tokens.
     * @param amount The amount of tokens to mint.
     */
    function mint(address to, uint256 amount) external;

    /**
     * @notice Function to burn tokens.
     * @dev Can only be called by the minter address.
     * @param from The address that will have its tokens burnt.
     * @param amount The amount of tokens to burn.
     */
    function burn(address from, uint256 amount) external;
}

File 11 of 17 : IERC20Named.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';

/**
 * @title IERC20Named Interface
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20Named is IERC20 {
    /**
     * @notice Getter for the name of the token.
     * @return string Name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @notice Getter for the symbol of the token.
     * @return string The symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @notice Getter for the decimals of the token.
     * @return uint8 The decimals of the token.
     */
    function decimals() external view returns (uint8);
}

File 12 of 17 : IInterchainToken.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IInterchainTokenStandard } from './IInterchainTokenStandard.sol';
import { IMinter } from './IMinter.sol';
import { IERC20MintableBurnable } from './IERC20MintableBurnable.sol';
import { IERC20Named } from './IERC20Named.sol';

/**
 * @title IInterchainToken interface
 * @dev Extends IInterchainTokenStandard and IMinter.
 */
interface IInterchainToken is IInterchainTokenStandard, IMinter, IERC20MintableBurnable, IERC20Named {
    error InterchainTokenServiceAddressZero();
    error TokenIdZero();
    error TokenNameEmpty();
    error TokenSymbolEmpty();
    error AlreadyInitialized();

    /**
     * @notice Getter for the interchain token service contract.
     * @dev Needs to be overwitten.
     * @return interchainTokenServiceAddress The interchain token service address.
     */
    function interchainTokenService() external view returns (address interchainTokenServiceAddress);

    /**
     * @notice Getter for the tokenId used for this token.
     * @dev Needs to be overwitten.
     * @return tokenId_ The tokenId for this token.
     */
    function interchainTokenId() external view returns (bytes32 tokenId_);

    /**
     * @notice Setup function to initialize contract parameters.
     * @param tokenId_ The tokenId of the token.
     * @param minter The address of the token minter.
     * @param tokenName The name of the token.
     * @param tokenSymbol The symbopl of the token.
     * @param tokenDecimals The decimals of the token.
     */
    function init(bytes32 tokenId_, address minter, string calldata tokenName, string calldata tokenSymbol, uint8 tokenDecimals) external;
}

File 13 of 17 : IInterchainTokenStandard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title IInterchainTokenStandard interface
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IInterchainTokenStandard {
    /**
     * @notice Implementation of the interchainTransfer method.
     * @dev We chose to either pass `metadata` as raw data on a remote contract call, or if no data is passed, just do a transfer.
     * A different implementation could use metadata to specify a function to invoke, or for other purposes as well.
     * @param destinationChain The destination chain identifier.
     * @param recipient The bytes representation of the address of the recipient.
     * @param amount The amount of token to be transferred.
     * @param metadata Optional metadata for the call for additional effects (such as calling a destination contract).
     */
    function interchainTransfer(
        string calldata destinationChain,
        bytes calldata recipient,
        uint256 amount,
        bytes calldata metadata
    ) external payable;

    /**
     * @notice Implementation of the interchainTransferFrom method
     * @dev We chose to either pass `metadata` as raw data on a remote contract call, or, if no data is passed, just do a transfer.
     * A different implementation could use metadata to specify a function to invoke, or for other purposes as well.
     * @param sender The sender of the tokens. They need to have approved `msg.sender` before this is called.
     * @param destinationChain The string representation of the destination chain.
     * @param recipient The bytes representation of the address of the recipient.
     * @param amount The amount of token to be transferred.
     * @param metadata Optional metadata for the call for additional effects (such as calling a destination contract.)
     */
    function interchainTransferFrom(
        address sender,
        string calldata destinationChain,
        bytes calldata recipient,
        uint256 amount,
        bytes calldata metadata
    ) external payable;
}

File 14 of 17 : IMinter.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IRolesBase } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IRolesBase.sol';

/**
 * @title IMinter Interface
 * @notice An interface for a contract module which provides a basic access control mechanism, where
 * there is an account (a minter) that can be granted exclusive access to specific functions.
 */
interface IMinter is IRolesBase {
    /**
     * @notice Change the minter of the contract.
     * @dev Can only be called by the current minter.
     * @param minter_ The address of the new minter.
     */
    function transferMintership(address minter_) external;

    /**
     * @notice Proposed a change of the minter of the contract.
     * @dev Can only be called by the current minter.
     * @param minter_ The address of the new minter.
     */
    function proposeMintership(address minter_) external;

    /**
     * @notice Accept a change of the minter of the contract.
     * @dev Can only be called by the proposed minter.
     * @param fromMinter The previous minter.
     */
    function acceptMintership(address fromMinter) external;

    /**
     * @notice Query if an address is a minter
     * @param addr the address to query for
     * @return bool Boolean value representing whether or not the address is a minter.
     */
    function isMinter(address addr) external view returns (bool);
}

File 15 of 17 : ITransmitInterchainToken.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title ITransmitInterchainToken Interface
 * @notice Interface for transmiting interchain tokens via the interchain token service
 */
interface ITransmitInterchainToken {
    /**
     * @notice Transmit an interchain transfer for the given tokenId.
     * @dev Only callable by a token registered under a tokenId.
     * @param tokenId The tokenId of the token (which must be the msg.sender).
     * @param sourceAddress The address where the token is coming from.
     * @param destinationChain The name of the chain to send tokens to.
     * @param destinationAddress The destinationAddress for the interchainTransfer.
     * @param amount The amount of token to give.
     * @param metadata Optional metadata for the call for additional effects (such as calling a destination contract).
     */
    function transmitInterchainTransfer(
        bytes32 tokenId,
        address sourceAddress,
        string calldata destinationChain,
        bytes memory destinationAddress,
        uint256 amount,
        bytes calldata metadata
    ) external payable;
}

File 16 of 17 : Minter.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IMinter } from '../interfaces/IMinter.sol';

import { RolesBase } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/RolesBase.sol';
import { RolesConstants } from './RolesConstants.sol';

/**
 * @title Minter Contract
 * @notice A contract module which provides a basic access control mechanism, where
 * there is an account (a minter) that can be granted exclusive access to
 * specific functions.
 * @dev This module is used through inheritance.
 */
contract Minter is IMinter, RolesBase, RolesConstants {
    /**
     * @notice Internal function that stores the new minter address in the correct storage slot.
     * @param minter_ The address of the new minter.
     */
    function _addMinter(address minter_) internal {
        _addRole(minter_, uint8(Roles.MINTER));
    }

    /**
     * @notice Changes the minter of the contract.
     * @dev Can only be called by the current minter.
     * @param minter_ The address of the new minter.
     */
    function transferMintership(address minter_) external onlyRole(uint8(Roles.MINTER)) {
        _transferRole(msg.sender, minter_, uint8(Roles.MINTER));
    }

    /**
     * @notice Proposes a change of the minter of the contract.
     * @dev Can only be called by the current minter.
     * @param minter_ The address of the new minter.
     */
    function proposeMintership(address minter_) external onlyRole(uint8(Roles.MINTER)) {
        _proposeRole(msg.sender, minter_, uint8(Roles.MINTER));
    }

    /**
     * @notice Accept a change of the minter of the contract.
     * @dev Can only be called by the proposed minter.
     * @param fromMinter The previous minter.
     */
    function acceptMintership(address fromMinter) external {
        _acceptRole(fromMinter, msg.sender, uint8(Roles.MINTER));
    }

    /**
     * @notice Query if an address is a minter
     * @param addr the address to query for
     * @return bool Boolean value representing whether or not the address is a minter.
     */
    function isMinter(address addr) external view returns (bool) {
        return hasRole(addr, uint8(Roles.MINTER));
    }
}

File 17 of 17 : RolesConstants.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title RolesConstants
 * @notice This contract contains enum values representing different contract roles.
 */
contract RolesConstants {
    enum Roles {
        MINTER,
        OPERATOR,
        FLOW_LIMITER
    }
}

Settings
{
  "evmVersion": "london",
  "optimizer": {
    "enabled": true,
    "runs": 1000,
    "details": {
      "peephole": true,
      "inliner": true,
      "jumpdestRemover": true,
      "orderLiterals": true,
      "deduplicate": true,
      "cse": true,
      "constantOptimizer": true,
      "yul": true,
      "yulDetails": {
        "stackAllocation": true
      }
    }
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"interchainTokenServiceAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"InterchainTokenServiceAddressZero","type":"error"},{"inputs":[],"name":"InvalidAccount","type":"error"},{"inputs":[{"internalType":"address","name":"fromAccount","type":"address"},{"internalType":"address","name":"toAccount","type":"address"},{"internalType":"uint256","name":"accountRoles","type":"uint256"}],"name":"InvalidProposedRoles","type":"error"},{"inputs":[],"name":"InvalidS","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"InvalidV","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"accountRoles","type":"uint256"}],"name":"MissingAllRoles","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"accountRoles","type":"uint256"}],"name":"MissingAnyOfRoles","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint8","name":"role","type":"uint8"}],"name":"MissingRole","type":"error"},{"inputs":[],"name":"PermitExpired","type":"error"},{"inputs":[],"name":"TokenIdZero","type":"error"},{"inputs":[],"name":"TokenNameEmpty","type":"error"},{"inputs":[],"name":"TokenSymbolEmpty","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"accountRoles","type":"uint256"}],"name":"RolesAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"fromAccount","type":"address"},{"indexed":true,"internalType":"address","name":"toAccount","type":"address"},{"indexed":false,"internalType":"uint256","name":"accountRoles","type":"uint256"}],"name":"RolesProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"accountRoles","type":"uint256"}],"name":"RolesRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fromMinter","type":"address"}],"name":"acceptMintership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint8","name":"role","type":"uint8"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenId_","type":"bytes32"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"uint8","name":"tokenDecimals","type":"uint8"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"interchainTokenId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"interchainTokenService","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"bytes","name":"recipient","type":"bytes"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"metadata","type":"bytes"}],"name":"interchainTransfer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"bytes","name":"recipient","type":"bytes"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"metadata","type":"bytes"}],"name":"interchainTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nameHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter_","type":"address"}],"name":"proposeMintership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter_","type":"address"}],"name":"transferMintership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

OVERVIEW

CeDeFiAi streamlining Crypto Management Integrating Chains, CEXs, DEXs, Lending Protocols & More.

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.