Source Code
Overview
FTM Balance
More Info
ContractCreator
Multichain Info
N/A
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
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.
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x4a8bcfff...72272b245 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
InterchainTokenDeployer
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { Create3 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/deploy/Create3.sol'; import { IInterchainTokenDeployer } from '../interfaces/IInterchainTokenDeployer.sol'; import { IInterchainToken } from '../interfaces/IInterchainToken.sol'; /** * @title InterchainTokenDeployer * @notice This contract is used to deploy new instances of the InterchainTokenProxy contract. */ contract InterchainTokenDeployer is IInterchainTokenDeployer, Create3 { address public immutable implementationAddress; /** * @notice Constructor for the InterchainTokenDeployer contract. * @param implementationAddress_ Address of the InterchainToken contract. */ constructor(address implementationAddress_) { if (implementationAddress_ == address(0)) revert AddressZero(); implementationAddress = implementationAddress_; } /** * @notice Deploys a new instance of the InterchainTokenProxy contract. * @param salt The salt used by Create3Deployer. * @param tokenId TokenId for the token. * @param minter Address of the minter. * @param name Name of the token. * @param symbol Symbol of the token. * @param decimals Decimals of the token. * @return tokenAddress Address of the deployed token. */ function deployInterchainToken( bytes32 salt, bytes32 tokenId, address minter, string calldata name, string calldata symbol, uint8 decimals ) external returns (address tokenAddress) { // Use a minimal proxy for cheap token deployment and auto-verification on explorers // https://eips.ethereum.org/EIPS/eip-1167 // The minimal proxy bytecode is the same as https://github.com/OpenZeppelin/openzeppelin-contracts/blob/94697be8a3f0dfcd95dfb13ffbd39b5973f5c65d/contracts/proxy/Clones.sol#L28 // The minimal proxy bytecode is 0x37 = 55 bytes long bytes memory bytecode = new bytes(0x37); address implementation = implementationAddress; /// @solidity memory-safe-assembly assembly { // The first 0x20 = 32 bytes (0x00 - 0x19) are reserved for the length. // The next 0x14 = 20 bytes (0x20 - 0x33) are the ones below. mstore(add(bytecode, 0x20), shl(0x60, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)) // The next 0x14 = 20 bytes (0x34 - 0x47) are the implementation address. mstore(add(bytecode, 0x34), shl(0x60, implementation)) // The last 0x0f = 15 bytes (0x48 - 0x56) are the ones below. mstore(add(bytecode, 0x48), shl(0x88, 0x5af43d82803e903d91602b57fd5bf3)) } tokenAddress = _create3(bytecode, salt); if (tokenAddress.code.length == 0) revert TokenDeploymentFailed(); IInterchainToken(tokenAddress).init(tokenId, minter, name, symbol, decimals); } /** * @notice Returns the interchain token deployment address. * @param salt The deployment salt. * @return tokenAddress The token address. */ function deployedAddress(bytes32 salt) external view returns (address tokenAddress) { return _create3Address(salt); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IDeploy } from '../interfaces/IDeploy.sol'; import { ContractAddress } from '../libs/ContractAddress.sol'; import { CreateDeploy } from './CreateDeploy.sol'; import { Create3Address } from './Create3Address.sol'; /** * @title Create3 contract * @notice This contract can be used to deploy a contract with a deterministic address that depends only on * the deployer address and deployment salt, not the contract bytecode and constructor parameters. */ contract Create3 is Create3Address, IDeploy { using ContractAddress for address; /** * @notice Deploys a new contract using the `CREATE3` method. * @dev This function first deploys the CreateDeploy contract using * the `CREATE2` opcode and then utilizes the CreateDeploy to deploy the * new contract with the `CREATE` opcode. * @param bytecode The bytecode of the contract to be deployed * @param deploySalt A salt to influence the contract address * @return deployed The address of the deployed contract */ function _create3(bytes memory bytecode, bytes32 deploySalt) internal returns (address deployed) { deployed = _create3Address(deploySalt); if (bytecode.length == 0) revert EmptyBytecode(); if (deployed.isContract()) revert AlreadyDeployed(); // Deploy using create2 CreateDeploy create = new CreateDeploy{ salt: deploySalt }(); if (address(create) == address(0)) revert DeployFailed(); // Deploy using create create.deploy(bytecode); } }
// SPDX-License-Identifier: MIT import { CreateDeploy } from './CreateDeploy.sol'; pragma solidity ^0.8.0; /** * @title Create3Address contract * @notice This contract can be used to predict the deterministic deployment address of a contract deployed with the `CREATE3` technique. */ contract Create3Address { /// @dev bytecode hash of the CreateDeploy helper contract bytes32 internal immutable createDeployBytecodeHash; constructor() { createDeployBytecodeHash = keccak256(type(CreateDeploy).creationCode); } /** * @notice Compute the deployed address that will result from the `CREATE3` method. * @param deploySalt A salt to influence the contract address * @return deployed The deterministic contract address if it was deployed */ function _create3Address(bytes32 deploySalt) internal view returns (address deployed) { address deployer = address( uint160(uint256(keccak256(abi.encodePacked(hex'ff', address(this), deploySalt, createDeployBytecodeHash)))) ); deployed = address(uint160(uint256(keccak256(abi.encodePacked(hex'd6_94', deployer, hex'01'))))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title CreateDeploy Contract * @notice This contract deploys new contracts using the `CREATE` opcode and is used as part of * the `CREATE3` deployment method. */ contract CreateDeploy { /** * @dev Deploys a new contract with the specified bytecode using the `CREATE` opcode. * @param bytecode The bytecode of the contract to be deployed */ // slither-disable-next-line locked-ether function deploy(bytes memory bytecode) external payable { assembly { if iszero(create(0, add(bytecode, 32), mload(bytecode))) { revert(0, 0) } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IDeploy Interface * @notice This interface defines the errors for a contract that is responsible for deploying new contracts. */ interface IDeploy { error EmptyBytecode(); error AlreadyDeployed(); error DeployFailed(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { error InvalidAccount(); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IRolesBase Interface * @notice IRolesBase is an interface that abstracts the implementation of a * contract with role control internal functions. */ interface IRolesBase { error MissingRole(address account, uint8 role); error MissingAllRoles(address account, uint256 accountRoles); error MissingAnyOfRoles(address account, uint256 accountRoles); error InvalidProposedRoles(address fromAccount, address toAccount, uint256 accountRoles); event RolesProposed(address indexed fromAccount, address indexed toAccount, uint256 accountRoles); event RolesAdded(address indexed account, uint256 accountRoles); event RolesRemoved(address indexed account, uint256 accountRoles); /** * @notice Checks if an account has a role. * @param account The address to check * @param role The role to check * @return True if the account has the role, false otherwise */ function hasRole(address account, uint8 role) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library ContractAddress { function isContract(address contractAddress) internal view returns (bool) { bytes32 existingCodeHash = contractAddress.codehash; // https://eips.ethereum.org/EIPS/eip-1052 // keccak256('') == 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 return existingCodeHash != bytes32(0) && existingCodeHash != 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IERC20MintableBurnable Interface * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20MintableBurnable { /** * @notice Function to mint new tokens. * @dev Can only be called by the minter address. * @param to The address that will receive the minted tokens. * @param amount The amount of tokens to mint. */ function mint(address to, uint256 amount) external; /** * @notice Function to burn tokens. * @dev Can only be called by the minter address. * @param from The address that will have its tokens burnt. * @param amount The amount of tokens to burn. */ function burn(address from, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol'; /** * @title IERC20Named Interface * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Named is IERC20 { /** * @notice Getter for the name of the token. * @return string Name of the token. */ function name() external view returns (string memory); /** * @notice Getter for the symbol of the token. * @return string The symbol of the token. */ function symbol() external view returns (string memory); /** * @notice Getter for the decimals of the token. * @return uint8 The decimals of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IInterchainTokenStandard } from './IInterchainTokenStandard.sol'; import { IMinter } from './IMinter.sol'; import { IERC20MintableBurnable } from './IERC20MintableBurnable.sol'; import { IERC20Named } from './IERC20Named.sol'; /** * @title IInterchainToken interface * @dev Extends IInterchainTokenStandard and IMinter. */ interface IInterchainToken is IInterchainTokenStandard, IMinter, IERC20MintableBurnable, IERC20Named { error InterchainTokenServiceAddressZero(); error TokenIdZero(); error TokenNameEmpty(); error TokenSymbolEmpty(); error AlreadyInitialized(); /** * @notice Getter for the interchain token service contract. * @dev Needs to be overwitten. * @return interchainTokenServiceAddress The interchain token service address. */ function interchainTokenService() external view returns (address interchainTokenServiceAddress); /** * @notice Getter for the tokenId used for this token. * @dev Needs to be overwitten. * @return tokenId_ The tokenId for this token. */ function interchainTokenId() external view returns (bytes32 tokenId_); /** * @notice Setup function to initialize contract parameters. * @param tokenId_ The tokenId of the token. * @param minter The address of the token minter. * @param tokenName The name of the token. * @param tokenSymbol The symbopl of the token. * @param tokenDecimals The decimals of the token. */ function init(bytes32 tokenId_, address minter, string calldata tokenName, string calldata tokenSymbol, uint8 tokenDecimals) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IInterchainTokenDeployer * @notice This interface is used to deploy new instances of the InterchainTokenProxy contract. */ interface IInterchainTokenDeployer { error AddressZero(); error TokenDeploymentFailed(); /** * @notice Returns the interchain token implementation address. * @return address The interchain token implementation address. */ function implementationAddress() external view returns (address); /** * @notice Returns the interchain token deployment address. * @param salt The deployment salt. * @return tokenAddress The token address. */ function deployedAddress(bytes32 salt) external view returns (address tokenAddress); /** * @notice Deploys a new instance of the InterchainTokenProxy contract. * @param salt The salt used by Create3Deployer. * @param tokenId tokenId of the token. * @param minter Address of the minter. * @param name Name of the token. * @param symbol Symbol of the token. * @param decimals Decimals of the token. * @return tokenAddress Address of the deployed token. */ function deployInterchainToken( bytes32 salt, bytes32 tokenId, address minter, string calldata name, string calldata symbol, uint8 decimals ) external returns (address tokenAddress); }
// 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); }
{ "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": {} }
[{"inputs":[{"internalType":"address","name":"implementationAddress_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressZero","type":"error"},{"inputs":[],"name":"AlreadyDeployed","type":"error"},{"inputs":[],"name":"DeployFailed","type":"error"},{"inputs":[],"name":"EmptyBytecode","type":"error"},{"inputs":[],"name":"TokenDeploymentFailed","type":"error"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"deployInterchainToken","outputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"deployedAddress","outputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementationAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063b97a231914610046578063ee85660314610089578063f575f35b1461009c575b600080fd5b61006d7f0000000000000000000000007f9f70da4af54671a6abac58e705b5634cac881981565b6040516001600160a01b03909116815260200160405180910390f35b61006d61009736600461050e565b6100af565b61006d6100aa366004610570565b6100c0565b60006100ba8261023d565b92915050565b6040805160378082526060820190925260009182919060208201818036833750507f3d602d80600a3d3981f3363d3d373d3d3d363d730000000000000000000000006020830152507f0000000000000000000000007f9f70da4af54671a6abac58e705b5634cac8819606081901b60348301527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006048830152909150610166828c61033f565b9250826001600160a01b03163b6000036101ac576040517fd0a30aa600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f8626698f0000000000000000000000000000000000000000000000000000000081526001600160a01b03841690638626698f906101fd908d908d908d908d908d908d908d90600401610654565b600060405180830381600087803b15801561021757600080fd5b505af115801561022b573d6000803e3d6000fd5b50505050505098975050505050505050565b604080517fff0000000000000000000000000000000000000000000000000000000000000060208083019190915230606090811b6bffffffffffffffffffffffff19908116602185015260358401959095527fdb4bab1640a2602c9f66f33765d12be4af115accf74b24515702961e82a71327605580850191909152845180850390910181526075840185528051908301207fd6940000000000000000000000000000000000000000000000000000000000006095850152901b90931660978201527f010000000000000000000000000000000000000000000000000000000000000060ab8201528151608c81830301815260ac909101909152805191012090565b600061034a8261023d565b90508251600003610387576040517f21744a5900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610399816001600160a01b03166104be565b156103d0576040517fa6ef0ba100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000826040516103df90610501565b8190604051809103906000f59050801580156103ff573d6000803e3d6000fd5b5090506001600160a01b038116610442576040517fb4f5411100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517e7743600000000000000000000000000000000000000000000000000000000081526001600160a01b0382169062774360906104859087906004016106a8565b600060405180830381600087803b15801561049f57600080fd5b505af11580156104b3573d6000803e3d6000fd5b505050505092915050565b60006001600160a01b0382163f80158015906104fa57507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708114155b9392505050565b610182806106f783390190565b60006020828403121561052057600080fd5b5035919050565b60008083601f84011261053957600080fd5b50813567ffffffffffffffff81111561055157600080fd5b60208301915083602082850101111561056957600080fd5b9250929050565b60008060008060008060008060c0898b03121561058c57600080fd5b883597506020890135965060408901356001600160a01b03811681146105b157600080fd5b9550606089013567ffffffffffffffff808211156105ce57600080fd5b6105da8c838d01610527565b909750955060808b01359150808211156105f357600080fd5b506106008b828c01610527565b90945092505060a089013560ff8116811461061a57600080fd5b809150509295985092959890939650565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8781526001600160a01b038716602082015260a06040820152600061067d60a08301878961062b565b828103606084015261069081868861062b565b91505060ff8316608083015298975050505050505050565b600060208083528351808285015260005b818110156106d5578581018301518582016040015282016106b9565b506000604082860101526040601f19601f830116850101925050509291505056fe608060405234801561001057600080fd5b50610162806100206000396000f3fe60806040526004361061001d5760003560e01c806277436014610022575b600080fd5b61003561003036600461007b565b610037565b005b8051602082016000f061004957600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561008d57600080fd5b813567ffffffffffffffff808211156100a557600080fd5b818401915084601f8301126100b957600080fd5b8135818111156100cb576100cb61004c565b604051601f8201601f19908116603f011681019083821181831017156100f3576100f361004c565b8160405282815287602084870101111561010c57600080fd5b82602086016020830137600092810160200192909252509594505050505056fea264697066735822122094780ce55d28f1d568f4e0ab1b9dc230b96e952b73d2e06456fbff2289fa27f464736f6c63430008150033a2646970667358221220a22dca97b82cbb80af6662dc2915302b8b5c33ad873ff9322fb2d8c4716b727e64736f6c63430008150033
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.