Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 8057445 | 769 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
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)
// 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);
}
}
}// 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;
}// 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);
}// 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);
}// 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)
}
}
}// 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);
}
}// 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);
}
}// 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);
}
}// 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;
}// 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;
}// 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);
}// 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;
}// 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;
}// 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);
}// 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;
}// 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));
}
}// 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
}
}{
"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 Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"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"}]Contract Creation Code
60a060405234801561001057600080fd5b5060405162001d3b38038062001d3b83398101604081905261003191610092565b61005a60017fc778385ecb3e8cecb82223fa1f343ec6865b2d64c65b0c15c7e8aef225d9e21455565b6001600160a01b0381166100815760405163a76361c360e01b815260040160405180910390fd5b6001600160a01b03166080526100c2565b6000602082840312156100a457600080fd5b81516001600160a01b03811681146100bb57600080fd5b9392505050565b608051611c48620000f360003960008181610226015281816108cc01528181610a030152610b040152611c486000f3fe6080604052600436106101ac5760003560e01c806395a8c58d116100ec578063aa271e1a1161008a578063cf86a95a11610064578063cf86a95a14610550578063d505accf14610570578063dd62ed3e14610590578063f172a4ce146105c857600080fd5b8063aa271e1a146104fd578063b5ef694d1461051d578063bc0ba3c51461053d57600080fd5b80639dc29fac116100c65780639dc29fac1461048a578063a457c2d7146104aa578063a60fee37146104ca578063a9059cbb146104dd57600080fd5b806395a8c58d1461043557806395d89b41146104555780639c1766771461046a57600080fd5b8063313ce5671161015957806340c10f191161013357806340c10f191461039957806370a08231146103bb5780637ecebe00146103e85780638626698f1461041557600080fd5b8063313ce567146102a55780633644e515146102d1578063395093511461037957600080fd5b8063129d81881161018a578063129d81881461025057806318160ddd1461026f57806323b872dd1461028557600080fd5b806306fdde03146101b1578063095ea7b3146101dc57806309c6bed91461020c575b600080fd5b3480156101bd57600080fd5b506101c66105de565b6040516101d391906115c3565b60405180910390f35b3480156101e857600080fd5b506101fc6101f7366004611612565b61066c565b60405190151581526020016101d3565b34801561021857600080fd5b506040516001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001681526020016101d3565b34801561025c57600080fd5b506008545b6040519081526020016101d3565b34801561027b57600080fd5b5061026160025481565b34801561029157600080fd5b506101fc6102a036600461163c565b610683565b3480156102b157600080fd5b506007546102bf9060ff1681565b60405160ff90911681526020016101d3565b3480156102dd57600080fd5b5060035460408051808201825260018152603160f81b60209182015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81830152808301939093527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608401524660808401523060a0808501919091528251808503909101815260c09093019091528151910120610261565b34801561038557600080fd5b506101fc610394366004611612565b6106da565b3480156103a557600080fd5b506103b96103b4366004611612565b610711565b005b3480156103c757600080fd5b506102616103d6366004611678565b60006020819052908152604090205481565b3480156103f457600080fd5b50610261610403366004611678565b60046020526000908152604090205481565b34801561042157600080fd5b506103b96104303660046116ed565b610768565b34801561044157600080fd5b506101fc610450366004611788565b610941565b34801561046157600080fd5b506101c6610963565b34801561047657600080fd5b506103b9610485366004611678565b610970565b34801561049657600080fd5b506103b96104a5366004611612565b61097f565b3480156104b657600080fd5b506101fc6104c5366004611612565b6109bf565b6103b96104d83660046117bb565b6109f6565b3480156104e957600080fd5b506101fc6104f8366004611612565b610aa2565b34801561050957600080fd5b506101fc610518366004611678565b610aaf565b34801561052957600080fd5b506103b9610538366004611678565b610abb565b6103b961054b36600461186f565b610b01565b34801561055c57600080fd5b506103b961056b366004611678565b610b67565b34801561057c57600080fd5b506103b961058b366004611913565b610ba9565b34801561059c57600080fd5b506102616105ab36600461197d565b600160209081526000928352604080842090915290825290205481565b3480156105d457600080fd5b5061026160035481565b600580546105eb906119a7565b80601f0160208091040260200160405190810160405280929190818152602001828054610617906119a7565b80156106645780601f1061063957610100808354040283529160200191610664565b820191906000526020600020905b81548152906001019060200180831161064757829003601f168201915b505050505081565b6000610679338484610eea565b5060015b92915050565b6001600160a01b038316600090815260016020908152604080832033845290915281205460001981146106c4576106c485336106bf86856119f7565b610eea565b6106cf858585610f87565b506001949350505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916106799185906106bf908690611a0a565b600061072c61071f33611063565b600160ff84161b16151590565b6107595760405163bb6c163960e01b815233600482015260ff821660248201526044015b60405180910390fd5b6107638383611077565b505050565b7fc778385ecb3e8cecb82223fa1f343ec6865b2d64c65b0c15c7e8aef225d9e21454156107c1576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107ea60017fc778385ecb3e8cecb82223fa1f343ec6865b2d64c65b0c15c7e8aef225d9e21455565b86610821576040517f248fd78f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084900361085c576040517f0d7673b500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000829003610897576040517ff09ce01300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60056108a4858783611a81565b5060066108b2838583611a81565b506007805460ff191660ff831617905560088790556108f07f0000000000000000000000000000000000000000000000000000000000000000611128565b6108f986611128565b61093885858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061113392505050565b50505050505050565b600061095c61094f84611063565b600160ff85161b16151590565b9392505050565b600680546105eb906119a7565b61097c81336000611140565b50565b600061098d61071f33611063565b6109b55760405163bb6c163960e01b815233600482015260ff82166024820152604401610750565b6107638383611151565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916106799185906106bf9086906119f7565b610a018833856111fc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370756cde34610a3a60085490565b8b8b8b8b8b8b8b8b6040518b63ffffffff1660e01b8152600401610a6699989796959493929190611b6b565b6000604051808303818588803b158015610a7f57600080fd5b505af1158015610a93573d6000803e3d6000fd5b50505050505050505050505050565b6000610679338484610f87565b600061067d8282610941565b6000610ac961071f33611063565b610af15760405163bb6c163960e01b815233600482015260ff82166024820152604401610750565b610afd33836000611240565b5050565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370756cde34610b3b60085490565b848c8c8c8c8c8c8c6040518b63ffffffff1660e01b8152600401610a6699989796959493929190611b6b565b6000610b7561071f33611063565b610b9d5760405163bb6c163960e01b815233600482015260ff82166024820152604401610750565b610afd33836000611251565b83421115610be3576040517f1a15a3cc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115610c3d576040517f40c1e74800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260ff16601b14158015610c5557508260ff16601c14155b15610c8c576040517f119bce3900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518060400160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250610d6060035460408051808201825260018152603160f81b60209182015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81830152808301939093527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608401524660808401523060a0808501919091528251808503909101815260c0909301909152815191012090565b6001600160a01b038a16600090815260046020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928d928d928d92909190610dae83611bd2565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810188905260e00160405160208183030381529060405280519060200120604051602001610e1293929190611beb565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015610e7d573d6000803e3d6000fd5b505050602060405103519050886001600160a01b0316816001600160a01b031614610ed4576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610edf898989610eea565b505050505050505050565b6001600160a01b0383161580610f0757506001600160a01b038216155b15610f2557604051630da30f6560e31b815260040160405180910390fd5b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0383161580610fa457506001600160a01b038216155b15610fc257604051630da30f6560e31b815260040160405180910390fd5b6001600160a01b03831660009081526020819052604081208054839290610fea9084906119f7565b90915550506001600160a01b03821660009081526020819052604081208054839290611017908490611a0a565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610f7a91815260200190565b60008061106f83611262565b549392505050565b6001600160a01b03821661109e57604051630da30f6560e31b815260040160405180910390fd5b80600260008282546110b09190611a0a565b90915550506001600160a01b038216600090815260208190526040812080548392906110dd908490611a0a565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b61097c8160006112cf565b8051602090910120600355565b6107638383600160ff85161b6112df565b6001600160a01b03821661117857604051630da30f6560e31b815260040160405180910390fd5b6001600160a01b038216600090815260208190526040812080548392906111a09084906119f7565b9250508190555080600260008282546111b991906119f7565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200161111c565b6001600160a01b03808416600090815260016020908152604080832093861683529290522054600019811461123a5761123a84846106bf85856119f7565b50505050565b6107638383600160ff85161b611352565b6107638383600160ff85161b6113e4565b60007fde9bdca322e1a848f72215bc15cf2c87fe7749145789a9ee281a2a6290af26ab826040516020016112b292919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b604051602081830303815290604052805190602001209050919050565b610afd82600160ff84161b61142f565b806112ea8484611490565b1461133b576040517f6004fe400000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301528316602482015260448101829052606401610750565b611347838360006114a6565b6107638383836113e4565b61136561135e84611063565b8216821490565b61139457604051631fe9beed60e21b81526001600160a01b038416600482015260248101829052604401610750565b61139f8383836114a6565b816001600160a01b0316836001600160a01b03167ff7158d1591c2cf17c0e6b9459d86365c47fe0969c79f40ef49e0c437d8f3991483604051610f7a91815260200190565b6113f061135e84611063565b61141f57604051631fe9beed60e21b81526001600160a01b038416600482015260248101829052604401610750565b61142983826114bb565b61076382825b60008161143b84611063565b1790506114488382611510565b826001600160a01b03167f34e73c57659d4b6809b53db4feee9b007b892e978114eda420d2991aba1501438360405161148391815260200190565b60405180910390a2505050565b60008061149d8484611523565b54949350505050565b60006114b28484611523565b91909155505050565b600081196114c884611063565b1690506114d58382611510565b826001600160a01b03167fccf920c8facee98a9c2a6c6124f2857b87b17e9f3a819bfcc6945196ee77366b8360405161148391815260200190565b600061151b83611262565b919091555050565b60007ff96e07b2f4fbb81c31567d2b261589af429e98f0958d53f7e6ad5d63aea0ab7c838360405160200161158193929190928352606091821b6bffffffffffffffffffffffff199081166020850152911b16603482015260480190565b60405160208183030381529060405280519060200120905092915050565b60005b838110156115ba5781810151838201526020016115a2565b50506000910152565b60208152600082518060208401526115e281604085016020870161159f565b601f01601f19169190910160400192915050565b80356001600160a01b038116811461160d57600080fd5b919050565b6000806040838503121561162557600080fd5b61162e836115f6565b946020939093013593505050565b60008060006060848603121561165157600080fd5b61165a846115f6565b9250611668602085016115f6565b9150604084013590509250925092565b60006020828403121561168a57600080fd5b61095c826115f6565b60008083601f8401126116a557600080fd5b50813567ffffffffffffffff8111156116bd57600080fd5b6020830191508360208285010111156116d557600080fd5b9250929050565b803560ff8116811461160d57600080fd5b600080600080600080600060a0888a03121561170857600080fd5b87359650611718602089016115f6565b9550604088013567ffffffffffffffff8082111561173557600080fd5b6117418b838c01611693565b909750955060608a013591508082111561175a57600080fd5b506117678a828b01611693565b909450925061177a9050608089016116dc565b905092959891949750929550565b6000806040838503121561179b57600080fd5b6117a4836115f6565b91506117b2602084016116dc565b90509250929050565b60008060008060008060008060a0898b0312156117d757600080fd5b6117e0896115f6565b9750602089013567ffffffffffffffff808211156117fd57600080fd5b6118098c838d01611693565b909950975060408b013591508082111561182257600080fd5b61182e8c838d01611693565b909750955060608b0135945060808b013591508082111561184e57600080fd5b5061185b8b828c01611693565b999c989b5096995094979396929594505050565b60008060008060008060006080888a03121561188a57600080fd5b873567ffffffffffffffff808211156118a257600080fd5b6118ae8b838c01611693565b909950975060208a01359150808211156118c757600080fd5b6118d38b838c01611693565b909750955060408a0135945060608a01359150808211156118f357600080fd5b506119008a828b01611693565b989b979a50959850939692959293505050565b600080600080600080600060e0888a03121561192e57600080fd5b611937886115f6565b9650611945602089016115f6565b95506040880135945060608801359350611961608089016116dc565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561199057600080fd5b611999836115f6565b91506117b2602084016115f6565b600181811c908216806119bb57607f821691505b6020821081036119db57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561067d5761067d6119e1565b8082018082111561067d5761067d6119e1565b634e487b7160e01b600052604160045260246000fd5b601f82111561076357600081815260208120601f850160051c81016020861015611a5a5750805b601f850160051c820191505b81811015611a7957828155600101611a66565b505050505050565b67ffffffffffffffff831115611a9957611a99611a1d565b611aad83611aa783546119a7565b83611a33565b6000601f841160018114611ae15760008515611ac95750838201355b600019600387901b1c1916600186901b178355611b3b565b600083815260209020601f19861690835b82811015611b125786850135825560209485019460019092019101611af2565b5086821015611b2f5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8981526001600160a01b038916602082015260c060408201526000611b9460c08301898b611b42565b8281036060840152611ba781888a611b42565b905085608084015282810360a0840152611bc2818587611b42565b9c9b505050505050505050505050565b600060018201611be457611be46119e1565b5060010190565b60008451611bfd81846020890161159f565b9190910192835250602082015260400191905056fea26469706673582212203daee882a83c8072ebb1f4308392c6f302a1c043ed2eda3bf4b01322f3ef9bcf64736f6c63430008150033000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c
Deployed Bytecode
0x6080604052600436106101ac5760003560e01c806395a8c58d116100ec578063aa271e1a1161008a578063cf86a95a11610064578063cf86a95a14610550578063d505accf14610570578063dd62ed3e14610590578063f172a4ce146105c857600080fd5b8063aa271e1a146104fd578063b5ef694d1461051d578063bc0ba3c51461053d57600080fd5b80639dc29fac116100c65780639dc29fac1461048a578063a457c2d7146104aa578063a60fee37146104ca578063a9059cbb146104dd57600080fd5b806395a8c58d1461043557806395d89b41146104555780639c1766771461046a57600080fd5b8063313ce5671161015957806340c10f191161013357806340c10f191461039957806370a08231146103bb5780637ecebe00146103e85780638626698f1461041557600080fd5b8063313ce567146102a55780633644e515146102d1578063395093511461037957600080fd5b8063129d81881161018a578063129d81881461025057806318160ddd1461026f57806323b872dd1461028557600080fd5b806306fdde03146101b1578063095ea7b3146101dc57806309c6bed91461020c575b600080fd5b3480156101bd57600080fd5b506101c66105de565b6040516101d391906115c3565b60405180910390f35b3480156101e857600080fd5b506101fc6101f7366004611612565b61066c565b60405190151581526020016101d3565b34801561021857600080fd5b506040516001600160a01b037f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c1681526020016101d3565b34801561025c57600080fd5b506008545b6040519081526020016101d3565b34801561027b57600080fd5b5061026160025481565b34801561029157600080fd5b506101fc6102a036600461163c565b610683565b3480156102b157600080fd5b506007546102bf9060ff1681565b60405160ff90911681526020016101d3565b3480156102dd57600080fd5b5060035460408051808201825260018152603160f81b60209182015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81830152808301939093527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608401524660808401523060a0808501919091528251808503909101815260c09093019091528151910120610261565b34801561038557600080fd5b506101fc610394366004611612565b6106da565b3480156103a557600080fd5b506103b96103b4366004611612565b610711565b005b3480156103c757600080fd5b506102616103d6366004611678565b60006020819052908152604090205481565b3480156103f457600080fd5b50610261610403366004611678565b60046020526000908152604090205481565b34801561042157600080fd5b506103b96104303660046116ed565b610768565b34801561044157600080fd5b506101fc610450366004611788565b610941565b34801561046157600080fd5b506101c6610963565b34801561047657600080fd5b506103b9610485366004611678565b610970565b34801561049657600080fd5b506103b96104a5366004611612565b61097f565b3480156104b657600080fd5b506101fc6104c5366004611612565b6109bf565b6103b96104d83660046117bb565b6109f6565b3480156104e957600080fd5b506101fc6104f8366004611612565b610aa2565b34801561050957600080fd5b506101fc610518366004611678565b610aaf565b34801561052957600080fd5b506103b9610538366004611678565b610abb565b6103b961054b36600461186f565b610b01565b34801561055c57600080fd5b506103b961056b366004611678565b610b67565b34801561057c57600080fd5b506103b961058b366004611913565b610ba9565b34801561059c57600080fd5b506102616105ab36600461197d565b600160209081526000928352604080842090915290825290205481565b3480156105d457600080fd5b5061026160035481565b600580546105eb906119a7565b80601f0160208091040260200160405190810160405280929190818152602001828054610617906119a7565b80156106645780601f1061063957610100808354040283529160200191610664565b820191906000526020600020905b81548152906001019060200180831161064757829003601f168201915b505050505081565b6000610679338484610eea565b5060015b92915050565b6001600160a01b038316600090815260016020908152604080832033845290915281205460001981146106c4576106c485336106bf86856119f7565b610eea565b6106cf858585610f87565b506001949350505050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916106799185906106bf908690611a0a565b600061072c61071f33611063565b600160ff84161b16151590565b6107595760405163bb6c163960e01b815233600482015260ff821660248201526044015b60405180910390fd5b6107638383611077565b505050565b7fc778385ecb3e8cecb82223fa1f343ec6865b2d64c65b0c15c7e8aef225d9e21454156107c1576040517f0dc149f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107ea60017fc778385ecb3e8cecb82223fa1f343ec6865b2d64c65b0c15c7e8aef225d9e21455565b86610821576040517f248fd78f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600084900361085c576040517f0d7673b500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000829003610897576040517ff09ce01300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60056108a4858783611a81565b5060066108b2838583611a81565b506007805460ff191660ff831617905560088790556108f07f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c611128565b6108f986611128565b61093885858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061113392505050565b50505050505050565b600061095c61094f84611063565b600160ff85161b16151590565b9392505050565b600680546105eb906119a7565b61097c81336000611140565b50565b600061098d61071f33611063565b6109b55760405163bb6c163960e01b815233600482015260ff82166024820152604401610750565b6107638383611151565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916106799185906106bf9086906119f7565b610a018833856111fc565b7f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c6001600160a01b03166370756cde34610a3a60085490565b8b8b8b8b8b8b8b8b6040518b63ffffffff1660e01b8152600401610a6699989796959493929190611b6b565b6000604051808303818588803b158015610a7f57600080fd5b505af1158015610a93573d6000803e3d6000fd5b50505050505050505050505050565b6000610679338484610f87565b600061067d8282610941565b6000610ac961071f33611063565b610af15760405163bb6c163960e01b815233600482015260ff82166024820152604401610750565b610afd33836000611240565b5050565b337f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c6001600160a01b03166370756cde34610b3b60085490565b848c8c8c8c8c8c8c6040518b63ffffffff1660e01b8152600401610a6699989796959493929190611b6b565b6000610b7561071f33611063565b610b9d5760405163bb6c163960e01b815233600482015260ff82166024820152604401610750565b610afd33836000611251565b83421115610be3576040517f1a15a3cc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115610c3d576040517f40c1e74800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260ff16601b14158015610c5557508260ff16601c14155b15610c8c576040517f119bce3900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518060400160405280600281526020017f1901000000000000000000000000000000000000000000000000000000000000815250610d6060035460408051808201825260018152603160f81b60209182015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81830152808301939093527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608401524660808401523060a0808501919091528251808503909101815260c0909301909152815191012090565b6001600160a01b038a16600090815260046020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9928d928d928d92909190610dae83611bd2565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810188905260e00160405160208183030381529060405280519060200120604051602001610e1293929190611beb565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015610e7d573d6000803e3d6000fd5b505050602060405103519050886001600160a01b0316816001600160a01b031614610ed4576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610edf898989610eea565b505050505050505050565b6001600160a01b0383161580610f0757506001600160a01b038216155b15610f2557604051630da30f6560e31b815260040160405180910390fd5b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0383161580610fa457506001600160a01b038216155b15610fc257604051630da30f6560e31b815260040160405180910390fd5b6001600160a01b03831660009081526020819052604081208054839290610fea9084906119f7565b90915550506001600160a01b03821660009081526020819052604081208054839290611017908490611a0a565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610f7a91815260200190565b60008061106f83611262565b549392505050565b6001600160a01b03821661109e57604051630da30f6560e31b815260040160405180910390fd5b80600260008282546110b09190611a0a565b90915550506001600160a01b038216600090815260208190526040812080548392906110dd908490611a0a565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b61097c8160006112cf565b8051602090910120600355565b6107638383600160ff85161b6112df565b6001600160a01b03821661117857604051630da30f6560e31b815260040160405180910390fd5b6001600160a01b038216600090815260208190526040812080548392906111a09084906119f7565b9250508190555080600260008282546111b991906119f7565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200161111c565b6001600160a01b03808416600090815260016020908152604080832093861683529290522054600019811461123a5761123a84846106bf85856119f7565b50505050565b6107638383600160ff85161b611352565b6107638383600160ff85161b6113e4565b60007fde9bdca322e1a848f72215bc15cf2c87fe7749145789a9ee281a2a6290af26ab826040516020016112b292919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b604051602081830303815290604052805190602001209050919050565b610afd82600160ff84161b61142f565b806112ea8484611490565b1461133b576040517f6004fe400000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301528316602482015260448101829052606401610750565b611347838360006114a6565b6107638383836113e4565b61136561135e84611063565b8216821490565b61139457604051631fe9beed60e21b81526001600160a01b038416600482015260248101829052604401610750565b61139f8383836114a6565b816001600160a01b0316836001600160a01b03167ff7158d1591c2cf17c0e6b9459d86365c47fe0969c79f40ef49e0c437d8f3991483604051610f7a91815260200190565b6113f061135e84611063565b61141f57604051631fe9beed60e21b81526001600160a01b038416600482015260248101829052604401610750565b61142983826114bb565b61076382825b60008161143b84611063565b1790506114488382611510565b826001600160a01b03167f34e73c57659d4b6809b53db4feee9b007b892e978114eda420d2991aba1501438360405161148391815260200190565b60405180910390a2505050565b60008061149d8484611523565b54949350505050565b60006114b28484611523565b91909155505050565b600081196114c884611063565b1690506114d58382611510565b826001600160a01b03167fccf920c8facee98a9c2a6c6124f2857b87b17e9f3a819bfcc6945196ee77366b8360405161148391815260200190565b600061151b83611262565b919091555050565b60007ff96e07b2f4fbb81c31567d2b261589af429e98f0958d53f7e6ad5d63aea0ab7c838360405160200161158193929190928352606091821b6bffffffffffffffffffffffff199081166020850152911b16603482015260480190565b60405160208183030381529060405280519060200120905092915050565b60005b838110156115ba5781810151838201526020016115a2565b50506000910152565b60208152600082518060208401526115e281604085016020870161159f565b601f01601f19169190910160400192915050565b80356001600160a01b038116811461160d57600080fd5b919050565b6000806040838503121561162557600080fd5b61162e836115f6565b946020939093013593505050565b60008060006060848603121561165157600080fd5b61165a846115f6565b9250611668602085016115f6565b9150604084013590509250925092565b60006020828403121561168a57600080fd5b61095c826115f6565b60008083601f8401126116a557600080fd5b50813567ffffffffffffffff8111156116bd57600080fd5b6020830191508360208285010111156116d557600080fd5b9250929050565b803560ff8116811461160d57600080fd5b600080600080600080600060a0888a03121561170857600080fd5b87359650611718602089016115f6565b9550604088013567ffffffffffffffff8082111561173557600080fd5b6117418b838c01611693565b909750955060608a013591508082111561175a57600080fd5b506117678a828b01611693565b909450925061177a9050608089016116dc565b905092959891949750929550565b6000806040838503121561179b57600080fd5b6117a4836115f6565b91506117b2602084016116dc565b90509250929050565b60008060008060008060008060a0898b0312156117d757600080fd5b6117e0896115f6565b9750602089013567ffffffffffffffff808211156117fd57600080fd5b6118098c838d01611693565b909950975060408b013591508082111561182257600080fd5b61182e8c838d01611693565b909750955060608b0135945060808b013591508082111561184e57600080fd5b5061185b8b828c01611693565b999c989b5096995094979396929594505050565b60008060008060008060006080888a03121561188a57600080fd5b873567ffffffffffffffff808211156118a257600080fd5b6118ae8b838c01611693565b909950975060208a01359150808211156118c757600080fd5b6118d38b838c01611693565b909750955060408a0135945060608a01359150808211156118f357600080fd5b506119008a828b01611693565b989b979a50959850939692959293505050565b600080600080600080600060e0888a03121561192e57600080fd5b611937886115f6565b9650611945602089016115f6565b95506040880135945060608801359350611961608089016116dc565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561199057600080fd5b611999836115f6565b91506117b2602084016115f6565b600181811c908216806119bb57607f821691505b6020821081036119db57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561067d5761067d6119e1565b8082018082111561067d5761067d6119e1565b634e487b7160e01b600052604160045260246000fd5b601f82111561076357600081815260208120601f850160051c81016020861015611a5a5750805b601f850160051c820191505b81811015611a7957828155600101611a66565b505050505050565b67ffffffffffffffff831115611a9957611a99611a1d565b611aad83611aa783546119a7565b83611a33565b6000601f841160018114611ae15760008515611ac95750838201355b600019600387901b1c1916600186901b178355611b3b565b600083815260209020601f19861690835b82811015611b125786850135825560209485019460019092019101611af2565b5086821015611b2f5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8981526001600160a01b038916602082015260c060408201526000611b9460c08301898b611b42565b8281036060840152611ba781888a611b42565b905085608084015282810360a0840152611bc2818587611b42565b9c9b505050505050505050505050565b600060018201611be457611be46119e1565b5060010190565b60008451611bfd81846020890161159f565b9190910192835250602082015260400191905056fea26469706673582212203daee882a83c8072ebb1f4308392c6f302a1c043ed2eda3bf4b01322f3ef9bcf64736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c
-----Decoded View---------------
Arg [0] : interchainTokenServiceAddress (address): 0xB5FB4BE02232B1bBA4dC8f81dc24C26980dE9e3C
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.