Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Sponsored
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
113652706 | 300 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
InterchainTokenFactory
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 { SafeTokenTransfer, SafeTokenTransferFrom, SafeTokenCall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/SafeTransfer.sol'; import { Multicall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Multicall.sol'; import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol'; import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol'; import { IInterchainTokenService } from './interfaces/IInterchainTokenService.sol'; import { IInterchainTokenFactory } from './interfaces/IInterchainTokenFactory.sol'; import { ITokenManagerType } from './interfaces/ITokenManagerType.sol'; import { ITokenManager } from './interfaces/ITokenManager.sol'; import { IInterchainToken } from './interfaces/IInterchainToken.sol'; /** * @title InterchainTokenFactory * @notice This contract is responsible for deploying new interchain tokens and managing their token managers. */ contract InterchainTokenFactory is IInterchainTokenFactory, ITokenManagerType, Multicall, Upgradable { using AddressBytes for bytes; using AddressBytes for address; using SafeTokenTransfer for IInterchainToken; using SafeTokenTransferFrom for IInterchainToken; using SafeTokenCall for IInterchainToken; IInterchainTokenService public immutable interchainTokenService; bytes32 public immutable chainNameHash; IAxelarGateway public immutable gateway; bytes32 private constant CONTRACT_ID = keccak256('interchain-token-factory'); bytes32 internal constant PREFIX_CANONICAL_TOKEN_SALT = keccak256('canonical-token-salt'); bytes32 internal constant PREFIX_INTERCHAIN_TOKEN_SALT = keccak256('interchain-token-salt'); address private constant TOKEN_FACTORY_DEPLOYER = address(0); /** * @notice Constructs the InterchainTokenFactory contract. * @param interchainTokenService_ The address of the interchain token service. */ constructor(address interchainTokenService_) { if (interchainTokenService_ == address(0)) revert ZeroAddress(); interchainTokenService = IInterchainTokenService(interchainTokenService_); chainNameHash = interchainTokenService.chainNameHash(); gateway = interchainTokenService.gateway(); } /** * @notice Getter for the contract id. * @return bytes32 The contract id of this contract. */ function contractId() external pure returns (bytes32) { return CONTRACT_ID; } /** * @notice Calculates the salt for an interchain token. * @param chainNameHash_ The hash of the chain name. * @param deployer The address of the deployer. * @param salt A unique identifier to generate the salt. * @return bytes32 The calculated salt for the interchain token. */ function interchainTokenSalt(bytes32 chainNameHash_, address deployer, bytes32 salt) public pure returns (bytes32) { return keccak256(abi.encode(PREFIX_INTERCHAIN_TOKEN_SALT, chainNameHash_, deployer, salt)); } /** * @notice Calculates the salt for a canonical interchain token. * @param chainNameHash_ The hash of the chain name. * @param tokenAddress The address of the token. * @return salt The calculated salt for the interchain token. */ function canonicalInterchainTokenSalt(bytes32 chainNameHash_, address tokenAddress) public pure returns (bytes32 salt) { salt = keccak256(abi.encode(PREFIX_CANONICAL_TOKEN_SALT, chainNameHash_, tokenAddress)); } /** * @notice Computes the ID for an interchain token based on the deployer and a salt. * @param deployer The address that deployed the interchain token. * @param salt A unique identifier used in the deployment process. * @return tokenId The ID of the interchain token. */ function interchainTokenId(address deployer, bytes32 salt) public view returns (bytes32 tokenId) { tokenId = interchainTokenService.interchainTokenId(TOKEN_FACTORY_DEPLOYER, interchainTokenSalt(chainNameHash, deployer, salt)); } /** * @notice Computes the ID for a canonical interchain token based on its address. * @param tokenAddress The address of the canonical interchain token. * @return tokenId The ID of the canonical interchain token. */ function canonicalInterchainTokenId(address tokenAddress) public view returns (bytes32 tokenId) { tokenId = interchainTokenService.interchainTokenId( TOKEN_FACTORY_DEPLOYER, canonicalInterchainTokenSalt(chainNameHash, tokenAddress) ); } /** * @notice Retrieves the address of an interchain token based on the deployer and a salt. * @param deployer The address that deployed the interchain token. * @param salt A unique identifier used in the deployment process. * @return tokenAddress The address of the interchain token. */ function interchainTokenAddress(address deployer, bytes32 salt) public view returns (address tokenAddress) { tokenAddress = interchainTokenService.interchainTokenAddress(interchainTokenId(deployer, salt)); } /** * @notice Deploys a new interchain token with specified parameters. * @dev Creates a new token and optionally mints an initial amount to a specified minter. * @param salt The unique salt for deploying the token. * @param name The name of the token. * @param symbol The symbol of the token. * @param decimals The number of decimals for the token. * @param initialSupply The amount of tokens to mint initially (can be zero). * @param minter The address to receive the initially minted tokens. * @return tokenId The tokenId corresponding to the deployed InterchainToken. */ function deployInterchainToken( bytes32 salt, string calldata name, string calldata symbol, uint8 decimals, uint256 initialSupply, address minter ) external payable returns (bytes32 tokenId) { address sender = msg.sender; salt = interchainTokenSalt(chainNameHash, sender, salt); bytes memory minterBytes = new bytes(0); if (initialSupply > 0) { minterBytes = address(this).toBytes(); } else if (minter != address(0)) { minterBytes = minter.toBytes(); } tokenId = _deployInterchainToken(salt, '', name, symbol, decimals, minterBytes, 0); if (initialSupply > 0) { IInterchainToken token = IInterchainToken(interchainTokenService.interchainTokenAddress(tokenId)); ITokenManager tokenManager = ITokenManager(interchainTokenService.tokenManagerAddress(tokenId)); token.mint(sender, initialSupply); token.transferMintership(minter); tokenManager.removeFlowLimiter(address(this)); // If minter == address(0), we still set it as a flow limiter for consistency with the remote token manager. tokenManager.addFlowLimiter(minter); tokenManager.transferOperatorship(minter); } } /** * @notice Deploys a remote interchain token on a specified destination chain. * @param originalChainName The name of the chain where the token originally exists. * @param salt The unique salt for deploying the token. * @param minter The address to distribute the token on the destination chain. * @param destinationChain The name of the destination chain. * @param gasValue The amount of gas to send for the deployment. * @return tokenId The tokenId corresponding to the deployed InterchainToken. */ function deployRemoteInterchainToken( string calldata originalChainName, bytes32 salt, address minter, string memory destinationChain, uint256 gasValue ) external payable returns (bytes32 tokenId) { string memory tokenName; string memory tokenSymbol; uint8 tokenDecimals; bytes memory minter_ = new bytes(0); { bytes32 chainNameHash_; if (bytes(originalChainName).length == 0) { chainNameHash_ = chainNameHash; } else { chainNameHash_ = keccak256(bytes(originalChainName)); } address sender = msg.sender; salt = interchainTokenSalt(chainNameHash_, sender, salt); tokenId = interchainTokenService.interchainTokenId(TOKEN_FACTORY_DEPLOYER, salt); IInterchainToken token = IInterchainToken(interchainTokenService.interchainTokenAddress(tokenId)); tokenName = token.name(); tokenSymbol = token.symbol(); tokenDecimals = token.decimals(); if (minter != address(0)) { if (!token.isMinter(minter)) revert NotMinter(minter); minter_ = minter.toBytes(); } } tokenId = _deployInterchainToken(salt, destinationChain, tokenName, tokenSymbol, tokenDecimals, minter_, gasValue); } /** * @notice Deploys a new interchain token with specified parameters. * @param salt The unique salt for deploying the token. * @param destinationChain The name of the destination chain. * @param tokenName The name of the token. * @param tokenSymbol The symbol of the token. * @param tokenDecimals The number of decimals for the token. * @param minter The address to receive the initially minted tokens. * @param gasValue The amount of gas to send for the transfer. * @return tokenId The tokenId corresponding to the deployed InterchainToken. */ function _deployInterchainToken( bytes32 salt, string memory destinationChain, string memory tokenName, string memory tokenSymbol, uint8 tokenDecimals, bytes memory minter, uint256 gasValue ) internal returns (bytes32 tokenId) { // slither-disable-next-line arbitrary-send-eth tokenId = interchainTokenService.deployInterchainToken{ value: gasValue }( salt, destinationChain, tokenName, tokenSymbol, tokenDecimals, minter, gasValue ); } /** * @notice Registers a canonical token as an interchain token and deploys its token manager. * @param tokenAddress The address of the canonical token. * @return tokenId The tokenId corresponding to the registered canonical token. */ function registerCanonicalInterchainToken(address tokenAddress) external payable returns (bytes32 tokenId) { bytes memory params = abi.encode('', tokenAddress); if (_isGatewayToken(tokenAddress)) revert GatewayToken(tokenAddress); bytes32 salt = canonicalInterchainTokenSalt(chainNameHash, tokenAddress); tokenId = interchainTokenService.deployTokenManager(salt, '', TokenManagerType.LOCK_UNLOCK, params, 0); } /** * @notice Deploys a canonical interchain token on a remote chain. * @param originalChain The name of the chain where the token originally exists. * @param originalTokenAddress The address of the original token on the original chain. * @param destinationChain The name of the chain where the token will be deployed. * @param gasValue The gas amount to be sent for deployment. * @return tokenId The tokenId corresponding to the deployed InterchainToken. */ function deployRemoteCanonicalInterchainToken( string calldata originalChain, address originalTokenAddress, string calldata destinationChain, uint256 gasValue ) external payable returns (bytes32 tokenId) { bytes32 salt; IInterchainToken token; { bytes32 chainNameHash_; if (bytes(originalChain).length == 0) { chainNameHash_ = chainNameHash; } else { chainNameHash_ = keccak256(bytes(originalChain)); } // This ensures that the token manager has been deployed by this address, so it's safe to trust it. salt = canonicalInterchainTokenSalt(chainNameHash_, originalTokenAddress); tokenId = interchainTokenService.interchainTokenId(TOKEN_FACTORY_DEPLOYER, salt); token = IInterchainToken(interchainTokenService.validTokenAddress(tokenId)); } // The 3 lines below will revert if the token does not exist. string memory tokenName = token.name(); string memory tokenSymbol = token.symbol(); uint8 tokenDecimals = token.decimals(); tokenId = _deployInterchainToken(salt, destinationChain, tokenName, tokenSymbol, tokenDecimals, '', gasValue); } /** * @notice Checks if a given token is a gateway token. * @param token The address of the token to check. * @return bool True if the token is a gateway token, false otherwise. */ function _isGatewayToken(address token) internal view returns (bool) { string memory symbol = IInterchainToken(token).symbol(); return token == gateway.tokenAddresses(symbol); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAxelarGateway } from './IAxelarGateway.sol'; interface IAxelarExecutable { error InvalidAddress(); error NotApprovedByGateway(); function gateway() external view returns (IAxelarGateway); function execute( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external; function executeWithToken( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, string calldata tokenSymbol, uint256 amount ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAxelarExecutable } from './IAxelarExecutable.sol'; /** * @title IAxelarExpressExecutable * @notice Interface for the Axelar Express Executable contract. */ interface IAxelarExpressExecutable is IAxelarExecutable { // Custom errors error AlreadyExecuted(); error InsufficientValue(); error ExpressExecutorAlreadySet(); /** * @notice Emitted when an express execution is successfully performed. * @param commandId The unique identifier for the command. * @param sourceChain The source chain. * @param sourceAddress The source address. * @param payloadHash The hash of the payload. * @param expressExecutor The address of the express executor. */ event ExpressExecuted( bytes32 indexed commandId, string sourceChain, string sourceAddress, bytes32 payloadHash, address indexed expressExecutor ); /** * @notice Emitted when an express execution with a token is successfully performed. * @param commandId The unique identifier for the command. * @param sourceChain The source chain. * @param sourceAddress The source address. * @param payloadHash The hash of the payload. * @param symbol The token symbol. * @param amount The amount of tokens. * @param expressExecutor The address of the express executor. */ event ExpressExecutedWithToken( bytes32 indexed commandId, string sourceChain, string sourceAddress, bytes32 payloadHash, string symbol, uint256 indexed amount, address indexed expressExecutor ); /** * @notice Emitted when an express execution is fulfilled. * @param commandId The commandId for the contractCall. * @param sourceChain The source chain. * @param sourceAddress The source address. * @param payloadHash The hash of the payload. * @param expressExecutor The address of the express executor. */ event ExpressExecutionFulfilled( bytes32 indexed commandId, string sourceChain, string sourceAddress, bytes32 payloadHash, address indexed expressExecutor ); /** * @notice Emitted when an express execution with a token is fulfilled. * @param commandId The commandId for the contractCallWithToken. * @param sourceChain The source chain. * @param sourceAddress The source address. * @param payloadHash The hash of the payload. * @param symbol The token symbol. * @param amount The amount of tokens. * @param expressExecutor The address of the express executor. */ event ExpressExecutionWithTokenFulfilled( bytes32 indexed commandId, string sourceChain, string sourceAddress, bytes32 payloadHash, string symbol, uint256 indexed amount, address indexed expressExecutor ); /** * @notice Returns the express executor for a given command. * @param commandId The commandId for the contractCall. * @param sourceChain The source chain. * @param sourceAddress The source address. * @param payloadHash The hash of the payload. * @return expressExecutor The address of the express executor. */ function getExpressExecutor( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash ) external view returns (address expressExecutor); /** * @notice Returns the express executor with token for a given command. * @param commandId The commandId for the contractCallWithToken. * @param sourceChain The source chain. * @param sourceAddress The source address. * @param payloadHash The hash of the payload. * @param symbol The token symbol. * @param amount The amount of tokens. * @return expressExecutor The address of the express executor. */ function getExpressExecutorWithToken( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash, string calldata symbol, uint256 amount ) external view returns (address expressExecutor); /** * @notice Express executes a contract call. * @param commandId The commandId for the contractCall. * @param sourceChain The source chain. * @param sourceAddress The source address. * @param payload The payload data. */ function expressExecute( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external payable; /** * @notice Express executes a contract call with token. * @param commandId The commandId for the contractCallWithToken. * @param sourceChain The source chain. * @param sourceAddress The source address. * @param payload The payload data. * @param symbol The token symbol. * @param amount The amount of token. */ function expressExecuteWithToken( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, string calldata symbol, uint256 amount ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IGovernable } from './IGovernable.sol'; import { IImplementation } from './IImplementation.sol'; interface IAxelarGateway is IImplementation, IGovernable { /**********\ |* Errors *| \**********/ error NotSelf(); error InvalidCodeHash(); error SetupFailed(); error InvalidAuthModule(); error InvalidTokenDeployer(); error InvalidAmount(); error InvalidChainId(); error InvalidCommands(); error TokenDoesNotExist(string symbol); error TokenAlreadyExists(string symbol); error TokenDeployFailed(string symbol); error TokenContractDoesNotExist(address token); error BurnFailed(string symbol); error MintFailed(string symbol); error InvalidSetMintLimitsParams(); error ExceedMintLimit(string symbol); /**********\ |* Events *| \**********/ event TokenSent( address indexed sender, string destinationChain, string destinationAddress, string symbol, uint256 amount ); event ContractCall( address indexed sender, string destinationChain, string destinationContractAddress, bytes32 indexed payloadHash, bytes payload ); event ContractCallWithToken( address indexed sender, string destinationChain, string destinationContractAddress, bytes32 indexed payloadHash, bytes payload, string symbol, uint256 amount ); event Executed(bytes32 indexed commandId); event TokenDeployed(string symbol, address tokenAddresses); event ContractCallApproved( bytes32 indexed commandId, string sourceChain, string sourceAddress, address indexed contractAddress, bytes32 indexed payloadHash, bytes32 sourceTxHash, uint256 sourceEventIndex ); event ContractCallApprovedWithMint( bytes32 indexed commandId, string sourceChain, string sourceAddress, address indexed contractAddress, bytes32 indexed payloadHash, string symbol, uint256 amount, bytes32 sourceTxHash, uint256 sourceEventIndex ); event ContractCallExecuted(bytes32 indexed commandId); event TokenMintLimitUpdated(string symbol, uint256 limit); event OperatorshipTransferred(bytes newOperatorsData); event Upgraded(address indexed implementation); /********************\ |* Public Functions *| \********************/ function sendToken( string calldata destinationChain, string calldata destinationAddress, string calldata symbol, uint256 amount ) external; function callContract( string calldata destinationChain, string calldata contractAddress, bytes calldata payload ) external; function callContractWithToken( string calldata destinationChain, string calldata contractAddress, bytes calldata payload, string calldata symbol, uint256 amount ) external; function isContractCallApproved( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, address contractAddress, bytes32 payloadHash ) external view returns (bool); function isContractCallAndMintApproved( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, address contractAddress, bytes32 payloadHash, string calldata symbol, uint256 amount ) external view returns (bool); function validateContractCall( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash ) external returns (bool); function validateContractCallAndMint( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash, string calldata symbol, uint256 amount ) external returns (bool); /***********\ |* Getters *| \***********/ function authModule() external view returns (address); function tokenDeployer() external view returns (address); function tokenMintLimit(string memory symbol) external view returns (uint256); function tokenMintAmount(string memory symbol) external view returns (uint256); function allTokensFrozen() external view returns (bool); function implementation() external view returns (address); function tokenAddresses(string memory symbol) external view returns (address); function tokenFrozen(string memory symbol) external view returns (bool); function isCommandExecuted(bytes32 commandId) external view returns (bool); /************************\ |* Governance Functions *| \************************/ function setTokenMintLimits(string[] calldata symbols, uint256[] calldata limits) external; function upgrade( address newImplementation, bytes32 newImplementationCodeHash, bytes calldata setupParams ) external; /**********************\ |* External Functions *| \**********************/ function execute(bytes calldata input) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAxelarExpressExecutable } from './IAxelarExpressExecutable.sol'; /** * @title IAxelarValuedExpressExecutable * @dev Interface for the Axelar Valued Express Executable contract. */ interface IAxelarValuedExpressExecutable is IAxelarExpressExecutable { /** * @dev Returns the value (token address and amount) associated with a contract call * @param sourceChain The source blockchain. * @param sourceAddress The source address. * @param payload The payload data. * @return tokenAddress The address of the token used. * @return value The value associated with the contract call. */ function contractCallValue( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external view returns (address tokenAddress, uint256 value); /** * @dev Returns the value (token address and amount) associated with a contract call with token. * @param sourceChain The source blockchain. * @param sourceAddress The source address. * @param payload The payload data. * @param symbol The token symbol. * @param amount The amount of tokens. * @return tokenAddress The address of the token used. * @return value The value associated with the contract call. */ function contractCallWithTokenValue( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload, string calldata symbol, uint256 amount ) external view returns (address tokenAddress, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // General interface for upgradable contracts interface IContractIdentifier { /** * @notice Returns the contract ID. It can be used as a check during upgrades. * @dev Meant to be overridden in derived contracts. * @return bytes32 The contract ID */ function contractId() external pure returns (bytes32); }
// 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 IGovernable Interface * @notice This is an interface used by the AxelarGateway contract to manage governance and mint limiter roles. */ interface IGovernable { error NotGovernance(); error NotMintLimiter(); error InvalidGovernance(); error InvalidMintLimiter(); event GovernanceTransferred(address indexed previousGovernance, address indexed newGovernance); event MintLimiterTransferred(address indexed previousGovernance, address indexed newGovernance); /** * @notice Returns the governance address. * @return address of the governance */ function governance() external view returns (address); /** * @notice Returns the mint limiter address. * @return address of the mint limiter */ function mintLimiter() external view returns (address); /** * @notice Transfer the governance role to another address. * @param newGovernance The new governance address */ function transferGovernance(address newGovernance) external; /** * @notice Transfer the mint limiter role to another address. * @param newGovernance The new mint limiter address */ function transferMintLimiter(address newGovernance) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IContractIdentifier } from './IContractIdentifier.sol'; interface IImplementation is IContractIdentifier { error NotProxy(); function setup(bytes calldata data) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IContractIdentifier } from './IContractIdentifier.sol'; /** * @title IInterchainAddressTracker * @dev Manages trusted addresses by chain, keeps track of addresses supported by the Axelar gateway contract */ interface IInterchainAddressTracker { error ZeroAddress(); error LengthMismatch(); error ZeroStringLength(); error UntrustedChain(); event TrustedAddressSet(string chain, string address_); event TrustedAddressRemoved(string chain); /** * @dev Gets the name of the chain this is deployed at */ function chainName() external view returns (string memory); /** * @dev Gets the trusted address at a remote chain * @param chain Chain name of the remote chain * @return trustedAddress_ The trusted address for the chain. Returns '' if the chain is untrusted */ function trustedAddress(string memory chain) external view returns (string memory trustedAddress_); /** * @dev Gets the trusted address hash for a chain * @param chain Chain name * @return trustedAddressHash_ the hash of the trusted address for that chain */ function trustedAddressHash(string memory chain) external view returns (bytes32 trustedAddressHash_); /** * @dev Checks whether the interchain sender is a trusted address * @param chain Chain name of the sender * @param address_ Address of the sender * @return bool true if the sender chain/address are trusted, false otherwise */ function isTrustedAddress(string calldata chain, string calldata address_) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IMulticall * @notice This contract is a multi-functional smart contract which allows for multiple * contract calls in a single transaction. */ interface IMulticall { error MulticallFailed(); /** * @notice Performs multiple delegate calls and returns the results of all calls as an array * @dev This function requires that the contract has sufficient balance for the delegate calls. * If any of the calls fail, the function will revert with the failure message. * @param data An array of encoded function calls * @return results An bytes array with the return data of each function call */ function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IOwnable Interface * @notice IOwnable is an interface that abstracts the implementation of a * contract with ownership control features. It's commonly used in upgradable * contracts and includes the functionality to get current owner, transfer * ownership, and propose and accept ownership. */ interface IOwnable { error NotOwner(); error InvalidOwner(); error InvalidOwnerAddress(); event OwnershipTransferStarted(address indexed newOwner); event OwnershipTransferred(address indexed newOwner); /** * @notice Returns the current owner of the contract. * @return address The address of the current owner */ function owner() external view returns (address); /** * @notice Returns the address of the pending owner of the contract. * @return address The address of the pending owner */ function pendingOwner() external view returns (address); /** * @notice Transfers ownership of the contract to a new address * @param newOwner The address to transfer ownership to */ function transferOwnership(address newOwner) external; /** * @notice Proposes to transfer the contract's ownership to a new address. * The new owner needs to accept the ownership explicitly. * @param newOwner The address to transfer ownership to */ function proposeOwnership(address newOwner) external; /** * @notice Transfers ownership to the pending owner. * @dev Can only be called by the pending owner */ function acceptOwnership() external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Pausable * @notice This contract provides a mechanism to halt the execution of specific functions * if a pause condition is activated. */ interface IPausable { event Paused(address indexed account); event Unpaused(address indexed account); error Pause(); error NotPaused(); /** * @notice Check if the contract is paused * @return paused A boolean representing the pause status. True if paused, false otherwise. */ function paused() external view returns (bool); }
// 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; import { IOwnable } from './IOwnable.sol'; import { IImplementation } from './IImplementation.sol'; // General interface for upgradable contracts interface IUpgradable is IOwnable, IImplementation { error InvalidCodeHash(); error InvalidImplementation(); error SetupFailed(); event Upgraded(address indexed newImplementation); function implementation() external view returns (address); function upgrade( address newImplementation, bytes32 newImplementationCodeHash, bytes calldata params ) external; }
// 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 { IERC20 } from '../interfaces/IERC20.sol'; error TokenTransferFailed(); /* * @title SafeTokenCall * @dev This library is used for performing safe token transfers. */ library SafeTokenCall { /* * @notice Make a safe call to a token contract. * @param token The token contract to interact with. * @param callData The function call data. * @throws TokenTransferFailed error if transfer of token is not successful. */ function safeCall(IERC20 token, bytes memory callData) internal { (bool success, bytes memory returnData) = address(token).call(callData); bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool))); if (!transferred || address(token).code.length == 0) revert TokenTransferFailed(); } } /* * @title SafeTokenTransfer * @dev This library safely transfers tokens from the contract to a recipient. */ library SafeTokenTransfer { /* * @notice Transfer tokens to a recipient. * @param token The token contract. * @param receiver The recipient of the tokens. * @param amount The amount of tokens to transfer. */ function safeTransfer( IERC20 token, address receiver, uint256 amount ) internal { SafeTokenCall.safeCall(token, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount)); } } /* * @title SafeTokenTransferFrom * @dev This library helps to safely transfer tokens on behalf of a token holder. */ library SafeTokenTransferFrom { /* * @notice Transfer tokens on behalf of a token holder. * @param token The token contract. * @param from The address of the token holder. * @param to The address the tokens are to be sent to. * @param amount The amount of tokens to be transferred. */ function safeTransferFrom( IERC20 token, address from, address to, uint256 amount ) internal { SafeTokenCall.safeCall(token, abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, amount)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IImplementation } from '../interfaces/IImplementation.sol'; /** * @title Implementation * @notice This contract serves as a base for other contracts and enforces a proxy-first access restriction. * @dev Derived contracts must implement the setup function. */ abstract contract Implementation is IImplementation { address private immutable implementationAddress; /** * @dev Contract constructor that sets the implementation address to the address of this contract. */ constructor() { implementationAddress = address(this); } /** * @dev Modifier to require the caller to be the proxy contract. * Reverts if the caller is the current contract (i.e., the implementation contract itself). */ modifier onlyProxy() { if (implementationAddress == address(this)) revert NotProxy(); _; } /** * @notice Initializes contract parameters. * This function is intended to be overridden by derived contracts. * The overriding function must have the onlyProxy modifier. * @param params The parameters to be used for initialization */ function setup(bytes calldata params) external virtual; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IImplementation } from '../interfaces/IImplementation.sol'; import { IUpgradable } from '../interfaces/IUpgradable.sol'; import { Ownable } from '../utils/Ownable.sol'; import { Implementation } from './Implementation.sol'; /** * @title Upgradable Contract * @notice This contract provides an interface for upgradable smart contracts and includes the functionality to perform upgrades. */ abstract contract Upgradable is Ownable, Implementation, IUpgradable { // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1) bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @notice Constructor sets the implementation address to the address of the contract itself * @dev This is used in the onlyProxy modifier to prevent certain functions from being called directly * on the implementation contract itself. * @dev The owner is initially set as address(1) because the actual owner is set within the proxy. It is not * set as the zero address because Ownable is designed to throw an error for ownership transfers to the zero address. */ constructor() Ownable(address(1)) {} /** * @notice Returns the address of the current implementation * @return implementation_ Address of the current implementation */ function implementation() public view returns (address implementation_) { assembly { implementation_ := sload(_IMPLEMENTATION_SLOT) } } /** * @notice Upgrades the contract to a new implementation * @param newImplementation The address of the new implementation contract * @param newImplementationCodeHash The codehash of the new implementation contract * @param params Optional setup parameters for the new implementation contract * @dev This function is only callable by the owner. */ function upgrade( address newImplementation, bytes32 newImplementationCodeHash, bytes calldata params ) external override onlyOwner { if (IUpgradable(newImplementation).contractId() != IUpgradable(implementation()).contractId()) revert InvalidImplementation(); if (newImplementationCodeHash != newImplementation.codehash) revert InvalidCodeHash(); emit Upgraded(newImplementation); if (params.length > 0) { // slither-disable-next-line controlled-delegatecall (bool success, ) = newImplementation.delegatecall(abi.encodeWithSelector(this.setup.selector, params)); if (!success) revert SetupFailed(); } assembly { sstore(_IMPLEMENTATION_SLOT, newImplementation) } } /** * @notice Sets up the contract with initial data * @param data Initialization data for the contract * @dev This function is only callable by the proxy contract. */ function setup(bytes calldata data) external override(IImplementation, Implementation) onlyProxy { _setup(data); } /** * @notice Internal function to set up the contract with initial data * @param data Initialization data for the contract * @dev This function should be implemented in derived contracts. */ function _setup(bytes calldata data) internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IMulticall } from '../interfaces/IMulticall.sol'; /** * @title Multicall * @notice This contract is a multi-functional smart contract which allows for multiple * contract calls in a single transaction. */ contract Multicall is IMulticall { /** * @notice Performs multiple delegate calls and returns the results of all calls as an array * @dev This function requires that the contract has sufficient balance for the delegate calls. * If any of the calls fail, the function will revert with the failure message. * @param data An array of encoded function calls * @return results An bytes array with the return data of each function call */ function multicall(bytes[] calldata data) public payable returns (bytes[] memory results) { results = new bytes[](data.length); bool success; bytes memory result; for (uint256 i = 0; i < data.length; ++i) { // slither-disable-next-line calls-loop,delegatecall-loop (success, result) = address(this).delegatecall(data[i]); if (!success) { if (result.length == 0) revert MulticallFailed(); assembly { revert(add(32, result), mload(result)) } } results[i] = result; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IOwnable } from '../interfaces/IOwnable.sol'; /** * @title Ownable * @notice A contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The owner account is set through ownership transfer. This module makes * it possible to transfer the ownership of the contract to a new account in one * step, as well as to an interim pending owner. In the second flow the ownership does not * change until the pending owner accepts the ownership transfer. */ abstract contract Ownable is IOwnable { // keccak256('owner') bytes32 internal constant _OWNER_SLOT = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0; // keccak256('ownership-transfer') bytes32 internal constant _OWNERSHIP_TRANSFER_SLOT = 0x9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d1; /** * @notice Initializes the contract by transferring ownership to the owner parameter. * @param _owner Address to set as the initial owner of the contract */ constructor(address _owner) { _transferOwnership(_owner); } /** * @notice Modifier that throws an error if called by any account other than the owner. */ modifier onlyOwner() { if (owner() != msg.sender) revert NotOwner(); _; } /** * @notice Returns the current owner of the contract. * @return owner_ The current owner of the contract */ function owner() public view returns (address owner_) { assembly { owner_ := sload(_OWNER_SLOT) } } /** * @notice Returns the pending owner of the contract. * @return owner_ The pending owner of the contract */ function pendingOwner() public view returns (address owner_) { assembly { owner_ := sload(_OWNERSHIP_TRANSFER_SLOT) } } /** * @notice Transfers ownership of the contract to a new account `newOwner`. * @dev Can only be called by the current owner. * @param newOwner The address to transfer ownership to */ function transferOwnership(address newOwner) external virtual onlyOwner { _transferOwnership(newOwner); } /** * @notice Propose to transfer ownership of the contract to a new account `newOwner`. * @dev Can only be called by the current owner. The ownership does not change * until the new owner accepts the ownership transfer. * @param newOwner The address to transfer ownership to */ function proposeOwnership(address newOwner) external virtual onlyOwner { if (newOwner == address(0)) revert InvalidOwnerAddress(); emit OwnershipTransferStarted(newOwner); assembly { sstore(_OWNERSHIP_TRANSFER_SLOT, newOwner) } } /** * @notice Accepts ownership of the contract. * @dev Can only be called by the pending owner */ function acceptOwnership() external virtual { address newOwner = pendingOwner(); if (newOwner != msg.sender) revert InvalidOwner(); _transferOwnership(newOwner); } /** * @notice Internal function to transfer ownership of the contract to a new account `newOwner`. * @dev Called in the constructor to set the initial owner. * @param newOwner The address to transfer ownership to */ function _transferOwnership(address newOwner) internal virtual { if (newOwner == address(0)) revert InvalidOwnerAddress(); emit OwnershipTransferred(newOwner); assembly { sstore(_OWNER_SLOT, newOwner) sstore(_OWNERSHIP_TRANSFER_SLOT, 0) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IInterchainAddressTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IInterchainAddressTracker.sol'; /** * @title IAddressTracker Interface * @notice This interface allows setting and removing a trusted address for a specific chain. * @dev Extends the IInterchainAddressTracker interface. */ interface IAddressTracker is IInterchainAddressTracker { /** * @notice Sets the trusted address for the specified chain. * @param chain Chain name to be trusted. * @param address_ Trusted address to be added for the chain. */ function setTrustedAddress(string memory chain, string memory address_) external; /** * @notice Remove the trusted address of the chain. * @param chain Chain name to remove the trusted address for. */ function removeTrustedAddress(string calldata chain) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IBaseTokenManager * @notice This contract is defines the base token manager interface implemented by all token managers. */ interface IBaseTokenManager { /** * @notice A function that returns the token id. */ function interchainTokenId() external view returns (bytes32); /** * @notice A function that should return the address of the token. * Must be overridden in the inheriting contract. * @return address address of the token. */ function tokenAddress() external view returns (address); /** * @notice A function that should return the token address from the init params. */ function getTokenAddressFromParams(bytes calldata params) external pure returns (address); }
// 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; /** * @title FlowLimit Interface * @notice Interface for flow limit logic for interchain token transfers. */ interface IFlowLimit { error FlowLimitExceeded(uint256 limit, uint256 flowAmount, address tokenManager); event FlowLimitSet(bytes32 indexed tokenId, address operator, uint256 flowLimit_); /** * @notice Returns the current flow limit. * @return flowLimit_ The current flow limit value. */ function flowLimit() external view returns (uint256 flowLimit_); /** * @notice Returns the current flow out amount. * @return flowOutAmount_ The current flow out amount. */ function flowOutAmount() external view returns (uint256 flowOutAmount_); /** * @notice Returns the current flow in amount. * @return flowInAmount_ The current flow in amount. */ function flowInAmount() external view returns (uint256 flowInAmount_); }
// 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; import { IMulticall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IMulticall.sol'; import { IUpgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IUpgradable.sol'; import { IInterchainTokenService } from './IInterchainTokenService.sol'; /** * @title IInterchainTokenFactory Interface * @notice This interface defines functions for deploying new interchain tokens and managing their token managers. */ interface IInterchainTokenFactory is IUpgradable, IMulticall { error ZeroAddress(); error InvalidChainName(); error NotMinter(address minter); error NotOperator(address operator); error GatewayToken(address tokenAddress); /** * @notice Returns the address of the interchain token service. * @return IInterchainTokenService The address of the interchain token service. */ function interchainTokenService() external view returns (IInterchainTokenService); /** * @notice Returns the hash of the chain name. * @return bytes32 The hash of the chain name. */ function chainNameHash() external view returns (bytes32); /** * @notice Calculates the salt for an interchain token. * @param chainNameHash_ The hash of the chain name. * @param deployer The address of the deployer. * @param salt A unique identifier to generate the salt. * @return bytes32 The calculated salt for the interchain token. */ function interchainTokenSalt(bytes32 chainNameHash_, address deployer, bytes32 salt) external view returns (bytes32); /** * @notice Computes the ID for an interchain token based on the deployer and a salt. * @param deployer The address that deployed the interchain token. * @param salt A unique identifier used in the deployment process. * @return tokenId The ID of the interchain token. */ function interchainTokenId(address deployer, bytes32 salt) external view returns (bytes32 tokenId); /** * @notice Retrieves the address of an interchain token based on the deployer and a salt. * @param deployer The address that deployed the interchain token. * @param salt A unique identifier used in the deployment process. * @return tokenAddress The address of the interchain token. */ function interchainTokenAddress(address deployer, bytes32 salt) external view returns (address tokenAddress); /** * @notice Deploys a new interchain token with specified parameters. * @param salt The unique salt for deploying the token. * @param name The name of the token. * @param symbol The symbol of the token. * @param decimals The number of decimals for the token. * @param initialSupply The amount of tokens to mint initially (can be zero). * @param minter The address to receive the initially minted tokens. * @return tokenId The tokenId corresponding to the deployed InterchainToken. */ function deployInterchainToken( bytes32 salt, string calldata name, string calldata symbol, uint8 decimals, uint256 initialSupply, address minter ) external payable returns (bytes32 tokenId); /** * @notice Deploys a remote interchain token on a specified destination chain. * @param originalChainName The name of the chain where the token originally exists. * @param salt The unique salt for deploying the token. * @param minter The address to distribute the token on the destination chain. * @param destinationChain The name of the destination chain. * @param gasValue The amount of gas to send for the deployment. * @return tokenId The tokenId corresponding to the deployed InterchainToken. */ function deployRemoteInterchainToken( string calldata originalChainName, bytes32 salt, address minter, string memory destinationChain, uint256 gasValue ) external payable returns (bytes32 tokenId); /** * @notice Calculates the salt for a canonical interchain token. * @param chainNameHash_ The hash of the chain name. * @param tokenAddress The address of the token. * @return salt The calculated salt for the interchain token. */ function canonicalInterchainTokenSalt(bytes32 chainNameHash_, address tokenAddress) external view returns (bytes32 salt); /** * @notice Computes the ID for a canonical interchain token based on its address. * @param tokenAddress The address of the canonical interchain token. * @return tokenId The ID of the canonical interchain token. */ function canonicalInterchainTokenId(address tokenAddress) external view returns (bytes32 tokenId); /** * @notice Registers a canonical token as an interchain token and deploys its token manager. * @param tokenAddress The address of the canonical token. * @return tokenId The tokenId corresponding to the registered canonical token. */ function registerCanonicalInterchainToken(address tokenAddress) external payable returns (bytes32 tokenId); /** * @notice Deploys a canonical interchain token on a remote chain. * @param originalChain The name of the chain where the token originally exists. * @param originalTokenAddress The address of the original token on the original chain. * @param destinationChain The name of the chain where the token will be deployed. * @param gasValue The gas amount to be sent for deployment. * @return tokenId The tokenId corresponding to the deployed canonical InterchainToken. */ function deployRemoteCanonicalInterchainToken( string calldata originalChain, address originalTokenAddress, string calldata destinationChain, uint256 gasValue ) external payable returns (bytes32 tokenId); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAxelarValuedExpressExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarValuedExpressExecutable.sol'; import { IMulticall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IMulticall.sol'; import { IPausable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IPausable.sol'; import { IUpgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IUpgradable.sol'; import { ITransmitInterchainToken } from './ITransmitInterchainToken.sol'; import { ITokenManagerType } from './ITokenManagerType.sol'; import { ITokenManagerImplementation } from './ITokenManagerImplementation.sol'; import { IOperator } from './IOperator.sol'; import { IAddressTracker } from './IAddressTracker.sol'; /** * @title IInterchainTokenService Interface * @notice Interface for the Interchain Token Service */ interface IInterchainTokenService is ITransmitInterchainToken, ITokenManagerType, ITokenManagerImplementation, IAxelarValuedExpressExecutable, IOperator, IPausable, IMulticall, IAddressTracker, IUpgradable { error InvalidTokenManagerImplementationType(address implementation); error InvalidChainName(); error NotRemoteService(); error TokenManagerDoesNotExist(bytes32 tokenId); error NotToken(address caller, address token); error ExecuteWithInterchainTokenFailed(address contractAddress); error ExpressExecuteWithInterchainTokenFailed(address contractAddress); error GatewayToken(); error TokenManagerDeploymentFailed(bytes error); error InterchainTokenDeploymentFailed(bytes error); error InvalidMessageType(uint256 messageType); error InvalidMetadataVersion(uint32 version); error ExecuteWithTokenNotSupported(); error InvalidExpressMessageType(uint256 messageType); error TakeTokenFailed(bytes data); error GiveTokenFailed(bytes data); error TokenHandlerFailed(bytes data); error EmptyData(); event InterchainTransfer( bytes32 indexed tokenId, address indexed sourceAddress, string destinationChain, bytes destinationAddress, uint256 amount, bytes32 indexed dataHash ); event InterchainTransferReceived( bytes32 indexed commandId, bytes32 indexed tokenId, string sourceChain, bytes sourceAddress, address indexed destinationAddress, uint256 amount, bytes32 dataHash ); event TokenManagerDeploymentStarted( bytes32 indexed tokenId, string destinationChain, TokenManagerType indexed tokenManagerType, bytes params ); event InterchainTokenDeploymentStarted( bytes32 indexed tokenId, string tokenName, string tokenSymbol, uint8 tokenDecimals, bytes minter, string destinationChain ); event TokenManagerDeployed(bytes32 indexed tokenId, address tokenManager, TokenManagerType indexed tokenManagerType, bytes params); event InterchainTokenDeployed( bytes32 indexed tokenId, address tokenAddress, address indexed minter, string name, string symbol, uint8 decimals ); event InterchainTokenIdClaimed(bytes32 indexed tokenId, address indexed deployer, bytes32 indexed salt); /** * @notice Returns the address of the token manager deployer contract. * @return tokenManagerDeployerAddress The address of the token manager deployer contract. */ function tokenManagerDeployer() external view returns (address tokenManagerDeployerAddress); /** * @notice Returns the address of the interchain token deployer contract. * @return interchainTokenDeployerAddress The address of the interchain token deployer contract. */ function interchainTokenDeployer() external view returns (address interchainTokenDeployerAddress); /** * @notice Returns the address of TokenManager implementation. * @return tokenManagerAddress_ The address of the token manager contract. */ function tokenManager() external view returns (address tokenManagerAddress_); /** * @notice Returns the address of TokenHandler implementation. * @return tokenHandlerAddress The address of the token handler contract. */ function tokenHandler() external view returns (address tokenHandlerAddress); /** * @notice Returns the address of the interchain token factory. * @return address The address of the interchain token factory. */ function interchainTokenFactory() external view returns (address); /** * @notice Returns the hash of the chain name. * @return bytes32 The hash of the chain name. */ function chainNameHash() external view returns (bytes32); /** * @notice Returns the address of the token manager associated with the given tokenId. * @param tokenId The tokenId of the token manager. * @return tokenManagerAddress_ The address of the token manager. */ function tokenManagerAddress(bytes32 tokenId) external view returns (address tokenManagerAddress_); /** * @notice Returns the address of the valid token manager associated with the given tokenId. * @param tokenId The tokenId of the token manager. * @return tokenManagerAddress_ The address of the valid token manager. */ function validTokenManagerAddress(bytes32 tokenId) external view returns (address tokenManagerAddress_); /** * @notice Returns the address of the token that an existing tokenManager points to. * @param tokenId The tokenId of the token manager. * @return tokenAddress The address of the token. */ function validTokenAddress(bytes32 tokenId) external view returns (address tokenAddress); /** * @notice Returns the address of the interchain token associated with the given tokenId. * @param tokenId The tokenId of the interchain token. * @return tokenAddress The address of the interchain token. */ function interchainTokenAddress(bytes32 tokenId) external view returns (address tokenAddress); /** * @notice Returns the custom tokenId associated with the given operator and salt. * @param operator_ The operator address. * @param salt The salt used for token id calculation. * @return tokenId The custom tokenId associated with the operator and salt. */ function interchainTokenId(address operator_, bytes32 salt) external view returns (bytes32 tokenId); /** * @notice Deploys a custom token manager contract on a remote chain. * @param salt The salt used for token manager deployment. * @param destinationChain The name of the destination chain. * @param tokenManagerType The type of token manager. * @param params The deployment parameters. * @param gasValue The gas value for deployment. * @return tokenId The tokenId associated with the token manager. */ function deployTokenManager( bytes32 salt, string calldata destinationChain, TokenManagerType tokenManagerType, bytes calldata params, uint256 gasValue ) external payable returns (bytes32 tokenId); /** * @notice Deploys and registers an interchain token on a remote chain. * @param salt The salt used for token deployment. * @param destinationChain The name of the destination chain. Use '' for this chain. * @param name The name of the interchain tokens. * @param symbol The symbol of the interchain tokens. * @param decimals The number of decimals for the interchain tokens. * @param minter The minter data for mint/burn operations. * @param gasValue The gas value for deployment. * @return tokenId The tokenId corresponding to the deployed InterchainToken. */ function deployInterchainToken( bytes32 salt, string calldata destinationChain, string memory name, string memory symbol, uint8 decimals, bytes memory minter, uint256 gasValue ) external payable returns (bytes32 tokenId); /** * @notice Initiates an interchain transfer of a specified token to a destination chain. * @param tokenId The unique identifier of the token to be transferred. * @param destinationChain The destination chain to send the tokens to. * @param destinationAddress The address on the destination chain to send the tokens to. * @param amount The amount of tokens to be transferred. * @param metadata Optional metadata for the call for additional effects (such as calling a destination contract). */ function interchainTransfer( bytes32 tokenId, string calldata destinationChain, bytes calldata destinationAddress, uint256 amount, bytes calldata metadata, uint256 gasValue ) external payable; /** * @notice Initiates an interchain call contract with interchain token to a destination chain. * @param tokenId The unique identifier of the token to be transferred. * @param destinationChain The destination chain to send the tokens to. * @param destinationAddress The address on the destination chain to send the tokens to. * @param amount The amount of tokens to be transferred. * @param data Additional data to be passed along with the transfer. */ function callContractWithInterchainToken( bytes32 tokenId, string calldata destinationChain, bytes calldata destinationAddress, uint256 amount, bytes calldata data, uint256 gasValue ) external payable; /** * @notice Sets the flow limits for multiple tokens. * @param tokenIds An array of tokenIds. * @param flowLimits An array of flow limits corresponding to the tokenIds. */ function setFlowLimits(bytes32[] calldata tokenIds, uint256[] calldata flowLimits) external; /** * @notice Returns the flow limit for a specific token. * @param tokenId The tokenId of the token. * @return flowLimit_ The flow limit for the token. */ function flowLimit(bytes32 tokenId) external view returns (uint256 flowLimit_); /** * @notice Returns the total amount of outgoing flow for a specific token. * @param tokenId The tokenId of the token. * @return flowOutAmount_ The total amount of outgoing flow for the token. */ function flowOutAmount(bytes32 tokenId) external view returns (uint256 flowOutAmount_); /** * @notice Returns the total amount of incoming flow for a specific token. * @param tokenId The tokenId of the token. * @return flowInAmount_ The total amount of incoming flow for the token. */ function flowInAmount(bytes32 tokenId) external view returns (uint256 flowInAmount_); /** * @notice Allows the owner to pause/unpause the token service. * @param paused whether to pause or unpause. */ function setPauseStatus(bool paused) 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; import { IRolesBase } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IRolesBase.sol'; /** * @title IOperator Interface * @notice An interface for a contract module which provides a basic access control mechanism, where * there is an account (a operator) that can be granted exclusive access to specific functions. */ interface IOperator is IRolesBase { /** * @notice Change the operator of the contract. * @dev Can only be called by the current operator. * @param operator_ The address of the new operator. */ function transferOperatorship(address operator_) external; /** * @notice Proposed a change of the operator of the contract. * @dev Can only be called by the current operator. * @param operator_ The address of the new operator. */ function proposeOperatorship(address operator_) external; /** * @notice Accept a proposed change of operatorship. * @dev Can only be called by the proposed operator. * @param fromOperator The previous operator of the contract. */ function acceptOperatorship(address fromOperator) external; /** * @notice Query if an address is a operator. * @param addr The address to query for. * @return bool Boolean value representing whether or not the address is an operator. */ function isOperator(address addr) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IImplementation } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IImplementation.sol'; import { IBaseTokenManager } from './IBaseTokenManager.sol'; import { IOperator } from './IOperator.sol'; import { IFlowLimit } from './IFlowLimit.sol'; /** * @title ITokenManager Interface * @notice This contract is responsible for managing tokens, such as setting locking token balances, or setting flow limits, for interchain transfers. */ interface ITokenManager is IBaseTokenManager, IOperator, IFlowLimit, IImplementation { error TokenLinkerZeroAddress(); error NotService(address caller); error TakeTokenFailed(); error GiveTokenFailed(); error NotToken(address caller); error ZeroAddress(); error AlreadyFlowLimiter(address flowLimiter); error NotFlowLimiter(address flowLimiter); error NotSupported(); /** * @notice Returns implementation type of this token manager. * @return uint256 The implementation type of this token manager. */ function implementationType() external view returns (uint256); function addFlowIn(uint256 amount) external; function addFlowOut(uint256 amount) external; /** * @notice This function adds a flow limiter for this TokenManager. * @dev Can only be called by the operator. * @param flowLimiter the address of the new flow limiter. */ function addFlowLimiter(address flowLimiter) external; /** * @notice This function removes a flow limiter for this TokenManager. * @dev Can only be called by the operator. * @param flowLimiter the address of an existing flow limiter. */ function removeFlowLimiter(address flowLimiter) external; /** * @notice Query if an address is a flow limiter. * @param addr The address to query for. * @return bool Boolean value representing whether or not the address is a flow limiter. */ function isFlowLimiter(address addr) external view returns (bool); /** * @notice This function sets the flow limit for this TokenManager. * @dev Can only be called by the flow limiters. * @param flowLimit_ The maximum difference between the tokens flowing in and/or out at any given interval of time (6h). */ function setFlowLimit(uint256 flowLimit_) external; /** * @notice A function to renew approval to the service if we need to. */ function approveService() external; /** * @notice Getter function for the parameters of a lock/unlock TokenManager. * @dev This function will be mainly used by frontends. * @param operator_ The operator of the TokenManager. * @param tokenAddress_ The token to be managed. * @return params_ The resulting params to be passed to custom TokenManager deployments. */ function params(bytes calldata operator_, address tokenAddress_) external pure returns (bytes memory params_); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ITokenManagerImplementation Interface * @notice Interface for returning the token manager implementation type. */ interface ITokenManagerImplementation { /** * @notice Returns the implementation address for a given token manager type. * @param tokenManagerType The type of token manager. * @return tokenManagerAddress_ The address of the token manager implementation. */ function tokenManagerImplementation(uint256 tokenManagerType) external view returns (address tokenManagerAddress_); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ITokenManagerType Interface * @notice A simple interface that defines all the token manager types. */ interface ITokenManagerType { enum TokenManagerType { MINT_BURN, MINT_BURN_FROM, LOCK_UNLOCK, LOCK_UNLOCK_FEE } }
// 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; }
{ "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
[{"inputs":[{"internalType":"address","name":"interchainTokenService_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"GatewayToken","type":"error"},{"inputs":[],"name":"InvalidChainName","type":"error"},{"inputs":[],"name":"InvalidCodeHash","type":"error"},{"inputs":[],"name":"InvalidImplementation","type":"error"},{"inputs":[],"name":"InvalidOwner","type":"error"},{"inputs":[],"name":"InvalidOwnerAddress","type":"error"},{"inputs":[],"name":"MulticallFailed","type":"error"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"NotMinter","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"NotOperator","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"NotProxy","type":"error"},{"inputs":[],"name":"SetupFailed","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newImplementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"canonicalInterchainTokenId","outputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"chainNameHash_","type":"bytes32"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"canonicalInterchainTokenSalt","outputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"chainNameHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"address","name":"minter","type":"address"}],"name":"deployInterchainToken","outputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"originalChain","type":"string"},{"internalType":"address","name":"originalTokenAddress","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"uint256","name":"gasValue","type":"uint256"}],"name":"deployRemoteCanonicalInterchainToken","outputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"originalChainName","type":"string"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"uint256","name":"gasValue","type":"uint256"}],"name":"deployRemoteInterchainToken","outputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"gateway","outputs":[{"internalType":"contract IAxelarGateway","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"implementation_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"deployer","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"interchainTokenAddress","outputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"deployer","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"interchainTokenId","outputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"chainNameHash_","type":"bytes32"},{"internalType":"address","name":"deployer","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"interchainTokenSalt","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"interchainTokenService","outputs":[{"internalType":"contract IInterchainTokenService","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"proposeOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"registerCanonicalInterchainToken","outputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes32","name":"newImplementationCodeHash","type":"bytes32"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"upgrade","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b5060405162002b8538038062002b8583398101604081905262000035916200021e565b6001620000428162000161565b50306080526001600160a01b0381166200006f5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660a08190526040805163864a0dcf60e01b8152905163864a0dcf916004808201926020929091908290030181865afa158015620000ba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000e0919062000245565b60c0818152505060a0516001600160a01b031663116191b66040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000128573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200014e91906200021e565b6001600160a01b031660e052506200025f565b6001600160a01b0381166200018957604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616390600090a27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05560007f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b6001600160a01b03811681146200021b57600080fd5b50565b6000602082840312156200023157600080fd5b81516200023e8162000205565b9392505050565b6000602082840312156200025857600080fd5b5051919050565b60805160a05160c05160e05161286e62000317600039600081816101dd0152611fa0015260008181610381015281816105a701528181610a960152818161108f015281816117c30152818161195c0152611c2b01526000818161018c015281816106fa015281816107aa01528181610b5001528181610be701528181610e9a01528181611156015281816111fb0152818161181a01528181611a1201528181611bf70152611dbb01526000611411015261286e6000f3fe6080604052600436106101755760003560e01c80638da5cb5b116100cb578063a5269ef11161007f578063b229288811610059578063b229288814610503578063e30c397814610523578063f2fde38b1461055757600080fd5b8063a5269ef1146104b0578063a75483d1146104d0578063ac9650d8146104e357600080fd5b8063993a5b9e116100b0578063993a5b9e1461045d5780639ded06df14610470578063a3499c731461049057600080fd5b80638da5cb5b146103a35780639417bfe1146103d757600080fd5b80635d79c00e1161012d57806379ba50971161010757806379ba5097146103275780638291286c1461033c578063864a0dcf1461036f57600080fd5b80635d79c00e146102d25780637100e6a9146102e5578063710bf3221461030557600080fd5b80633e12f8c51161015e5780633e12f8c5146101ff57806352a3702f146102205780635c60da1b1461029e57600080fd5b806309c6bed91461017a578063116191b6146101cb575b600080fd5b34801561018657600080fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101d757600080fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b61021261020d36600461209f565b610577565b6040519081526020016101c2565b34801561022c57600080fd5b5061021261023b366004612148565b604080517f9ca52083bb00ac0f5bed7edcaabb0534d03efb0719807b54a8029c4d1313630960208201529081018390526001600160a01b038216606082015260009060800160405160208183030381529060405280519060200120905092915050565b3480156102aa57600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546101ae565b6102126102e03660046121e7565b610a73565b3480156102f157600080fd5b506101ae6103003660046122ba565b610e96565b34801561031157600080fd5b506103256103203660046122e6565b610f37565b005b34801561033357600080fd5b50610325611006565b34801561034857600080fd5b507f80547d63ed663962b99f8ed432bff3879a35b5418af92258aa171feef14cc3cc610212565b34801561037b57600080fd5b506102127f000000000000000000000000000000000000000000000000000000000000000081565b3480156103af57600080fd5b507f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0546101ae565b3480156103e357600080fd5b506102126103f2366004612303565b604080517ff84d43c32bc607f1bdb175c63a0cf1939bf0cc8cc3565450be225afbb5a1098560208201529081018490526001600160a01b03831660608201526080810182905260009060a0016040516020818303038152906040528051906020012090509392505050565b61021261046b36600461233b565b611080565b34801561047c57600080fd5b5061032561048b3660046123c8565b61140e565b34801561049c57600080fd5b506103256104ab36600461240a565b611474565b3480156104bc57600080fd5b506102126104cb3660046122ba565b611793565b6102126104de3660046122e6565b6118c8565b6104f66104f1366004612466565b611a9a565b6040516101c2919061252b565b34801561050f57600080fd5b5061021261051e3660046122e6565b611bf3565b34801561052f57600080fd5b507f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d1546101ae565b34801561056357600080fd5b506103256105723660046122e6565b611d39565b604080517ff84d43c32bc607f1bdb175c63a0cf1939bf0cc8cc3565450be225afbb5a109856020808301919091527f000000000000000000000000000000000000000000000000000000000000000082840152336060830181905260808084018d90528451808503909101815260a0909301909352815191012060009190604080516000815260208101909152909a50841561061d5761061630611d89565b9050610641565b6001600160a01b038416156106415761063e846001600160a01b0316611d89565b90505b6106d98b604051806020016040528060008152508c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508e93508992509050611db7565b92508415610a6557604051631d05ce3f60e31b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e82e71f890602401602060405180830381865afa158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d919061258d565b6040517ff8c8a826000000000000000000000000000000000000000000000000000000008152600481018690529091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f8c8a82690602401602060405180830381865afa1580156107f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610815919061258d565b6040517f40c10f190000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152602482018a9052919250908316906340c10f1990604401600060405180830381600087803b15801561087c57600080fd5b505af1158015610890573d6000803e3d6000fd5b50506040517fcf86a95a0000000000000000000000000000000000000000000000000000000081526001600160a01b0389811660048301528516925063cf86a95a9150602401600060405180830381600087803b1580156108f057600080fd5b505af1158015610904573d6000803e3d6000fd5b50506040517fe915cfd10000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038416925063e915cfd19150602401600060405180830381600087803b15801561096257600080fd5b505af1158015610976573d6000803e3d6000fd5b50506040517f120a63b50000000000000000000000000000000000000000000000000000000081526001600160a01b0389811660048301528416925063120a63b59150602401600060405180830381600087803b1580156109d657600080fd5b505af11580156109ea573d6000803e3d6000fd5b50506040517f4a6a42d80000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015284169250634a6a42d89150602401600060405180830381600087803b158015610a4a57600080fd5b505af1158015610a5e573d6000803e3d6000fd5b5050505050505b505098975050505050505050565b604080516000808252602082019092526060908190839060008a8103610aba57507f0000000000000000000000000000000000000000000000000000000000000000610ad5565b8b8b604051610aca9291906125aa565b604051809103902090505b604080517ff84d43c32bc607f1bdb175c63a0cf1939bf0cc8cc3565450be225afbb5a10985602080830191909152818301849052336060830181905260808084018f90528451808503909101815260a0909301909352815191012060405163a5269ef160e01b81526000600482015260248101829052909b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5269ef190604401602060405180830381865afa158015610b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc391906125ba565b604051631d05ce3f60e31b8152600481018290529097506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063e82e71f890602401602060405180830381865afa158015610c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c52919061258d565b9050806001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015610c92573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cba91908101906125d3565b9650806001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610cfa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d2291908101906125d3565b9550806001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d86919061264a565b94506001600160a01b038b1615610e75576040517faa271e1a0000000000000000000000000000000000000000000000000000000081526001600160a01b038c8116600483015282169063aa271e1a90602401602060405180830381865afa158015610df6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1a9190612667565b610e60576040517f361c31f20000000000000000000000000000000000000000000000000000000081526001600160a01b038c1660048201526024015b60405180910390fd5b610e728b6001600160a01b0316611d89565b93505b505050610e878988868686868c611db7565b9b9a5050505050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e82e71f8610ed18585611793565b6040518263ffffffff1660e01b8152600401610eef91815260200190565b602060405180830381865afa158015610f0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f30919061258d565b9392505050565b33610f607f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614610f87576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b038116610fae57604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907fd9be0e8e07417e00f2521db636cb53e316fd288f5051f16d2aa2bf0c3938a87690600090a27f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b60006110307f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d15490565b90506001600160a01b0381163314611074576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61107d81611e61565b50565b60008080808881036110b357507f00000000000000000000000000000000000000000000000000000000000000006110ce565b89896040516110c39291906125aa565b604051809103902090505b6111368189604080517f9ca52083bb00ac0f5bed7edcaabb0534d03efb0719807b54a8029c4d1313630960208201529081018390526001600160a01b038216606082015260009060800160405160208183030381529060405280519060200120905092915050565b60405163a5269ef160e01b815260006004820152602481018290529093507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a5269ef190604401602060405180830381865afa1580156111a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c991906125ba565b6040517f1a083d39000000000000000000000000000000000000000000000000000000008152600481018290529094507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631a083d3990602401602060405180830381865afa15801561124a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126e919061258d565b9150506000816001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156112b1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112d991908101906125d3565b90506000826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801561131b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261134391908101906125d3565b90506000836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611385573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a9919061264a565b90506113fe858a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091529081528993508892508791508d611db7565b9c9b505050505050505050505050565b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031603611470576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b3361149d7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b0316146114c4576040516330cd747160e01b815260040160405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b0316638291286c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611523573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154791906125ba565b846001600160a01b0316638291286c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611585573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a991906125ba565b146115e0576040517f68155f9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836001600160a01b03163f8314611623576040517f8f84fb2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b038516907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2801561176c576000846001600160a01b0316639ded06df60e01b8484604051602401611684929190612689565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516116ef91906126b8565b600060405180830381855af49150503d806000811461172a576040519150601f19603f3d011682016040523d82523d6000602084013e61172f565b606091505b505090508061176a576040517f97905dfb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b5050507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b604080517ff84d43c32bc607f1bdb175c63a0cf1939bf0cc8cc3565450be225afbb5a109856020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401526001600160a01b03858116606084015260808084018690528451808503909101815260a090930190935281519101206000917f0000000000000000000000000000000000000000000000000000000000000000169063a5269ef19083906040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156118a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3091906125ba565b600080826040516020016118f9919060408082526000908201526001600160a01b0391909116602082015260600190565b604051602081830303815290604052905061191383611f04565b15611955576040517f94a58e2b0000000000000000000000000000000000000000000000000000000081526001600160a01b0384166004820152602401610e57565b60006119df7f000000000000000000000000000000000000000000000000000000000000000085604080517f9ca52083bb00ac0f5bed7edcaabb0534d03efb0719807b54a8029c4d1313630960208201529081018390526001600160a01b038216606082015260009060800160405160208183030381529060405280519060200120905092915050565b6040517f98d78c820000000000000000000000000000000000000000000000000000000081529091506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906398d78c8290611a4f90849060029087906000906004016126d4565b6020604051808303816000875af1158015611a6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9291906125ba565b949350505050565b60608167ffffffffffffffff811115611ab557611ab5612178565b604051908082528060200260200182016040528015611ae857816020015b6060815260200190600190039081611ad35790505b5090506000606060005b84811015611bea5730868683818110611b0d57611b0d612730565b9050602002810190611b1f9190612746565b604051611b2d9291906125aa565b600060405180830381855af49150503d8060008114611b68576040519150601f19603f3d011682016040523d82523d6000602084013e611b6d565b606091505b50909350915082611bbb578151600003611bb3576040517f4d6a232800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815182602001fd5b81848281518110611bce57611bce612730565b602002602001018190525080611be39061278d565b9050611af2565b50505092915050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a5269ef16000611cae7f000000000000000000000000000000000000000000000000000000000000000086604080517f9ca52083bb00ac0f5bed7edcaabb0534d03efb0719807b54a8029c4d1313630960208201529081018390526001600160a01b038216606082015260009060800160405160208183030381529060405280519060200120905092915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015611d0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3391906125ba565b92915050565b33611d627f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614611074576040516330cd747160e01b815260040160405180910390fd5b6040805160148082528183019092526060916020820181803683375050506014808201939093529182525090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e1d40c77838a8a8a8a8a8a8a6040518963ffffffff1660e01b8152600401611e1297969594939291906127b4565b60206040518083038185885af1158015611e30573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611e5591906125ba565b98975050505050505050565b6001600160a01b038116611e8857604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616390600090a27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05560007f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b600080826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611f45573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f6d91908101906125d3565b6040517f935b13f60000000000000000000000000000000000000000000000000000000081529091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063935b13f690611fd5908490600401612825565b602060405180830381865afa158015611ff2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612016919061258d565b6001600160a01b0316836001600160a01b031614915050919050565b60008083601f84011261204457600080fd5b50813567ffffffffffffffff81111561205c57600080fd5b60208301915083602082850101111561207457600080fd5b9250929050565b60ff8116811461107d57600080fd5b6001600160a01b038116811461107d57600080fd5b60008060008060008060008060c0898b0312156120bb57600080fd5b88359750602089013567ffffffffffffffff808211156120da57600080fd5b6120e68c838d01612032565b909950975060408b01359150808211156120ff57600080fd5b5061210c8b828c01612032565b90965094505060608901356121208161207b565b92506080890135915060a08901356121378161208a565b809150509295985092959890939650565b6000806040838503121561215b57600080fd5b82359150602083013561216d8161208a565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156121b7576121b7612178565b604052919050565b600067ffffffffffffffff8211156121d9576121d9612178565b50601f01601f191660200190565b60008060008060008060a0878903121561220057600080fd5b863567ffffffffffffffff8082111561221857600080fd5b6122248a838b01612032565b909850965060208901359550604089013591506122408261208a565b9093506060880135908082111561225657600080fd5b508701601f8101891361226857600080fd5b803561227b612276826121bf565b61218e565b8181528a602083850101111561229057600080fd5b81602084016020830137600060208383010152809450505050608087013590509295509295509295565b600080604083850312156122cd57600080fd5b82356122d88161208a565b946020939093013593505050565b6000602082840312156122f857600080fd5b8135610f308161208a565b60008060006060848603121561231857600080fd5b83359250602084013561232a8161208a565b929592945050506040919091013590565b6000806000806000806080878903121561235457600080fd5b863567ffffffffffffffff8082111561236c57600080fd5b6123788a838b01612032565b90985096506020890135915061238d8261208a565b909450604088013590808211156123a357600080fd5b506123b089828a01612032565b979a9699509497949695606090950135949350505050565b600080602083850312156123db57600080fd5b823567ffffffffffffffff8111156123f257600080fd5b6123fe85828601612032565b90969095509350505050565b6000806000806060858703121561242057600080fd5b843561242b8161208a565b935060208501359250604085013567ffffffffffffffff81111561244e57600080fd5b61245a87828801612032565b95989497509550505050565b6000806020838503121561247957600080fd5b823567ffffffffffffffff8082111561249157600080fd5b818501915085601f8301126124a557600080fd5b8135818111156124b457600080fd5b8660208260051b85010111156124c957600080fd5b60209290920196919550909350505050565b60005b838110156124f65781810151838201526020016124de565b50506000910152565b600081518084526125178160208601602086016124db565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561258057603f1988860301845261256e8583516124ff565b94509285019290850190600101612552565b5092979650505050505050565b60006020828403121561259f57600080fd5b8151610f308161208a565b8183823760009101908152919050565b6000602082840312156125cc57600080fd5b5051919050565b6000602082840312156125e557600080fd5b815167ffffffffffffffff8111156125fc57600080fd5b8201601f8101841361260d57600080fd5b805161261b612276826121bf565b81815285602083850101111561263057600080fd5b6126418260208301602086016124db565b95945050505050565b60006020828403121561265c57600080fd5b8151610f308161207b565b60006020828403121561267957600080fd5b81518015158114610f3057600080fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b600082516126ca8184602087016124db565b9190910192915050565b84815260a06020820152600060a082015260006004851061270557634e487b7160e01b600052602160045260246000fd5b84604083015260c0606083015261271f60c08301856124ff565b905082608083015295945050505050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261275d57600080fd5b83018035915067ffffffffffffffff82111561277857600080fd5b60200191503681900382131561207457600080fd5b6000600182016127ad57634e487b7160e01b600052601160045260246000fd5b5060010190565b87815260e0602082015260006127cd60e08301896124ff565b82810360408401526127df81896124ff565b905082810360608401526127f381886124ff565b905060ff8616608084015282810360a084015261281081866124ff565b9150508260c083015298975050505050505050565b602081526000610f3060208301846124ff56fea26469706673582212201dd24b41eec30f006454347e9cdc29f9b6e4f4417fd319013938b3660bd3fc6e64736f6c63430008150033000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c
Deployed Bytecode
0x6080604052600436106101755760003560e01c80638da5cb5b116100cb578063a5269ef11161007f578063b229288811610059578063b229288814610503578063e30c397814610523578063f2fde38b1461055757600080fd5b8063a5269ef1146104b0578063a75483d1146104d0578063ac9650d8146104e357600080fd5b8063993a5b9e116100b0578063993a5b9e1461045d5780639ded06df14610470578063a3499c731461049057600080fd5b80638da5cb5b146103a35780639417bfe1146103d757600080fd5b80635d79c00e1161012d57806379ba50971161010757806379ba5097146103275780638291286c1461033c578063864a0dcf1461036f57600080fd5b80635d79c00e146102d25780637100e6a9146102e5578063710bf3221461030557600080fd5b80633e12f8c51161015e5780633e12f8c5146101ff57806352a3702f146102205780635c60da1b1461029e57600080fd5b806309c6bed91461017a578063116191b6146101cb575b600080fd5b34801561018657600080fd5b506101ae7f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c81565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101d757600080fd5b506101ae7f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e3181565b61021261020d36600461209f565b610577565b6040519081526020016101c2565b34801561022c57600080fd5b5061021261023b366004612148565b604080517f9ca52083bb00ac0f5bed7edcaabb0534d03efb0719807b54a8029c4d1313630960208201529081018390526001600160a01b038216606082015260009060800160405160208183030381529060405280519060200120905092915050565b3480156102aa57600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546101ae565b6102126102e03660046121e7565b610a73565b3480156102f157600080fd5b506101ae6103003660046122ba565b610e96565b34801561031157600080fd5b506103256103203660046122e6565b610f37565b005b34801561033357600080fd5b50610325611006565b34801561034857600080fd5b507f80547d63ed663962b99f8ed432bff3879a35b5418af92258aa171feef14cc3cc610212565b34801561037b57600080fd5b506102127f09d0f27659ee556a8134fa56941e42400e672aecc2d4cfc61cdb0fcea4590e0581565b3480156103af57600080fd5b507f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0546101ae565b3480156103e357600080fd5b506102126103f2366004612303565b604080517ff84d43c32bc607f1bdb175c63a0cf1939bf0cc8cc3565450be225afbb5a1098560208201529081018490526001600160a01b03831660608201526080810182905260009060a0016040516020818303038152906040528051906020012090509392505050565b61021261046b36600461233b565b611080565b34801561047c57600080fd5b5061032561048b3660046123c8565b61140e565b34801561049c57600080fd5b506103256104ab36600461240a565b611474565b3480156104bc57600080fd5b506102126104cb3660046122ba565b611793565b6102126104de3660046122e6565b6118c8565b6104f66104f1366004612466565b611a9a565b6040516101c2919061252b565b34801561050f57600080fd5b5061021261051e3660046122e6565b611bf3565b34801561052f57600080fd5b507f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d1546101ae565b34801561056357600080fd5b506103256105723660046122e6565b611d39565b604080517ff84d43c32bc607f1bdb175c63a0cf1939bf0cc8cc3565450be225afbb5a109856020808301919091527f09d0f27659ee556a8134fa56941e42400e672aecc2d4cfc61cdb0fcea4590e0582840152336060830181905260808084018d90528451808503909101815260a0909301909352815191012060009190604080516000815260208101909152909a50841561061d5761061630611d89565b9050610641565b6001600160a01b038416156106415761063e846001600160a01b0316611d89565b90505b6106d98b604051806020016040528060008152508c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508b8b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508e93508992509050611db7565b92508415610a6557604051631d05ce3f60e31b8152600481018490526000907f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c6001600160a01b03169063e82e71f890602401602060405180830381865afa158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d919061258d565b6040517ff8c8a826000000000000000000000000000000000000000000000000000000008152600481018690529091506000906001600160a01b037f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c169063f8c8a82690602401602060405180830381865afa1580156107f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610815919061258d565b6040517f40c10f190000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152602482018a9052919250908316906340c10f1990604401600060405180830381600087803b15801561087c57600080fd5b505af1158015610890573d6000803e3d6000fd5b50506040517fcf86a95a0000000000000000000000000000000000000000000000000000000081526001600160a01b0389811660048301528516925063cf86a95a9150602401600060405180830381600087803b1580156108f057600080fd5b505af1158015610904573d6000803e3d6000fd5b50506040517fe915cfd10000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038416925063e915cfd19150602401600060405180830381600087803b15801561096257600080fd5b505af1158015610976573d6000803e3d6000fd5b50506040517f120a63b50000000000000000000000000000000000000000000000000000000081526001600160a01b0389811660048301528416925063120a63b59150602401600060405180830381600087803b1580156109d657600080fd5b505af11580156109ea573d6000803e3d6000fd5b50506040517f4a6a42d80000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015284169250634a6a42d89150602401600060405180830381600087803b158015610a4a57600080fd5b505af1158015610a5e573d6000803e3d6000fd5b5050505050505b505098975050505050505050565b604080516000808252602082019092526060908190839060008a8103610aba57507f09d0f27659ee556a8134fa56941e42400e672aecc2d4cfc61cdb0fcea4590e05610ad5565b8b8b604051610aca9291906125aa565b604051809103902090505b604080517ff84d43c32bc607f1bdb175c63a0cf1939bf0cc8cc3565450be225afbb5a10985602080830191909152818301849052336060830181905260808084018f90528451808503909101815260a0909301909352815191012060405163a5269ef160e01b81526000600482015260248101829052909b507f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c6001600160a01b03169063a5269ef190604401602060405180830381865afa158015610b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc391906125ba565b604051631d05ce3f60e31b8152600481018290529097506000906001600160a01b037f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c169063e82e71f890602401602060405180830381865afa158015610c2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c52919061258d565b9050806001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015610c92573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cba91908101906125d3565b9650806001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610cfa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d2291908101906125d3565b9550806001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d86919061264a565b94506001600160a01b038b1615610e75576040517faa271e1a0000000000000000000000000000000000000000000000000000000081526001600160a01b038c8116600483015282169063aa271e1a90602401602060405180830381865afa158015610df6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1a9190612667565b610e60576040517f361c31f20000000000000000000000000000000000000000000000000000000081526001600160a01b038c1660048201526024015b60405180910390fd5b610e728b6001600160a01b0316611d89565b93505b505050610e878988868686868c611db7565b9b9a5050505050505050505050565b60007f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c6001600160a01b031663e82e71f8610ed18585611793565b6040518263ffffffff1660e01b8152600401610eef91815260200190565b602060405180830381865afa158015610f0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f30919061258d565b9392505050565b33610f607f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614610f87576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b038116610fae57604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907fd9be0e8e07417e00f2521db636cb53e316fd288f5051f16d2aa2bf0c3938a87690600090a27f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b60006110307f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d15490565b90506001600160a01b0381163314611074576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61107d81611e61565b50565b60008080808881036110b357507f09d0f27659ee556a8134fa56941e42400e672aecc2d4cfc61cdb0fcea4590e056110ce565b89896040516110c39291906125aa565b604051809103902090505b6111368189604080517f9ca52083bb00ac0f5bed7edcaabb0534d03efb0719807b54a8029c4d1313630960208201529081018390526001600160a01b038216606082015260009060800160405160208183030381529060405280519060200120905092915050565b60405163a5269ef160e01b815260006004820152602481018290529093507f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c6001600160a01b03169063a5269ef190604401602060405180830381865afa1580156111a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c991906125ba565b6040517f1a083d39000000000000000000000000000000000000000000000000000000008152600481018290529094507f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c6001600160a01b031690631a083d3990602401602060405180830381865afa15801561124a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126e919061258d565b9150506000816001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156112b1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112d991908101906125d3565b90506000826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801561131b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261134391908101906125d3565b90506000836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611385573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a9919061264a565b90506113fe858a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525060408051602081019091529081528993508892508791508d611db7565b9c9b505050505050505050505050565b307f000000000000000000000000440b118f34d6224b20b4641835ac9161bd4f09946001600160a01b031603611470576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b3361149d7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b0316146114c4576040516330cd747160e01b815260040160405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b0316638291286c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611523573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154791906125ba565b846001600160a01b0316638291286c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611585573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a991906125ba565b146115e0576040517f68155f9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836001600160a01b03163f8314611623576040517f8f84fb2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b038516907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2801561176c576000846001600160a01b0316639ded06df60e01b8484604051602401611684929190612689565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516116ef91906126b8565b600060405180830381855af49150503d806000811461172a576040519150601f19603f3d011682016040523d82523d6000602084013e61172f565b606091505b505090508061176a576040517f97905dfb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b5050507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b604080517ff84d43c32bc607f1bdb175c63a0cf1939bf0cc8cc3565450be225afbb5a109856020808301919091527f09d0f27659ee556a8134fa56941e42400e672aecc2d4cfc61cdb0fcea4590e05828401526001600160a01b03858116606084015260808084018690528451808503909101815260a090930190935281519101206000917f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c169063a5269ef19083906040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156118a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3091906125ba565b600080826040516020016118f9919060408082526000908201526001600160a01b0391909116602082015260600190565b604051602081830303815290604052905061191383611f04565b15611955576040517f94a58e2b0000000000000000000000000000000000000000000000000000000081526001600160a01b0384166004820152602401610e57565b60006119df7f09d0f27659ee556a8134fa56941e42400e672aecc2d4cfc61cdb0fcea4590e0585604080517f9ca52083bb00ac0f5bed7edcaabb0534d03efb0719807b54a8029c4d1313630960208201529081018390526001600160a01b038216606082015260009060800160405160208183030381529060405280519060200120905092915050565b6040517f98d78c820000000000000000000000000000000000000000000000000000000081529091506001600160a01b037f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c16906398d78c8290611a4f90849060029087906000906004016126d4565b6020604051808303816000875af1158015611a6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9291906125ba565b949350505050565b60608167ffffffffffffffff811115611ab557611ab5612178565b604051908082528060200260200182016040528015611ae857816020015b6060815260200190600190039081611ad35790505b5090506000606060005b84811015611bea5730868683818110611b0d57611b0d612730565b9050602002810190611b1f9190612746565b604051611b2d9291906125aa565b600060405180830381855af49150503d8060008114611b68576040519150601f19603f3d011682016040523d82523d6000602084013e611b6d565b606091505b50909350915082611bbb578151600003611bb3576040517f4d6a232800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815182602001fd5b81848281518110611bce57611bce612730565b602002602001018190525080611be39061278d565b9050611af2565b50505092915050565b60007f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c6001600160a01b031663a5269ef16000611cae7f09d0f27659ee556a8134fa56941e42400e672aecc2d4cfc61cdb0fcea4590e0586604080517f9ca52083bb00ac0f5bed7edcaabb0534d03efb0719807b54a8029c4d1313630960208201529081018390526001600160a01b038216606082015260009060800160405160208183030381529060405280519060200120905092915050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa158015611d0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3391906125ba565b92915050565b33611d627f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614611074576040516330cd747160e01b815260040160405180910390fd5b6040805160148082528183019092526060916020820181803683375050506014808201939093529182525090565b60007f000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c6001600160a01b031663e1d40c77838a8a8a8a8a8a8a6040518963ffffffff1660e01b8152600401611e1297969594939291906127b4565b60206040518083038185885af1158015611e30573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611e5591906125ba565b98975050505050505050565b6001600160a01b038116611e8857604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616390600090a27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05560007f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b600080826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611f45573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611f6d91908101906125d3565b6040517f935b13f60000000000000000000000000000000000000000000000000000000081529091506001600160a01b037f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31169063935b13f690611fd5908490600401612825565b602060405180830381865afa158015611ff2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612016919061258d565b6001600160a01b0316836001600160a01b031614915050919050565b60008083601f84011261204457600080fd5b50813567ffffffffffffffff81111561205c57600080fd5b60208301915083602082850101111561207457600080fd5b9250929050565b60ff8116811461107d57600080fd5b6001600160a01b038116811461107d57600080fd5b60008060008060008060008060c0898b0312156120bb57600080fd5b88359750602089013567ffffffffffffffff808211156120da57600080fd5b6120e68c838d01612032565b909950975060408b01359150808211156120ff57600080fd5b5061210c8b828c01612032565b90965094505060608901356121208161207b565b92506080890135915060a08901356121378161208a565b809150509295985092959890939650565b6000806040838503121561215b57600080fd5b82359150602083013561216d8161208a565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156121b7576121b7612178565b604052919050565b600067ffffffffffffffff8211156121d9576121d9612178565b50601f01601f191660200190565b60008060008060008060a0878903121561220057600080fd5b863567ffffffffffffffff8082111561221857600080fd5b6122248a838b01612032565b909850965060208901359550604089013591506122408261208a565b9093506060880135908082111561225657600080fd5b508701601f8101891361226857600080fd5b803561227b612276826121bf565b61218e565b8181528a602083850101111561229057600080fd5b81602084016020830137600060208383010152809450505050608087013590509295509295509295565b600080604083850312156122cd57600080fd5b82356122d88161208a565b946020939093013593505050565b6000602082840312156122f857600080fd5b8135610f308161208a565b60008060006060848603121561231857600080fd5b83359250602084013561232a8161208a565b929592945050506040919091013590565b6000806000806000806080878903121561235457600080fd5b863567ffffffffffffffff8082111561236c57600080fd5b6123788a838b01612032565b90985096506020890135915061238d8261208a565b909450604088013590808211156123a357600080fd5b506123b089828a01612032565b979a9699509497949695606090950135949350505050565b600080602083850312156123db57600080fd5b823567ffffffffffffffff8111156123f257600080fd5b6123fe85828601612032565b90969095509350505050565b6000806000806060858703121561242057600080fd5b843561242b8161208a565b935060208501359250604085013567ffffffffffffffff81111561244e57600080fd5b61245a87828801612032565b95989497509550505050565b6000806020838503121561247957600080fd5b823567ffffffffffffffff8082111561249157600080fd5b818501915085601f8301126124a557600080fd5b8135818111156124b457600080fd5b8660208260051b85010111156124c957600080fd5b60209290920196919550909350505050565b60005b838110156124f65781810151838201526020016124de565b50506000910152565b600081518084526125178160208601602086016124db565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561258057603f1988860301845261256e8583516124ff565b94509285019290850190600101612552565b5092979650505050505050565b60006020828403121561259f57600080fd5b8151610f308161208a565b8183823760009101908152919050565b6000602082840312156125cc57600080fd5b5051919050565b6000602082840312156125e557600080fd5b815167ffffffffffffffff8111156125fc57600080fd5b8201601f8101841361260d57600080fd5b805161261b612276826121bf565b81815285602083850101111561263057600080fd5b6126418260208301602086016124db565b95945050505050565b60006020828403121561265c57600080fd5b8151610f308161207b565b60006020828403121561267957600080fd5b81518015158114610f3057600080fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b600082516126ca8184602087016124db565b9190910192915050565b84815260a06020820152600060a082015260006004851061270557634e487b7160e01b600052602160045260246000fd5b84604083015260c0606083015261271f60c08301856124ff565b905082608083015295945050505050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261275d57600080fd5b83018035915067ffffffffffffffff82111561277857600080fd5b60200191503681900382131561207457600080fd5b6000600182016127ad57634e487b7160e01b600052601160045260246000fd5b5060010190565b87815260e0602082015260006127cd60e08301896124ff565b82810360408401526127df81896124ff565b905082810360608401526127f381886124ff565b905060ff8616608084015282810360a084015261281081866124ff565b9150508260c083015298975050505050505050565b602081526000610f3060208301846124ff56fea26469706673582212201dd24b41eec30f006454347e9cdc29f9b6e4f4417fd319013938b3660bd3fc6e64736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c
-----Decoded View---------------
Arg [0] : interchainTokenService_ (address): 0xB5FB4BE02232B1bBA4dC8f81dc24C26980dE9e3C
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000b5fb4be02232b1bba4dc8f81dc24c26980de9e3c
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.