creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IProxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// General interface for upgradable contracts\ninterface IProxy {\n    error InvalidOwner();\n    error InvalidImplementation();\n    error SetupFailed();\n    error NotOwner();\n    error AlreadyInitialized();\n\n    function implementation() external view returns (address);\n\n    function setup(bytes calldata setupParams) external;\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/BaseProxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IProxy } from '../interfaces/IProxy.sol';\n\n/**\n * @title BaseProxy Contract\n * @dev This abstract contract implements a basic proxy that stores an implementation address. Fallback function\n * calls are delegated to the implementation. This contract is meant to be inherited by other proxy contracts.\n */\nabstract contract BaseProxy is IProxy {\n    // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n    // keccak256('owner')\n    bytes32 internal constant _OWNER_SLOT = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0;\n\n    /**\n     * @dev Returns the current implementation address.\n     * @return implementation_ The address of the current implementation contract\n     */\n    function implementation() public view virtual returns (address implementation_) {\n        assembly {\n            implementation_ := sload(_IMPLEMENTATION_SLOT)\n        }\n    }\n\n    /**\n     * @dev Shadows the setup function of the implementation contract so it can't be called directly via the proxy.\n     * @param params The setup parameters for the implementation contract.\n     */\n    function setup(bytes calldata params) external {}\n\n    /**\n     * @dev Returns the contract ID. It can be used as a check during upgrades. Meant to be implemented in derived contracts.\n     * @return bytes32 The contract ID\n     */\n    function contractId() internal pure virtual returns (bytes32);\n\n    /**\n     * @dev Fallback function. Delegates the call to the current implementation contract.\n     */\n    fallback() external payable virtual {\n        address implementation_ = implementation();\n        assembly {\n            calldatacopy(0, 0, calldatasize())\n\n            let result := delegatecall(gas(), implementation_, 0, calldatasize(), 0, 0)\n            returndatacopy(0, 0, returndatasize())\n\n            switch result\n            case 0 {\n                revert(0, returndatasize())\n            }\n            default {\n                return(0, returndatasize())\n            }\n        }\n    }\n\n    /**\n     * @dev Payable fallback function. Can be overridden in derived contracts.\n     */\n    receive() external payable virtual {}\n}\n"
      },
      "contracts/interfaces/IBaseTokenManager.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title IBaseTokenManager\n * @notice This contract is defines the base token manager interface implemented by all token managers.\n */\ninterface IBaseTokenManager {\n    /**\n     * @notice A function that returns the token id.\n     */\n    function interchainTokenId() external view returns (bytes32);\n\n    /**\n     * @notice A function that should return the address of the token.\n     * Must be overridden in the inheriting contract.\n     * @return address address of the token.\n     */\n    function tokenAddress() external view returns (address);\n\n    /**\n     * @notice A function that should return the token address from the init params.\n     */\n    function getTokenAddressFromParams(bytes calldata params) external pure returns (address);\n}\n"
      },
      "contracts/interfaces/ITokenManagerImplementation.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ITokenManagerImplementation Interface\n * @notice Interface for returning the token manager implementation type.\n */\ninterface ITokenManagerImplementation {\n    /**\n     * @notice Returns the implementation address for a given token manager type.\n     * @param tokenManagerType The type of token manager.\n     * @return tokenManagerAddress_ The address of the token manager implementation.\n     */\n    function tokenManagerImplementation(uint256 tokenManagerType) external view returns (address tokenManagerAddress_);\n}\n"
      },
      "contracts/interfaces/ITokenManagerProxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IProxy } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IProxy.sol';\n\n/**\n * @title ITokenManagerProxy Interface\n * @notice This interface is for a proxy for token manager contracts.\n */\ninterface ITokenManagerProxy is IProxy {\n    error ZeroAddress();\n\n    /**\n     * @notice Returns implementation type of this token manager.\n     * @return uint256 The implementation type of this token manager.\n     */\n    function implementationType() external view returns (uint256);\n\n    /**\n     * @notice Returns the interchain token ID of the token manager.\n     * @return bytes32 The interchain token ID of the token manager.\n     */\n    function interchainTokenId() external view returns (bytes32);\n\n    /**\n     * @notice Returns token address that this token manager manages.\n     * @return address The token address.\n     */\n    function tokenAddress() external view returns (address);\n\n    /**\n     * @notice Returns implementation type and token address.\n     * @return uint256 The implementation type.\n     * @return address The token address.\n     */\n    function getImplementationTypeAndTokenAddress() external view returns (uint256, address);\n}\n"
      },
      "contracts/proxies/TokenManagerProxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IProxy } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IProxy.sol';\nimport { BaseProxy } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/BaseProxy.sol';\n\nimport { IBaseTokenManager } from '../interfaces/IBaseTokenManager.sol';\nimport { ITokenManagerProxy } from '../interfaces/ITokenManagerProxy.sol';\nimport { ITokenManagerImplementation } from '../interfaces/ITokenManagerImplementation.sol';\n\n/**\n * @title TokenManagerProxy\n * @notice This contract is a proxy for token manager contracts.\n * @dev This contract implements BaseProxy and ITokenManagerProxy.\n */\ncontract TokenManagerProxy is BaseProxy, ITokenManagerProxy {\n    bytes32 private constant CONTRACT_ID = keccak256('token-manager');\n\n    address public immutable interchainTokenService;\n    uint256 public immutable implementationType;\n    bytes32 public immutable interchainTokenId;\n    address public immutable tokenAddress;\n\n    /**\n     * @notice Constructs the TokenManagerProxy contract.\n     * @param interchainTokenService_ The address of the interchain token service.\n     * @param implementationType_ The token manager type.\n     * @param tokenId The identifier for the token.\n     * @param params The initialization parameters for the token manager contract.\n     */\n    constructor(address interchainTokenService_, uint256 implementationType_, bytes32 tokenId, bytes memory params) {\n        if (interchainTokenService_ == address(0)) revert ZeroAddress();\n\n        interchainTokenService = interchainTokenService_;\n        implementationType = implementationType_;\n        interchainTokenId = tokenId;\n\n        address implementation_ = _tokenManagerImplementation(interchainTokenService_, implementationType_);\n        if (implementation_ == address(0)) revert InvalidImplementation();\n\n        (bool success, ) = implementation_.delegatecall(abi.encodeWithSelector(IProxy.setup.selector, params));\n        if (!success) revert SetupFailed();\n\n        tokenAddress = IBaseTokenManager(implementation_).getTokenAddressFromParams(params);\n    }\n\n    /**\n     * @notice Getter for the contract id.\n     * @return bytes32 The contract id.\n     */\n    function contractId() internal pure override returns (bytes32) {\n        return CONTRACT_ID;\n    }\n\n    /**\n     * @notice Returns implementation type and token address.\n     * @return implementationType_ The implementation type.\n     * @return tokenAddress_ The token address.\n     */\n    function getImplementationTypeAndTokenAddress() external view returns (uint256 implementationType_, address tokenAddress_) {\n        implementationType_ = implementationType;\n        tokenAddress_ = tokenAddress;\n    }\n\n    /**\n     * @notice Returns the address of the current implementation.\n     * @return implementation_ The address of the current implementation.\n     */\n    function implementation() public view override(BaseProxy, IProxy) returns (address implementation_) {\n        implementation_ = _tokenManagerImplementation(interchainTokenService, implementationType);\n    }\n\n    /**\n     * @notice Returns the implementation address from the interchain token service for the provided type.\n     * @param interchainTokenService_ The address of the interchain token service.\n     * @param implementationType_ The token manager type.\n     * @return implementation_ The address of the implementation.\n     */\n    function _tokenManagerImplementation(\n        address interchainTokenService_,\n        uint256 implementationType_\n    ) internal view returns (address implementation_) {\n        implementation_ = ITokenManagerImplementation(interchainTokenService_).tokenManagerImplementation(implementationType_);\n    }\n}\n"
      }
    },
    "settings": {
      "evmVersion": "london",
      "optimizer": {
        "enabled": true,
        "runs": 1000,
        "details": {
          "peephole": true,
          "inliner": true,
          "jumpdestRemover": true,
          "orderLiterals": true,
          "deduplicate": true,
          "cse": true,
          "constantOptimizer": true,
          "yul": true,
          "yulDetails": {
            "stackAllocation": true
          }
        }
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}