Source Code
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 2263733 | 677 days ago | Contract Creation | 0 FRAX |
Cross-Chain Transactions
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:
InterchainTokenService
Compiler Version
v0.8.21+commit.d9974bed
Contract Source Code (Solidity)
/** *Submitted for verification at fraxscan.com on 2024-04-11 */ // Sources flattened with hardhat v2.19.1 https://hardhat.org // SPDX-License-Identifier: MIT // File @axelar-network/axelar-gmp-sdk-solidity/contracts/deploy/[email protected] // Original license: 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) } } } } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/deploy/[email protected] // Original license: SPDX_License_Identifier: MIT 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'))))); } } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: 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; } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: 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); } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; interface IImplementation is IContractIdentifier { error NotProxy(); function setup(bytes calldata data) external; } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; 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; } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; 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; } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @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; } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/express/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; abstract contract ExpressExecutorTracker is IAxelarExpressExecutable { bytes32 internal constant PREFIX_EXPRESS_EXECUTE = keccak256('express-execute'); bytes32 internal constant PREFIX_EXPRESS_EXECUTE_WITH_TOKEN = keccak256('express-execute-with-token'); function _expressExecuteSlot( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash ) internal pure returns (bytes32 slot) { slot = keccak256(abi.encode(PREFIX_EXPRESS_EXECUTE, commandId, sourceChain, sourceAddress, payloadHash)); } function _expressExecuteWithTokenSlot( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash, string calldata symbol, uint256 amount ) internal pure returns (bytes32 slot) { slot = keccak256( abi.encode( PREFIX_EXPRESS_EXECUTE_WITH_TOKEN, commandId, sourceChain, sourceAddress, payloadHash, symbol, amount ) ); } function getExpressExecutor( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash ) external view returns (address expressExecutor) { bytes32 slot = _expressExecuteSlot(commandId, sourceChain, sourceAddress, payloadHash); assembly { expressExecutor := sload(slot) } } function getExpressExecutorWithToken( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash, string calldata symbol, uint256 amount ) external view returns (address expressExecutor) { bytes32 slot = _expressExecuteWithTokenSlot(commandId, sourceChain, sourceAddress, payloadHash, symbol, amount); assembly { expressExecutor := sload(slot) } } function _setExpressExecutor( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash, address expressExecutor ) internal { bytes32 slot = _expressExecuteSlot(commandId, sourceChain, sourceAddress, payloadHash); address currentExecutor; assembly { currentExecutor := sload(slot) } if (currentExecutor != address(0)) revert ExpressExecutorAlreadySet(); assembly { sstore(slot, expressExecutor) } } function _setExpressExecutorWithToken( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash, string calldata symbol, uint256 amount, address expressExecutor ) internal { bytes32 slot = _expressExecuteWithTokenSlot(commandId, sourceChain, sourceAddress, payloadHash, symbol, amount); address currentExecutor; assembly { currentExecutor := sload(slot) } if (currentExecutor != address(0)) revert ExpressExecutorAlreadySet(); assembly { sstore(slot, expressExecutor) } } function _popExpressExecutor( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash ) internal returns (address expressExecutor) { bytes32 slot = _expressExecuteSlot(commandId, sourceChain, sourceAddress, payloadHash); assembly { expressExecutor := sload(slot) if expressExecutor { sstore(slot, 0) } } } function _popExpressExecutorWithToken( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash, string calldata symbol, uint256 amount ) internal returns (address expressExecutor) { bytes32 slot = _expressExecuteWithTokenSlot(commandId, sourceChain, sourceAddress, payloadHash, symbol, amount); assembly { expressExecutor := sload(slot) if expressExecutor { sstore(slot, 0) } } } } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: 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; } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; // 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; } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title IAxelarGasService Interface * @notice This is an interface for the AxelarGasService contract which manages gas payments * and refunds for cross-chain communication on the Axelar network. * @dev This interface inherits IUpgradable */ interface IAxelarGasService is IUpgradable { error NothingReceived(); error InvalidAddress(); error NotCollector(); error InvalidAmounts(); event GasPaidForContractCall( address indexed sourceAddress, string destinationChain, string destinationAddress, bytes32 indexed payloadHash, address gasToken, uint256 gasFeeAmount, address refundAddress ); event GasPaidForContractCallWithToken( address indexed sourceAddress, string destinationChain, string destinationAddress, bytes32 indexed payloadHash, string symbol, uint256 amount, address gasToken, uint256 gasFeeAmount, address refundAddress ); event NativeGasPaidForContractCall( address indexed sourceAddress, string destinationChain, string destinationAddress, bytes32 indexed payloadHash, uint256 gasFeeAmount, address refundAddress ); event NativeGasPaidForContractCallWithToken( address indexed sourceAddress, string destinationChain, string destinationAddress, bytes32 indexed payloadHash, string symbol, uint256 amount, uint256 gasFeeAmount, address refundAddress ); event GasPaidForExpressCall( address indexed sourceAddress, string destinationChain, string destinationAddress, bytes32 indexed payloadHash, address gasToken, uint256 gasFeeAmount, address refundAddress ); event GasPaidForExpressCallWithToken( address indexed sourceAddress, string destinationChain, string destinationAddress, bytes32 indexed payloadHash, string symbol, uint256 amount, address gasToken, uint256 gasFeeAmount, address refundAddress ); event NativeGasPaidForExpressCall( address indexed sourceAddress, string destinationChain, string destinationAddress, bytes32 indexed payloadHash, uint256 gasFeeAmount, address refundAddress ); event NativeGasPaidForExpressCallWithToken( address indexed sourceAddress, string destinationChain, string destinationAddress, bytes32 indexed payloadHash, string symbol, uint256 amount, uint256 gasFeeAmount, address refundAddress ); event GasAdded( bytes32 indexed txHash, uint256 indexed logIndex, address gasToken, uint256 gasFeeAmount, address refundAddress ); event NativeGasAdded(bytes32 indexed txHash, uint256 indexed logIndex, uint256 gasFeeAmount, address refundAddress); event ExpressGasAdded( bytes32 indexed txHash, uint256 indexed logIndex, address gasToken, uint256 gasFeeAmount, address refundAddress ); event NativeExpressGasAdded( bytes32 indexed txHash, uint256 indexed logIndex, uint256 gasFeeAmount, address refundAddress ); event Refunded( bytes32 indexed txHash, uint256 indexed logIndex, address payable receiver, address token, uint256 amount ); /** * @notice Pay for gas using ERC20 tokens for a contract call on a destination chain. * @dev This function is called on the source chain before calling the gateway to execute a remote contract. * @param sender The address making the payment * @param destinationChain The target chain where the contract call will be made * @param destinationAddress The target address on the destination chain * @param payload Data payload for the contract call * @param gasToken The address of the ERC20 token used to pay for gas * @param gasFeeAmount The amount of tokens to pay for gas * @param refundAddress The address where refunds, if any, should be sent */ function payGasForContractCall( address sender, string calldata destinationChain, string calldata destinationAddress, bytes calldata payload, address gasToken, uint256 gasFeeAmount, address refundAddress ) external; /** * @notice Pay for gas using ERC20 tokens for a contract call with tokens on a destination chain. * @dev This function is called on the source chain before calling the gateway to execute a remote contract. * @param sender The address making the payment * @param destinationChain The target chain where the contract call with tokens will be made * @param destinationAddress The target address on the destination chain * @param payload Data payload for the contract call with tokens * @param symbol The symbol of the token to be sent with the call * @param amount The amount of tokens to be sent with the call * @param gasToken The address of the ERC20 token used to pay for gas * @param gasFeeAmount The amount of tokens to pay for gas * @param refundAddress The address where refunds, if any, should be sent */ function payGasForContractCallWithToken( address sender, string calldata destinationChain, string calldata destinationAddress, bytes calldata payload, string calldata symbol, uint256 amount, address gasToken, uint256 gasFeeAmount, address refundAddress ) external; /** * @notice Pay for gas using native currency for a contract call on a destination chain. * @dev This function is called on the source chain before calling the gateway to execute a remote contract. * @param sender The address making the payment * @param destinationChain The target chain where the contract call will be made * @param destinationAddress The target address on the destination chain * @param payload Data payload for the contract call * @param refundAddress The address where refunds, if any, should be sent */ function payNativeGasForContractCall( address sender, string calldata destinationChain, string calldata destinationAddress, bytes calldata payload, address refundAddress ) external payable; /** * @notice Pay for gas using native currency for a contract call with tokens on a destination chain. * @dev This function is called on the source chain before calling the gateway to execute a remote contract. * @param sender The address making the payment * @param destinationChain The target chain where the contract call with tokens will be made * @param destinationAddress The target address on the destination chain * @param payload Data payload for the contract call with tokens * @param symbol The symbol of the token to be sent with the call * @param amount The amount of tokens to be sent with the call * @param refundAddress The address where refunds, if any, should be sent */ function payNativeGasForContractCallWithToken( address sender, string calldata destinationChain, string calldata destinationAddress, bytes calldata payload, string calldata symbol, uint256 amount, address refundAddress ) external payable; /** * @notice Pay for gas using ERC20 tokens for an express contract call on a destination chain. * @dev This function is called on the source chain before calling the gateway to express execute a remote contract. * @param sender The address making the payment * @param destinationChain The target chain where the contract call will be made * @param destinationAddress The target address on the destination chain * @param payload Data payload for the contract call * @param gasToken The address of the ERC20 token used to pay for gas * @param gasFeeAmount The amount of tokens to pay for gas * @param refundAddress The address where refunds, if any, should be sent */ function payGasForExpressCall( address sender, string calldata destinationChain, string calldata destinationAddress, bytes calldata payload, address gasToken, uint256 gasFeeAmount, address refundAddress ) external; /** * @notice Pay for gas using ERC20 tokens for an express contract call with tokens on a destination chain. * @dev This function is called on the source chain before calling the gateway to express execute a remote contract. * @param sender The address making the payment * @param destinationChain The target chain where the contract call with tokens will be made * @param destinationAddress The target address on the destination chain * @param payload Data payload for the contract call with tokens * @param symbol The symbol of the token to be sent with the call * @param amount The amount of tokens to be sent with the call * @param gasToken The address of the ERC20 token used to pay for gas * @param gasFeeAmount The amount of tokens to pay for gas * @param refundAddress The address where refunds, if any, should be sent */ function payGasForExpressCallWithToken( address sender, string calldata destinationChain, string calldata destinationAddress, bytes calldata payload, string calldata symbol, uint256 amount, address gasToken, uint256 gasFeeAmount, address refundAddress ) external; /** * @notice Pay for gas using native currency for an express contract call on a destination chain. * @dev This function is called on the source chain before calling the gateway to express execute a remote contract. * @param sender The address making the payment * @param destinationChain The target chain where the contract call will be made * @param destinationAddress The target address on the destination chain * @param payload Data payload for the contract call * @param refundAddress The address where refunds, if any, should be sent */ function payNativeGasForExpressCall( address sender, string calldata destinationChain, string calldata destinationAddress, bytes calldata payload, address refundAddress ) external payable; /** * @notice Pay for gas using native currency for an express contract call with tokens on a destination chain. * @dev This function is called on the source chain before calling the gateway to express execute a remote contract. * @param sender The address making the payment * @param destinationChain The target chain where the contract call with tokens will be made * @param destinationAddress The target address on the destination chain * @param payload Data payload for the contract call with tokens * @param symbol The symbol of the token to be sent with the call * @param amount The amount of tokens to be sent with the call * @param refundAddress The address where refunds, if any, should be sent */ function payNativeGasForExpressCallWithToken( address sender, string calldata destinationChain, string calldata destinationAddress, bytes calldata payload, string calldata symbol, uint256 amount, address refundAddress ) external payable; /** * @notice Add additional gas payment using ERC20 tokens after initiating a cross-chain call. * @dev This function can be called on the source chain after calling the gateway to execute a remote contract. * @param txHash The transaction hash of the cross-chain call * @param logIndex The log index for the cross-chain call * @param gasToken The ERC20 token address used to add gas * @param gasFeeAmount The amount of tokens to add as gas * @param refundAddress The address where refunds, if any, should be sent */ function addGas( bytes32 txHash, uint256 logIndex, address gasToken, uint256 gasFeeAmount, address refundAddress ) external; /** * @notice Add additional gas payment using native currency after initiating a cross-chain call. * @dev This function can be called on the source chain after calling the gateway to execute a remote contract. * @param txHash The transaction hash of the cross-chain call * @param logIndex The log index for the cross-chain call * @param refundAddress The address where refunds, if any, should be sent */ function addNativeGas( bytes32 txHash, uint256 logIndex, address refundAddress ) external payable; /** * @notice Add additional gas payment using ERC20 tokens after initiating an express cross-chain call. * @dev This function can be called on the source chain after calling the gateway to express execute a remote contract. * @param txHash The transaction hash of the cross-chain call * @param logIndex The log index for the cross-chain call * @param gasToken The ERC20 token address used to add gas * @param gasFeeAmount The amount of tokens to add as gas * @param refundAddress The address where refunds, if any, should be sent */ function addExpressGas( bytes32 txHash, uint256 logIndex, address gasToken, uint256 gasFeeAmount, address refundAddress ) external; /** * @notice Add additional gas payment using native currency after initiating an express cross-chain call. * @dev This function can be called on the source chain after calling the gateway to express execute a remote contract. * @param txHash The transaction hash of the cross-chain call * @param logIndex The log index for the cross-chain call * @param refundAddress The address where refunds, if any, should be sent */ function addNativeExpressGas( bytes32 txHash, uint256 logIndex, address refundAddress ) external payable; /** * @notice Allows the gasCollector to collect accumulated fees from the contract. * @dev Use address(0) as the token address for native currency. * @param receiver The address to receive the collected fees * @param tokens Array of token addresses to be collected * @param amounts Array of amounts to be collected for each respective token address */ function collectFees( address payable receiver, address[] calldata tokens, uint256[] calldata amounts ) external; /** * @notice Refunds gas payment to the receiver in relation to a specific cross-chain transaction. * @dev Only callable by the gasCollector. * @dev Use address(0) as the token address to refund native currency. * @param txHash The transaction hash of the cross-chain call * @param logIndex The log index for the cross-chain call * @param receiver The address to receive the refund * @param token The token address to be refunded * @param amount The amount to refund */ function refund( bytes32 txHash, uint256 logIndex, address payable receiver, address token, uint256 amount ) external; /** * @notice Returns the address of the designated gas collector. * @return address of the gas collector */ function gasCollector() external returns (address); } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @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); } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @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); } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { error InvalidAccount(); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/libs/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; 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)); } } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @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; } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @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) } } } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @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 {} } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/libs/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; library StringStorage { struct Wrapper { string value; } function set(bytes32 slot, string memory value) internal { _getStorageStruct(slot).value = value; } function get(bytes32 slot) internal view returns (string memory value) { value = _getStorageStruct(slot).value; } function clear(bytes32 slot) internal { delete _getStorageStruct(slot).value; } function _getStorageStruct(bytes32 slot) internal pure returns (Wrapper storage wrapper) { assembly { wrapper.slot := slot } } } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title InterchainAddressTracker * @dev Manages and validates trusted interchain addresses of an application. */ contract InterchainAddressTracker is IInterchainAddressTracker { bytes32 internal constant PREFIX_ADDRESS_MAPPING = keccak256('interchain-address-tracker-address-mapping'); bytes32 internal constant PREFIX_ADDRESS_HASH_MAPPING = keccak256('interchain-address-tracker-address-hash-mapping'); // bytes32(uint256(keccak256('interchain-address-tracker-chain-name')) - 1) bytes32 internal constant _CHAIN_NAME_SLOT = 0x0e2c162a1f4b5cff9fdbd6b34678a9bcb9898a0b9fbca695b112d61688d8b2ac; function _setChainName(string memory chainName_) internal { StringStorage.set(_CHAIN_NAME_SLOT, chainName_); } /** * @dev Gets the name of the chain this is deployed at */ function chainName() external view returns (string memory chainName_) { chainName_ = StringStorage.get(_CHAIN_NAME_SLOT); } /** * @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) public view returns (string memory trustedAddress_) { trustedAddress_ = StringStorage.get(_getTrustedAddressSlot(chain)); } /** * @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) public view returns (bytes32 trustedAddressHash_) { bytes32 slot = _getTrustedAddressHashSlot(chain); assembly { trustedAddressHash_ := sload(slot) } } /** * @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_) public view returns (bool) { bytes32 addressHash = keccak256(bytes(address_)); return addressHash == trustedAddressHash(chain); } /** * @dev Gets the key for the trusted address at a remote chain * @param chain Chain name of the remote chain * @return slot the slot to store the trusted address in */ function _getTrustedAddressSlot(string memory chain) internal pure returns (bytes32 slot) { slot = keccak256(abi.encode(PREFIX_ADDRESS_MAPPING, chain)); } /** * @dev Gets the key for the trusted address at a remote chain * @param chain Chain name of the remote chain * @return slot the slot to store the trusted address hash in */ function _getTrustedAddressHashSlot(string memory chain) internal pure returns (bytes32 slot) { slot = keccak256(abi.encode(PREFIX_ADDRESS_HASH_MAPPING, chain)); } /** * @dev Sets the trusted address and its hash for a remote chain * @param chain Chain name of the remote chain * @param address_ the string representation of the trusted address */ function _setTrustedAddress(string memory chain, string memory address_) internal { if (bytes(chain).length == 0) revert ZeroStringLength(); if (bytes(address_).length == 0) revert ZeroStringLength(); StringStorage.set(_getTrustedAddressSlot(chain), address_); bytes32 slot = _getTrustedAddressHashSlot(chain); bytes32 addressHash = keccak256(bytes(address_)); assembly { sstore(slot, addressHash) } emit TrustedAddressSet(chain, address_); } /** * @dev Remove the trusted address of the chain. * @param chain Chain name that should be made untrusted */ function _removeTrustedAddress(string memory chain) internal { if (bytes(chain).length == 0) revert ZeroStringLength(); StringStorage.clear(_getTrustedAddressSlot(chain)); bytes32 slot = _getTrustedAddressHashSlot(chain); assembly { sstore(slot, 0) } emit TrustedAddressRemoved(chain); } } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: 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); } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @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; } } } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: 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); } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/utils/[email protected] // Original license: 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. */ contract Pausable is IPausable { // uint256(keccak256('paused')) - 1 uint256 internal constant PAUSE_SLOT = 0xee35723ac350a69d2a92d3703f17439cbaadf2f093a21ba5bf5f1a53eb2a14d8; /** * @notice A modifier that throws a Paused custom error if the contract is paused * @dev This modifier should be used with functions that can be paused */ modifier whenNotPaused() { if (paused()) revert Pause(); _; } modifier whenPaused() { if (!paused()) revert NotPaused(); _; } /** * @notice Check if the contract is paused * @return paused_ A boolean representing the pause status. True if paused, false otherwise. */ function paused() public view returns (bool paused_) { assembly { paused_ := sload(PAUSE_SLOT) } } /** * @notice Pauses the contract * @dev This function should be callable by the owner/governance. */ function _pause() internal { _setPaused(true); emit Paused(msg.sender); } /** * @notice Unpauses the contract * @dev This function should be callable by the owner/governance. */ function _unpause() internal { _setPaused(false); emit Unpaused(msg.sender); } /** * @notice Sets the pause status of the contract * @dev This is an internal function, meaning it can only be called from within the contract itself * or from derived contracts. * @param paused_ The new pause status */ function _setPaused(bool paused_) internal { assembly { sstore(PAUSE_SLOT, paused_) } } } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title IRolesBase Interface * @notice IRolesBase is an interface that abstracts the implementation of a * contract with role control internal functions. */ interface IRolesBase { error MissingRole(address account, uint8 role); error MissingAllRoles(address account, uint256 accountRoles); error MissingAnyOfRoles(address account, uint256 accountRoles); error InvalidProposedRoles(address fromAccount, address toAccount, uint256 accountRoles); event RolesProposed(address indexed fromAccount, address indexed toAccount, uint256 accountRoles); event RolesAdded(address indexed account, uint256 accountRoles); event RolesRemoved(address indexed account, uint256 accountRoles); /** * @notice Checks if an account has a role. * @param account The address to check * @param role The role to check * @return True if the account has the role, false otherwise */ function hasRole(address account, uint8 role) external view returns (bool); } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title RolesBase * @notice A contract module which provides a set if internal functions * for implementing role control features. */ contract RolesBase is IRolesBase { bytes32 internal constant ROLES_PREFIX = keccak256('roles'); bytes32 internal constant PROPOSE_ROLES_PREFIX = keccak256('propose-roles'); /** * @notice Modifier that throws an error if called by any account missing the role. */ modifier onlyRole(uint8 role) { if (!_hasRole(_getRoles(msg.sender), role)) revert MissingRole(msg.sender, role); _; } /** * @notice Modifier that throws an error if called by an account without all the roles. */ modifier withEveryRole(uint8[] memory roles) { uint256 accountRoles = _toAccountRoles(roles); if (!_hasAllTheRoles(_getRoles(msg.sender), accountRoles)) revert MissingAllRoles(msg.sender, accountRoles); _; } /** * @notice Modifier that throws an error if called by an account without any of the roles. */ modifier withAnyRole(uint8[] memory roles) { uint256 accountRoles = _toAccountRoles(roles); if (!_hasAnyOfRoles(_getRoles(msg.sender), accountRoles)) revert MissingAnyOfRoles(msg.sender, accountRoles); _; } /** * @notice Checks if an account has a role. * @param account The address to check * @param role The role to check * @return True if the account has the role, false otherwise */ function hasRole(address account, uint8 role) public view returns (bool) { return _hasRole(_getRoles(account), role); } /** * @notice Internal function to convert an array of roles to a uint256. * @param roles The roles to convert * @return accountRoles The roles in uint256 format */ function _toAccountRoles(uint8[] memory roles) internal pure returns (uint256) { uint256 length = roles.length; uint256 accountRoles; for (uint256 i = 0; i < length; ++i) { accountRoles |= (1 << roles[i]); } return accountRoles; } /** * @notice Internal function to get the key of the roles mapping. * @param account The address to get the key for * @return key The key of the roles mapping */ function _rolesKey(address account) internal view virtual returns (bytes32 key) { return keccak256(abi.encodePacked(ROLES_PREFIX, account)); } /** * @notice Internal function to get the roles of an account. * @param account The address to get the roles for * @return accountRoles The roles of the account in uint256 format */ function _getRoles(address account) internal view returns (uint256 accountRoles) { bytes32 key = _rolesKey(account); assembly { accountRoles := sload(key) } } /** * @notice Internal function to set the roles of an account. * @param account The address to set the roles for * @param accountRoles The roles to set */ function _setRoles(address account, uint256 accountRoles) private { bytes32 key = _rolesKey(account); assembly { sstore(key, accountRoles) } } /** * @notice Internal function to get the key of the proposed roles mapping. * @param fromAccount The address of the current role * @param toAccount The address of the pending role * @return key The key of the proposed roles mapping */ function _proposalKey(address fromAccount, address toAccount) internal view virtual returns (bytes32 key) { return keccak256(abi.encodePacked(PROPOSE_ROLES_PREFIX, fromAccount, toAccount)); } /** * @notice Internal function to get the proposed roles of an account. * @param fromAccount The address of the current role * @param toAccount The address of the pending role * @return proposedRoles_ The proposed roles of the account in uint256 format */ function _getProposedRoles(address fromAccount, address toAccount) internal view returns (uint256 proposedRoles_) { bytes32 key = _proposalKey(fromAccount, toAccount); assembly { proposedRoles_ := sload(key) } } /** * @notice Internal function to set the proposed roles of an account. * @param fromAccount The address of the current role * @param toAccount The address of the pending role * @param proposedRoles_ The proposed roles to set in uint256 format */ function _setProposedRoles( address fromAccount, address toAccount, uint256 proposedRoles_ ) private { bytes32 key = _proposalKey(fromAccount, toAccount); assembly { sstore(key, proposedRoles_) } } /** * @notice Internal function to add a role to an account. * @dev emits a RolesAdded event. * @param account The address to add the role to * @param role The role to add */ function _addRole(address account, uint8 role) internal { _addAccountRoles(account, 1 << role); } /** * @notice Internal function to add roles to an account. * @dev emits a RolesAdded event. * @dev Called in the constructor to set the initial roles. * @param account The address to add roles to * @param roles The roles to add */ function _addRoles(address account, uint8[] memory roles) internal { _addAccountRoles(account, _toAccountRoles(roles)); } /** * @notice Internal function to add roles to an account. * @dev emits a RolesAdded event. * @dev Called in the constructor to set the initial roles. * @param account The address to add roles to * @param accountRoles The roles to add */ function _addAccountRoles(address account, uint256 accountRoles) internal { uint256 newAccountRoles = _getRoles(account) | accountRoles; _setRoles(account, newAccountRoles); emit RolesAdded(account, accountRoles); } /** * @notice Internal function to remove a role from an account. * @dev emits a RolesRemoved event. * @param account The address to remove the role from * @param role The role to remove */ function _removeRole(address account, uint8 role) internal { _removeAccountRoles(account, 1 << role); } /** * @notice Internal function to remove roles from an account. * @dev emits a RolesRemoved event. * @param account The address to remove roles from * @param roles The roles to remove */ function _removeRoles(address account, uint8[] memory roles) internal { _removeAccountRoles(account, _toAccountRoles(roles)); } /** * @notice Internal function to remove roles from an account. * @dev emits a RolesRemoved event. * @param account The address to remove roles from * @param accountRoles The roles to remove */ function _removeAccountRoles(address account, uint256 accountRoles) internal { uint256 newAccountRoles = _getRoles(account) & ~accountRoles; _setRoles(account, newAccountRoles); emit RolesRemoved(account, accountRoles); } /** * @notice Internal function to check if an account has a role. * @param accountRoles The roles of the account in uint256 format * @param role The role to check * @return True if the account has the role, false otherwise */ function _hasRole(uint256 accountRoles, uint8 role) internal pure returns (bool) { return accountRoles & (1 << role) != 0; } /** * @notice Internal function to check if an account has all the roles. * @param hasAccountRoles The roles of the account in uint256 format * @param mustHaveAccountRoles The roles the account must have * @return True if the account has all the roles, false otherwise */ function _hasAllTheRoles(uint256 hasAccountRoles, uint256 mustHaveAccountRoles) internal pure returns (bool) { return (hasAccountRoles & mustHaveAccountRoles) == mustHaveAccountRoles; } /** * @notice Internal function to check if an account has any of the roles. * @param hasAccountRoles The roles of the account in uint256 format * @param mustHaveAnyAccountRoles The roles to check in uint256 format * @return True if the account has any of the roles, false otherwise */ function _hasAnyOfRoles(uint256 hasAccountRoles, uint256 mustHaveAnyAccountRoles) internal pure returns (bool) { return (hasAccountRoles & mustHaveAnyAccountRoles) != 0; } /** * @notice Internal function to propose to transfer roles of message sender to a new account. * @dev Original account must have all the proposed roles. * @dev Emits a RolesProposed event. * @dev Roles are not transferred until the new role accepts the role transfer. * @param fromAccount The address of the current roles * @param toAccount The address to transfer roles to * @param role The role to transfer */ function _proposeRole( address fromAccount, address toAccount, uint8 role ) internal { _proposeAccountRoles(fromAccount, toAccount, 1 << role); } /** * @notice Internal function to propose to transfer roles of message sender to a new account. * @dev Original account must have all the proposed roles. * @dev Emits a RolesProposed event. * @dev Roles are not transferred until the new role accepts the role transfer. * @param fromAccount The address of the current roles * @param toAccount The address to transfer roles to * @param roles The roles to transfer */ function _proposeRoles( address fromAccount, address toAccount, uint8[] memory roles ) internal { _proposeAccountRoles(fromAccount, toAccount, _toAccountRoles(roles)); } /** * @notice Internal function to propose to transfer roles of message sender to a new account. * @dev Original account must have all the proposed roles. * @dev Emits a RolesProposed event. * @dev Roles are not transferred until the new role accepts the role transfer. * @param fromAccount The address of the current roles * @param toAccount The address to transfer roles to * @param accountRoles The account roles to transfer */ function _proposeAccountRoles( address fromAccount, address toAccount, uint256 accountRoles ) internal { if (!_hasAllTheRoles(_getRoles(fromAccount), accountRoles)) revert MissingAllRoles(fromAccount, accountRoles); _setProposedRoles(fromAccount, toAccount, accountRoles); emit RolesProposed(fromAccount, toAccount, accountRoles); } /** * @notice Internal function to accept roles transferred from another account. * @dev Pending account needs to pass all the proposed roles. * @dev Emits RolesRemoved and RolesAdded events. * @param fromAccount The address of the current role * @param role The role to accept */ function _acceptRole( address fromAccount, address toAccount, uint8 role ) internal virtual { _acceptAccountRoles(fromAccount, toAccount, 1 << role); } /** * @notice Internal function to accept roles transferred from another account. * @dev Pending account needs to pass all the proposed roles. * @dev Emits RolesRemoved and RolesAdded events. * @param fromAccount The address of the current role * @param roles The roles to accept */ function _acceptRoles( address fromAccount, address toAccount, uint8[] memory roles ) internal virtual { _acceptAccountRoles(fromAccount, toAccount, _toAccountRoles(roles)); } /** * @notice Internal function to accept roles transferred from another account. * @dev Pending account needs to pass all the proposed roles. * @dev Emits RolesRemoved and RolesAdded events. * @param fromAccount The address of the current role * @param accountRoles The account roles to accept */ function _acceptAccountRoles( address fromAccount, address toAccount, uint256 accountRoles ) internal virtual { if (_getProposedRoles(fromAccount, toAccount) != accountRoles) { revert InvalidProposedRoles(fromAccount, toAccount, accountRoles); } _setProposedRoles(fromAccount, toAccount, 0); _transferAccountRoles(fromAccount, toAccount, accountRoles); } /** * @notice Internal function to transfer roles from one account to another. * @dev Original account must have all the proposed roles. * @param fromAccount The address of the current role * @param toAccount The address to transfer role to * @param role The role to transfer */ function _transferRole( address fromAccount, address toAccount, uint8 role ) internal { _transferAccountRoles(fromAccount, toAccount, 1 << role); } /** * @notice Internal function to transfer roles from one account to another. * @dev Original account must have all the proposed roles. * @param fromAccount The address of the current role * @param toAccount The address to transfer role to * @param roles The roles to transfer */ function _transferRoles( address fromAccount, address toAccount, uint8[] memory roles ) internal { _transferAccountRoles(fromAccount, toAccount, _toAccountRoles(roles)); } /** * @notice Internal function to transfer roles from one account to another. * @dev Original account must have all the proposed roles. * @param fromAccount The address of the current role * @param toAccount The address to transfer role to * @param accountRoles The account roles to transfer */ function _transferAccountRoles( address fromAccount, address toAccount, uint256 accountRoles ) internal { if (!_hasAllTheRoles(_getRoles(fromAccount), accountRoles)) revert MissingAllRoles(fromAccount, accountRoles); _removeAccountRoles(fromAccount, accountRoles); _addAccountRoles(toAccount, accountRoles); } } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/libs/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title AddressBytesUtils * @dev This library provides utility functions to convert between `address` and `bytes`. */ library AddressBytes { error InvalidBytesLength(bytes bytesAddress); /** * @dev Converts a bytes address to an address type. * @param bytesAddress The bytes representation of an address * @return addr The converted address */ function toAddress(bytes memory bytesAddress) internal pure returns (address addr) { if (bytesAddress.length != 20) revert InvalidBytesLength(bytesAddress); assembly { addr := mload(add(bytesAddress, 20)) } } /** * @dev Converts an address to bytes. * @param addr The address to be converted * @return bytesAddress The bytes representation of the address */ function toBytes(address addr) internal pure returns (bytes memory bytesAddress) { bytesAddress = new bytes(20); // we can test if using a single 32 byte variable that is the address with the length together and using one mstore would be slightly cheaper. assembly { mstore(add(bytesAddress, 20), addr) mstore(bytesAddress, 20) } } } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/libs/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; library StringToBytes32 { error InvalidStringLength(); function toBytes32(string memory str) internal pure returns (bytes32) { // Converting a string to bytes32 for immutable storage bytes memory stringBytes = bytes(str); // We can store up to 31 bytes of data as 1 byte is for encoding length if (stringBytes.length == 0 || stringBytes.length > 31) revert InvalidStringLength(); uint256 stringNumber = uint256(bytes32(stringBytes)); // Storing string length as the last byte of the data stringNumber |= 0xff & stringBytes.length; return bytes32(stringNumber); } } library Bytes32ToString { function toTrimmedString(bytes32 stringData) internal pure returns (string memory converted) { // recovering string length as the last byte of the data uint256 length = 0xff & uint256(stringData); // restoring the string with the correct length assembly { converted := mload(0x40) // new "memory end" including padding (the string isn't larger than 32 bytes) mstore(0x40, add(converted, 0x40)) // store length in memory mstore(converted, length) // write actual data mstore(add(converted, 0x20), stringData) } } } // File contracts/interfaces/IInterchainTokenDeployer.sol // Original license: 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); } // File contracts/interfaces/IInterchainTokenExecutable.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title IInterchainTokenExecutable * @notice Contracts should implement this interface to accept calls from the InterchainTokenService. */ interface IInterchainTokenExecutable { /** * @notice This will be called after the tokens are sent to this contract. * @dev Execution should revert unless the msg.sender is the InterchainTokenService * @param commandId The unique message id for the call. * @param sourceChain The name of the source chain. * @param sourceAddress The address that sent the contract call. * @param data The data to be processed. * @param tokenId The tokenId of the token manager managing the token. * @param token The address of the token. * @param amount The amount of tokens that were sent. * @return bytes32 Hash indicating success of the execution. */ function executeWithInterchainToken( bytes32 commandId, string calldata sourceChain, bytes calldata sourceAddress, bytes calldata data, bytes32 tokenId, address token, uint256 amount ) external returns (bytes32); } // File contracts/interfaces/IInterchainTokenExpressExecutable.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title IInterchainTokenExpressExecutable * @notice Contracts should implement this interface to accept express calls from the InterchainTokenService. */ interface IInterchainTokenExpressExecutable is IInterchainTokenExecutable { /** * @notice Executes express logic in the context of an interchain token transfer. * @dev Only callable by the interchain token service. * @param commandId The unique message id for the call. * @param sourceChain The source chain of the token transfer. * @param sourceAddress The source address of the token transfer. * @param data The data associated with the token transfer. * @param tokenId The token ID. * @param token The token address. * @param amount The amount of tokens to be transferred. * @return bytes32 Hash indicating success of the express execution. */ function expressExecuteWithInterchainToken( bytes32 commandId, string calldata sourceChain, bytes calldata sourceAddress, bytes calldata data, bytes32 tokenId, address token, uint256 amount ) external returns (bytes32); } // File contracts/interfaces/IAddressTracker.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @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; } // File contracts/interfaces/IOperator.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @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); } // File contracts/interfaces/ITokenManagerImplementation.sol // Original license: 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_); } // File contracts/interfaces/ITokenManagerType.sol // Original license: 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 { NATIVE_INTERCHAIN_TOKEN, // This type is reserved for interchain tokens deployed by ITS, and can't be used by custom token managers. MINT_BURN_FROM, // The token will be minted/burned on transfers. The token needs to give mint permission to the token manager, but burning happens via an approval. LOCK_UNLOCK, // The token will be locked/unlocked at the token manager. LOCK_UNLOCK_FEE, // The token will be locked/unlocked at the token manager, which will account for any fee-on-transfer behaviour. MINT_BURN // The token will be minted/burned on transfers. The token needs to give mint and burn permission to the token manager. } } // File contracts/interfaces/ITransmitInterchainToken.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title ITransmitInterchainToken Interface * @notice Interface for transmiting interchain tokens via the interchain token service */ interface ITransmitInterchainToken { /** * @notice Transmit an interchain transfer for the given tokenId. * @dev Only callable by a token registered under a tokenId. * @param tokenId The tokenId of the token (which must be the msg.sender). * @param sourceAddress The address where the token is coming from. * @param destinationChain The name of the chain to send tokens to. * @param destinationAddress The destinationAddress for the interchainTransfer. * @param amount The amount of token to give. * @param metadata Optional metadata for the call for additional effects (such as calling a destination contract). */ function transmitInterchainTransfer( bytes32 tokenId, address sourceAddress, string calldata destinationChain, bytes memory destinationAddress, uint256 amount, bytes calldata metadata ) external payable; } // File contracts/interfaces/IInterchainTokenService.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @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(); error CannotDeploy(TokenManagerType); 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. Cannot be NATIVE_INTERCHAIN_TOKEN. * @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; } // File contracts/interfaces/ITokenHandler.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title ITokenHandler Interface * @notice This interface is responsible for handling tokens before initiating an interchain token transfer, or after receiving one. */ interface ITokenHandler { error UnsupportedTokenManagerType(uint256 tokenManagerType); /** * @notice This function gives token to a specified address from the token manager. * @param tokenManagerType The token manager type. * @param tokenAddress The address of the token to give. * @param tokenManager The address of the token manager. * @param to The address to give tokens to. * @param amount The amount of tokens to give. * @return uint256 The amount of token actually given, which could be different for certain token type. */ function giveToken( uint256 tokenManagerType, address tokenAddress, address tokenManager, address to, uint256 amount ) external payable returns (uint256); /** * @notice This function takes token from a specified address to the token manager. * @param tokenManagerType The token manager type. * @param tokenAddress The address of the token to give. * @param tokenManager The address of the token manager. * @param from The address to take tokens from. * @param amount The amount of token to take. * @return uint256 The amount of token actually taken, which could be different for certain token type. */ function takeToken( uint256 tokenManagerType, address tokenAddress, address tokenManager, address from, uint256 amount ) external payable returns (uint256); /** * @notice This function transfers token from and to a specified address. * @param tokenManagerType The token manager type. * @param tokenAddress the address of the token to give. * @param from The address to transfer tokens from. * @param to The address to transfer tokens to. * @param amount The amount of token to transfer. * @return uint256 The amount of token actually transferred, which could be different for certain token type. */ function transferTokenFrom( uint256 tokenManagerType, address tokenAddress, address from, address to, uint256 amount ) external payable returns (uint256); } // File contracts/interfaces/IBaseTokenManager.sol // Original license: 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); } // File contracts/interfaces/IFlowLimit.sol // Original license: 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_); } // File contracts/interfaces/ITokenManager.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @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_); /** * @notice External function to allow the service to mint tokens through the tokenManager * @dev This function should revert if called by anyone but the service. * @param tokenAddress_ The address of the token, since its cheaper to pass it in instead of reading it as the token manager. * @param to The recipient. * @param amount The amount to mint. */ function mintToken(address tokenAddress_, address to, uint256 amount) external; /** * @notice External function to allow the service to burn tokens through the tokenManager * @dev This function should revert if called by anyone but the service. * @param tokenAddress_ The address of the token, since its cheaper to pass it in instead of reading it as the token manager. * @param from The address to burn the token from. * @param amount The amount to burn. */ function burnToken(address tokenAddress_, address from, uint256 amount) external; } // File contracts/interfaces/ITokenManagerDeployer.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title ITokenManagerDeployer Interface * @notice This interface is used to deploy new instances of the TokenManagerProxy contract. */ interface ITokenManagerDeployer { error AddressZero(); error TokenManagerDeploymentFailed(); /** * @notice Deploys a new instance of the TokenManagerProxy contract. * @param tokenId The token ID. * @param implementationType Token manager implementation type. * @param params Additional parameters used in the setup of the token manager. * @return tokenManager Address of the deployed tokenManager. */ function deployTokenManager( bytes32 tokenId, uint256 implementationType, bytes calldata params ) external payable returns (address tokenManager); } // File @axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; // General interface for upgradable contracts interface IProxy { error InvalidOwner(); error InvalidImplementation(); error SetupFailed(); error NotOwner(); error AlreadyInitialized(); function implementation() external view returns (address); function setup(bytes calldata setupParams) external; } // File contracts/interfaces/ITokenManagerProxy.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title ITokenManagerProxy Interface * @notice This interface is for a proxy for token manager contracts. */ interface ITokenManagerProxy is IProxy { error ZeroAddress(); /** * @notice Returns implementation type of this token manager. * @return uint256 The implementation type of this token manager. */ function implementationType() external view returns (uint256); /** * @notice Returns the interchain token ID of the token manager. * @return bytes32 The interchain token ID of the token manager. */ function interchainTokenId() external view returns (bytes32); /** * @notice Returns token address that this token manager manages. * @return address The token address. */ function tokenAddress() external view returns (address); /** * @notice Returns implementation type and token address. * @return uint256 The implementation type. * @return address The token address. */ function getImplementationTypeAndTokenAddress() external view returns (uint256, address); } // File contracts/utils/RolesConstants.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title RolesConstants * @notice This contract contains enum values representing different contract roles. */ contract RolesConstants { enum Roles { MINTER, OPERATOR, FLOW_LIMITER } } // File contracts/utils/Operator.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title Operator Contract * @notice 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. * @dev This module is used through inheritance. */ contract Operator is IOperator, RolesBase, RolesConstants { /** * @notice Internal function that stores the new operator address in the correct storage slot * @param operator The address of the new operator */ function _addOperator(address operator) internal { _addRole(operator, uint8(Roles.OPERATOR)); } /** * @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 onlyRole(uint8(Roles.OPERATOR)) { _transferRole(msg.sender, operator, uint8(Roles.OPERATOR)); } /** * @notice Propose 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 onlyRole(uint8(Roles.OPERATOR)) { _proposeRole(msg.sender, operator, uint8(Roles.OPERATOR)); } /** * @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 { _acceptRole(fromOperator, msg.sender, uint8(Roles.OPERATOR)); } /** * @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) { return hasRole(addr, uint8(Roles.OPERATOR)); } } // File contracts/InterchainTokenService.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title The Interchain Token Service * @notice This contract is responsible for facilitating interchain token transfers. * It (mostly) does not handle tokens, but is responsible for the messaging that needs to occur for interchain transfers to happen. * @dev The only storage used in this contract is for Express calls. * Furthermore, no ether is intended to or should be sent to this contract except as part of deploy/interchainTransfer payable methods for gas payment. */ contract InterchainTokenService is Upgradable, Operator, Pausable, Multicall, Create3Address, ExpressExecutorTracker, InterchainAddressTracker, IInterchainTokenService { using StringToBytes32 for string; using Bytes32ToString for bytes32; using AddressBytes for bytes; using AddressBytes for address; using SafeTokenTransferFrom for IERC20; IAxelarGateway public immutable gateway; IAxelarGasService public immutable gasService; address public immutable interchainTokenFactory; bytes32 public immutable chainNameHash; address public immutable interchainTokenDeployer; address public immutable tokenManagerDeployer; /** * @dev Token manager implementation addresses */ address public immutable tokenManager; address public immutable tokenHandler; bytes32 internal constant PREFIX_INTERCHAIN_TOKEN_ID = keccak256('its-interchain-token-id'); bytes32 internal constant PREFIX_INTERCHAIN_TOKEN_SALT = keccak256('its-interchain-token-salt'); bytes32 private constant CONTRACT_ID = keccak256('interchain-token-service'); bytes32 private constant EXECUTE_SUCCESS = keccak256('its-execute-success'); bytes32 private constant EXPRESS_EXECUTE_SUCCESS = keccak256('its-express-execute-success'); /** * @dev The message types that are sent between InterchainTokenService on different chains. */ uint256 private constant MESSAGE_TYPE_INTERCHAIN_TRANSFER = 0; uint256 private constant MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN = 1; uint256 private constant MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER = 2; /** * @dev Tokens and token managers deployed via the Token Factory contract use a special deployer address. * This removes the dependency on the address the token factory was deployed too to be able to derive the same tokenId. */ address internal constant TOKEN_FACTORY_DEPLOYER = address(0); /** * @dev Latest version of metadata that's supported. */ enum MetadataVersion { CONTRACT_CALL, EXPRESS_CALL } uint32 internal constant LATEST_METADATA_VERSION = 1; /** * @notice Constructor for the Interchain Token Service. * @dev All of the variables passed here are stored as immutable variables. * @param tokenManagerDeployer_ The address of the TokenManagerDeployer. * @param interchainTokenDeployer_ The address of the InterchainTokenDeployer. * @param gateway_ The address of the AxelarGateway. * @param gasService_ The address of the AxelarGasService. * @param interchainTokenFactory_ The address of the InterchainTokenFactory. * @param chainName_ The name of the chain that this contract is deployed on. * @param tokenManagerImplementation_ The tokenManager implementation. * @param tokenHandler_ The tokenHandler implementation. */ constructor( address tokenManagerDeployer_, address interchainTokenDeployer_, address gateway_, address gasService_, address interchainTokenFactory_, string memory chainName_, address tokenManagerImplementation_, address tokenHandler_ ) { if ( gasService_ == address(0) || tokenManagerDeployer_ == address(0) || interchainTokenDeployer_ == address(0) || gateway_ == address(0) || interchainTokenFactory_ == address(0) || tokenManagerImplementation_ == address(0) || tokenHandler_ == address(0) ) revert ZeroAddress(); gateway = IAxelarGateway(gateway_); gasService = IAxelarGasService(gasService_); tokenManagerDeployer = tokenManagerDeployer_; interchainTokenDeployer = interchainTokenDeployer_; interchainTokenFactory = interchainTokenFactory_; if (bytes(chainName_).length == 0) revert InvalidChainName(); chainNameHash = keccak256(bytes(chainName_)); tokenManager = tokenManagerImplementation_; tokenHandler = tokenHandler_; } /*******\ MODIFIERS \*******/ /** * @notice This modifier is used to ensure that only a remote InterchainTokenService can invoke the execute function. * @param sourceChain The source chain of the contract call. * @param sourceAddress The source address that the call came from. */ modifier onlyRemoteService(string calldata sourceChain, string calldata sourceAddress) { if (!isTrustedAddress(sourceChain, sourceAddress)) revert NotRemoteService(); _; } /*****\ GETTERS \*****/ /** * @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 address of a TokenManager from a specific tokenId. * @dev The TokenManager does not need to exist already. * @param tokenId The tokenId. * @return tokenManagerAddress_ The deployment address of the TokenManager. */ function tokenManagerAddress(bytes32 tokenId) public view returns (address tokenManagerAddress_) { tokenManagerAddress_ = _create3Address(tokenId); } /** * @notice Returns the address of a TokenManager from a specific tokenId. * @dev The TokenManager needs to exist already. * @param tokenId The tokenId. * @return tokenManagerAddress_ The deployment address of the TokenManager. */ function validTokenManagerAddress(bytes32 tokenId) public view returns (address tokenManagerAddress_) { tokenManagerAddress_ = tokenManagerAddress(tokenId); if (tokenManagerAddress_.code.length == 0) revert TokenManagerDoesNotExist(tokenId); } /** * @notice Returns the address of the token that an existing tokenManager points to. * @param tokenId The tokenId. * @return tokenAddress The address of the token. */ function validTokenAddress(bytes32 tokenId) public view returns (address tokenAddress) { address tokenManagerAddress_ = validTokenManagerAddress(tokenId); tokenAddress = ITokenManager(tokenManagerAddress_).tokenAddress(); } /** * @notice Returns the address of the interchain token associated with the given tokenId. * @dev The token does not need to exist. * @param tokenId The tokenId of the interchain token. * @return tokenAddress The address of the interchain token. */ function interchainTokenAddress(bytes32 tokenId) public view returns (address tokenAddress) { tokenId = _getInterchainTokenSalt(tokenId); tokenAddress = _create3Address(tokenId); } /** * @notice Calculates the tokenId that would correspond to a link for a given deployer with a specified salt. * @param sender The address of the TokenManager deployer. * @param salt The salt that the deployer uses for the deployment. * @return tokenId The tokenId that the custom TokenManager would get (or has gotten). */ function interchainTokenId(address sender, bytes32 salt) public pure returns (bytes32 tokenId) { tokenId = keccak256(abi.encode(PREFIX_INTERCHAIN_TOKEN_ID, sender, salt)); } /** * @notice Getter function for TokenManager implementation. This will mainly be called by TokenManager proxies * to figure out their implementations. * @return tokenManagerAddress The address of the TokenManager implementation. */ function tokenManagerImplementation(uint256 /*tokenManagerType*/) external view returns (address) { return tokenManager; } /** * @notice Getter function for the flow limit of an existing TokenManager with a given tokenId. * @param tokenId The tokenId of the TokenManager. * @return flowLimit_ The flow limit. */ function flowLimit(bytes32 tokenId) external view returns (uint256 flowLimit_) { ITokenManager tokenManager_ = ITokenManager(validTokenManagerAddress(tokenId)); flowLimit_ = tokenManager_.flowLimit(); } /** * @notice Getter function for the flow out amount of an existing TokenManager with a given tokenId. * @param tokenId The tokenId of the TokenManager. * @return flowOutAmount_ The flow out amount. */ function flowOutAmount(bytes32 tokenId) external view returns (uint256 flowOutAmount_) { ITokenManager tokenManager_ = ITokenManager(validTokenManagerAddress(tokenId)); flowOutAmount_ = tokenManager_.flowOutAmount(); } /** * @notice Getter function for the flow in amount of an existing TokenManager with a given tokenId. * @param tokenId The tokenId of the TokenManager. * @return flowInAmount_ The flow in amount. */ function flowInAmount(bytes32 tokenId) external view returns (uint256 flowInAmount_) { ITokenManager tokenManager_ = ITokenManager(validTokenManagerAddress(tokenId)); flowInAmount_ = tokenManager_.flowInAmount(); } /************\ USER FUNCTIONS \************/ /** * @notice Used to deploy remote custom TokenManagers. * @dev At least the `gasValue` amount of native token must be passed to the function call. `gasValue` exists because this function can be * part of a multicall involving multiple functions that could make remote contract calls. * @param salt The salt to be used during deployment. * @param destinationChain The name of the chain to deploy the TokenManager and standardized token to. * @param tokenManagerType The type of token manager to be deployed. Cannot be NATIVE_INTERCHAIN_TOKEN. * @param params The params that will be used to initialize the TokenManager. * @param gasValue The amount of native tokens to be used to pay for gas for the remote deployment. * @return tokenId The tokenId corresponding to the deployed TokenManager. */ function deployTokenManager( bytes32 salt, string calldata destinationChain, TokenManagerType tokenManagerType, bytes calldata params, uint256 gasValue ) external payable whenNotPaused returns (bytes32 tokenId) { // Custom token managers can't be deployed with Interchain token mint burn type, which is reserved for interchain tokens if (tokenManagerType == TokenManagerType.NATIVE_INTERCHAIN_TOKEN) revert CannotDeploy(tokenManagerType); address deployer = msg.sender; if (deployer == interchainTokenFactory) { deployer = TOKEN_FACTORY_DEPLOYER; } tokenId = interchainTokenId(deployer, salt); emit InterchainTokenIdClaimed(tokenId, deployer, salt); if (bytes(destinationChain).length == 0) { _deployTokenManager(tokenId, tokenManagerType, params); } else { _deployRemoteTokenManager(tokenId, destinationChain, gasValue, tokenManagerType, params); } } /** * @notice Used to deploy an interchain token alongside a TokenManager in another chain. * @dev At least the `gasValue` amount of native token must be passed to the function call. `gasValue` exists because this function can be * part of a multicall involving multiple functions that could make remote contract calls. If the `minter` parameter is empty bytes then * a mint/burn TokenManager is used, otherwise a lock/unlock TokenManager is used. * @param salt The salt to be used during deployment. * @param destinationChain The name of the destination chain to deploy to. * @param name The name of the token to be deployed. * @param symbol The symbol of the token to be deployed. * @param decimals The decimals of the token to be deployed. * @param minter The address that will be able to mint and burn the deployed token. * @param gasValue The amount of native tokens to be used to pay for gas for the remote 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 whenNotPaused returns (bytes32 tokenId) { address deployer = msg.sender; if (deployer == interchainTokenFactory) deployer = TOKEN_FACTORY_DEPLOYER; tokenId = interchainTokenId(deployer, salt); if (bytes(destinationChain).length == 0) { address tokenAddress = _deployInterchainToken(tokenId, minter, name, symbol, decimals); _deployTokenManager(tokenId, TokenManagerType.NATIVE_INTERCHAIN_TOKEN, abi.encode(minter, tokenAddress)); } else { _deployRemoteInterchainToken(tokenId, name, symbol, decimals, minter, destinationChain, gasValue); } } /** * @notice Returns the amount of token that this call is worth. * @dev If `tokenAddress` is `0`, then value is in terms of the native token, otherwise it's in terms of the token address. * @param sourceChain The source chain. * @param sourceAddress The source address on the source chain. * @param payload The payload sent with the call. * @return address The token address. * @return uint256 The value the call is worth. */ function contractCallValue( string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) public view virtual onlyRemoteService(sourceChain, sourceAddress) whenNotPaused returns (address, uint256) { (uint256 messageType, bytes32 tokenId, , uint256 amount) = abi.decode(payload, (uint256, bytes32, bytes, uint256)); if (messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER) { revert InvalidExpressMessageType(messageType); } return (validTokenAddress(tokenId), amount); } /** * @notice Express executes operations based on the payload and selector. * @param commandId The unique message id. * @param sourceChain The chain where the transaction originates from. * @param sourceAddress The address of the remote ITS where the transaction originates from. * @param payload The encoded data payload for the transaction. */ function expressExecute( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external payable whenNotPaused { uint256 messageType = abi.decode(payload, (uint256)); if (messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER) { revert InvalidExpressMessageType(messageType); } if (gateway.isCommandExecuted(commandId)) revert AlreadyExecuted(); address expressExecutor = msg.sender; bytes32 payloadHash = keccak256(payload); emit ExpressExecuted(commandId, sourceChain, sourceAddress, payloadHash, expressExecutor); _setExpressExecutor(commandId, sourceChain, sourceAddress, payloadHash, expressExecutor); _expressExecute(commandId, sourceChain, payload); } /** * @notice Uses the caller's tokens to fullfill a sendCall ahead of time. Use this only if you have detected an outgoing * interchainTransfer that matches the parameters passed here. * @param commandId The unique message id of the transfer being expressed. * @param sourceChain the name of the chain where the interchainTransfer originated from. * @param payload the payload of the receive token */ function _expressExecute(bytes32 commandId, string calldata sourceChain, bytes calldata payload) internal { (, bytes32 tokenId, bytes memory sourceAddress, bytes memory destinationAddressBytes, uint256 amount, bytes memory data) = abi .decode(payload, (uint256, bytes32, bytes, bytes, uint256, bytes)); address destinationAddress = destinationAddressBytes.toAddress(); IERC20 token; { ITokenManager tokenManager_ = ITokenManager(tokenManagerAddress(tokenId)); token = IERC20(tokenManager_.tokenAddress()); (bool success, bytes memory returnData) = tokenHandler.delegatecall( abi.encodeWithSelector( ITokenHandler.transferTokenFrom.selector, tokenManager_.implementationType(), address(token), msg.sender, destinationAddress, amount ) ); if (!success) revert TokenHandlerFailed(returnData); amount = abi.decode(returnData, (uint256)); } // slither-disable-next-line reentrancy-events emit InterchainTransferReceived( commandId, tokenId, sourceChain, sourceAddress, destinationAddress, amount, data.length == 0 ? bytes32(0) : keccak256(data) ); if (data.length != 0) { bytes32 result = IInterchainTokenExpressExecutable(destinationAddress).expressExecuteWithInterchainToken( commandId, sourceChain, sourceAddress, data, tokenId, address(token), amount ); if (result != EXPRESS_EXECUTE_SUCCESS) revert ExpressExecuteWithInterchainTokenFailed(destinationAddress); } } /** * @notice Initiates an interchain transfer of a specified token to a destination chain. * @dev The function retrieves the TokenManager associated with the tokenId. * @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 whenNotPaused { amount = _takeToken(tokenId, msg.sender, amount, false); (MetadataVersion metadataVersion, bytes memory data) = _decodeMetadata(metadata); _transmitInterchainTransfer(tokenId, msg.sender, destinationChain, destinationAddress, amount, metadataVersion, data, gasValue); } /** * @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 memory data, uint256 gasValue ) external payable whenNotPaused { if (data.length == 0) revert EmptyData(); amount = _takeToken(tokenId, msg.sender, amount, false); _transmitInterchainTransfer( tokenId, msg.sender, destinationChain, destinationAddress, amount, MetadataVersion.CONTRACT_CALL, data, gasValue ); } /******************\ TOKEN ONLY FUNCTIONS \******************/ /** * @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 whenNotPaused { amount = _takeToken(tokenId, sourceAddress, amount, true); (MetadataVersion metadataVersion, bytes memory data) = _decodeMetadata(metadata); _transmitInterchainTransfer(tokenId, sourceAddress, destinationChain, destinationAddress, amount, metadataVersion, data, msg.value); } /*************\ OWNER FUNCTIONS \*************/ /** * @notice Used to set a flow limit for a token manager that has the service as its operator. * @param tokenIds An array of the tokenIds of the tokenManagers to set the flow limits of. * @param flowLimits The flowLimits to set. */ function setFlowLimits(bytes32[] calldata tokenIds, uint256[] calldata flowLimits) external onlyRole(uint8(Roles.OPERATOR)) { uint256 length = tokenIds.length; if (length != flowLimits.length) revert LengthMismatch(); for (uint256 i; i < length; ++i) { ITokenManager tokenManager_ = ITokenManager(validTokenManagerAddress(tokenIds[i])); // slither-disable-next-line calls-loop tokenManager_.setFlowLimit(flowLimits[i]); } } /** * @notice Used to set a trusted address for a chain. * @param chain The chain to set the trusted address of. * @param address_ The address to set as trusted. */ function setTrustedAddress(string memory chain, string memory address_) external onlyOwner { _setTrustedAddress(chain, address_); } /** * @notice Used to remove a trusted address for a chain. * @param chain The chain to set the trusted address of. */ function removeTrustedAddress(string memory chain) external onlyOwner { _removeTrustedAddress(chain); } /** * @notice Allows the owner to pause/unpause the token service. * @param paused Boolean value representing whether to pause or unpause. */ function setPauseStatus(bool paused) external onlyOwner { if (paused) { _pause(); } else { _unpause(); } } /****************\ INTERNAL FUNCTIONS \****************/ function _setup(bytes calldata params) internal override { (address operator, string memory chainName_, string[] memory trustedChainNames, string[] memory trustedAddresses) = abi.decode( params, (address, string, string[], string[]) ); uint256 length = trustedChainNames.length; if (operator == address(0)) revert ZeroAddress(); if (bytes(chainName_).length == 0 || keccak256(bytes(chainName_)) != chainNameHash) revert InvalidChainName(); if (length != trustedAddresses.length) revert LengthMismatch(); _addOperator(operator); _setChainName(chainName_); for (uint256 i; i < length; ++i) { _setTrustedAddress(trustedChainNames[i], trustedAddresses[i]); } } /** * @notice Executes operations based on the payload and selector. * @param commandId The unique message id. * @param sourceChain The chain where the transaction originates from. * @param sourceAddress The address of the remote ITS where the transaction originates from. * @param payload The encoded data payload for the transaction. */ function execute( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external onlyRemoteService(sourceChain, sourceAddress) whenNotPaused { bytes32 payloadHash = keccak256(payload); if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash)) revert NotApprovedByGateway(); uint256 messageType = abi.decode(payload, (uint256)); if (messageType == MESSAGE_TYPE_INTERCHAIN_TRANSFER) { address expressExecutor = _popExpressExecutor(commandId, sourceChain, sourceAddress, payloadHash); _processInterchainTransferPayload(commandId, expressExecutor, sourceChain, payload); if (expressExecutor != address(0)) { emit ExpressExecutionFulfilled(commandId, sourceChain, sourceAddress, payloadHash, expressExecutor); } } else if (messageType == MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER) { _processDeployTokenManagerPayload(payload); } else if (messageType == MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN) { _processDeployInterchainTokenPayload(payload); } else { revert InvalidMessageType(messageType); } } function contractCallWithTokenValue( string calldata /*sourceChain*/, string calldata /*sourceAddress*/, bytes calldata /*payload*/, string calldata /*symbol*/, uint256 /*amount*/ ) public view virtual returns (address, uint256) { revert ExecuteWithTokenNotSupported(); } function expressExecuteWithToken( bytes32 /*commandId*/, string calldata /*sourceChain*/, string calldata /*sourceAddress*/, bytes calldata /*payload*/, string calldata /*tokenSymbol*/, uint256 /*amount*/ ) external payable { revert ExecuteWithTokenNotSupported(); } function executeWithToken( bytes32 /*commandId*/, string calldata /*sourceChain*/, string calldata /*sourceAddress*/, bytes calldata /*payload*/, string calldata /*tokenSymbol*/, uint256 /*amount*/ ) external pure { revert ExecuteWithTokenNotSupported(); } /** * @notice Processes the payload data for a send token call. * @param commandId The unique message id. * @param expressExecutor The address of the express executor. Equals `address(0)` if it wasn't expressed. * @param sourceChain The chain where the transaction originates from. * @param payload The encoded data payload to be processed. */ function _processInterchainTransferPayload( bytes32 commandId, address expressExecutor, string calldata sourceChain, bytes calldata payload ) internal { bytes32 tokenId; bytes memory sourceAddress; address destinationAddress; uint256 amount; bytes memory data; { bytes memory destinationAddressBytes; (, tokenId, sourceAddress, destinationAddressBytes, amount, data) = abi.decode( payload, (uint256, bytes32, bytes, bytes, uint256, bytes) ); destinationAddress = destinationAddressBytes.toAddress(); } // Return token to the existing express caller if (expressExecutor != address(0)) { // slither-disable-next-line unused-return _giveToken(tokenId, expressExecutor, amount); return; } address tokenAddress; (amount, tokenAddress) = _giveToken(tokenId, destinationAddress, amount); // slither-disable-next-line reentrancy-events emit InterchainTransferReceived( commandId, tokenId, sourceChain, sourceAddress, destinationAddress, amount, data.length == 0 ? bytes32(0) : keccak256(data) ); if (data.length != 0) { bytes32 result = IInterchainTokenExecutable(destinationAddress).executeWithInterchainToken( commandId, sourceChain, sourceAddress, data, tokenId, tokenAddress, amount ); if (result != EXECUTE_SUCCESS) revert ExecuteWithInterchainTokenFailed(destinationAddress); } } /** * @notice Processes a deploy token manager payload. */ function _processDeployTokenManagerPayload(bytes calldata payload) internal { (, bytes32 tokenId, TokenManagerType tokenManagerType, bytes memory params) = abi.decode( payload, (uint256, bytes32, TokenManagerType, bytes) ); if (tokenManagerType == TokenManagerType.NATIVE_INTERCHAIN_TOKEN) revert CannotDeploy(tokenManagerType); _deployTokenManager(tokenId, tokenManagerType, params); } /** * @notice Processes a deploy interchain token manager payload. * @param payload The encoded data payload to be processed. */ function _processDeployInterchainTokenPayload(bytes calldata payload) internal { (, bytes32 tokenId, string memory name, string memory symbol, uint8 decimals, bytes memory minterBytes) = abi.decode( payload, (uint256, bytes32, string, string, uint8, bytes) ); address tokenAddress; tokenAddress = _deployInterchainToken(tokenId, minterBytes, name, symbol, decimals); _deployTokenManager(tokenId, TokenManagerType.NATIVE_INTERCHAIN_TOKEN, abi.encode(minterBytes, tokenAddress)); } /** * @notice Calls a contract on a specific destination chain with the given payload * @param destinationChain The target chain where the contract will be called. * @param payload The data payload for the transaction. * @param gasValue The amount of gas to be paid for the transaction. */ function _callContract( string calldata destinationChain, bytes memory payload, MetadataVersion metadataVersion, uint256 gasValue ) internal { string memory destinationAddress = trustedAddress(destinationChain); if (bytes(destinationAddress).length == 0) revert UntrustedChain(); if (gasValue > 0) { if (metadataVersion == MetadataVersion.CONTRACT_CALL) { gasService.payNativeGasForContractCall{ value: gasValue }( address(this), destinationChain, destinationAddress, payload, // solhint-disable-next-line avoid-tx-origin tx.origin ); } else if (metadataVersion == MetadataVersion.EXPRESS_CALL) { gasService.payNativeGasForExpressCall{ value: gasValue }( address(this), destinationChain, destinationAddress, payload, // solhint-disable-next-line avoid-tx-origin tx.origin ); } else { revert InvalidMetadataVersion(uint32(metadataVersion)); } } gateway.callContract(destinationChain, destinationAddress, payload); } /** * @notice Deploys a token manager on a destination chain. * @param tokenId The ID of the token. * @param destinationChain The chain where the token manager will be deployed. * @param gasValue The amount of gas to be paid for the transaction. * @param tokenManagerType The type of token manager to be deployed. * @param params Additional parameters for the token manager deployment. */ function _deployRemoteTokenManager( bytes32 tokenId, string calldata destinationChain, uint256 gasValue, TokenManagerType tokenManagerType, bytes memory params ) internal { // slither-disable-next-line unused-return validTokenManagerAddress(tokenId); emit TokenManagerDeploymentStarted(tokenId, destinationChain, tokenManagerType, params); bytes memory payload = abi.encode(MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER, tokenId, tokenManagerType, params); _callContract(destinationChain, payload, MetadataVersion.CONTRACT_CALL, gasValue); } /** * @notice Deploys an interchain token on a destination chain. * @param tokenId The ID of the token. * @param name The name of the token. * @param symbol The symbol of the token. * @param decimals The number of decimals of the token. * @param minter The minter address for the token. * @param destinationChain The destination chain where the token will be deployed. * @param gasValue The amount of gas to be paid for the transaction. */ function _deployRemoteInterchainToken( bytes32 tokenId, string memory name, string memory symbol, uint8 decimals, bytes memory minter, string calldata destinationChain, uint256 gasValue ) internal { // slither-disable-next-line unused-return validTokenManagerAddress(tokenId); // slither-disable-next-line reentrancy-events emit InterchainTokenDeploymentStarted(tokenId, name, symbol, decimals, minter, destinationChain); bytes memory payload = abi.encode(MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN, tokenId, name, symbol, decimals, minter); _callContract(destinationChain, payload, MetadataVersion.CONTRACT_CALL, gasValue); } /** * @notice Deploys a token manager. * @param tokenId The ID of the token. * @param tokenManagerType The type of the token manager to be deployed. * @param params Additional parameters for the token manager deployment. */ function _deployTokenManager(bytes32 tokenId, TokenManagerType tokenManagerType, bytes memory params) internal { (bool success, bytes memory returnData) = tokenManagerDeployer.delegatecall( abi.encodeWithSelector(ITokenManagerDeployer.deployTokenManager.selector, tokenId, tokenManagerType, params) ); if (!success) revert TokenManagerDeploymentFailed(returnData); address tokenManager_; assembly { tokenManager_ := mload(add(returnData, 0x20)) } if (tokenManagerType == TokenManagerType.LOCK_UNLOCK || tokenManagerType == TokenManagerType.LOCK_UNLOCK_FEE) { ITokenManager(tokenManager_).approveService(); } // slither-disable-next-line reentrancy-events emit TokenManagerDeployed(tokenId, tokenManager_, tokenManagerType, params); } /** * @notice Computes the salt for an interchain token deployment. * @param tokenId The ID of the token. * @return salt The computed salt for the token deployment. */ function _getInterchainTokenSalt(bytes32 tokenId) internal pure returns (bytes32 salt) { return keccak256(abi.encode(PREFIX_INTERCHAIN_TOKEN_SALT, tokenId)); } /** * @notice Deploys an interchain token. * @param tokenId The ID of the token. * @param minterBytes The minter address for the token. * @param name The name of the token. * @param symbol The symbol of the token. * @param decimals The number of decimals of the token. */ function _deployInterchainToken( bytes32 tokenId, bytes memory minterBytes, string memory name, string memory symbol, uint8 decimals ) internal returns (address tokenAddress) { bytes32 salt = _getInterchainTokenSalt(tokenId); address minter; if (bytes(minterBytes).length != 0) minter = minterBytes.toAddress(); (bool success, bytes memory returnData) = interchainTokenDeployer.delegatecall( abi.encodeWithSelector(IInterchainTokenDeployer.deployInterchainToken.selector, salt, tokenId, minter, name, symbol, decimals) ); if (!success) { revert InterchainTokenDeploymentFailed(returnData); } assembly { tokenAddress := mload(add(returnData, 0x20)) } // slither-disable-next-line reentrancy-events emit InterchainTokenDeployed(tokenId, tokenAddress, minter, name, symbol, decimals); } /** * @notice Decodes the metadata into a version number and data bytes. * @dev The function expects the metadata to have the version in the first 4 bytes, followed by the actual data. * @param metadata The bytes containing the metadata to decode. * @return version The version number extracted from the metadata. * @return data The data bytes extracted from the metadata. */ function _decodeMetadata(bytes calldata metadata) internal pure returns (MetadataVersion version, bytes memory data) { if (metadata.length < 4) return (MetadataVersion.CONTRACT_CALL, data); uint32 versionUint = uint32(bytes4(metadata[:4])); if (versionUint > LATEST_METADATA_VERSION) revert InvalidMetadataVersion(versionUint); version = MetadataVersion(versionUint); if (metadata.length == 4) return (version, data); data = metadata[4:]; } /** * @notice Transmit a callContractWithInterchainToken for the given tokenId. * @param tokenId The tokenId of the TokenManager (which must be the msg.sender). * @param sourceAddress The address where the token is coming from, which will also be used for gas reimbursement. * @param destinationChain The name of the chain to send tokens to. * @param destinationAddress The destinationAddress for the interchainTransfer. * @param amount The amount of tokens to send. * @param metadataVersion The version of the metadata. * @param data The data to be passed with the token transfer. */ function _transmitInterchainTransfer( bytes32 tokenId, address sourceAddress, string calldata destinationChain, bytes memory destinationAddress, uint256 amount, MetadataVersion metadataVersion, bytes memory data, uint256 gasValue ) internal { // slither-disable-next-line reentrancy-events emit InterchainTransfer( tokenId, sourceAddress, destinationChain, destinationAddress, amount, data.length == 0 ? bytes32(0) : keccak256(data) ); bytes memory payload = abi.encode( MESSAGE_TYPE_INTERCHAIN_TRANSFER, tokenId, sourceAddress.toBytes(), destinationAddress, amount, data ); _callContract(destinationChain, payload, metadataVersion, gasValue); } /** * @dev Takes token from a sender via the token service. `tokenOnly` indicates if the caller should be restricted to the token only. */ function _takeToken(bytes32 tokenId, address from, uint256 amount, bool tokenOnly) internal returns (uint256) { address tokenManager_ = tokenManagerAddress(tokenId); uint256 tokenManagerType; address tokenAddress; (tokenManagerType, tokenAddress) = ITokenManagerProxy(tokenManager_).getImplementationTypeAndTokenAddress(); if (tokenOnly && msg.sender != tokenAddress) revert NotToken(msg.sender, tokenAddress); (bool success, bytes memory data) = tokenHandler.delegatecall( abi.encodeWithSelector(ITokenHandler.takeToken.selector, tokenManagerType, tokenAddress, tokenManager_, from, amount) ); if (!success) revert TakeTokenFailed(data); amount = abi.decode(data, (uint256)); /// @dev Track the flow amount being sent out as a message ITokenManager(tokenManager_).addFlowOut(amount); return amount; } /** * @dev Gives token to recipient via the token service. */ function _giveToken(bytes32 tokenId, address to, uint256 amount) internal returns (uint256, address) { address tokenManager_ = tokenManagerAddress(tokenId); (uint256 tokenManagerType, address tokenAddress) = ITokenManagerProxy(tokenManager_).getImplementationTypeAndTokenAddress(); /// @dev Track the flow amount being received via the message ITokenManager(tokenManager_).addFlowIn(amount); (bool success, bytes memory data) = tokenHandler.delegatecall( abi.encodeWithSelector(ITokenHandler.giveToken.selector, tokenManagerType, tokenAddress, tokenManager_, to, amount) ); if (!success) revert GiveTokenFailed(data); amount = abi.decode(data, (uint256)); return (amount, tokenAddress); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"tokenManagerDeployer_","type":"address"},{"internalType":"address","name":"interchainTokenDeployer_","type":"address"},{"internalType":"address","name":"gateway_","type":"address"},{"internalType":"address","name":"gasService_","type":"address"},{"internalType":"address","name":"interchainTokenFactory_","type":"address"},{"internalType":"string","name":"chainName_","type":"string"},{"internalType":"address","name":"tokenManagerImplementation_","type":"address"},{"internalType":"address","name":"tokenHandler_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyExecuted","type":"error"},{"inputs":[{"internalType":"enum ITokenManagerType.TokenManagerType","name":"","type":"uint8"}],"name":"CannotDeploy","type":"error"},{"inputs":[],"name":"EmptyData","type":"error"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"ExecuteWithInterchainTokenFailed","type":"error"},{"inputs":[],"name":"ExecuteWithTokenNotSupported","type":"error"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"ExpressExecuteWithInterchainTokenFailed","type":"error"},{"inputs":[],"name":"ExpressExecutorAlreadySet","type":"error"},{"inputs":[],"name":"GatewayToken","type":"error"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"GiveTokenFailed","type":"error"},{"inputs":[],"name":"InsufficientValue","type":"error"},{"inputs":[{"internalType":"bytes","name":"error","type":"bytes"}],"name":"InterchainTokenDeploymentFailed","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[{"internalType":"bytes","name":"bytesAddress","type":"bytes"}],"name":"InvalidBytesLength","type":"error"},{"inputs":[],"name":"InvalidChainName","type":"error"},{"inputs":[],"name":"InvalidCodeHash","type":"error"},{"inputs":[{"internalType":"uint256","name":"messageType","type":"uint256"}],"name":"InvalidExpressMessageType","type":"error"},{"inputs":[],"name":"InvalidImplementation","type":"error"},{"inputs":[{"internalType":"uint256","name":"messageType","type":"uint256"}],"name":"InvalidMessageType","type":"error"},{"inputs":[{"internalType":"uint32","name":"version","type":"uint32"}],"name":"InvalidMetadataVersion","type":"error"},{"inputs":[],"name":"InvalidOwner","type":"error"},{"inputs":[],"name":"InvalidOwnerAddress","type":"error"},{"inputs":[{"internalType":"address","name":"fromAccount","type":"address"},{"internalType":"address","name":"toAccount","type":"address"},{"internalType":"uint256","name":"accountRoles","type":"uint256"}],"name":"InvalidProposedRoles","type":"error"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"}],"name":"InvalidTokenManagerImplementationType","type":"error"},{"inputs":[],"name":"LengthMismatch","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"accountRoles","type":"uint256"}],"name":"MissingAllRoles","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"accountRoles","type":"uint256"}],"name":"MissingAnyOfRoles","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint8","name":"role","type":"uint8"}],"name":"MissingRole","type":"error"},{"inputs":[],"name":"MulticallFailed","type":"error"},{"inputs":[],"name":"NotApprovedByGateway","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"NotPaused","type":"error"},{"inputs":[],"name":"NotProxy","type":"error"},{"inputs":[],"name":"NotRemoteService","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"NotToken","type":"error"},{"inputs":[],"name":"Pause","type":"error"},{"inputs":[],"name":"SetupFailed","type":"error"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"TakeTokenFailed","type":"error"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"TokenHandlerFailed","type":"error"},{"inputs":[{"internalType":"bytes","name":"error","type":"bytes"}],"name":"TokenManagerDeploymentFailed","type":"error"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"name":"TokenManagerDoesNotExist","type":"error"},{"inputs":[],"name":"UntrustedChain","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroStringLength","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"commandId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"sourceChain","type":"string"},{"indexed":false,"internalType":"string","name":"sourceAddress","type":"string"},{"indexed":false,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"expressExecutor","type":"address"}],"name":"ExpressExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"commandId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"sourceChain","type":"string"},{"indexed":false,"internalType":"string","name":"sourceAddress","type":"string"},{"indexed":false,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"expressExecutor","type":"address"}],"name":"ExpressExecutedWithToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"commandId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"sourceChain","type":"string"},{"indexed":false,"internalType":"string","name":"sourceAddress","type":"string"},{"indexed":false,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"expressExecutor","type":"address"}],"name":"ExpressExecutionFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"commandId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"sourceChain","type":"string"},{"indexed":false,"internalType":"string","name":"sourceAddress","type":"string"},{"indexed":false,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"expressExecutor","type":"address"}],"name":"ExpressExecutionWithTokenFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"InterchainTokenDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"tokenName","type":"string"},{"indexed":false,"internalType":"string","name":"tokenSymbol","type":"string"},{"indexed":false,"internalType":"uint8","name":"tokenDecimals","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"minter","type":"bytes"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"}],"name":"InterchainTokenDeploymentStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"deployer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"InterchainTokenIdClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"dataHash","type":"bytes32"}],"name":"InterchainTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"commandId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"sourceChain","type":"string"},{"indexed":false,"internalType":"bytes","name":"sourceAddress","type":"bytes"},{"indexed":true,"internalType":"address","name":"destinationAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"dataHash","type":"bytes32"}],"name":"InterchainTransferReceived","type":"event"},{"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":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"accountRoles","type":"uint256"}],"name":"RolesAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"fromAccount","type":"address"},{"indexed":true,"internalType":"address","name":"toAccount","type":"address"},{"indexed":false,"internalType":"uint256","name":"accountRoles","type":"uint256"}],"name":"RolesProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"accountRoles","type":"uint256"}],"name":"RolesRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"tokenManager","type":"address"},{"indexed":true,"internalType":"enum ITokenManagerType.TokenManagerType","name":"tokenManagerType","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"params","type":"bytes"}],"name":"TokenManagerDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":true,"internalType":"enum ITokenManagerType.TokenManagerType","name":"tokenManagerType","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"params","type":"bytes"}],"name":"TokenManagerDeploymentStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"chain","type":"string"}],"name":"TrustedAddressRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"chain","type":"string"},{"indexed":false,"internalType":"string","name":"address_","type":"string"}],"name":"TrustedAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newImplementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[{"internalType":"address","name":"fromOperator","type":"address"}],"name":"acceptOperatorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"gasValue","type":"uint256"}],"name":"callContractWithInterchainToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"chainName","outputs":[{"internalType":"string","name":"chainName_","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chainNameHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"contractCallValue","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"contractCallWithTokenValue","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"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":"destinationChain","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"bytes","name":"minter","type":"bytes"},{"internalType":"uint256","name":"gasValue","type":"uint256"}],"name":"deployInterchainToken","outputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"enum ITokenManagerType.TokenManagerType","name":"tokenManagerType","type":"uint8"},{"internalType":"bytes","name":"params","type":"bytes"},{"internalType":"uint256","name":"gasValue","type":"uint256"}],"name":"deployTokenManager","outputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commandId","type":"bytes32"},{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"executeWithToken","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commandId","type":"bytes32"},{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"expressExecute","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"expressExecuteWithToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"name":"flowInAmount","outputs":[{"internalType":"uint256","name":"flowInAmount_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"name":"flowLimit","outputs":[{"internalType":"uint256","name":"flowLimit_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"name":"flowOutAmount","outputs":[{"internalType":"uint256","name":"flowOutAmount_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasService","outputs":[{"internalType":"contract IAxelarGasService","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gateway","outputs":[{"internalType":"contract IAxelarGateway","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commandId","type":"bytes32"},{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes32","name":"payloadHash","type":"bytes32"}],"name":"getExpressExecutor","outputs":[{"internalType":"address","name":"expressExecutor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commandId","type":"bytes32"},{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getExpressExecutorWithToken","outputs":[{"internalType":"address","name":"expressExecutor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint8","name":"role","type":"uint8"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"implementation_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"name":"interchainTokenAddress","outputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"interchainTokenDeployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"interchainTokenFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"interchainTokenId","outputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"metadata","type":"bytes"},{"internalType":"uint256","name":"gasValue","type":"uint256"}],"name":"interchainTransfer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"chain","type":"string"},{"internalType":"string","name":"address_","type":"string"}],"name":"isTrustedAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"paused","outputs":[{"internalType":"bool","name":"paused_","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"proposeOperatorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"proposeOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"chain","type":"string"}],"name":"removeTrustedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"tokenIds","type":"bytes32[]"},{"internalType":"uint256[]","name":"flowLimits","type":"uint256[]"}],"name":"setFlowLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"paused","type":"bool"}],"name":"setPauseStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"chain","type":"string"},{"internalType":"string","name":"address_","type":"string"}],"name":"setTrustedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenHandler","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"name":"tokenManagerAddress","outputs":[{"internalType":"address","name":"tokenManagerAddress_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenManagerDeployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenManagerImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"transferOperatorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"},{"internalType":"address","name":"sourceAddress","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"metadata","type":"bytes"}],"name":"transmitInterchainTransfer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"chain","type":"string"}],"name":"trustedAddress","outputs":[{"internalType":"string","name":"trustedAddress_","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"chain","type":"string"}],"name":"trustedAddressHash","outputs":[{"internalType":"bytes32","name":"trustedAddressHash_","type":"bytes32"}],"stateMutability":"view","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"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"name":"validTokenAddress","outputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenId","type":"bytes32"}],"name":"validTokenManagerAddress","outputs":[{"internalType":"address","name":"tokenManagerAddress_","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6101c06040523480156200001257600080fd5b5060405162005ee438038062005ee4833981016040819052620000359162000272565b600162000042816200018d565b5030608052604051620000586020820162000231565b601f1982820381018352601f9091011660405280516020919091012060a0526001600160a01b03851615806200009557506001600160a01b038816155b80620000a857506001600160a01b038716155b80620000bb57506001600160a01b038616155b80620000ce57506001600160a01b038416155b80620000e157506001600160a01b038216155b80620000f457506001600160a01b038116155b15620001135760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0380871660c05285811660e052888116610160528781166101405284166101005282516000036200015e57604051630470832760e11b815260040160405180910390fd5b8251602090930192909220610120526001600160a01b0390811661018052166101a05250620003ca9350505050565b6001600160a01b038116620001b557604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616390600090a27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05560007f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b6101828062005d6283390190565b80516001600160a01b03811681146200025757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080600080600080600080610100898b0312156200029057600080fd5b6200029b896200023f565b97506020620002ac818b016200023f565b9750620002bc60408b016200023f565b9650620002cc60608b016200023f565b9550620002dc60808b016200023f565b60a08b01519095506001600160401b0380821115620002fa57600080fd5b818c0191508c601f8301126200030f57600080fd5b8151818111156200032457620003246200025c565b604051601f8201601f19908116603f011681019083821181831017156200034f576200034f6200025c565b816040528281528f868487010111156200036857600080fd5b600093505b828410156200038c57848401860151818501870152928501926200036d565b6000868483010152809850505050505050620003ab60c08a016200023f565b9150620003bb60e08a016200023f565b90509295985092959890939650565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516158ba620004a8600039600081816103ff0152818161261f0152818161290d015261398801526000818161049401526107200152600081816106580152612dea01526000818161055b015261341c0152600081816107b101526130ce01526000818161098c015281816116420152611fb701526000818161062401528181613ba80152613c6901526000818161036c01528181610df5015281816111a60152613d0e015260006136a20152600061175201526158ba6000f3fe6080604052600436106103555760003560e01c8063864a0dcf116101bb578063c8bb7067116100f7578063e30c397811610095578063e82e71f81161006f578063e82e71f814610a96578063f2fde38b14610ab6578063f8c8a82614610ad6578063ffd5982a14610af657600080fd5b8063e30c397814610a34578063e4a974cc14610a68578063e7e3ffc814610a7657600080fd5b8063da081c73116100d1578063da081c73146109ce578063da4886df146109e1578063dc88dfd114610a01578063e1d40c7714610a2157600080fd5b8063c8bb70671461095a578063ca58b6441461097a578063d8dab96b146109ae57600080fd5b80639f409d7711610164578063ac9650d81161013e578063ac9650d8146108da578063c38bb537146108fa578063c506bff41461091a578063c7e6a3cc1461093a57600080fd5b80639f409d771461087a578063a3499c731461089a578063a5269ef1146108ba57600080fd5b806395a8c58d1161019557806395a8c58d1461082757806398d78c82146108475780639ded06df1461085a57600080fd5b8063864a0dcf1461079f578063868a166d146107d35780638da5cb5b146107f357600080fd5b80635a6fd76e116102955780636f3eef621161023357806379ba50971161020d57806379ba5097146106ed5780637e151fa6146107025780638291286c1461074257806383d296961461077f57600080fd5b80636f3eef621461069a57806370756cde146106ba578063710bf322146106cd57600080fd5b8063656576361161026f57806365657636146105ff5780636a22d8cc146106125780636ac0d112146106465780636d70f7ae1461067a57600080fd5b80635a6fd76e1461057d5780635c60da1b1461059d5780635c975abb146105d157600080fd5b80632a709b141161030257806349160658116102dc57806349160658146104f65780634a6a42d8146105165780634b4578ba146105365780634f9ae6081461054957600080fd5b80632a709b1414610482578063465a09e0146104b6578063477aedc7146104d657600080fd5b80631b3d6e87116103335780631b3d6e87146103ed5780631c93b03a146104215780631f26d7301461044357600080fd5b8063116191b61461035a5780631a083d39146103ab5780631a98b2e0146103cb575b600080fd5b34801561036657600080fd5b5061038e7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156103b757600080fd5b5061038e6103c6366004614079565b610b16565b3480156103d757600080fd5b506103eb6103e63660046140d4565b610b8d565b005b3480156103f957600080fd5b5061038e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561042d57600080fd5b50610436610ba6565b6040516103a291906141fe565b34801561044f57600080fd5b5061046361045e366004614211565b610bd6565b604080516001600160a01b0390931683526020830191909152016103a2565b34801561048e57600080fd5b5061038e7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104c257600080fd5b506103eb6104d1366004614322565b610bf2565b3480156104e257600080fd5b506104366104f1366004614445565b610d37565b34801561050257600080fd5b506103eb610511366004614482565b610d50565b34801561052257600080fd5b506103eb61053136600461453b565b610faf565b6103eb610544366004614558565b610ff5565b34801561055557600080fd5b5061038e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561058957600080fd5b5061038e610598366004614079565b6110be565b3480156105a957600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5461038e565b3480156105dd57600080fd5b50600080516020615865833981519152545b60405190151581526020016103a2565b6103eb61060d366004614482565b611117565b34801561061e57600080fd5b5061038e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561065257600080fd5b5061038e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561068657600080fd5b506105ef61069536600461453b565b6112e1565b3480156106a657600080fd5b506103eb6106b536600461453b565b6112ee565b6103eb6106c8366004614608565b611330565b3480156106d957600080fd5b506103eb6106e836600461453b565b61138f565b3480156106f957600080fd5b506103eb61145e565b34801561070e57600080fd5b5061038e61071d366004614079565b507f000000000000000000000000000000000000000000000000000000000000000090565b34801561074e57600080fd5b507ff407da03daa7b4243ffb261daad9b01d221ea90ab941948cd48101563654ea865b6040519081526020016103a2565b34801561078b57600080fd5b5061046361079a3660046146c2565b6114d8565b3480156107ab57600080fd5b506107717f000000000000000000000000000000000000000000000000000000000000000081565b3480156107df57600080fd5b5061038e6107ee36600461475c565b61158e565b3480156107ff57600080fd5b507f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05461038e565b34801561083357600080fd5b506105ef610842366004614822565b6115b2565b610771610855366004614866565b6115cd565b34801561086657600080fd5b506103eb6108753660046148fc565b61174f565b34801561088657600080fd5b506103eb61089536600461493e565b6117bb565b3480156108a657600080fd5b506103eb6108b53660046149a2565b611815565b3480156108c657600080fd5b506107716108d53660046149f2565b611b07565b6108ed6108e8366004614a1e565b611b6e565b6040516103a29190614a54565b34801561090657600080fd5b506103eb610915366004614ac4565b611cc7565b34801561092657600080fd5b506105ef610935366004614ae1565b611d2d565b34801561094657600080fd5b5061038e610955366004614b41565b611d93565b34801561096657600080fd5b50610771610975366004614079565b611db1565b34801561098657600080fd5b5061038e7f000000000000000000000000000000000000000000000000000000000000000081565b3480156109ba57600080fd5b506107716109c9366004614079565b611e21565b6103eb6109dc36600461475c565b611e6d565b3480156109ed57600080fd5b506103eb6109fc36600461453b565b611f11565b348015610a0d57600080fd5b506103eb610a1c366004614445565b611f1d565b610771610a2f366004614bc3565b611f76565b348015610a4057600080fd5b507f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d15461038e565b6103eb6103e63660046140d4565b348015610a8257600080fd5b50610771610a91366004614079565b612057565b348015610aa257600080fd5b5061038e610ab1366004614079565b6120a3565b348015610ac257600080fd5b506103eb610ad136600461453b565b6120b9565b348015610ae257600080fd5b5061038e610af1366004614079565b612109565b348015610b0257600080fd5b50610771610b11366004614445565b612114565b600080610b22836110be565b9050806001600160a01b0316639d76ea586040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b869190614c99565b9392505050565b6040516327616c7360e11b815260040160405180910390fd5b6060610bd17f0e2c162a1f4b5cff9fdbd6b34678a9bcb9898a0b9fbca695b112d61688d8b2ac612128565b905090565b6000806040516327616c7360e11b815260040160405180910390fd5b6001610c0d610c00336121bb565b600160ff84161b16151590565b610c3a5760405163bb6c163960e01b815233600482015260ff821660248201526044015b60405180910390fd5b83828114610c74576040517fff633a3800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d2e576000610ca2888884818110610c9657610c96614ccc565b905060200201356110be565b9050806001600160a01b031663a56dbe63878785818110610cc557610cc5614ccc565b905060200201356040518263ffffffff1660e01b8152600401610cea91815260200190565b600060405180830381600087803b158015610d0457600080fd5b505af1158015610d18573d6000803e3d6000fd5b505050505080610d2790614ce2565b9050610c77565b50505050505050565b6060610d4a610d45836121c7565b612128565b92915050565b85858585610d6084848484611d2d565b610d7d5760405163157e5fbf60e21b815260040160405180910390fd5b6000805160206158658339815191525415610dab576040516334c2d01160e11b815260040160405180910390fd5b60008686604051610dbd929190614d09565b6040519081900381207f5f6970c300000000000000000000000000000000000000000000000000000000825291506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690635f6970c390610e34908f908f908f908f908f908990600401614d42565b6020604051808303816000875af1158015610e53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e779190614d83565b610ead576040517f500c44b400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610ebb87890189614079565b905080610f42576000610ed28e8e8e8e8e88612219565b9050610ee28e828f8f8d8d612246565b6001600160a01b03811615610f3c57806001600160a01b03168e7f8fe61b2d4701a29265508750790e322b2c214399abdf98472158b8908b660d418f8f8f8f89604051610f33959493929190614da0565b60405180910390a35b50610fa0565b60028103610f5957610f54888861240e565b610fa0565b60018103610f6b57610f54888861246d565b6040517f495f232e00000000000000000000000000000000000000000000000000000000815260048101829052602401610c31565b50505050505050505050505050565b6001610fbd610c00336121bb565b610fe55760405163bb6c163960e01b815233600482015260ff82166024820152604401610c31565b610ff1338360016124b4565b5050565b6000805160206158658339815191525415611023576040516334c2d01160e11b815260040160405180910390fd5b815160000361105e576040517f99d8fec900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61106b88338560006124ca565b92506110b48833898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508c935091508a905089612762565b5050505050505050565b60006110c982612109565b9050806001600160a01b03163b600003611112576040517f2dd85afc00000000000000000000000000000000000000000000000000000000815260048101839052602401610c31565b919050565b6000805160206158658339815191525415611145576040516334c2d01160e11b815260040160405180910390fd5b600061115382840184614079565b905080156111775760405163e94617f560e01b815260048101829052602401610c31565b6040517fd26ff210000000000000000000000000000000000000000000000000000000008152600481018990527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d26ff21090602401602060405180830381865afa1580156111f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112199190614d83565b15611250576040517f0dc1019700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405133906000906112659086908690614d09565b60405180910390209050816001600160a01b03168a7f6e18757e81c44a367109cbaa499add16f2ae7168aab9715c3cdc36b0f7ccce928b8b8b8b876040516112b1959493929190614da0565b60405180910390a36112c88a8a8a8a8a868861280c565b6112d58a8a8a888861286c565b50505050505050505050565b6000610d4a8260016115b2565b60016112fc610c00336121bb565b6113245760405163bb6c163960e01b815233600482015260ff82166024820152604401610c31565b610ff133836001612bf4565b600080516020615865833981519152541561135e576040516334c2d01160e11b815260040160405180910390fd5b61136b88888560016124ca565b925060008061137a8484612c05565b915091506112d58a8a8a8a8a8a888834612762565b336113b87f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b0316146113df576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b03811661140657604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907fd9be0e8e07417e00f2521db636cb53e316fd288f5051f16d2aa2bf0c3938a87690600090a27f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b60006114887f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d15490565b90506001600160a01b03811633146114cc576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114d581612cd8565b50565b600080878787876114eb84848484611d2d565b6115085760405163157e5fbf60e21b815260040160405180910390fd5b6000805160206158658339815191525415611536576040516334c2d01160e11b815260040160405180910390fd5b600080806115468a8c018c614dda565b93505092509250600083146115715760405163e94617f560e01b815260048101849052602401610c31565b61157a82610b16565b9f909e509c50505050505050505050505050565b6000806115a28b8b8b8b8b8b8b8b8b612d7b565b549b9a5050505050505050505050565b6000610b866115c0846121bb565b600160ff85161b16151590565b60006115e56000805160206158658339815191525490565b15611603576040516334c2d01160e11b815260040160405180910390fd5b600085600481111561161757611617614cb6565b036116375784604051630a7dda8360e01b8152600401610c319190614e54565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016810361166c575060005b611676818a611b07565b915088816001600160a01b0316837f04ddbfaa222e81ab9447c070310e87608bf6a4c5d42be5c2fdf0f370b186af7960405160405180910390a460008790036116ff576116fa828787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612de592505050565b611743565b611743828989868a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612fce92505050565b50979650505050505050565b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316036117b1576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ff1828261305f565b336117e47f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b03161461180b576040516330cd747160e01b815260040160405180910390fd5b610ff182826131ca565b3361183e7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614611865576040516330cd747160e01b815260040160405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b0316638291286c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e89190614e62565b846001600160a01b0316638291286c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611926573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194a9190614e62565b14611981576040517f68155f9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836001600160a01b03163f83146119c4576040517f8f84fb2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b038516907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a28015611ae0576000846001600160a01b0316639ded06df60e01b8484604051602401611a25929190614e7b565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051611a639190614e8f565b600060405180830381855af49150503d8060008114611a9e576040519150601f19603f3d011682016040523d82523d6000602084013e611aa3565b606091505b5050905080611ade576040517f97905dfb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b5050507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b604080517f980c3be34c7ee75cc250c76223092614e21653cdf2faece10ac24fcef821df1060208201526001600160a01b03841691810191909152606081018290526000906080015b60405160208183030381529060405280519060200120905092915050565b60608167ffffffffffffffff811115611b8957611b8961438e565b604051908082528060200260200182016040528015611bbc57816020015b6060815260200190600190039081611ba75790505b5090506000606060005b84811015611cbe5730868683818110611be157611be1614ccc565b9050602002810190611bf39190614eab565b604051611c01929190614d09565b600060405180830381855af49150503d8060008114611c3c576040519150601f19603f3d011682016040523d82523d6000602084013e611c41565b606091505b50909350915082611c8f578151600003611c87576040517f4d6a232800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815182602001fd5b81848281518110611ca257611ca2614ccc565b602002602001018190525080611cb790614ce2565b9050611bc6565b50505092915050565b33611cf07f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614611d17576040516330cd747160e01b815260040160405180910390fd5b8015611d25576114d5613279565b6114d56132bd565b6000808383604051611d40929190614d09565b60405180910390209050611d8986868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061211492505050565b1495945050505050565b600080611da4888888888888613301565b5498975050505050505050565b600080611dbd836110be565b9050806001600160a01b0316637dbab19b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b869190614e62565b600080611e2d836110be565b9050806001600160a01b0316632f3c78886040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dfd573d6000803e3d6000fd5b6000805160206158658339815191525415611e9b576040516334c2d01160e11b815260040160405180910390fd5b611ea889338660006124ca565b9350600080611eb78585612c05565b91509150611f048b338c8c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508a91508990508b612762565b5050505050505050505050565b6114d581336001613362565b33611f467f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614611f6d576040516330cd747160e01b815260040160405180910390fd5b6114d581613373565b6000611f8e6000805160206158658339815191525490565b15611fac576040516334c2d01160e11b815260040160405180910390fd5b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168103611fe1575060005b611feb818b611b07565b9150600088900361203a57600061200583868a8a8a6133f2565b90506120348360008784604051602001612020929190614ef2565b604051602081830303815290604052612de5565b5061204a565b61204a82888888888e8e8a61357f565b5098975050505050505050565b600080612063836110be565b9050806001600160a01b0316638b38b35d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dfd573d6000803e3d6000fd5b60006120ae82613613565b9150610d4a8261364e565b336120e27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b0316146114cc576040516330cd747160e01b815260040160405180910390fd5b6000610d4a8261364e565b60008061212083613750565b549392505050565b606081805461213690614f1d565b80601f016020809104026020016040519081016040528092919081815260200182805461216290614f1d565b80156121af5780601f10612184576101008083540402835291602001916121af565b820191906000526020600020905b81548152906001019060200180831161219257829003601f168201915b50505050509050919050565b60008061212083613785565b60007fa5b4aa1bcb538076d57d083e3004c6907e2eba42d84c21922d441967a02b472f826040516020016121fc929190614f57565b604051602081830303815290604052805190602001209050919050565b60008061222a888888888888613301565b905080549150811561223b57600081555b509695505050505050565b600060608180828061225a87890189614f70565b939a5091985090955090935091506122739050816137d5565b9350506001600160a01b038a161561229c57612290858b8461381c565b50505050505050612406565b60006122a986858561381c565b8092508194505050836001600160a01b0316868d7fbdb65cfd017af0876344138f62bc895163b5fd120cbe6e666ed306afd658de4b8d8d8a8989516000146122f757895160208b01206122fa565b60005b60405161230b959493929190615014565b60405180910390a48151156123ff576000846001600160a01b031663292415028e8d8d8a888d898c6040518963ffffffff1660e01b815260040161235698979695949392919061504f565b6020604051808303816000875af1158015612375573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123999190614e62565b90507fe84001f3dedacf7f9ddc370e9f09c26b37473e9e959ffdc4925f6fe33c9877e48114610fa0576040517f1ef6f3b30000000000000000000000000000000000000000000000000000000081526001600160a01b0386166004820152602401610c31565b5050505050505b505050505050565b6000808061241e848601866150b9565b919550935091506000905082600481111561243b5761243b614cb6565b0361245b5781604051630a7dda8360e01b8152600401610c319190614e54565b612466838383612de5565b5050505050565b60008080808061247f8688018861511a565b9550955095509550955050600061249986838787876133f2565b90506110b48660008484604051602001612020929190614ef2565b6124c58383600160ff85161b613a57565b505050565b6000806124d686612109565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa158015612518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061253c91906151ab565b90925090508480156125575750336001600160a01b03821614155b1561259f576040517f409304db0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0382166024820152604401610c31565b60408051602481018490526001600160a01b0383811660448301528581166064830152898116608483015260a48083018a90528351808403909101815260c490920183526020820180516001600160e01b03167fb2668ef600000000000000000000000000000000000000000000000000000000179052915160009283927f00000000000000000000000000000000000000000000000000000000000000009091169161264c9190614e8f565b600060405180830381855af49150503d8060008114612687576040519150601f19603f3d011682016040523d82523d6000602084013e61268c565b606091505b5091509150816126ca57806040517f1a59c9bd000000000000000000000000000000000000000000000000000000008152600401610c3191906141fe565b808060200190518101906126de9190614e62565b6040517fdce29136000000000000000000000000000000000000000000000000000000008152600481018290529098506001600160a01b0386169063dce2913690602401600060405180830381600087803b15801561273c57600080fd5b505af1158015612750573d6000803e3d6000fd5b50999c9b505050505050505050505050565b8151156127755781516020830120612778565b60005b886001600160a01b03168a7fcd05f5b9dc4bb03babf40f5da98f5f46819846207d916f89b67d36fd1f7fd74f8a8a8a8a6040516127b894939291906151db565b60405180910390a46000808a6127d68b6001600160a01b0316613aad565b8888876040516020016127ee96959493929190615213565b60405160208183030381529060405290506112d58888838786613adb565b600061281c888888888888613301565b80549091506001600160a01b03811615612862576040517f725f13f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5055505050505050565b60008080808061287e86880188614f70565b95509550955095509550506000612894846137d5565b90506000806128a288612109565b9050806001600160a01b0316639d76ea586040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129069190614c99565b91506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166345537d7060e01b846001600160a01b0316634fdf7cb56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561297b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299f9190614e62565b60405160248101919091526001600160a01b0380881660448301523360648301528816608482015260a481018a905260c40160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612a0f9190614e8f565b600060405180830381855af49150503d8060008114612a4a576040519150601f19603f3d011682016040523d82523d6000602084013e612a4f565b606091505b509150915081612a8d57806040517f3a5cf905000000000000000000000000000000000000000000000000000000008152600401610c3191906141fe565b80806020019051810190612aa19190614e62565b9650505050816001600160a01b0316878d7fbdb65cfd017af0876344138f62bc895163b5fd120cbe6e666ed306afd658de4b8e8e8b8a8a51600014612aec578a5160208c0120612aef565b60005b604051612b00959493929190615014565b60405180910390a48251156123ff576000826001600160a01b03166377c790258e8e8e8b898e898d6040518963ffffffff1660e01b8152600401612b4b98979695949392919061504f565b6020604051808303816000875af1158015612b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b8e9190614e62565b90507f692b2deb10f974787eb65450ba9a90dc0bb28141a633fa3fb556d5292fba42e18114610fa0576040517fc646a6230000000000000000000000000000000000000000000000000000000081526001600160a01b0384166004820152602401610c31565b6124c58383600160ff85161b613d77565b600060606004831015612c1b5760009150612cd1565b6000612c2a600482868861526b565b612c3391615295565b60e01c90506001811115612c625760405163b47a9b4b60e01b815263ffffffff82166004820152602401610c31565b8063ffffffff166001811115612c7a57612c7a614cb6565b92506004849003612c8b5750612cd1565b612c98846004818861526b565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929450505050505b9250929050565b6001600160a01b038116612cff57604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616390600090a27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05560007f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b60007febf4535caee8019297b7be3ed867db0d00b69fedcdda98c5e2c41ea6e41a98d58a8a8a8a8a8a8a8a8a604051602001612dc09a999897969594939291906152c5565b6040516020818303038152906040528051906020012090509998505050505050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636519d04b60e01b868686604051602401612e2f9392919061532b565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612e6d9190614e8f565b600060405180830381855af49150503d8060008114612ea8576040519150601f19603f3d011682016040523d82523d6000602084013e612ead565b606091505b509150915081612eeb57806040517ff9eef82a000000000000000000000000000000000000000000000000000000008152600401610c3191906141fe565b60208101516002856004811115612f0457612f04614cb6565b1480612f2157506003856004811115612f1f57612f1f614cb6565b145b15612f7a57806001600160a01b031663274158386040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612f6157600080fd5b505af1158015612f75573d6000803e3d6000fd5b505050505b846004811115612f8c57612f8c614cb6565b867f5284c2478b9c1a55e973429331078be39b5fb3eeb9d87d10b34d65a4c89ee4eb8387604051612fbe92919061535a565b60405180910390a3505050505050565b612fd7866110be565b50816004811115612fea57612fea614cb6565b867fc92a73c79b84dd58e39d4e09fbf47f3f8bd145222bfff3d803eec161bed1c19487878560405161301e9392919061537c565b60405180910390a36000600287848460405160200161304094939291906153ac565b6040516020818303038152906040529050610d2e868683600088613adb565b600080808061307085870187615477565b8151939750919550935091506001600160a01b0385166130bc576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835115806130f05750835160208501207f000000000000000000000000000000000000000000000000000000000000000014155b15613127576040517f08e1064e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81518114613161576040517fff633a3800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61316a85613e0f565b61317384613e1a565b60005b818110156110b4576131ba84828151811061319357613193614ccc565b60200260200101518483815181106131ad576131ad614ccc565b60200260200101516131ca565b6131c381614ce2565b9050613176565b81516000036131ec5760405163deba168960e01b815260040160405180910390fd5b805160000361320e5760405163deba168960e01b815260040160405180910390fd5b61322061321a836121c7565b82613e40565b600061322b83613750565b82516020840120808255604051919250907fdb6b260ea45f7fe513e1d3b8c21017a29e3a41610e95aefb8862b81c69aec61c9061326b9086908690615506565b60405180910390a150505050565b613290600160008051602061586583398151915255565b60405133907f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890600090a2565b6132d4600060008051602061586583398151915255565b60405133907f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90600090a2565b60007f2a41fec9a0df4e0996b975f71622c7164b0f652ea69d9dbcd6b24e81b20ab5e5878787878787604051602001613340979695949392919061552b565b6040516020818303038152906040528051906020012090509695505050505050565b6124c58383600160ff85161b613e4b565b80516000036133955760405163deba168960e01b815260040160405180910390fd5b6133a66133a1826121c7565b613ebe565b60006133b182613750565b9050600081557ff9400637a329865492b8d0d4dba4eafc7e8d5d0fae5e27b56766816d2ae1b2ca826040516133e691906141fe565b60405180910390a15050565b6000806133fe87613613565b90506000865160001461341757613414876137d5565b90505b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f575f35b60e01b858c868c8c8c60405160240161346796959493929190615573565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516134a59190614e8f565b600060405180830381855af49150503d80600081146134e0576040519150601f19603f3d011682016040523d82523d6000602084013e6134e5565b606091505b50915091508161352357806040517fc226af8b000000000000000000000000000000000000000000000000000000008152600401610c3191906141fe565b60208101519450826001600160a01b03168a7ff0d7beb2b03d35e597f432391dc2a6f6eb1a621be6cb5b325f55a49090085239878b8b8b60405161356a94939291906155ca565b60405180910390a35050505095945050505050565b613588886110be565b50877fe470f4bdd33c8676127d3c20ff725d8dc1605609001389ce3a59c28b54b7992f8888888888886040516135c396959493929190615613565b60405180910390a26000600189898989896040516020016135e99695949392919061566a565b6040516020818303038152906040529050613608848483600086613adb565b505050505050505050565b604080517f610507e221586f499adb972fbdbe7f0619bdae0112c78ebaa562448d0ca7071f60208201529081018290526000906060016121fc565b604080517fff0000000000000000000000000000000000000000000000000000000000000060208083019190915230606090811b6bffffffffffffffffffffffff19908116602185015260358401959095527f0000000000000000000000000000000000000000000000000000000000000000605580850191909152845180850390910181526075840185528051908301207fd6940000000000000000000000000000000000000000000000000000000000006095850152901b90931660978201527f010000000000000000000000000000000000000000000000000000000000000060ab8201528151608c81830301815260ac909101909152805191012090565b60007f5f58fea7d48d37d5d1cc2546dfcc3d3cbfe8d758d5ca19c44087f52e15a10505826040516020016121fc929190614f57565b60007fde9bdca322e1a848f72215bc15cf2c87fe7749145789a9ee281a2a6290af26ab826040516020016121fc92919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b6000815160141461381457816040517fd08dbec5000000000000000000000000000000000000000000000000000000008152600401610c3191906141fe565b506014015190565b600080600061382a86612109565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa15801561386c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061389091906151ab565b6040517f10d8d8e30000000000000000000000000000000000000000000000000000000081526004810189905291935091506001600160a01b038416906310d8d8e390602401600060405180830381600087803b1580156138f057600080fd5b505af1158015613904573d6000803e3d6000fd5b505060408051602481018690526001600160a01b03858116604483015287811660648301528b8116608483015260a48083018c90528351808403909101815260c490920183526020820180516001600160e01b03167f72689126000000000000000000000000000000000000000000000000000000001790529151600094508493507f0000000000000000000000000000000000000000000000000000000000000000909216916139b59190614e8f565b600060405180830381855af49150503d80600081146139f0576040519150601f19603f3d011682016040523d82523d6000602084013e6139f5565b606091505b509150915081613a3357806040517f0f940973000000000000000000000000000000000000000000000000000000008152600401610c3191906141fe565b80806020019051810190613a479190614e62565b9a92995091975050505050505050565b613a6a613a63846121bb565b8216821490565b613a9957604051631fe9beed60e21b81526001600160a01b038416600482015260248101829052604401610c31565b613aa38382613ec9565b6124c58282613f2b565b6040805160148082528183019092526060916020820181803683375050506014808201939093529182525090565b6000613b1c86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610d3792505050565b90508051600003613b59576040517ff9188a6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115613cde576000836001811115613b7357613b73614cb6565b03613c20576040517f0c93e3bb0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630c93e3bb908490613be99030908b908b9088908c9032906004016156b8565b6000604051808303818588803b158015613c0257600080fd5b505af1158015613c16573d6000803e3d6000fd5b5050505050613cde565b6001836001811115613c3457613c34614cb6565b03613caa576040517ff61ed2180000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f61ed218908490613be99030908b908b9088908c9032906004016156b8565b826001811115613cbc57613cbc614cb6565b60405163b47a9b4b60e01b815263ffffffff9091166004820152602401610c31565b6040517f1c92115f0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631c92115f90613d49908990899086908a90600401615719565b600060405180830381600087803b158015613d6357600080fd5b505af11580156112d5573d6000803e3d6000fd5b613d83613a63846121bb565b613db257604051631fe9beed60e21b81526001600160a01b038416600482015260248101829052604401610c31565b613dbd838383613f7f565b816001600160a01b0316836001600160a01b03167ff7158d1591c2cf17c0e6b9459d86365c47fe0969c79f40ef49e0c437d8f3991483604051613e0291815260200190565b60405180910390a3505050565b6114d5816001613f94565b6114d57f0e2c162a1f4b5cff9fdbd6b34678a9bcb9898a0b9fbca695b112d61688d8b2ac825b816124c582826157a4565b80613e568484613fa4565b14613ea7576040517f6004fe400000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301528316602482015260448101829052606401610c31565b613eb383836000613f7f565b6124c5838383613a57565b6114d581600061402b565b60008119613ed6846121bb565b169050613ee38382613fba565b826001600160a01b03167fccf920c8facee98a9c2a6c6124f2857b87b17e9f3a819bfcc6945196ee77366b83604051613f1e91815260200190565b60405180910390a2505050565b600081613f37846121bb565b179050613f448382613fba565b826001600160a01b03167f34e73c57659d4b6809b53db4feee9b007b892e978114eda420d2991aba15014383604051613f1e91815260200190565b6000613f8b8484613fcd565b91909155505050565b610ff182600160ff84161b613f2b565b600080613fb18484613fcd565b54949350505050565b6000613fc583613785565b919091555050565b60007ff96e07b2f4fbb81c31567d2b261589af429e98f0958d53f7e6ad5d63aea0ab7c8383604051602001611b5093929190928352606091821b6bffffffffffffffffffffffff199081166020850152911b16603482015260480190565b50805461403790614f1d565b6000825580601f10614047575050565b601f0160209004906000526020600020908101906114d591905b808211156140755760008155600101614061565b5090565b60006020828403121561408b57600080fd5b5035919050565b60008083601f8401126140a457600080fd5b50813567ffffffffffffffff8111156140bc57600080fd5b602083019150836020828501011115612cd157600080fd5b60008060008060008060008060008060c08b8d0312156140f357600080fd5b8a35995060208b013567ffffffffffffffff8082111561411257600080fd5b61411e8e838f01614092565b909b50995060408d013591508082111561413757600080fd5b6141438e838f01614092565b909950975060608d013591508082111561415c57600080fd5b6141688e838f01614092565b909750955060808d013591508082111561418157600080fd5b5061418e8d828e01614092565b9150809450508092505060a08b013590509295989b9194979a5092959850565b60005b838110156141c95781810151838201526020016141b1565b50506000910152565b600081518084526141ea8160208601602086016141ae565b601f01601f19169290920160200192915050565b602081526000610b8660208301846141d2565b600080600080600080600080600060a08a8c03121561422f57600080fd5b893567ffffffffffffffff8082111561424757600080fd5b6142538d838e01614092565b909b50995060208c013591508082111561426c57600080fd5b6142788d838e01614092565b909950975060408c013591508082111561429157600080fd5b61429d8d838e01614092565b909750955060608c01359150808211156142b657600080fd5b506142c38c828d01614092565b9a9d999c50979a9699959894979660800135949350505050565b60008083601f8401126142ef57600080fd5b50813567ffffffffffffffff81111561430757600080fd5b6020830191508360208260051b8501011115612cd157600080fd5b6000806000806040858703121561433857600080fd5b843567ffffffffffffffff8082111561435057600080fd5b61435c888389016142dd565b9096509450602087013591508082111561437557600080fd5b50614382878288016142dd565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156143cd576143cd61438e565b604052919050565b600082601f8301126143e657600080fd5b813567ffffffffffffffff8111156144005761440061438e565b614413601f8201601f19166020016143a4565b81815284602083860101111561442857600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561445757600080fd5b813567ffffffffffffffff81111561446e57600080fd5b61447a848285016143d5565b949350505050565b60008060008060008060006080888a03121561449d57600080fd5b87359650602088013567ffffffffffffffff808211156144bc57600080fd5b6144c88b838c01614092565b909850965060408a01359150808211156144e157600080fd5b6144ed8b838c01614092565b909650945060608a013591508082111561450657600080fd5b506145138a828b01614092565b989b979a50959850939692959293505050565b6001600160a01b03811681146114d557600080fd5b60006020828403121561454d57600080fd5b8135610b8681614526565b60008060008060008060008060c0898b03121561457457600080fd5b88359750602089013567ffffffffffffffff8082111561459357600080fd5b61459f8c838d01614092565b909950975060408b01359150808211156145b857600080fd5b6145c48c838d01614092565b909750955060608b0135945060808b01359150808211156145e457600080fd5b506145f18b828c016143d5565b92505060a089013590509295985092959890939650565b60008060008060008060008060c0898b03121561462457600080fd5b88359750602089013561463681614526565b9650604089013567ffffffffffffffff8082111561465357600080fd5b61465f8c838d01614092565b909850965060608b013591508082111561467857600080fd5b6146848c838d016143d5565b955060808b0135945060a08b01359150808211156146a157600080fd5b506146ae8b828c01614092565b999c989b5096995094979396929594505050565b600080600080600080606087890312156146db57600080fd5b863567ffffffffffffffff808211156146f357600080fd5b6146ff8a838b01614092565b9098509650602089013591508082111561471857600080fd5b6147248a838b01614092565b9096509450604089013591508082111561473d57600080fd5b5061474a89828a01614092565b979a9699509497509295939492505050565b600080600080600080600080600060c08a8c03121561477a57600080fd5b8935985060208a013567ffffffffffffffff8082111561479957600080fd5b6147a58d838e01614092565b909a50985060408c01359150808211156147be57600080fd5b6147ca8d838e01614092565b909850965060608c0135955060808c01359150808211156147ea57600080fd5b506147f78c828d01614092565b9a9d999c50979a9699959894979660a00135949350505050565b803560ff8116811461111257600080fd5b6000806040838503121561483557600080fd5b823561484081614526565b915061484e60208401614811565b90509250929050565b80356005811061111257600080fd5b600080600080600080600060a0888a03121561488157600080fd5b87359650602088013567ffffffffffffffff808211156148a057600080fd5b6148ac8b838c01614092565b90985096508691506148c060408b01614857565b955060608a01359150808211156148d657600080fd5b506148e38a828b01614092565b989b979a50959894979596608090950135949350505050565b6000806020838503121561490f57600080fd5b823567ffffffffffffffff81111561492657600080fd5b61493285828601614092565b90969095509350505050565b6000806040838503121561495157600080fd5b823567ffffffffffffffff8082111561496957600080fd5b614975868387016143d5565b9350602085013591508082111561498b57600080fd5b50614998858286016143d5565b9150509250929050565b600080600080606085870312156149b857600080fd5b84356149c381614526565b935060208501359250604085013567ffffffffffffffff8111156149e657600080fd5b61438287828801614092565b60008060408385031215614a0557600080fd5b8235614a1081614526565b946020939093013593505050565b60008060208385031215614a3157600080fd5b823567ffffffffffffffff811115614a4857600080fd5b614932858286016142dd565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015614aa957603f19888603018452614a978583516141d2565b94509285019290850190600101614a7b565b5092979650505050505050565b80151581146114d557600080fd5b600060208284031215614ad657600080fd5b8135610b8681614ab6565b60008060008060408587031215614af757600080fd5b843567ffffffffffffffff80821115614b0f57600080fd5b614b1b88838901614092565b90965094506020870135915080821115614b3457600080fd5b5061438287828801614092565b60008060008060008060808789031215614b5a57600080fd5b86359550602087013567ffffffffffffffff80821115614b7957600080fd5b614b858a838b01614092565b90975095506040890135915080821115614b9e57600080fd5b50614bab89828a01614092565b979a9699509497949695606090950135949350505050565b60008060008060008060008060e0898b031215614bdf57600080fd5b88359750602089013567ffffffffffffffff80821115614bfe57600080fd5b614c0a8c838d01614092565b909950975060408b0135915080821115614c2357600080fd5b614c2f8c838d016143d5565b965060608b0135915080821115614c4557600080fd5b614c518c838d016143d5565b9550614c5f60808c01614811565b945060a08b0135915080821115614c7557600080fd5b50614c828b828c016143d5565b92505060c089013590509295985092959890939650565b600060208284031215614cab57600080fd5b8151610b8681614526565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060018201614d0257634e487b7160e01b600052601160045260246000fd5b5060010190565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b868152608060208201526000614d5c608083018789614d19565b8281036040840152614d6f818688614d19565b915050826060830152979650505050505050565b600060208284031215614d9557600080fd5b8151610b8681614ab6565b606081526000614db4606083018789614d19565b8281036020840152614dc7818688614d19565b9150508260408301529695505050505050565b60008060008060808587031215614df057600080fd5b8435935060208501359250604085013567ffffffffffffffff811115614e1557600080fd5b614e21878288016143d5565b949793965093946060013593505050565b60058110614e5057634e487b7160e01b600052602160045260246000fd5b9052565b60208101610d4a8284614e32565b600060208284031215614e7457600080fd5b5051919050565b60208152600061447a602083018486614d19565b60008251614ea18184602087016141ae565b9190910192915050565b6000808335601e19843603018112614ec257600080fd5b83018035915067ffffffffffffffff821115614edd57600080fd5b602001915036819003821315612cd157600080fd5b604081526000614f0560408301856141d2565b90506001600160a01b03831660208301529392505050565b600181811c90821680614f3157607f821691505b602082108103614f5157634e487b7160e01b600052602260045260246000fd5b50919050565b82815260406020820152600061447a60408301846141d2565b60008060008060008060c08789031215614f8957600080fd5b8635955060208701359450604087013567ffffffffffffffff80821115614faf57600080fd5b614fbb8a838b016143d5565b95506060890135915080821115614fd157600080fd5b614fdd8a838b016143d5565b94506080890135935060a0890135915080821115614ffa57600080fd5b5061500789828a016143d5565b9150509295509295509295565b608081526000615028608083018789614d19565b828103602084015261503a81876141d2565b60408401959095525050606001529392505050565b88815260e06020820152600061506960e08301898b614d19565b828103604084015261507b81896141d2565b9050828103606084015261508f81886141d2565b608084019690965250506001600160a01b039290921660a083015260c09091015295945050505050565b600080600080608085870312156150cf57600080fd5b84359350602085013592506150e660408601614857565b9150606085013567ffffffffffffffff81111561510257600080fd5b61510e878288016143d5565b91505092959194509250565b60008060008060008060c0878903121561513357600080fd5b8635955060208701359450604087013567ffffffffffffffff8082111561515957600080fd5b6151658a838b016143d5565b9550606089013591508082111561517b57600080fd5b6151878a838b016143d5565b945061519560808a01614811565b935060a0890135915080821115614ffa57600080fd5b600080604083850312156151be57600080fd5b8251915060208301516151d081614526565b809150509250929050565b6060815260006151ef606083018688614d19565b828103602084015261520181866141d2565b91505082604083015295945050505050565b86815285602082015260c06040820152600061523260c08301876141d2565b828103606084015261524481876141d2565b905084608084015282810360a084015261525e81856141d2565b9998505050505050505050565b6000808585111561527b57600080fd5b8386111561528857600080fd5b5050820193919092039150565b6001600160e01b031981358181169160048510156152bd5780818660040360031b1b83161692505b505092915050565b8a815289602082015260e0604082015260006152e560e083018a8c614d19565b82810360608401526152f881898b614d19565b905086608084015282810360a0840152615313818688614d19565b9150508260c08301529b9a5050505050505050505050565b83815261533b6020820184614e32565b60606040820152600061535160608301846141d2565b95945050505050565b6001600160a01b038316815260406020820152600061447a60408301846141d2565b604081526000615390604083018587614d19565b82810360208401526153a281856141d2565b9695505050505050565b8481528360208201526153c26040820184614e32565b6080606082015260006153a260808301846141d2565b600082601f8301126153e957600080fd5b8135602067ffffffffffffffff808311156154065761540661438e565b8260051b6154158382016143a4565b938452858101830193838101908886111561542f57600080fd5b84880192505b8583101561546b5782358481111561544d5760008081fd5b61545b8a87838c01016143d5565b8352509184019190840190615435565b98975050505050505050565b6000806000806080858703121561548d57600080fd5b843561549881614526565b9350602085013567ffffffffffffffff808211156154b557600080fd5b6154c1888389016143d5565b945060408701359150808211156154d757600080fd5b6154e3888389016153d8565b935060608701359150808211156154f957600080fd5b5061510e878288016153d8565b60408152600061551960408301856141d2565b828103602084015261535181856141d2565b87815286602082015260a06040820152600061554b60a083018789614d19565b828103606084015261555e818688614d19565b91505082608083015298975050505050505050565b8681528560208201526001600160a01b038516604082015260c0606082015260006155a160c08301866141d2565b82810360808401526155b381866141d2565b91505060ff831660a0830152979650505050505050565b6001600160a01b03851681526080602082015260006155ec60808301866141d2565b82810360408401526155fe81866141d2565b91505060ff8316606083015295945050505050565b60a08152600061562660a08301896141d2565b828103602084015261563881896141d2565b905060ff87166040840152828103606084015261565581876141d2565b9050828103608084015261525e818587614d19565b86815285602082015260c06040820152600061568960c08301876141d2565b828103606084015261569b81876141d2565b905060ff8516608084015282810360a084015261525e81856141d2565b60006001600160a01b03808916835260a060208401526156dc60a08401888a614d19565b83810360408501526156ee81886141d2565b9050838103606085015261570281876141d2565b925050808416608084015250979650505050505050565b60608152600061572d606083018688614d19565b828103602084015261573f81866141d2565b9050828103604084015261575381856141d2565b979650505050505050565b601f8211156124c557600081815260208120601f850160051c810160208610156157855750805b601f850160051c820191505b8181101561240657828155600101615791565b815167ffffffffffffffff8111156157be576157be61438e565b6157d2816157cc8454614f1d565b8461575e565b602080601f83116001811461580757600084156157ef5750858301515b600019600386901b1c1916600185901b178555612406565b600085815260208120601f198616915b8281101561583657888601518255948401946001909101908401615817565b50858210156158545787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056feee35723ac350a69d2a92d3703f17439cbaadf2f093a21ba5bf5f1a53eb2a14d8a2646970667358221220dc8540c7b8e2a681cfd9d2e77116365c3c98a566393ebb31308862b395663e1364736f6c63430008150033608060405234801561001057600080fd5b50610162806100206000396000f3fe60806040526004361061001d5760003560e01c806277436014610022575b600080fd5b61003561003036600461007b565b610037565b005b8051602082016000f061004957600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561008d57600080fd5b813567ffffffffffffffff808211156100a557600080fd5b818401915084601f8301126100b957600080fd5b8135818111156100cb576100cb61004c565b604051601f8201601f19908116603f011681019083821181831017156100f3576100f361004c565b8160405282815287602084870101111561010c57600080fd5b82602086016020830137600092810160200192909252509594505050505056fea264697066735822122094780ce55d28f1d568f4e0ab1b9dc230b96e952b73d2e06456fbff2289fa27f464736f6c63430008150033000000000000000000000000121b0e54cd7ad2bbcb4c4c9275697978ebaf365300000000000000000000000058667c5f134420bf6904c7dd01fddcb4fea3a760000000000000000000000000e432150cce91c13a887f7d836923d5597add8e310000000000000000000000002d5d7d31f671f86c782533cc367f14109a08271200000000000000000000000083a93500d23fbc3e82b410ad07a6a9f7a0670d66000000000000000000000000000000000000000000000000000000000000010000000000000000000000000081a0545091864617e7037171fdfcbbdcfe3aeb2300000000000000000000000007715674f74c560200c7c95430673180812fce7300000000000000000000000000000000000000000000000000000000000000076672617874616c00000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106103555760003560e01c8063864a0dcf116101bb578063c8bb7067116100f7578063e30c397811610095578063e82e71f81161006f578063e82e71f814610a96578063f2fde38b14610ab6578063f8c8a82614610ad6578063ffd5982a14610af657600080fd5b8063e30c397814610a34578063e4a974cc14610a68578063e7e3ffc814610a7657600080fd5b8063da081c73116100d1578063da081c73146109ce578063da4886df146109e1578063dc88dfd114610a01578063e1d40c7714610a2157600080fd5b8063c8bb70671461095a578063ca58b6441461097a578063d8dab96b146109ae57600080fd5b80639f409d7711610164578063ac9650d81161013e578063ac9650d8146108da578063c38bb537146108fa578063c506bff41461091a578063c7e6a3cc1461093a57600080fd5b80639f409d771461087a578063a3499c731461089a578063a5269ef1146108ba57600080fd5b806395a8c58d1161019557806395a8c58d1461082757806398d78c82146108475780639ded06df1461085a57600080fd5b8063864a0dcf1461079f578063868a166d146107d35780638da5cb5b146107f357600080fd5b80635a6fd76e116102955780636f3eef621161023357806379ba50971161020d57806379ba5097146106ed5780637e151fa6146107025780638291286c1461074257806383d296961461077f57600080fd5b80636f3eef621461069a57806370756cde146106ba578063710bf322146106cd57600080fd5b8063656576361161026f57806365657636146105ff5780636a22d8cc146106125780636ac0d112146106465780636d70f7ae1461067a57600080fd5b80635a6fd76e1461057d5780635c60da1b1461059d5780635c975abb146105d157600080fd5b80632a709b141161030257806349160658116102dc57806349160658146104f65780634a6a42d8146105165780634b4578ba146105365780634f9ae6081461054957600080fd5b80632a709b1414610482578063465a09e0146104b6578063477aedc7146104d657600080fd5b80631b3d6e87116103335780631b3d6e87146103ed5780631c93b03a146104215780631f26d7301461044357600080fd5b8063116191b61461035a5780631a083d39146103ab5780631a98b2e0146103cb575b600080fd5b34801561036657600080fd5b5061038e7f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e3181565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156103b757600080fd5b5061038e6103c6366004614079565b610b16565b3480156103d757600080fd5b506103eb6103e63660046140d4565b610b8d565b005b3480156103f957600080fd5b5061038e7f00000000000000000000000007715674f74c560200c7c95430673180812fce7381565b34801561042d57600080fd5b50610436610ba6565b6040516103a291906141fe565b34801561044f57600080fd5b5061046361045e366004614211565b610bd6565b604080516001600160a01b0390931683526020830191909152016103a2565b34801561048e57600080fd5b5061038e7f00000000000000000000000081a0545091864617e7037171fdfcbbdcfe3aeb2381565b3480156104c257600080fd5b506103eb6104d1366004614322565b610bf2565b3480156104e257600080fd5b506104366104f1366004614445565b610d37565b34801561050257600080fd5b506103eb610511366004614482565b610d50565b34801561052257600080fd5b506103eb61053136600461453b565b610faf565b6103eb610544366004614558565b610ff5565b34801561055557600080fd5b5061038e7f00000000000000000000000058667c5f134420bf6904c7dd01fddcb4fea3a76081565b34801561058957600080fd5b5061038e610598366004614079565b6110be565b3480156105a957600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5461038e565b3480156105dd57600080fd5b50600080516020615865833981519152545b60405190151581526020016103a2565b6103eb61060d366004614482565b611117565b34801561061e57600080fd5b5061038e7f0000000000000000000000002d5d7d31f671f86c782533cc367f14109a08271281565b34801561065257600080fd5b5061038e7f000000000000000000000000121b0e54cd7ad2bbcb4c4c9275697978ebaf365381565b34801561068657600080fd5b506105ef61069536600461453b565b6112e1565b3480156106a657600080fd5b506103eb6106b536600461453b565b6112ee565b6103eb6106c8366004614608565b611330565b3480156106d957600080fd5b506103eb6106e836600461453b565b61138f565b3480156106f957600080fd5b506103eb61145e565b34801561070e57600080fd5b5061038e61071d366004614079565b507f00000000000000000000000081a0545091864617e7037171fdfcbbdcfe3aeb2390565b34801561074e57600080fd5b507ff407da03daa7b4243ffb261daad9b01d221ea90ab941948cd48101563654ea865b6040519081526020016103a2565b34801561078b57600080fd5b5061046361079a3660046146c2565b6114d8565b3480156107ab57600080fd5b506107717f39520897016aaf0ab8e5bf7b0c72c0875359483112298e4b64220a3abfb31c1a81565b3480156107df57600080fd5b5061038e6107ee36600461475c565b61158e565b3480156107ff57600080fd5b507f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05461038e565b34801561083357600080fd5b506105ef610842366004614822565b6115b2565b610771610855366004614866565b6115cd565b34801561086657600080fd5b506103eb6108753660046148fc565b61174f565b34801561088657600080fd5b506103eb61089536600461493e565b6117bb565b3480156108a657600080fd5b506103eb6108b53660046149a2565b611815565b3480156108c657600080fd5b506107716108d53660046149f2565b611b07565b6108ed6108e8366004614a1e565b611b6e565b6040516103a29190614a54565b34801561090657600080fd5b506103eb610915366004614ac4565b611cc7565b34801561092657600080fd5b506105ef610935366004614ae1565b611d2d565b34801561094657600080fd5b5061038e610955366004614b41565b611d93565b34801561096657600080fd5b50610771610975366004614079565b611db1565b34801561098657600080fd5b5061038e7f00000000000000000000000083a93500d23fbc3e82b410ad07a6a9f7a0670d6681565b3480156109ba57600080fd5b506107716109c9366004614079565b611e21565b6103eb6109dc36600461475c565b611e6d565b3480156109ed57600080fd5b506103eb6109fc36600461453b565b611f11565b348015610a0d57600080fd5b506103eb610a1c366004614445565b611f1d565b610771610a2f366004614bc3565b611f76565b348015610a4057600080fd5b507f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d15461038e565b6103eb6103e63660046140d4565b348015610a8257600080fd5b50610771610a91366004614079565b612057565b348015610aa257600080fd5b5061038e610ab1366004614079565b6120a3565b348015610ac257600080fd5b506103eb610ad136600461453b565b6120b9565b348015610ae257600080fd5b5061038e610af1366004614079565b612109565b348015610b0257600080fd5b50610771610b11366004614445565b612114565b600080610b22836110be565b9050806001600160a01b0316639d76ea586040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b869190614c99565b9392505050565b6040516327616c7360e11b815260040160405180910390fd5b6060610bd17f0e2c162a1f4b5cff9fdbd6b34678a9bcb9898a0b9fbca695b112d61688d8b2ac612128565b905090565b6000806040516327616c7360e11b815260040160405180910390fd5b6001610c0d610c00336121bb565b600160ff84161b16151590565b610c3a5760405163bb6c163960e01b815233600482015260ff821660248201526044015b60405180910390fd5b83828114610c74576040517fff633a3800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d2e576000610ca2888884818110610c9657610c96614ccc565b905060200201356110be565b9050806001600160a01b031663a56dbe63878785818110610cc557610cc5614ccc565b905060200201356040518263ffffffff1660e01b8152600401610cea91815260200190565b600060405180830381600087803b158015610d0457600080fd5b505af1158015610d18573d6000803e3d6000fd5b505050505080610d2790614ce2565b9050610c77565b50505050505050565b6060610d4a610d45836121c7565b612128565b92915050565b85858585610d6084848484611d2d565b610d7d5760405163157e5fbf60e21b815260040160405180910390fd5b6000805160206158658339815191525415610dab576040516334c2d01160e11b815260040160405180910390fd5b60008686604051610dbd929190614d09565b6040519081900381207f5f6970c300000000000000000000000000000000000000000000000000000000825291506001600160a01b037f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e311690635f6970c390610e34908f908f908f908f908f908990600401614d42565b6020604051808303816000875af1158015610e53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e779190614d83565b610ead576040517f500c44b400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610ebb87890189614079565b905080610f42576000610ed28e8e8e8e8e88612219565b9050610ee28e828f8f8d8d612246565b6001600160a01b03811615610f3c57806001600160a01b03168e7f8fe61b2d4701a29265508750790e322b2c214399abdf98472158b8908b660d418f8f8f8f89604051610f33959493929190614da0565b60405180910390a35b50610fa0565b60028103610f5957610f54888861240e565b610fa0565b60018103610f6b57610f54888861246d565b6040517f495f232e00000000000000000000000000000000000000000000000000000000815260048101829052602401610c31565b50505050505050505050505050565b6001610fbd610c00336121bb565b610fe55760405163bb6c163960e01b815233600482015260ff82166024820152604401610c31565b610ff1338360016124b4565b5050565b6000805160206158658339815191525415611023576040516334c2d01160e11b815260040160405180910390fd5b815160000361105e576040517f99d8fec900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61106b88338560006124ca565b92506110b48833898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508c935091508a905089612762565b5050505050505050565b60006110c982612109565b9050806001600160a01b03163b600003611112576040517f2dd85afc00000000000000000000000000000000000000000000000000000000815260048101839052602401610c31565b919050565b6000805160206158658339815191525415611145576040516334c2d01160e11b815260040160405180910390fd5b600061115382840184614079565b905080156111775760405163e94617f560e01b815260048101829052602401610c31565b6040517fd26ff210000000000000000000000000000000000000000000000000000000008152600481018990527f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e316001600160a01b03169063d26ff21090602401602060405180830381865afa1580156111f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112199190614d83565b15611250576040517f0dc1019700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405133906000906112659086908690614d09565b60405180910390209050816001600160a01b03168a7f6e18757e81c44a367109cbaa499add16f2ae7168aab9715c3cdc36b0f7ccce928b8b8b8b876040516112b1959493929190614da0565b60405180910390a36112c88a8a8a8a8a868861280c565b6112d58a8a8a888861286c565b50505050505050505050565b6000610d4a8260016115b2565b60016112fc610c00336121bb565b6113245760405163bb6c163960e01b815233600482015260ff82166024820152604401610c31565b610ff133836001612bf4565b600080516020615865833981519152541561135e576040516334c2d01160e11b815260040160405180910390fd5b61136b88888560016124ca565b925060008061137a8484612c05565b915091506112d58a8a8a8a8a8a888834612762565b336113b87f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b0316146113df576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b03811661140657604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907fd9be0e8e07417e00f2521db636cb53e316fd288f5051f16d2aa2bf0c3938a87690600090a27f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b60006114887f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d15490565b90506001600160a01b03811633146114cc576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114d581612cd8565b50565b600080878787876114eb84848484611d2d565b6115085760405163157e5fbf60e21b815260040160405180910390fd5b6000805160206158658339815191525415611536576040516334c2d01160e11b815260040160405180910390fd5b600080806115468a8c018c614dda565b93505092509250600083146115715760405163e94617f560e01b815260048101849052602401610c31565b61157a82610b16565b9f909e509c50505050505050505050505050565b6000806115a28b8b8b8b8b8b8b8b8b612d7b565b549b9a5050505050505050505050565b6000610b866115c0846121bb565b600160ff85161b16151590565b60006115e56000805160206158658339815191525490565b15611603576040516334c2d01160e11b815260040160405180910390fd5b600085600481111561161757611617614cb6565b036116375784604051630a7dda8360e01b8152600401610c319190614e54565b336001600160a01b037f00000000000000000000000083a93500d23fbc3e82b410ad07a6a9f7a0670d6616810361166c575060005b611676818a611b07565b915088816001600160a01b0316837f04ddbfaa222e81ab9447c070310e87608bf6a4c5d42be5c2fdf0f370b186af7960405160405180910390a460008790036116ff576116fa828787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612de592505050565b611743565b611743828989868a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612fce92505050565b50979650505050505050565b307f0000000000000000000000006d59d9360bdae406614b7e61c53f43a03198a4ef6001600160a01b0316036117b1576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ff1828261305f565b336117e47f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b03161461180b576040516330cd747160e01b815260040160405180910390fd5b610ff182826131ca565b3361183e7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614611865576040516330cd747160e01b815260040160405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b0316638291286c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e89190614e62565b846001600160a01b0316638291286c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611926573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194a9190614e62565b14611981576040517f68155f9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836001600160a01b03163f83146119c4576040517f8f84fb2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b038516907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a28015611ae0576000846001600160a01b0316639ded06df60e01b8484604051602401611a25929190614e7b565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051611a639190614e8f565b600060405180830381855af49150503d8060008114611a9e576040519150601f19603f3d011682016040523d82523d6000602084013e611aa3565b606091505b5050905080611ade576040517f97905dfb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b5050507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b604080517f980c3be34c7ee75cc250c76223092614e21653cdf2faece10ac24fcef821df1060208201526001600160a01b03841691810191909152606081018290526000906080015b60405160208183030381529060405280519060200120905092915050565b60608167ffffffffffffffff811115611b8957611b8961438e565b604051908082528060200260200182016040528015611bbc57816020015b6060815260200190600190039081611ba75790505b5090506000606060005b84811015611cbe5730868683818110611be157611be1614ccc565b9050602002810190611bf39190614eab565b604051611c01929190614d09565b600060405180830381855af49150503d8060008114611c3c576040519150601f19603f3d011682016040523d82523d6000602084013e611c41565b606091505b50909350915082611c8f578151600003611c87576040517f4d6a232800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815182602001fd5b81848281518110611ca257611ca2614ccc565b602002602001018190525080611cb790614ce2565b9050611bc6565b50505092915050565b33611cf07f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614611d17576040516330cd747160e01b815260040160405180910390fd5b8015611d25576114d5613279565b6114d56132bd565b6000808383604051611d40929190614d09565b60405180910390209050611d8986868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061211492505050565b1495945050505050565b600080611da4888888888888613301565b5498975050505050505050565b600080611dbd836110be565b9050806001600160a01b0316637dbab19b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b869190614e62565b600080611e2d836110be565b9050806001600160a01b0316632f3c78886040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dfd573d6000803e3d6000fd5b6000805160206158658339815191525415611e9b576040516334c2d01160e11b815260040160405180910390fd5b611ea889338660006124ca565b9350600080611eb78585612c05565b91509150611f048b338c8c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508e92508a91508990508b612762565b5050505050505050505050565b6114d581336001613362565b33611f467f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614611f6d576040516330cd747160e01b815260040160405180910390fd5b6114d581613373565b6000611f8e6000805160206158658339815191525490565b15611fac576040516334c2d01160e11b815260040160405180910390fd5b336001600160a01b037f00000000000000000000000083a93500d23fbc3e82b410ad07a6a9f7a0670d66168103611fe1575060005b611feb818b611b07565b9150600088900361203a57600061200583868a8a8a6133f2565b90506120348360008784604051602001612020929190614ef2565b604051602081830303815290604052612de5565b5061204a565b61204a82888888888e8e8a61357f565b5098975050505050505050565b600080612063836110be565b9050806001600160a01b0316638b38b35d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dfd573d6000803e3d6000fd5b60006120ae82613613565b9150610d4a8261364e565b336120e27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b0316146114cc576040516330cd747160e01b815260040160405180910390fd5b6000610d4a8261364e565b60008061212083613750565b549392505050565b606081805461213690614f1d565b80601f016020809104026020016040519081016040528092919081815260200182805461216290614f1d565b80156121af5780601f10612184576101008083540402835291602001916121af565b820191906000526020600020905b81548152906001019060200180831161219257829003601f168201915b50505050509050919050565b60008061212083613785565b60007fa5b4aa1bcb538076d57d083e3004c6907e2eba42d84c21922d441967a02b472f826040516020016121fc929190614f57565b604051602081830303815290604052805190602001209050919050565b60008061222a888888888888613301565b905080549150811561223b57600081555b509695505050505050565b600060608180828061225a87890189614f70565b939a5091985090955090935091506122739050816137d5565b9350506001600160a01b038a161561229c57612290858b8461381c565b50505050505050612406565b60006122a986858561381c565b8092508194505050836001600160a01b0316868d7fbdb65cfd017af0876344138f62bc895163b5fd120cbe6e666ed306afd658de4b8d8d8a8989516000146122f757895160208b01206122fa565b60005b60405161230b959493929190615014565b60405180910390a48151156123ff576000846001600160a01b031663292415028e8d8d8a888d898c6040518963ffffffff1660e01b815260040161235698979695949392919061504f565b6020604051808303816000875af1158015612375573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123999190614e62565b90507fe84001f3dedacf7f9ddc370e9f09c26b37473e9e959ffdc4925f6fe33c9877e48114610fa0576040517f1ef6f3b30000000000000000000000000000000000000000000000000000000081526001600160a01b0386166004820152602401610c31565b5050505050505b505050505050565b6000808061241e848601866150b9565b919550935091506000905082600481111561243b5761243b614cb6565b0361245b5781604051630a7dda8360e01b8152600401610c319190614e54565b612466838383612de5565b5050505050565b60008080808061247f8688018861511a565b9550955095509550955050600061249986838787876133f2565b90506110b48660008484604051602001612020929190614ef2565b6124c58383600160ff85161b613a57565b505050565b6000806124d686612109565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa158015612518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061253c91906151ab565b90925090508480156125575750336001600160a01b03821614155b1561259f576040517f409304db0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0382166024820152604401610c31565b60408051602481018490526001600160a01b0383811660448301528581166064830152898116608483015260a48083018a90528351808403909101815260c490920183526020820180516001600160e01b03167fb2668ef600000000000000000000000000000000000000000000000000000000179052915160009283927f00000000000000000000000007715674f74c560200c7c95430673180812fce739091169161264c9190614e8f565b600060405180830381855af49150503d8060008114612687576040519150601f19603f3d011682016040523d82523d6000602084013e61268c565b606091505b5091509150816126ca57806040517f1a59c9bd000000000000000000000000000000000000000000000000000000008152600401610c3191906141fe565b808060200190518101906126de9190614e62565b6040517fdce29136000000000000000000000000000000000000000000000000000000008152600481018290529098506001600160a01b0386169063dce2913690602401600060405180830381600087803b15801561273c57600080fd5b505af1158015612750573d6000803e3d6000fd5b50999c9b505050505050505050505050565b8151156127755781516020830120612778565b60005b886001600160a01b03168a7fcd05f5b9dc4bb03babf40f5da98f5f46819846207d916f89b67d36fd1f7fd74f8a8a8a8a6040516127b894939291906151db565b60405180910390a46000808a6127d68b6001600160a01b0316613aad565b8888876040516020016127ee96959493929190615213565b60405160208183030381529060405290506112d58888838786613adb565b600061281c888888888888613301565b80549091506001600160a01b03811615612862576040517f725f13f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5055505050505050565b60008080808061287e86880188614f70565b95509550955095509550506000612894846137d5565b90506000806128a288612109565b9050806001600160a01b0316639d76ea586040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129069190614c99565b91506000807f00000000000000000000000007715674f74c560200c7c95430673180812fce736001600160a01b03166345537d7060e01b846001600160a01b0316634fdf7cb56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561297b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299f9190614e62565b60405160248101919091526001600160a01b0380881660448301523360648301528816608482015260a481018a905260c40160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612a0f9190614e8f565b600060405180830381855af49150503d8060008114612a4a576040519150601f19603f3d011682016040523d82523d6000602084013e612a4f565b606091505b509150915081612a8d57806040517f3a5cf905000000000000000000000000000000000000000000000000000000008152600401610c3191906141fe565b80806020019051810190612aa19190614e62565b9650505050816001600160a01b0316878d7fbdb65cfd017af0876344138f62bc895163b5fd120cbe6e666ed306afd658de4b8e8e8b8a8a51600014612aec578a5160208c0120612aef565b60005b604051612b00959493929190615014565b60405180910390a48251156123ff576000826001600160a01b03166377c790258e8e8e8b898e898d6040518963ffffffff1660e01b8152600401612b4b98979695949392919061504f565b6020604051808303816000875af1158015612b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b8e9190614e62565b90507f692b2deb10f974787eb65450ba9a90dc0bb28141a633fa3fb556d5292fba42e18114610fa0576040517fc646a6230000000000000000000000000000000000000000000000000000000081526001600160a01b0384166004820152602401610c31565b6124c58383600160ff85161b613d77565b600060606004831015612c1b5760009150612cd1565b6000612c2a600482868861526b565b612c3391615295565b60e01c90506001811115612c625760405163b47a9b4b60e01b815263ffffffff82166004820152602401610c31565b8063ffffffff166001811115612c7a57612c7a614cb6565b92506004849003612c8b5750612cd1565b612c98846004818861526b565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929450505050505b9250929050565b6001600160a01b038116612cff57604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616390600090a27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05560007f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b60007febf4535caee8019297b7be3ed867db0d00b69fedcdda98c5e2c41ea6e41a98d58a8a8a8a8a8a8a8a8a604051602001612dc09a999897969594939291906152c5565b6040516020818303038152906040528051906020012090509998505050505050505050565b6000807f000000000000000000000000121b0e54cd7ad2bbcb4c4c9275697978ebaf36536001600160a01b0316636519d04b60e01b868686604051602401612e2f9392919061532b565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612e6d9190614e8f565b600060405180830381855af49150503d8060008114612ea8576040519150601f19603f3d011682016040523d82523d6000602084013e612ead565b606091505b509150915081612eeb57806040517ff9eef82a000000000000000000000000000000000000000000000000000000008152600401610c3191906141fe565b60208101516002856004811115612f0457612f04614cb6565b1480612f2157506003856004811115612f1f57612f1f614cb6565b145b15612f7a57806001600160a01b031663274158386040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612f6157600080fd5b505af1158015612f75573d6000803e3d6000fd5b505050505b846004811115612f8c57612f8c614cb6565b867f5284c2478b9c1a55e973429331078be39b5fb3eeb9d87d10b34d65a4c89ee4eb8387604051612fbe92919061535a565b60405180910390a3505050505050565b612fd7866110be565b50816004811115612fea57612fea614cb6565b867fc92a73c79b84dd58e39d4e09fbf47f3f8bd145222bfff3d803eec161bed1c19487878560405161301e9392919061537c565b60405180910390a36000600287848460405160200161304094939291906153ac565b6040516020818303038152906040529050610d2e868683600088613adb565b600080808061307085870187615477565b8151939750919550935091506001600160a01b0385166130bc576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835115806130f05750835160208501207f39520897016aaf0ab8e5bf7b0c72c0875359483112298e4b64220a3abfb31c1a14155b15613127576040517f08e1064e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81518114613161576040517fff633a3800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61316a85613e0f565b61317384613e1a565b60005b818110156110b4576131ba84828151811061319357613193614ccc565b60200260200101518483815181106131ad576131ad614ccc565b60200260200101516131ca565b6131c381614ce2565b9050613176565b81516000036131ec5760405163deba168960e01b815260040160405180910390fd5b805160000361320e5760405163deba168960e01b815260040160405180910390fd5b61322061321a836121c7565b82613e40565b600061322b83613750565b82516020840120808255604051919250907fdb6b260ea45f7fe513e1d3b8c21017a29e3a41610e95aefb8862b81c69aec61c9061326b9086908690615506565b60405180910390a150505050565b613290600160008051602061586583398151915255565b60405133907f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890600090a2565b6132d4600060008051602061586583398151915255565b60405133907f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90600090a2565b60007f2a41fec9a0df4e0996b975f71622c7164b0f652ea69d9dbcd6b24e81b20ab5e5878787878787604051602001613340979695949392919061552b565b6040516020818303038152906040528051906020012090509695505050505050565b6124c58383600160ff85161b613e4b565b80516000036133955760405163deba168960e01b815260040160405180910390fd5b6133a66133a1826121c7565b613ebe565b60006133b182613750565b9050600081557ff9400637a329865492b8d0d4dba4eafc7e8d5d0fae5e27b56766816d2ae1b2ca826040516133e691906141fe565b60405180910390a15050565b6000806133fe87613613565b90506000865160001461341757613414876137d5565b90505b6000807f00000000000000000000000058667c5f134420bf6904c7dd01fddcb4fea3a7606001600160a01b031663f575f35b60e01b858c868c8c8c60405160240161346796959493929190615573565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516134a59190614e8f565b600060405180830381855af49150503d80600081146134e0576040519150601f19603f3d011682016040523d82523d6000602084013e6134e5565b606091505b50915091508161352357806040517fc226af8b000000000000000000000000000000000000000000000000000000008152600401610c3191906141fe565b60208101519450826001600160a01b03168a7ff0d7beb2b03d35e597f432391dc2a6f6eb1a621be6cb5b325f55a49090085239878b8b8b60405161356a94939291906155ca565b60405180910390a35050505095945050505050565b613588886110be565b50877fe470f4bdd33c8676127d3c20ff725d8dc1605609001389ce3a59c28b54b7992f8888888888886040516135c396959493929190615613565b60405180910390a26000600189898989896040516020016135e99695949392919061566a565b6040516020818303038152906040529050613608848483600086613adb565b505050505050505050565b604080517f610507e221586f499adb972fbdbe7f0619bdae0112c78ebaa562448d0ca7071f60208201529081018290526000906060016121fc565b604080517fff0000000000000000000000000000000000000000000000000000000000000060208083019190915230606090811b6bffffffffffffffffffffffff19908116602185015260358401959095527fdb4bab1640a2602c9f66f33765d12be4af115accf74b24515702961e82a71327605580850191909152845180850390910181526075840185528051908301207fd6940000000000000000000000000000000000000000000000000000000000006095850152901b90931660978201527f010000000000000000000000000000000000000000000000000000000000000060ab8201528151608c81830301815260ac909101909152805191012090565b60007f5f58fea7d48d37d5d1cc2546dfcc3d3cbfe8d758d5ca19c44087f52e15a10505826040516020016121fc929190614f57565b60007fde9bdca322e1a848f72215bc15cf2c87fe7749145789a9ee281a2a6290af26ab826040516020016121fc92919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b6000815160141461381457816040517fd08dbec5000000000000000000000000000000000000000000000000000000008152600401610c3191906141fe565b506014015190565b600080600061382a86612109565b9050600080826001600160a01b031663d4ae3c426040518163ffffffff1660e01b81526004016040805180830381865afa15801561386c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061389091906151ab565b6040517f10d8d8e30000000000000000000000000000000000000000000000000000000081526004810189905291935091506001600160a01b038416906310d8d8e390602401600060405180830381600087803b1580156138f057600080fd5b505af1158015613904573d6000803e3d6000fd5b505060408051602481018690526001600160a01b03858116604483015287811660648301528b8116608483015260a48083018c90528351808403909101815260c490920183526020820180516001600160e01b03167f72689126000000000000000000000000000000000000000000000000000000001790529151600094508493507f00000000000000000000000007715674f74c560200c7c95430673180812fce73909216916139b59190614e8f565b600060405180830381855af49150503d80600081146139f0576040519150601f19603f3d011682016040523d82523d6000602084013e6139f5565b606091505b509150915081613a3357806040517f0f940973000000000000000000000000000000000000000000000000000000008152600401610c3191906141fe565b80806020019051810190613a479190614e62565b9a92995091975050505050505050565b613a6a613a63846121bb565b8216821490565b613a9957604051631fe9beed60e21b81526001600160a01b038416600482015260248101829052604401610c31565b613aa38382613ec9565b6124c58282613f2b565b6040805160148082528183019092526060916020820181803683375050506014808201939093529182525090565b6000613b1c86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610d3792505050565b90508051600003613b59576040517ff9188a6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115613cde576000836001811115613b7357613b73614cb6565b03613c20576040517f0c93e3bb0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827121690630c93e3bb908490613be99030908b908b9088908c9032906004016156b8565b6000604051808303818588803b158015613c0257600080fd5b505af1158015613c16573d6000803e3d6000fd5b5050505050613cde565b6001836001811115613c3457613c34614cb6565b03613caa576040517ff61ed2180000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000002d5d7d31f671f86c782533cc367f14109a082712169063f61ed218908490613be99030908b908b9088908c9032906004016156b8565b826001811115613cbc57613cbc614cb6565b60405163b47a9b4b60e01b815263ffffffff9091166004820152602401610c31565b6040517f1c92115f0000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e311690631c92115f90613d49908990899086908a90600401615719565b600060405180830381600087803b158015613d6357600080fd5b505af11580156112d5573d6000803e3d6000fd5b613d83613a63846121bb565b613db257604051631fe9beed60e21b81526001600160a01b038416600482015260248101829052604401610c31565b613dbd838383613f7f565b816001600160a01b0316836001600160a01b03167ff7158d1591c2cf17c0e6b9459d86365c47fe0969c79f40ef49e0c437d8f3991483604051613e0291815260200190565b60405180910390a3505050565b6114d5816001613f94565b6114d57f0e2c162a1f4b5cff9fdbd6b34678a9bcb9898a0b9fbca695b112d61688d8b2ac825b816124c582826157a4565b80613e568484613fa4565b14613ea7576040517f6004fe400000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301528316602482015260448101829052606401610c31565b613eb383836000613f7f565b6124c5838383613a57565b6114d581600061402b565b60008119613ed6846121bb565b169050613ee38382613fba565b826001600160a01b03167fccf920c8facee98a9c2a6c6124f2857b87b17e9f3a819bfcc6945196ee77366b83604051613f1e91815260200190565b60405180910390a2505050565b600081613f37846121bb565b179050613f448382613fba565b826001600160a01b03167f34e73c57659d4b6809b53db4feee9b007b892e978114eda420d2991aba15014383604051613f1e91815260200190565b6000613f8b8484613fcd565b91909155505050565b610ff182600160ff84161b613f2b565b600080613fb18484613fcd565b54949350505050565b6000613fc583613785565b919091555050565b60007ff96e07b2f4fbb81c31567d2b261589af429e98f0958d53f7e6ad5d63aea0ab7c8383604051602001611b5093929190928352606091821b6bffffffffffffffffffffffff199081166020850152911b16603482015260480190565b50805461403790614f1d565b6000825580601f10614047575050565b601f0160209004906000526020600020908101906114d591905b808211156140755760008155600101614061565b5090565b60006020828403121561408b57600080fd5b5035919050565b60008083601f8401126140a457600080fd5b50813567ffffffffffffffff8111156140bc57600080fd5b602083019150836020828501011115612cd157600080fd5b60008060008060008060008060008060c08b8d0312156140f357600080fd5b8a35995060208b013567ffffffffffffffff8082111561411257600080fd5b61411e8e838f01614092565b909b50995060408d013591508082111561413757600080fd5b6141438e838f01614092565b909950975060608d013591508082111561415c57600080fd5b6141688e838f01614092565b909750955060808d013591508082111561418157600080fd5b5061418e8d828e01614092565b9150809450508092505060a08b013590509295989b9194979a5092959850565b60005b838110156141c95781810151838201526020016141b1565b50506000910152565b600081518084526141ea8160208601602086016141ae565b601f01601f19169290920160200192915050565b602081526000610b8660208301846141d2565b600080600080600080600080600060a08a8c03121561422f57600080fd5b893567ffffffffffffffff8082111561424757600080fd5b6142538d838e01614092565b909b50995060208c013591508082111561426c57600080fd5b6142788d838e01614092565b909950975060408c013591508082111561429157600080fd5b61429d8d838e01614092565b909750955060608c01359150808211156142b657600080fd5b506142c38c828d01614092565b9a9d999c50979a9699959894979660800135949350505050565b60008083601f8401126142ef57600080fd5b50813567ffffffffffffffff81111561430757600080fd5b6020830191508360208260051b8501011115612cd157600080fd5b6000806000806040858703121561433857600080fd5b843567ffffffffffffffff8082111561435057600080fd5b61435c888389016142dd565b9096509450602087013591508082111561437557600080fd5b50614382878288016142dd565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156143cd576143cd61438e565b604052919050565b600082601f8301126143e657600080fd5b813567ffffffffffffffff8111156144005761440061438e565b614413601f8201601f19166020016143a4565b81815284602083860101111561442857600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561445757600080fd5b813567ffffffffffffffff81111561446e57600080fd5b61447a848285016143d5565b949350505050565b60008060008060008060006080888a03121561449d57600080fd5b87359650602088013567ffffffffffffffff808211156144bc57600080fd5b6144c88b838c01614092565b909850965060408a01359150808211156144e157600080fd5b6144ed8b838c01614092565b909650945060608a013591508082111561450657600080fd5b506145138a828b01614092565b989b979a50959850939692959293505050565b6001600160a01b03811681146114d557600080fd5b60006020828403121561454d57600080fd5b8135610b8681614526565b60008060008060008060008060c0898b03121561457457600080fd5b88359750602089013567ffffffffffffffff8082111561459357600080fd5b61459f8c838d01614092565b909950975060408b01359150808211156145b857600080fd5b6145c48c838d01614092565b909750955060608b0135945060808b01359150808211156145e457600080fd5b506145f18b828c016143d5565b92505060a089013590509295985092959890939650565b60008060008060008060008060c0898b03121561462457600080fd5b88359750602089013561463681614526565b9650604089013567ffffffffffffffff8082111561465357600080fd5b61465f8c838d01614092565b909850965060608b013591508082111561467857600080fd5b6146848c838d016143d5565b955060808b0135945060a08b01359150808211156146a157600080fd5b506146ae8b828c01614092565b999c989b5096995094979396929594505050565b600080600080600080606087890312156146db57600080fd5b863567ffffffffffffffff808211156146f357600080fd5b6146ff8a838b01614092565b9098509650602089013591508082111561471857600080fd5b6147248a838b01614092565b9096509450604089013591508082111561473d57600080fd5b5061474a89828a01614092565b979a9699509497509295939492505050565b600080600080600080600080600060c08a8c03121561477a57600080fd5b8935985060208a013567ffffffffffffffff8082111561479957600080fd5b6147a58d838e01614092565b909a50985060408c01359150808211156147be57600080fd5b6147ca8d838e01614092565b909850965060608c0135955060808c01359150808211156147ea57600080fd5b506147f78c828d01614092565b9a9d999c50979a9699959894979660a00135949350505050565b803560ff8116811461111257600080fd5b6000806040838503121561483557600080fd5b823561484081614526565b915061484e60208401614811565b90509250929050565b80356005811061111257600080fd5b600080600080600080600060a0888a03121561488157600080fd5b87359650602088013567ffffffffffffffff808211156148a057600080fd5b6148ac8b838c01614092565b90985096508691506148c060408b01614857565b955060608a01359150808211156148d657600080fd5b506148e38a828b01614092565b989b979a50959894979596608090950135949350505050565b6000806020838503121561490f57600080fd5b823567ffffffffffffffff81111561492657600080fd5b61493285828601614092565b90969095509350505050565b6000806040838503121561495157600080fd5b823567ffffffffffffffff8082111561496957600080fd5b614975868387016143d5565b9350602085013591508082111561498b57600080fd5b50614998858286016143d5565b9150509250929050565b600080600080606085870312156149b857600080fd5b84356149c381614526565b935060208501359250604085013567ffffffffffffffff8111156149e657600080fd5b61438287828801614092565b60008060408385031215614a0557600080fd5b8235614a1081614526565b946020939093013593505050565b60008060208385031215614a3157600080fd5b823567ffffffffffffffff811115614a4857600080fd5b614932858286016142dd565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015614aa957603f19888603018452614a978583516141d2565b94509285019290850190600101614a7b565b5092979650505050505050565b80151581146114d557600080fd5b600060208284031215614ad657600080fd5b8135610b8681614ab6565b60008060008060408587031215614af757600080fd5b843567ffffffffffffffff80821115614b0f57600080fd5b614b1b88838901614092565b90965094506020870135915080821115614b3457600080fd5b5061438287828801614092565b60008060008060008060808789031215614b5a57600080fd5b86359550602087013567ffffffffffffffff80821115614b7957600080fd5b614b858a838b01614092565b90975095506040890135915080821115614b9e57600080fd5b50614bab89828a01614092565b979a9699509497949695606090950135949350505050565b60008060008060008060008060e0898b031215614bdf57600080fd5b88359750602089013567ffffffffffffffff80821115614bfe57600080fd5b614c0a8c838d01614092565b909950975060408b0135915080821115614c2357600080fd5b614c2f8c838d016143d5565b965060608b0135915080821115614c4557600080fd5b614c518c838d016143d5565b9550614c5f60808c01614811565b945060a08b0135915080821115614c7557600080fd5b50614c828b828c016143d5565b92505060c089013590509295985092959890939650565b600060208284031215614cab57600080fd5b8151610b8681614526565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060018201614d0257634e487b7160e01b600052601160045260246000fd5b5060010190565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b868152608060208201526000614d5c608083018789614d19565b8281036040840152614d6f818688614d19565b915050826060830152979650505050505050565b600060208284031215614d9557600080fd5b8151610b8681614ab6565b606081526000614db4606083018789614d19565b8281036020840152614dc7818688614d19565b9150508260408301529695505050505050565b60008060008060808587031215614df057600080fd5b8435935060208501359250604085013567ffffffffffffffff811115614e1557600080fd5b614e21878288016143d5565b949793965093946060013593505050565b60058110614e5057634e487b7160e01b600052602160045260246000fd5b9052565b60208101610d4a8284614e32565b600060208284031215614e7457600080fd5b5051919050565b60208152600061447a602083018486614d19565b60008251614ea18184602087016141ae565b9190910192915050565b6000808335601e19843603018112614ec257600080fd5b83018035915067ffffffffffffffff821115614edd57600080fd5b602001915036819003821315612cd157600080fd5b604081526000614f0560408301856141d2565b90506001600160a01b03831660208301529392505050565b600181811c90821680614f3157607f821691505b602082108103614f5157634e487b7160e01b600052602260045260246000fd5b50919050565b82815260406020820152600061447a60408301846141d2565b60008060008060008060c08789031215614f8957600080fd5b8635955060208701359450604087013567ffffffffffffffff80821115614faf57600080fd5b614fbb8a838b016143d5565b95506060890135915080821115614fd157600080fd5b614fdd8a838b016143d5565b94506080890135935060a0890135915080821115614ffa57600080fd5b5061500789828a016143d5565b9150509295509295509295565b608081526000615028608083018789614d19565b828103602084015261503a81876141d2565b60408401959095525050606001529392505050565b88815260e06020820152600061506960e08301898b614d19565b828103604084015261507b81896141d2565b9050828103606084015261508f81886141d2565b608084019690965250506001600160a01b039290921660a083015260c09091015295945050505050565b600080600080608085870312156150cf57600080fd5b84359350602085013592506150e660408601614857565b9150606085013567ffffffffffffffff81111561510257600080fd5b61510e878288016143d5565b91505092959194509250565b60008060008060008060c0878903121561513357600080fd5b8635955060208701359450604087013567ffffffffffffffff8082111561515957600080fd5b6151658a838b016143d5565b9550606089013591508082111561517b57600080fd5b6151878a838b016143d5565b945061519560808a01614811565b935060a0890135915080821115614ffa57600080fd5b600080604083850312156151be57600080fd5b8251915060208301516151d081614526565b809150509250929050565b6060815260006151ef606083018688614d19565b828103602084015261520181866141d2565b91505082604083015295945050505050565b86815285602082015260c06040820152600061523260c08301876141d2565b828103606084015261524481876141d2565b905084608084015282810360a084015261525e81856141d2565b9998505050505050505050565b6000808585111561527b57600080fd5b8386111561528857600080fd5b5050820193919092039150565b6001600160e01b031981358181169160048510156152bd5780818660040360031b1b83161692505b505092915050565b8a815289602082015260e0604082015260006152e560e083018a8c614d19565b82810360608401526152f881898b614d19565b905086608084015282810360a0840152615313818688614d19565b9150508260c08301529b9a5050505050505050505050565b83815261533b6020820184614e32565b60606040820152600061535160608301846141d2565b95945050505050565b6001600160a01b038316815260406020820152600061447a60408301846141d2565b604081526000615390604083018587614d19565b82810360208401526153a281856141d2565b9695505050505050565b8481528360208201526153c26040820184614e32565b6080606082015260006153a260808301846141d2565b600082601f8301126153e957600080fd5b8135602067ffffffffffffffff808311156154065761540661438e565b8260051b6154158382016143a4565b938452858101830193838101908886111561542f57600080fd5b84880192505b8583101561546b5782358481111561544d5760008081fd5b61545b8a87838c01016143d5565b8352509184019190840190615435565b98975050505050505050565b6000806000806080858703121561548d57600080fd5b843561549881614526565b9350602085013567ffffffffffffffff808211156154b557600080fd5b6154c1888389016143d5565b945060408701359150808211156154d757600080fd5b6154e3888389016153d8565b935060608701359150808211156154f957600080fd5b5061510e878288016153d8565b60408152600061551960408301856141d2565b828103602084015261535181856141d2565b87815286602082015260a06040820152600061554b60a083018789614d19565b828103606084015261555e818688614d19565b91505082608083015298975050505050505050565b8681528560208201526001600160a01b038516604082015260c0606082015260006155a160c08301866141d2565b82810360808401526155b381866141d2565b91505060ff831660a0830152979650505050505050565b6001600160a01b03851681526080602082015260006155ec60808301866141d2565b82810360408401526155fe81866141d2565b91505060ff8316606083015295945050505050565b60a08152600061562660a08301896141d2565b828103602084015261563881896141d2565b905060ff87166040840152828103606084015261565581876141d2565b9050828103608084015261525e818587614d19565b86815285602082015260c06040820152600061568960c08301876141d2565b828103606084015261569b81876141d2565b905060ff8516608084015282810360a084015261525e81856141d2565b60006001600160a01b03808916835260a060208401526156dc60a08401888a614d19565b83810360408501526156ee81886141d2565b9050838103606085015261570281876141d2565b925050808416608084015250979650505050505050565b60608152600061572d606083018688614d19565b828103602084015261573f81866141d2565b9050828103604084015261575381856141d2565b979650505050505050565b601f8211156124c557600081815260208120601f850160051c810160208610156157855750805b601f850160051c820191505b8181101561240657828155600101615791565b815167ffffffffffffffff8111156157be576157be61438e565b6157d2816157cc8454614f1d565b8461575e565b602080601f83116001811461580757600084156157ef5750858301515b600019600386901b1c1916600185901b178555612406565b600085815260208120601f198616915b8281101561583657888601518255948401946001909101908401615817565b50858210156158545787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056feee35723ac350a69d2a92d3703f17439cbaadf2f093a21ba5bf5f1a53eb2a14d8a2646970667358221220dc8540c7b8e2a681cfd9d2e77116365c3c98a566393ebb31308862b395663e1364736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000121b0e54cd7ad2bbcb4c4c9275697978ebaf365300000000000000000000000058667c5f134420bf6904c7dd01fddcb4fea3a760000000000000000000000000e432150cce91c13a887f7d836923d5597add8e310000000000000000000000002d5d7d31f671f86c782533cc367f14109a08271200000000000000000000000083a93500d23fbc3e82b410ad07a6a9f7a0670d66000000000000000000000000000000000000000000000000000000000000010000000000000000000000000081a0545091864617e7037171fdfcbbdcfe3aeb2300000000000000000000000007715674f74c560200c7c95430673180812fce7300000000000000000000000000000000000000000000000000000000000000076672617874616c00000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : tokenManagerDeployer_ (address): 0x121b0e54Cd7ad2BBCb4c4C9275697978EBaF3653
Arg [1] : interchainTokenDeployer_ (address): 0x58667c5f134420Bf6904C7dD01fDDcB4Fea3a760
Arg [2] : gateway_ (address): 0xe432150cce91c13a887f7D836923d5597adD8E31
Arg [3] : gasService_ (address): 0x2d5d7d31F671F86C782533cc367F14109a082712
Arg [4] : interchainTokenFactory_ (address): 0x83a93500d23Fbc3e82B410aD07A6a9F7A0670D66
Arg [5] : chainName_ (string): fraxtal
Arg [6] : tokenManagerImplementation_ (address): 0x81a0545091864617E7037171FdfcBbdCFE3aeb23
Arg [7] : tokenHandler_ (address): 0x07715674F74c560200c7C95430673180812fCE73
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 000000000000000000000000121b0e54cd7ad2bbcb4c4c9275697978ebaf3653
Arg [1] : 00000000000000000000000058667c5f134420bf6904c7dd01fddcb4fea3a760
Arg [2] : 000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31
Arg [3] : 0000000000000000000000002d5d7d31f671f86c782533cc367f14109a082712
Arg [4] : 00000000000000000000000083a93500d23fbc3e82b410ad07a6a9f7a0670d66
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [6] : 00000000000000000000000081a0545091864617e7037171fdfcbbdcfe3aeb23
Arg [7] : 00000000000000000000000007715674f74c560200c7c95430673180812fce73
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [9] : 6672617874616c00000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
121407:41952:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;121821:39;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;200:55:1;;;182:74;;170:2;155:18;121821:39:0;;;;;;;;127576:246;;;;;;;;;;-1:-1:-1;127576:246:0;;;;;:::i;:::-;;:::i;148147:329::-;;;;;;;;;;-1:-1:-1;148147:329:0;;;;;:::i;:::-;;:::i;:::-;;122243:37;;;;;;;;;;;;;;;59066:137;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;147457:335::-;;;;;;;;;;-1:-1:-1;147457:335:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;4799:55:1;;;4781:74;;4886:2;4871:18;;4864:34;;;;4754:18;147457:335:0;4607:297:1;122199:37:0;;;;;;;;;;;;;;;143435:505;;;;;;;;;;-1:-1:-1;143435:505:0;;;;;:::i;:::-;;:::i;59441:182::-;;;;;;;;;;-1:-1:-1;59441:182:0;;;;;:::i;:::-;;:::i;146157:1292::-;;;;;;;;;;-1:-1:-1;146157:1292:0;;;;;:::i;:::-;;:::i;119520:166::-;;;;;;;;;;-1:-1:-1;119520:166:0;;;;;:::i;:::-;;:::i;141117:668::-;;;;;;:::i;:::-;;:::i;122020:48::-;;;;;;;;;;;;;;;127103:266;;;;;;;;;;-1:-1:-1;127103:266:0;;;;;:::i;:::-;;:::i;55212:171::-;;;;;;;;;;-1:-1:-1;55344:20:0;55338:27;55212:171;;66790:134;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;66889:17:0;66790:134;;;10181:14:1;;10174:22;10156:41;;10144:2;10129:18;66790:134:0;10016:187:1;136134:850:0;;;;;;:::i;:::-;;:::i;121867:45::-;;;;;;;;;;;;;;;122075;;;;;;;;;;;;;;;120617:125;;;;;;;;;;-1:-1:-1;120617:125:0;;;;;:::i;:::-;;:::i;119892:164::-;;;;;;;;;;-1:-1:-1;119892:164:0;;;;;:::i;:::-;;:::i;142510:589::-;;;;;;:::i;:::-;;:::i;52695:287::-;;;;;;;;;;-1:-1:-1;52695:287:0;;;;;:::i;:::-;;:::i;53112:197::-;;;;;;;;;;;;;:::i;129146:136::-;;;;;;;;;;-1:-1:-1;129146:136:0;;;;;:::i;:::-;-1:-1:-1;129262:12:0;;129146:136;126286:91;;;;;;;;;;-1:-1:-1;122530:37:0;126286:91;;;11994:25:1;;;11982:2;11967:18;126286:91:0;11848:177:1;135160:578:0;;;;;;;;;;-1:-1:-1;135160:578:0;;;;;:::i;:::-;;:::i;121973:38::-;;;;;;;;;;;;;;;18139:493;;;;;;;;;;-1:-1:-1;18139:493:0;;;;;:::i;:::-;;:::i;51600:135::-;;;;;;;;;;-1:-1:-1;51705:11:0;51699:18;51600:135;;70694:133;;;;;;;;;;-1:-1:-1;70694:133:0;;;;;:::i;:::-;;:::i;131620:1045::-;;;;;;:::i;:::-;;:::i;56826:128::-;;;;;;;;;;-1:-1:-1;56826:128:0;;;;;:::i;:::-;;:::i;144142:145::-;;;;;;;;;;-1:-1:-1;144142:145:0;;;;;:::i;:::-;;:::i;55782:839::-;;;;;;;;;;-1:-1:-1;55782:839:0;;;;;:::i;:::-;;:::i;128688:187::-;;;;;;;;;;-1:-1:-1;128688:187:0;;;;;:::i;:::-;;:::i;64356:657::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;144727:164::-;;;;;;;;;;-1:-1:-1;144727:164:0;;;;;:::i;:::-;;:::i;60336:229::-;;;;;;;;;;-1:-1:-1;60336:229:0;;;;;:::i;:::-;;:::i;17730:401::-;;;;;;;;;;-1:-1:-1;17730:401:0;;;;;:::i;:::-;;:::i;130451:237::-;;;;;;;;;;-1:-1:-1;130451:237:0;;;;;:::i;:::-;;:::i;121919:47::-;;;;;;;;;;;;;;;129973:241;;;;;;;;;;-1:-1:-1;129973:241:0;;;;;:::i;:::-;;:::i;140035:572::-;;;;;;:::i;:::-;;:::i;120265:138::-;;;;;;;;;;-1:-1:-1;120265:138:0;;;;;:::i;:::-;;:::i;144437:117::-;;;;;;;;;;-1:-1:-1;144437:117:0;;;;;:::i;:::-;;:::i;133761:910::-;;;;;;:::i;:::-;;:::i;51877:155::-;;;;;;;;;;-1:-1:-1;51989:24:0;51983:31;51877:155;;147800:339;;;;;;:::i;129508:225::-;;;;;;;;;;-1:-1:-1;129508:225:0;;;;;:::i;:::-;;:::i;128116:203::-;;;;;;;;;;-1:-1:-1;128116:203:0;;;;;:::i;:::-;;:::i;52254:119::-;;;;;;;;;;-1:-1:-1;52254:119:0;;;;;:::i;:::-;;:::i;126664:163::-;;;;;;;;;;-1:-1:-1;126664:163:0;;;;;:::i;:::-;;:::i;59819:245::-;;;;;;;;;;-1:-1:-1;59819:245:0;;;;;:::i;:::-;;:::i;127576:246::-;127641:20;127674:28;127705:33;127730:7;127705:24;:33::i;:::-;127674:64;;127778:20;-1:-1:-1;;;;;127764:48:0;;:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;127749:65;127576:246;-1:-1:-1;;;127576:246:0:o;148147:329::-;148438:30;;-1:-1:-1;;;148438:30:0;;;;;;;;;;;59066:137;59110:24;59160:35;58781:66;59160:17;:35::i;:::-;59147:48;;59066:137;:::o;147457:335::-;147718:7;147727;147754:30;;-1:-1:-1;;;147754:30:0;;;;;;;;;;;143435:505;143542:14;69652:37;69661:21;69671:10;69661:9;:21::i;:::-;76977:1;:9;;;;76961:26;:31;;;76862:138;69652:37;69647:80;;69698:29;;-1:-1:-1;;;69698:29:0;;69710:10;69698:29;;;24264:74:1;24386:4;24374:17;;24354:18;;;24347:45;24237:18;;69698:29:0;;;;;;;;69647:80;143587:8;143617:27;;::::1;143613:56;;143653:16;;;;;;;;;;;;;;143613:56;143687:9;143682:251;143702:6;143698:1;:10;143682:251;;;143730:27;143774:37;143799:8;;143808:1;143799:11;;;;;;;:::i;:::-;;;;;;;143774:24;:37::i;:::-;143730:82;;143880:13;-1:-1:-1::0;;;;;143880:26:0::1;;143907:10;;143918:1;143907:13;;;;;;;:::i;:::-;;;;;;;143880:41;;;;;;;;;;;;;11994:25:1::0;;11982:2;11967:18;;11848:177;143880:41:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;143715:218;143710:3;;;;:::i;:::-;;;143682:251;;;;143559:381;143435:505:::0;;;;;:::o;59441:182::-;59507:29;59567:48;59585:29;59608:5;59585:22;:29::i;:::-;59567:17;:48::i;:::-;59549:66;59441:182;-1:-1:-1;;59441:182:0:o;146157:1292::-;146347:11;;146360:13;;126024:44;126041:11;;126054:13;;126024:16;:44::i;:::-;126019:76;;126077:18;;-1:-1:-1;;;126077:18:0;;;;;;;;;;;126019:76;-1:-1:-1;;;;;;;;;;;66889:17:0;66476:28:::1;;;66497:7;;-1:-1:-1::0;;;66497:7:0::1;;;;;;;;;;;66476:28;146400:19:::2;146432:7;;146422:18;;;;;;;:::i;:::-;;::::0;;;;::::2;::::0;;146458:80;;;146422:18;-1:-1:-1;;;;;;146458:7:0::2;:28;::::0;::::2;::::0;:80:::2;::::0;146487:9;;146498:11;;;;146511:13;;;;146422:18;;146458:80:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;146453:116;;146547:22;;;;;;;;;;;;;;146453:116;146582:19;146604:30;::::0;;::::2;146615:7:::0;146604:30:::2;:::i;:::-;146582:52:::0;-1:-1:-1;146582:52:0;146645:797:::2;;146713:23;146739:71;146759:9;146770:11;;146783:13;;146798:11;146739:19;:71::i;:::-;146713:97;;146827:83;146861:9;146872:15;146889:11;;146902:7;;146827:33;:83::i;:::-;-1:-1:-1::0;;;;;146931:29:0;::::2;::::0;146927:169:::2;;147064:15;-1:-1:-1::0;;;;;146986:94:0::2;147012:9;146986:94;147023:11;;147036:13;;147051:11;146986:94;;;;;;;;;;:::i;:::-;;;;;;;;146927:169;146698:409;146645:797;;;123074:1;147117:11;:48:::0;147113:329:::2;;147182:42;147216:7;;147182:33;:42::i;:::-;147113:329;;;123005:1;147246:11;:51:::0;147242:200:::2;;147314:45;147351:7;;147314:36;:45::i;147242:200::-;147399:31;::::0;::::2;::::0;;::::2;::::0;::::2;11994:25:1::0;;;11967:18;;147399:31:0::2;11848:177:1::0;147242:200:0::2;146389:1060;;146157:1292:::0;;;;;;;;;;;:::o;119520:166::-;119592:14;69652:37;69661:21;69671:10;69661:9;:21::i;69652:37::-;69647:80;;69698:29;;-1:-1:-1;;;69698:29:0;;69710:10;69698:29;;;24264:74:1;24386:4;24374:17;;24354:18;;;24347:45;24237:18;;69698:29:0;24094:304:1;69647:80:0;119620:58:::1;119634:10;119646:8:::0;119662:14:::1;119620:13;:58::i;:::-;119520:166:::0;;:::o;141117:668::-;-1:-1:-1;;;;;;;;;;;66889:17:0;66476:28;;;66497:7;;-1:-1:-1;;;66497:7:0;;;;;;;;;;;66476:28;141404:4:::1;:11;141419:1;141404:16:::0;141400:40:::1;;141429:11;;;;;;;;;;;;;;141400:40;141462:46;141473:7;141482:10;141494:6;141502:5;141462:10;:46::i;:::-;141453:55;;141521:256;141563:7;141585:10;141610:16;;141641:18;;141521:256;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;-1:-1:-1;141674:6:0;;-1:-1:-1;141521:256:0;-1:-1:-1;141739:4:0;;-1:-1:-1;141758:8:0;141521:27:::1;:256::i;:::-;141117:668:::0;;;;;;;;:::o;127103:266::-;127175:28;127239;127259:7;127239:19;:28::i;:::-;127216:51;;127282:20;-1:-1:-1;;;;;127282:32:0;;127318:1;127282:37;127278:83;;127328:33;;;;;;;;11994:25:1;;;11967:18;;127328:33:0;11848:177:1;127278:83:0;127103:266;;;:::o;136134:850::-;-1:-1:-1;;;;;;;;;;;66889:17:0;66476:28;;;66497:7;;-1:-1:-1;;;66497:7:0;;;;;;;;;;;66476:28;136346:19:::1;136368:30;::::0;;::::1;136379:7:::0;136368:30:::1;:::i;:::-;136346:52:::0;-1:-1:-1;136413:47:0;;136409:125:::1;;136484:38;::::0;-1:-1:-1;;;136484:38:0;;::::1;::::0;::::1;11994:25:1::0;;;11967:18;;136484:38:0::1;11848:177:1::0;136409:125:0::1;136550:36;::::0;;;;::::1;::::0;::::1;11994:25:1::0;;;136550:7:0::1;-1:-1:-1::0;;;;;136550:25:0::1;::::0;::::1;::::0;11967:18:1;;136550:36:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;136546:66;;;136595:17;;;;;;;;;;;;;;136546:66;136694:18;::::0;136651:10:::1;::::0;136625:23:::1;::::0;136694:18:::1;::::0;136704:7;;;;136694:18:::1;:::i;:::-;;;;;;;;136672:40;;136798:15;-1:-1:-1::0;;;;;136730:84:0::1;136746:9;136730:84;136757:11;;136770:13;;136785:11;136730:84;;;;;;;;;;:::i;:::-;;;;;;;;136827:88;136847:9;136858:11;;136871:13;;136886:11;136899:15;136827:19;:88::i;:::-;136928:48;136944:9;136955:11;;136968:7;;136928:15;:48::i;:::-;136335:649;;;136134:850:::0;;;;;;;:::o;120617:125::-;120674:4;120698:36;120706:4;120718:14;70694:133;:::i;119892:164::-;119963:14;69652:37;69661:21;69671:10;69661:9;:21::i;69652:37::-;69647:80;;69698:29;;-1:-1:-1;;;69698:29:0;;69710:10;69698:29;;;24264:74:1;24386:4;24374:17;;24354:18;;;24347:45;24237:18;;69698:29:0;24094:304:1;69647:80:0;119991:57:::1;120004:10;120016:8:::0;120032:14:::1;119991:12;:57::i;142510:589::-:0;-1:-1:-1;;;;;;;;;;;66889:17:0;66476:28;;;66497:7;;-1:-1:-1;;;66497:7:0;;;;;;;;;;;66476:28;142806:48:::1;142817:7;142826:13;142841:6;142849:4;142806:10;:48::i;:::-;142797:57;;142868:31;142901:17:::0;142922:25:::1;142938:8;;142922:15;:25::i;:::-;142867:80;;;;142960:131;142988:7;142997:13;143012:16;;143030:18;143050:6;143058:15;143075:4;143081:9;142960:27;:131::i;52695:287::-:0;51407:10;51396:7;51705:11;51699:18;;51600:135;51396:7;-1:-1:-1;;;;;51396:21:0;;51392:44;;51426:10;;-1:-1:-1;;;51426:10:0;;;;;;;;;;;51392:44;-1:-1:-1;;;;;52781:22:0;::::1;52777:56;;52812:21;;-1:-1:-1::0;;;52812:21:0::1;;;;;;;;;;;52777:56;52851:34;::::0;-1:-1:-1;;;;;52851:34:0;::::1;::::0;::::1;::::0;;;::::1;52929:24;52922:42:::0;52695:287::o;53112:197::-;53167:16;53186:14;51989:24;51983:31;;51877:155;53186:14;53167:33;-1:-1:-1;;;;;;53215:22:0;;53227:10;53215:22;53211:49;;53246:14;;;;;;;;;;;;;;53211:49;53273:28;53292:8;53273:18;:28::i;:::-;53156:153;53112:197::o;135160:578::-;135394:7;135403;135343:11;;135356:13;;126024:44;126041:11;;126054:13;;126024:16;:44::i;:::-;126019:76;;126077:18;;-1:-1:-1;;;126077:18:0;;;;;;;;;;;126019:76;-1:-1:-1;;;;;;;;;;;66889:17:0;66476:28:::1;;;66497:7;;-1:-1:-1::0;;;66497:7:0::1;;;;;;;;;;;66476:28;135424:19:::2;::::0;;135482:55:::2;::::0;;::::2;135493:7:::0;135482:55:::2;:::i;:::-;135423:114;;;;;;;122933:1;135554:11;:47;135550:125;;135625:38;::::0;-1:-1:-1;;;135625:38:0;;::::2;::::0;::::2;11994:25:1::0;;;11967:18;;135625:38:0::2;11848:177:1::0;135550:125:0::2;135695:26;135713:7;135695:17;:26::i;:::-;135687:43:::0;135723:6;;-1:-1:-1;135160:578:0;-1:-1:-1;;;;;;;;;;;;;135160:578:0:o;18139:493::-;18400:23;18436:12;18451:96;18480:9;18491:11;;18504:13;;18519:11;18532:6;;18540;18451:28;:96::i;:::-;18603:11;;18139:493;-1:-1:-1;;;;;;;;;;;18139:493:0:o;70694:133::-;70761:4;70785:34;70794:18;70804:7;70794:9;:18::i;:::-;76977:1;:9;;;;76961:26;:31;;;76862:138;131620:1045;131864:15;66480:8;-1:-1:-1;;;;;;;;;;;66889:17:0;;66790:134;66480:8;66476:28;;;66497:7;;-1:-1:-1;;;66497:7:0;;;;;;;;;;;66476:28;132046:40:::1;132026:16;:60;;;;;;;;:::i;:::-;::::0;132022:103:::1;;132108:16;132095:30;;-1:-1:-1::0;;;132095:30:0::1;;;;;;;;:::i;132022:103::-;132157:10;-1:-1:-1::0;;;;;132196:22:0::1;132184:34;::::0;;132180:100:::1;;-1:-1:-1::0;123397:1:0::1;132180:100;132302:33;132320:8;132330:4;132302:17;:33::i;:::-;132292:43;;132397:4;132387:8;-1:-1:-1::0;;;;;132353:49:0::1;132378:7;132353:49;;;;;;;;;;132453:1;132419:35:::0;;;132415:243:::1;;132471:54;132491:7;132500:16;132518:6;;132471:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;132471:19:0::1;::::0;-1:-1:-1;;;132471:54:0:i:1;:::-;132415:243;;;132558:88;132584:7;132593:16;;132611:8;132621:16;132639:6;;132558:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;132558:25:0::1;::::0;-1:-1:-1;;;132558:88:0:i:1;:::-;131881:784;131620:1045:::0;;;;;;;;;:::o;56826:128::-;49535:4;49502:21;-1:-1:-1;;;;;49502:38:0;;49498:61;;49549:10;;;;;;;;;;;;;;49498:61;56934:12:::1;56941:4;;56934:6;:12::i;144142:145::-:0;51407:10;51396:7;51705:11;51699:18;;51600:135;51396:7;-1:-1:-1;;;;;51396:21:0;;51392:44;;51426:10;;-1:-1:-1;;;51426:10:0;;;;;;;;;;;51392:44;144244:35:::1;144263:5;144270:8;144244:18;:35::i;55782:839::-:0;51407:10;51396:7;51705:11;51699:18;;51600:135;51396:7;-1:-1:-1;;;;;51396:21:0;;51392:44;;51426:10;;-1:-1:-1;;;51426:10:0;;;;;;;;;;;51392:44;55344:20;55338:27;-1:-1:-1;;;;;56008:40:0::1;;:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55973:17;-1:-1:-1::0;;;;;55961:41:0::1;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:89;55957:138;;56072:23;;;;;;;;;;;;;;55957:138;56141:17;-1:-1:-1::0;;;;;56141:26:0::1;;56112:25;:55;56108:85;;56176:17;;;;;;;;;;;;;;56108:85;56211:27;::::0;-1:-1:-1;;;;;56211:27:0;::::1;::::0;::::1;::::0;;;::::1;56255:17:::0;;56251:269:::1;;56356:12;56374:17;-1:-1:-1::0;;;;;56374:30:0::1;56428:19;;;56449:6;;56405:51;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;56405:51:0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;56405:51:0::1;-1:-1:-1::0;;;;;;56405:51:0;;::::1;::::0;;;::::1;::::0;;;56374:83;;::::1;::::0;56405:51;56374:83:::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56355:102;;;56479:7;56474:34;;56495:13;;;;;;;;;;;;;;56474:34;56274:246;56251:269;-1:-1:-1::0;;;56563:20:0::1;56556:47:::0;55782:839::o;128688:187::-;128814:52;;;122344:36;128814:52;;;28780:25:1;-1:-1:-1;;;;;28841:55:1;;28821:18;;;28814:83;;;;28913:18;;;28906:34;;;128766:15:0;;28753:18:1;;128814:52:0;;;;;;;;;;;;;128804:63;;;;;;128794:73;;128688:187;;;;:::o;64356:657::-;64422:22;64479:4;64467:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64457:34;;64502:12;64525:19;64560:9;64555:451;64575:15;;;64555:451;;;64711:4;64730;;64735:1;64730:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;64703:35;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64683:55:0;;-1:-1:-1;64683:55:0;-1:-1:-1;64683:55:0;64755:204;;64792:6;:13;64809:1;64792:18;64788:48;;64819:17;;;;;;;;;;;;;;64788:48;64917:6;64911:13;64902:6;64898:2;64894:15;64887:38;64755:204;64988:6;64975:7;64983:1;64975:10;;;;;;;;:::i;:::-;;;;;;:19;;;;64592:3;;;;:::i;:::-;;;64555:451;;;;64446:567;;64356:657;;;;:::o;144727:164::-;51407:10;51396:7;51705:11;51699:18;;51600:135;51396:7;-1:-1:-1;;;;;51396:21:0;;51392:44;;51426:10;;-1:-1:-1;;;51426:10:0;;;;;;;;;;;51392:44;144798:6:::1;144794:90;;;144821:8;:6;:8::i;144794:90::-;144862:10;:8;:10::i;60336:229::-:0;60432:4;60449:19;60487:8;;60471:26;;;;;;;:::i;:::-;;;;;;;;60449:48;;60532:25;60551:5;;60532:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60532:18:0;;-1:-1:-1;;;60532:25:0:i;:::-;60517:40;;60336:229;-1:-1:-1;;;;;60336:229:0:o;17730:401::-;17924:23;17960:12;17975:71;17995:9;18006:11;;18019:13;;18034:11;17975:19;:71::i;:::-;18102:11;;17730:401;-1:-1:-1;;;;;;;;17730:401:0:o;130451:237::-;130513:21;130547:27;130591:33;130616:7;130591:24;:33::i;:::-;130547:78;;130652:13;-1:-1:-1;;;;;130652:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;129973:241::-;130036:22;130071:27;130115:33;130140:7;130115:24;:33::i;:::-;130071:78;;130177:13;-1:-1:-1;;;;;130177:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;140035:572;-1:-1:-1;;;;;;;;;;;66889:17:0;66476:28;;;66497:7;;-1:-1:-1;;;66497:7:0;;;;;;;;;;;66476:28;140320:46:::1;140331:7;140340:10;140352:6;140360:5;140320:10;:46::i;:::-;140311:55;;140380:31;140413:17:::0;140434:25:::1;140450:8;;140434:15;:25::i;:::-;140379:80;;;;140472:127;140500:7;140509:10;140521:16;;140539:18;;140472:127;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;140559:6:0;;-1:-1:-1;140567:15:0;;-1:-1:-1;140584:4:0;;-1:-1:-1;140590:8:0;140472:27:::1;:127::i;:::-;140300:307;;140035:572:::0;;;;;;;;;:::o;120265:138::-;120335:60;120347:12;120361:10;120379:14;120335:11;:60::i;144437:117::-;51407:10;51396:7;51705:11;51699:18;;51600:135;51396:7;-1:-1:-1;;;;;51396:21:0;;51392:44;;51426:10;;-1:-1:-1;;;51426:10:0;;;;;;;;;;;51392:44;144518:28:::1;144540:5;144518:21;:28::i;133761:910::-:0;134047:15;66480:8;-1:-1:-1;;;;;;;;;;;66889:17:0;;66790:134;66480:8;66476:28;;;66497:7;;-1:-1:-1;;;66497:7:0;;;;;;;;;;;66476:28;134094:10:::1;-1:-1:-1::0;;;;;134133:22:0::1;134121:34;::::0;;134117:73:::1;;-1:-1:-1::0;123397:1:0::1;134117:73;134213:33;134231:8;134241:4;134213:17;:33::i;:::-;134203:43:::0;-1:-1:-1;134297:1:0::1;134263:35:::0;;;134259:405:::1;;134315:20;134338:63;134361:7;134370:6;134378:4;134384:6;134392:8;134338:22;:63::i;:::-;134315:86;;134418:104;134438:7;134447:40;134500:6;134508:12;134489:32;;;;;;;;;:::i;:::-;;;;;;;;;;;;;134418:19;:104::i;:::-;134300:234;134259:405;;;134555:97;134584:7;134593:4;134599:6;134607:8;134617:6;134625:16;;134643:8;134555:28;:97::i;:::-;134064:607;133761:910:::0;;;;;;;;;;:::o;129508:225::-;129567:18;129598:27;129642:33;129667:7;129642:24;:33::i;:::-;129598:78;;129700:13;-1:-1:-1;;;;;129700:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;128116:203;128186:20;128229:32;128253:7;128229:23;:32::i;:::-;128219:42;;128287:24;128303:7;128287:15;:24::i;52254:119::-;51407:10;51396:7;51705:11;51699:18;;51600:135;51396:7;-1:-1:-1;;;;;51396:21:0;;51392:44;;51426:10;;-1:-1:-1;;;51426:10:0;;;;;;;;;;;126664:163;126731:28;126795:24;126811:7;126795:15;:24::i;59819:245::-;59889:27;59929:12;59944:33;59971:5;59944:26;:33::i;:::-;60035:11;;59819:245;-1:-1:-1;;;59819:245:0:o;57623:127::-;57673:19;57731:4;57705:37;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57623:127;;;:::o;71902:203::-;71961:20;71994:11;72008:18;72018:7;72008:9;:18::i;60773:168::-;60849:12;58461:55;60926:5;60891:41;;;;;;;;;:::i;:::-;;;;;;;;;;;;;60881:52;;;;;;60874:59;;60773:168;;;:::o;19926:479::-;20116:23;20152:12;20167:71;20187:9;20198:11;;20211:13;;20226:11;20167:19;:71::i;:::-;20152:86;;20300:4;20294:11;20275:30;;20322:15;20319:68;;;20370:1;20364:4;20357:15;20319:68;20260:138;19926:479;;;;;;;;:::o;148869:1862::-;149072:15;149098:26;149072:15;;149098:26;;149359:118;;;;149388:7;149359:118;:::i;:::-;149291:186;;-1:-1:-1;149291:186:0;;-1:-1:-1;149291:186:0;;-1:-1:-1;149291:186:0;;-1:-1:-1;149291:186:0;-1:-1:-1;149513:35:0;;-1:-1:-1;149291:186:0;149513:33;:35::i;:::-;149492:56;-1:-1:-1;;;;;;;149632:29:0;;;149628:185;;149734:44;149745:7;149754:15;149771:6;149734:10;:44::i;:::-;;;149795:7;;;;;;;149628:185;149825:20;149881:47;149892:7;149901:18;149921:6;149881:10;:47::i;:::-;149856:72;;;;;;;;150143:18;-1:-1:-1;;;;;150002:253:0;150067:7;150043:9;150002:253;150089:11;;150115:13;150176:6;150197:4;:11;150212:1;150197:16;:47;;150229:15;;;;;;150197:47;;;150224:1;150197:47;150002:253;;;;;;;;;;:::i;:::-;;;;;;;;150272:11;;:16;150268:456;;150305:14;150349:18;-1:-1:-1;;;;;150322:73:0;;150414:9;150442:11;;150472:13;150504:4;150527:7;150553:12;150584:6;150322:283;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;150305:300;;122617:32;150626:6;:25;150622:90;;150660:52;;;;;-1:-1:-1;;;;;200:55:1;;150660:52:0;;;182:74:1;155:18;;150660:52:0;14:248:1;150268:456:0;149061:1670;;;;;;148869:1862;;;;;;;:::o;150815:457::-;150905:15;;;150980:101;;;;151005:7;150980:101;:::i;:::-;150902:179;;-1:-1:-1;150902:179:0;-1:-1:-1;150902:179:0;-1:-1:-1;151118:40:0;;-1:-1:-1;151098:16:0;:60;;;;;;;;:::i;:::-;;151094:103;;151180:16;151167:30;;-1:-1:-1;;;151167:30:0;;;;;;;;:::i;151094:103::-;151210:54;151230:7;151239:16;151257:6;151210:19;:54::i;:::-;150891:381;;;150815:457;;:::o;151432:559::-;151525:15;;;;;151628:106;;;;151653:7;151628:106;:::i;:::-;151522:212;;;;;;;;;;;151745:20;151793:68;151816:7;151825:11;151838:4;151844:6;151852:8;151793:22;:68::i;:::-;151778:83;;151874:109;151894:7;151903:40;151956:11;151969:12;151945:37;;;;;;;;;:::i;82475:193::-;82604:56;82626:11;82639:9;82650:1;:9;;;;82604:21;:56::i;:::-;82475:193;;;:::o;161537:937::-;161638:7;161658:21;161682:28;161702:7;161682:19;:28::i;:::-;161658:52;;161721:24;161756:20;161843:13;-1:-1:-1;;;;;161824:70:0;;:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;161789:107;;-1:-1:-1;161789:107:0;-1:-1:-1;161913:9:0;:39;;;;-1:-1:-1;161926:10:0;-1:-1:-1;;;;;161926:26:0;;;;161913:39;161909:86;;;161961:34;;;;;161970:10;161961:34;;;35248::1;-1:-1:-1;;;;;35318:15:1;;35298:18;;;35291:43;35160:18;;161961:34:0;35013:327:1;161909:86:0;162084:117;;;;;;35604:25:1;;;-1:-1:-1;;;;;35726:15:1;;;35706:18;;;35699:43;35778:15;;;35758:18;;;35751:43;35830:15;;;35810:18;;;35803:43;35862:19;;;;35855:35;;;162084:117:0;;;;;;;;;;35576:19:1;;;;162084:117:0;;;;;;;-1:-1:-1;;;;;162084:117:0;162107:32;162084:117;;;162044:168;;-1:-1:-1;;;;162044:12:0;:25;;;;:168;;162084:117;162044:168;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;162008:204;;;;162228:7;162223:42;;162260:4;162244:21;;;;;;;;;;;:::i;162223:42::-;162296:4;162285:27;;;;;;;;;;;;:::i;:::-;162393:47;;;;;;;;11994:25:1;;;162276:36:0;;-1:-1:-1;;;;;;162393:39:0;;;;;11967:18:1;;162393:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;162460:6:0;;161537:937;-1:-1:-1;;;;;;;;;;;;161537:937:0:o;160432:941::-;160990:11;;:16;:47;;161022:15;;;;;;160990:47;;;161017:1;160990:47;160877:13;-1:-1:-1;;;;;160822:226:0;160855:7;160822:226;160905:16;;160936:18;160969:6;160822:226;;;;;;;;;:::i;:::-;;;;;;;;161061:20;122933:1;161156:7;161178:23;:13;-1:-1:-1;;;;;161178:21:0;;:23::i;:::-;161216:18;161249:6;161270:4;161084:201;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;161061:224;;161298:67;161312:16;;161330:7;161339:15;161356:8;161298:13;:67::i;18640:589::-;18866:12;18881:71;18901:9;18912:11;;18925:13;;18940:11;18881:19;:71::i;:::-;19042:11;;18866:86;;-1:-1:-1;;;;;;19080:29:0;;;19076:69;;19118:27;;;;;;;;;;;;;;19076:69;-1:-1:-1;19182:29:0;-1:-1:-1;;;;;;18640:589:0:o;137435:1968::-;137555:15;;;;;137675:83;;;;137700:7;137675:83;:::i;:::-;137552:206;;;;;;;;;;;137769:26;137798:35;:23;:33;:35::i;:::-;137769:64;;137846:12;137884:27;137928:28;137948:7;137928:19;:28::i;:::-;137884:73;;137987:13;-1:-1:-1;;;;;137987:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;137972:44;;138034:12;138048:23;138075:12;-1:-1:-1;;;;;138075:25:0;138164:40;;;138227:13;-1:-1:-1;;;;;138227:32:0;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;138119:301;;;;;35604:25:1;;;;-1:-1:-1;;;;;35726:15:1;;;35706:18;;;35699:43;138321:10:0;35758:18:1;;;35751:43;35830:15;;35810:18;;;35803:43;35862:19;;;35855:35;;;35576:19;;138119:301:0;;;-1:-1:-1;;138119:301:0;;;;;;;;;;;;;;-1:-1:-1;;;;;138119:301:0;-1:-1:-1;;;;;;138119:301:0;;;;;;;;;;138075:360;;;;138119:301;138075:360;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;138033:402;;;;138455:7;138450:51;;138490:10;138471:30;;;;;;;;;;;:::i;138450:51::-;138536:10;138525:33;;;;;;;;;;;;:::i;:::-;138516:42;;137869:701;;;138784:18;-1:-1:-1;;;;;138643:253:0;138708:7;138684:9;138643:253;138730:11;;138756:13;138817:6;138838:4;:11;138853:1;138838:16;:47;;138870:15;;;;;;138838:47;;;138865:1;138838:47;138643:253;;;;;;;;;;:::i;:::-;;;;;;;;138913:11;;:16;138909:487;;138946:14;138997:18;-1:-1:-1;;;;;138963:87:0;;139069:9;139097:11;;139127:13;139159:4;139182:7;139216:5;139241:6;138963:299;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;138946:316;;122707:40;139283:6;:33;139279:105;;139325:59;;;;;-1:-1:-1;;;;;200:55:1;;139325:59:0;;;182:74:1;155:18;;139325:59:0;14:248:1;78503:191:0;78631:55;78652:11;78665:9;78676:1;:9;;;;78631:20;:55::i;159273:507::-;159346:23;159371:17;159423:1;159405:19;;159401:69;;;159434:29;159426:44;;;;159401:69;159483:18;159518:12;159528:1;159483:18;159518:8;;:12;:::i;:::-;159511:20;;;:::i;:::-;159504:28;;;-1:-1:-1;123620:1:0;159547:37;;159543:85;;;159593:35;;-1:-1:-1;;;159593:35:0;;38254:10:1;38242:23;;159593:35:0;;;38224:42:1;38197:18;;159593:35:0;38080:192:1;159543:85:0;159667:11;159651:28;;;;;;;;;;:::i;:::-;159641:38;-1:-1:-1;159715:1:0;159696:20;;;159692:48;;159718:22;;;159692:48;159760:12;:8;159769:1;159760:8;;:12;:::i;:::-;159753:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;159753:19:0;;-1:-1:-1;;;;;159273:507:0;;;;;;:::o;53562:311::-;-1:-1:-1;;;;;53640:22:0;;53636:56;;53671:21;;-1:-1:-1;;;53671:21:0;;;;;;;;;;;53636:56;53710:30;;-1:-1:-1;;;;;53710:30:0;;;;;;;;53784:11;53777:29;53853:1;53827:24;53820:35;53562:311::o;17138:584::-;17400:12;16750:39;17537:9;17565:11;;17595:13;;17627:11;17657:6;;17682;17456:247;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;17432:282;;;;;;17425:289;;17138:584;;;;;;;;;;;:::o;156286:873::-;156409:12;156423:23;156450:20;-1:-1:-1;;;;;156450:33:0;156521:49;;;156572:7;156581:16;156599:6;156498:108;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;156498:108:0;;;;;;;;;;;;;;-1:-1:-1;;;;;156498:108:0;-1:-1:-1;;;;;;156498:108:0;;;;;;;;;;156450:167;;;;156498:108;156450:167;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;156408:209;;;;156633:7;156628:61;;156678:10;156649:40;;;;;;;;;;;:::i;156628:61::-;156797:4;156781:21;;156775:28;156850;156830:16;:48;;;;;;;;:::i;:::-;;:104;;;-1:-1:-1;156902:32:0;156882:16;:52;;;;;;;;:::i;:::-;;156830:104;156826:182;;;156965:13;-1:-1:-1;;;;;156951:43:0;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;156826:182;157126:16;157081:70;;;;;;;;:::i;:::-;157102:7;157081:70;157111:13;157144:6;157081:70;;;;;;;:::i;:::-;;;;;;;;156397:762;;;156286:873;;;:::o;154124:635::-;154408:33;154433:7;154408:24;:33::i;:::-;;154516:16;154459:82;;;;;;;;:::i;:::-;154489:7;154459:82;154498:16;;154534:6;154459:82;;;;;;;;:::i;:::-;;;;;;;;154554:20;123074:1;154623:7;154632:16;154650:6;154577:80;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;154554:103;;154670:81;154684:16;;154702:7;154711:29;154742:8;154670:13;:81::i;144973:796::-;145042:16;;;;145157:94;;;;145182:6;145157:94;:::i;:::-;145279:24;;145041:210;;-1:-1:-1;145041:210:0;;-1:-1:-1;145041:210:0;-1:-1:-1;145041:210:0;-1:-1:-1;;;;;;145320:22:0;;145316:48;;145351:13;;;;;;;;;;;;;;145316:48;145379:24;;:29;;:78;;-1:-1:-1;145412:28:0;;;;;;145444:13;145412:45;;145379:78;145375:109;;;145466:18;;;;;;;;;;;;;;145375:109;145509:16;:23;145499:6;:33;145495:62;;145541:16;;;;;;;;;;;;;;145495:62;145570:22;145583:8;145570:12;:22::i;:::-;145603:25;145617:10;145603:13;:25::i;:::-;145646:9;145641:121;145661:6;145657:1;:10;145641:121;;;145689:61;145708:17;145726:1;145708:20;;;;;;;;:::i;:::-;;;;;;;145730:16;145747:1;145730:19;;;;;;;;:::i;:::-;;;;;;;145689:18;:61::i;:::-;145669:3;;;:::i;:::-;;;145641:121;;61552:538;61655:5;61649:19;61672:1;61649:24;61645:55;;61682:18;;-1:-1:-1;;;61682:18:0;;;;;;;;;;;61645:55;61721:8;61715:22;61741:1;61715:27;61711:58;;61751:18;;-1:-1:-1;;;61751:18:0;;;;;;;;;;;61711:58;61782;61800:29;61823:5;61800:22;:29::i;:::-;61831:8;61782:17;:58::i;:::-;61853:12;61868:33;61895:5;61868:26;:33::i;:::-;61934:26;;;;;;61995:25;;;62048:34;;61853:48;;-1:-1:-1;61934:26:0;62048:34;;;;62066:5;;61950:8;;62048:34;:::i;:::-;;;;;;;;61634:456;;61552:538;;:::o;67057:96::-;67095:16;67106:4;-1:-1:-1;;;;;;;;;;;67731:27:0;67653:123;67095:16;67127:18;;67134:10;;67127:18;;;;;67057:96::o;67288:101::-;67328:17;67339:5;-1:-1:-1;;;;;;;;;;;67731:27:0;67653:123;67328:17;67361:20;;67370:10;;67361:20;;;;;67288:101::o;16798:332::-;16993:12;16653:28;17070:9;17081:11;;17094:13;;17109:11;17035:86;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;17025:97;;;;;;17018:104;;16798:332;;;;;;;;:::o;80608:197::-;80743:54;80763:11;80776:9;80787:1;:9;;;;80743:19;:54::i;62232:365::-;62314:5;62308:19;62331:1;62308:24;62304:55;;62341:18;;-1:-1:-1;;;62341:18:0;;;;;;;;;;;62304:55;62372:50;62392:29;62415:5;62392:22;:29::i;:::-;62372:19;:50::i;:::-;62435:12;62450:33;62477:5;62450:26;:33::i;:::-;62435:48;;62531:1;62525:4;62518:15;62561:28;62583:5;62561:28;;;;;;:::i;:::-;;;;;;;;62293:304;62232:365;:::o;157864:984::-;158067:20;158100:12;158115:32;158139:7;158115:23;:32::i;:::-;158100:47;;158160:14;158195:11;158189:25;158218:1;158189:30;158185:68;;158230:23;:11;:21;:23::i;:::-;158221:32;;158185:68;158267:12;158281:23;158308;-1:-1:-1;;;;;158308:36:0;158382:55;;;158439:4;158445:7;158454:6;158462:4;158468:6;158476:8;158359:126;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;158359:126:0;;;;;;;;;;;;;;-1:-1:-1;;;;;158359:126:0;-1:-1:-1;;;;;;158359:126:0;;;;;;;;;;158308:188;;;;158359:126;158308:188;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;158266:230;;;;158512:7;158507:91;;158575:10;158543:43;;;;;;;;;;;:::i;158507:91::-;158672:4;158660:10;158656:21;158650:28;158634:44;;158809:6;-1:-1:-1;;;;;158762:78:0;158786:7;158762:78;158795:12;158817:4;158823:6;158831:8;158762:78;;;;;;;;;:::i;:::-;;;;;;;;158089:759;;;;157864:984;;;;;;;:::o;155266:753::-;155594:33;155619:7;155594:24;:33::i;:::-;;155734:7;155701:91;155743:4;155749:6;155757:8;155767:6;155775:16;;155701:91;;;;;;;;;;;:::i;:::-;;;;;;;;155805:20;123005:1;155877:7;155886:4;155892:6;155900:8;155910:6;155828:89;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;155805:112;;155930:81;155944:16;;155962:7;155971:29;156002:8;155930:13;:81::i;:::-;155531:488;155266:753;;;;;;;;:::o;157364:173::-;157479:49;;;122444:38;157479:49;;;46890:25:1;46931:18;;;46924:34;;;157437:12:0;;46863:18:1;;157479:49:0;46716:248:1;1799:373:0;1963:78;;;47267:66:1;1963:78:0;;;;47255:79:1;;;;1997:4:0;47371:2:1;47367:15;;;-1:-1:-1;;47363:53:1;;;47350:11;;;47343:74;47433:12;;;47426:28;;;;2016:24:0;47470:12:1;;;;47463:28;;;;1963:78:0;;;;;;;;;;47507:12:1;;;1963:78:0;;1953:89;;;;;;47873:66:1;2113:47:0;;;47861:79:1;47973:15;;47969:53;;;47956:11;;;47949:74;48053:66;48039:12;;;48032:88;2113:47:0;;;;;;;;;48136:12:1;;;;2113:47:0;;;2103:58;;;;;;1799:373::o;61154:177::-;61234:12;58588:60;61316:5;61276:46;;;;;;;;;:::i;71526:156::-;71593:11;69390:18;71665:7;71634:39;;;;;;;;48316:19:1;;;48373:2;48369:15;-1:-1:-1;;48365:53:1;48360:2;48351:12;;48344:75;48444:2;48435:12;;48159:294;84511:255:0;84580:12;84609;:19;84632:2;84609:25;84605:70;;84662:12;84643:32;;;;;;;;;;;:::i;84605:70::-;-1:-1:-1;84744:2:0;84726:21;84720:28;;84511:255::o;162561:795::-;162644:7;162653;162673:21;162697:28;162717:7;162697:19;:28::i;:::-;162673:52;;162739:24;162765:20;162808:13;-1:-1:-1;;;;;162789:70:0;;:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;162945:46;;;;;;;;11994:25:1;;;162738:123:0;;-1:-1:-1;162738:123:0;-1:-1:-1;;;;;;162945:38:0;;;;;11967:18:1;;162945:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;163080:115:0;;;;;;35604:25:1;;;-1:-1:-1;;;;;35726:15:1;;;35706:18;;;35699:43;35778:15;;;35758:18;;;35751:43;35830:15;;;35810:18;;;35803:43;35862:19;;;;35855:35;;;163080:115:0;;;;;;;;;;35576:19:1;;;;163080:115:0;;;;;;;-1:-1:-1;;;;;163080:115:0;163103:32;163080:115;;;163040:166;;-1:-1:-1;;;;;;163040:12:0;:25;;;;:166;;163080:115;163040:166;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;163004:202;;;;163222:7;163217:42;;163254:4;163238:21;;;;;;;;;;;:::i;163217:42::-;163290:4;163279:27;;;;;;;;;;;;:::i;:::-;163270:36;163335:12;;-1:-1:-1;162561:795:0;;-1:-1:-1;;;;;;;;162561:795:0:o;83560:375::-;83712:53;83728:22;83738:11;83728:9;:22::i;:::-;77443:38;;77442:64;;;77315:199;83712:53;83707:109;;83774:42;;-1:-1:-1;;;83774:42:0;;-1:-1:-1;;;;;4799:55:1;;83774:42:0;;;4781:74:1;4871:18;;;4864:34;;;4754:18;;83774:42:0;4607:297:1;83707:109:0;83829:46;83849:11;83862:12;83829:19;:46::i;:::-;83886:41;83903:9;83914:12;83886:16;:41::i;84952:398::-;85059:13;;;85069:2;85059:13;;;;;;;;;85006:25;;85059:13;;;;;;;;-1:-1:-1;;;85284:2:0;85266:21;;;85259:35;;;;85308:24;;;-1:-1:-1;85044:28:0;84952:398::o;152324:1356::-;152517:32;152552;152567:16;;152552:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;152552:14:0;;-1:-1:-1;;;152552:32:0:i;:::-;152517:67;;152605:18;152599:32;152635:1;152599:37;152595:66;;152645:16;;;;;;;;;;;;;;152595:66;152678:12;;152674:919;;152730:29;152711:15;:48;;;;;;;;:::i;:::-;;152707:875;;152780:299;;;;;-1:-1:-1;;;;;152780:10:0;:38;;;;152827:8;;152780:299;;152868:4;;152896:16;;;;152935:18;;152976:7;;153051:9;;152780:299;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;152707:875;;;153124:28;153105:15;:47;;;;;;;;:::i;:::-;;153101:481;;153173:298;;;;;-1:-1:-1;;;;;153173:10:0;:37;;;;153219:8;;153173:298;;153260:4;;153288:16;;;;153327:18;;153368:7;;153443:9;;153173:298;;;:::i;153101:481::-;153549:15;153542:23;;;;;;;;:::i;:::-;153519:47;;-1:-1:-1;;;153519:47:0;;38254:10:1;38242:23;;;153519:47:0;;;38224:42:1;38197:18;;153519:47:0;38080:192:1;153101:481:0;153605:67;;;;;-1:-1:-1;;;;;153605:7:0;:20;;;;:67;;153626:16;;;;153644:18;;153664:7;;153605:67;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79878:400;80029:53;80045:22;80055:11;80045:9;:22::i;80029:53::-;80024:109;;80091:42;;-1:-1:-1;;;80091:42:0;;-1:-1:-1;;;;;4799:55:1;;80091:42:0;;;4781:74:1;4871:18;;;4864:34;;;4754:18;;80091:42:0;4607:297:1;80024:109:0;80146:55;80164:11;80177:9;80188:12;80146:17;:55::i;:::-;80246:9;-1:-1:-1;;;;;80219:51:0;80233:11;-1:-1:-1;;;;;80219:51:0;;80257:12;80219:51;;;;11994:25:1;;11982:2;11967:18;;11848:177;80219:51:0;;;;;;;;79878:400;;;:::o;119218:109::-;119278:41;119287:8;119303:14;119278:8;:41::i;58856:124::-;58925:47;58781:66;58961:10;57502:113;57588:4;57570:37;57602:5;57588:4;57570:37;:::i;81705:442::-;81907:12;81862:41;81880:11;81893:9;81862:17;:41::i;:::-;:57;81858:155;;81943:58;;;;;-1:-1:-1;;;;;52319:15:1;;;81943:58:0;;;52301:34:1;52371:15;;52351:18;;;52344:43;52403:18;;;52396:34;;;52213:18;;81943:58:0;52038:398:1;81858:155:0;82025:44;82043:11;82056:9;82067:1;82025:17;:44::i;:::-;82080:59;82102:11;82115:9;82126:12;82080:21;:59::i;57758:93::-;57807:36;57832:4;57814:29;57807:36;:::i;76335:257::-;76423:23;76471:12;76470:13;76449:18;76459:7;76449:9;:18::i;:::-;:34;76423:60;;76496:35;76506:7;76515:15;76496:9;:35::i;:::-;76562:7;-1:-1:-1;;;;;76549:35:0;;76571:12;76549:35;;;;11994:25:1;;11982:2;11967:18;;11848:177;76549:35:0;;;;;;;;76412:180;76335:257;;:::o;75124:251::-;75209:23;75256:12;75235:18;75245:7;75235:9;:18::i;:::-;:33;75209:59;;75281:35;75291:7;75300:15;75281:9;:35::i;:::-;75345:7;-1:-1:-1;;;;;75334:33:0;;75354:12;75334:33;;;;11994:25:1;;11982:2;11967:18;;11848:177;73817:274:0;73961:11;73975:36;73988:11;74001:9;73975:12;:36::i;:::-;74046:27;;;;-1:-1:-1;;;73817:274:0:o;74309:111::-;74376:36;74393:7;74402:1;:9;;;;74376:16;:36::i;73270:256::-;73360:22;73395:11;73409:36;73422:11;73435:9;73409:12;:36::i;:::-;73498:10;;73270:256;-1:-1:-1;;;;73270:256:0:o;72298:187::-;72375:11;72389:18;72399:7;72389:9;:18::i;:::-;72442:25;;;;-1:-1:-1;;72298:187:0:o;72765:205::-;72858:11;69464:26;72938:11;72951:9;72899:62;;;;;;;;;52626:19:1;;;52733:2;52729:15;;;-1:-1:-1;;52725:24:1;;;52720:2;52711:12;;52704:46;52784:15;;52780:24;52775:2;52766:12;;52759:46;52830:2;52821:12;;52441:398;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;267:180:1:-;326:6;379:2;367:9;358:7;354:23;350:32;347:52;;;395:1;392;385:12;347:52;-1:-1:-1;418:23:1;;267:180;-1:-1:-1;267:180:1:o;683:348::-;735:8;745:6;799:3;792:4;784:6;780:17;776:27;766:55;;817:1;814;807:12;766:55;-1:-1:-1;840:20:1;;883:18;872:30;;869:50;;;915:1;912;905:12;869:50;952:4;944:6;940:17;928:29;;1004:3;997:4;988:6;980;976:19;972:30;969:39;966:59;;;1021:1;1018;1011:12;1036:1437;1187:6;1195;1203;1211;1219;1227;1235;1243;1251;1259;1312:3;1300:9;1291:7;1287:23;1283:33;1280:53;;;1329:1;1326;1319:12;1280:53;1365:9;1352:23;1342:33;;1426:2;1415:9;1411:18;1398:32;1449:18;1490:2;1482:6;1479:14;1476:34;;;1506:1;1503;1496:12;1476:34;1545:59;1596:7;1587:6;1576:9;1572:22;1545:59;:::i;:::-;1623:8;;-1:-1:-1;1519:85:1;-1:-1:-1;1711:2:1;1696:18;;1683:32;;-1:-1:-1;1727:16:1;;;1724:36;;;1756:1;1753;1746:12;1724:36;1795:61;1848:7;1837:8;1826:9;1822:24;1795:61;:::i;:::-;1875:8;;-1:-1:-1;1769:87:1;-1:-1:-1;1963:2:1;1948:18;;1935:32;;-1:-1:-1;1979:16:1;;;1976:36;;;2008:1;2005;1998:12;1976:36;2047:61;2100:7;2089:8;2078:9;2074:24;2047:61;:::i;:::-;2127:8;;-1:-1:-1;2021:87:1;-1:-1:-1;2215:3:1;2200:19;;2187:33;;-1:-1:-1;2232:16:1;;;2229:36;;;2261:1;2258;2251:12;2229:36;;2300:61;2353:7;2342:8;2331:9;2327:24;2300:61;:::i;:::-;2274:87;;2380:8;2370:18;;;2407:8;2397:18;;;2462:3;2451:9;2447:19;2434:33;2424:43;;1036:1437;;;;;;;;;;;;;:::o;2478:250::-;2563:1;2573:113;2587:6;2584:1;2581:13;2573:113;;;2663:11;;;2657:18;2644:11;;;2637:39;2609:2;2602:10;2573:113;;;-1:-1:-1;;2720:1:1;2702:16;;2695:27;2478:250::o;2733:271::-;2775:3;2813:5;2807:12;2840:6;2835:3;2828:19;2856:76;2925:6;2918:4;2913:3;2909:14;2902:4;2895:5;2891:16;2856:76;:::i;:::-;2986:2;2965:15;-1:-1:-1;;2961:29:1;2952:39;;;;2993:4;2948:50;;2733:271;-1:-1:-1;;2733:271:1:o;3009:220::-;3158:2;3147:9;3140:21;3121:4;3178:45;3219:2;3208:9;3204:18;3196:6;3178:45;:::i;3234:1368::-;3376:6;3384;3392;3400;3408;3416;3424;3432;3440;3493:3;3481:9;3472:7;3468:23;3464:33;3461:53;;;3510:1;3507;3500:12;3461:53;3550:9;3537:23;3579:18;3620:2;3612:6;3609:14;3606:34;;;3636:1;3633;3626:12;3606:34;3675:59;3726:7;3717:6;3706:9;3702:22;3675:59;:::i;:::-;3753:8;;-1:-1:-1;3649:85:1;-1:-1:-1;3841:2:1;3826:18;;3813:32;;-1:-1:-1;3857:16:1;;;3854:36;;;3886:1;3883;3876:12;3854:36;3925:61;3978:7;3967:8;3956:9;3952:24;3925:61;:::i;:::-;4005:8;;-1:-1:-1;3899:87:1;-1:-1:-1;4093:2:1;4078:18;;4065:32;;-1:-1:-1;4109:16:1;;;4106:36;;;4138:1;4135;4128:12;4106:36;4177:61;4230:7;4219:8;4208:9;4204:24;4177:61;:::i;:::-;4257:8;;-1:-1:-1;4151:87:1;-1:-1:-1;4345:2:1;4330:18;;4317:32;;-1:-1:-1;4361:16:1;;;4358:36;;;4390:1;4387;4380:12;4358:36;;4429:61;4482:7;4471:8;4460:9;4456:24;4429:61;:::i;:::-;3234:1368;;;;-1:-1:-1;3234:1368:1;;;;;;;;4509:8;4591:3;4576:19;4563:33;;3234:1368;-1:-1:-1;;;;3234:1368:1:o;4909:367::-;4972:8;4982:6;5036:3;5029:4;5021:6;5017:17;5013:27;5003:55;;5054:1;5051;5044:12;5003:55;-1:-1:-1;5077:20:1;;5120:18;5109:30;;5106:50;;;5152:1;5149;5142:12;5106:50;5189:4;5181:6;5177:17;5165:29;;5249:3;5242:4;5232:6;5229:1;5225:14;5217:6;5213:27;5209:38;5206:47;5203:67;;;5266:1;5263;5256:12;5281:773;5403:6;5411;5419;5427;5480:2;5468:9;5459:7;5455:23;5451:32;5448:52;;;5496:1;5493;5486:12;5448:52;5536:9;5523:23;5565:18;5606:2;5598:6;5595:14;5592:34;;;5622:1;5619;5612:12;5592:34;5661:70;5723:7;5714:6;5703:9;5699:22;5661:70;:::i;:::-;5750:8;;-1:-1:-1;5635:96:1;-1:-1:-1;5838:2:1;5823:18;;5810:32;;-1:-1:-1;5854:16:1;;;5851:36;;;5883:1;5880;5873:12;5851:36;;5922:72;5986:7;5975:8;5964:9;5960:24;5922:72;:::i;:::-;5281:773;;;;-1:-1:-1;6013:8:1;-1:-1:-1;;;;5281:773:1:o;6059:184::-;-1:-1:-1;;;6108:1:1;6101:88;6208:4;6205:1;6198:15;6232:4;6229:1;6222:15;6248:275;6319:2;6313:9;6384:2;6365:13;;-1:-1:-1;;6361:27:1;6349:40;;6419:18;6404:34;;6440:22;;;6401:62;6398:88;;;6466:18;;:::i;:::-;6502:2;6495:22;6248:275;;-1:-1:-1;6248:275:1:o;6528:531::-;6571:5;6624:3;6617:4;6609:6;6605:17;6601:27;6591:55;;6642:1;6639;6632:12;6591:55;6678:6;6665:20;6704:18;6700:2;6697:26;6694:52;;;6726:18;;:::i;:::-;6770:55;6813:2;6794:13;;-1:-1:-1;;6790:27:1;6819:4;6786:38;6770:55;:::i;:::-;6850:2;6841:7;6834:19;6896:3;6889:4;6884:2;6876:6;6872:15;6868:26;6865:35;6862:55;;;6913:1;6910;6903:12;6862:55;6978:2;6971:4;6963:6;6959:17;6952:4;6943:7;6939:18;6926:55;7026:1;7001:16;;;7019:4;6997:27;6990:38;;;;7005:7;6528:531;-1:-1:-1;;;6528:531:1:o;7064:322::-;7133:6;7186:2;7174:9;7165:7;7161:23;7157:32;7154:52;;;7202:1;7199;7192:12;7154:52;7242:9;7229:23;7275:18;7267:6;7264:30;7261:50;;;7307:1;7304;7297:12;7261:50;7330;7372:7;7363:6;7352:9;7348:22;7330:50;:::i;:::-;7320:60;7064:322;-1:-1:-1;;;;7064:322:1:o;7391:1078::-;7512:6;7520;7528;7536;7544;7552;7560;7613:3;7601:9;7592:7;7588:23;7584:33;7581:53;;;7630:1;7627;7620:12;7581:53;7666:9;7653:23;7643:33;;7727:2;7716:9;7712:18;7699:32;7750:18;7791:2;7783:6;7780:14;7777:34;;;7807:1;7804;7797:12;7777:34;7846:59;7897:7;7888:6;7877:9;7873:22;7846:59;:::i;:::-;7924:8;;-1:-1:-1;7820:85:1;-1:-1:-1;8012:2:1;7997:18;;7984:32;;-1:-1:-1;8028:16:1;;;8025:36;;;8057:1;8054;8047:12;8025:36;8096:61;8149:7;8138:8;8127:9;8123:24;8096:61;:::i;:::-;8176:8;;-1:-1:-1;8070:87:1;-1:-1:-1;8264:2:1;8249:18;;8236:32;;-1:-1:-1;8280:16:1;;;8277:36;;;8309:1;8306;8299:12;8277:36;;8348:61;8401:7;8390:8;8379:9;8375:24;8348:61;:::i;:::-;7391:1078;;;;-1:-1:-1;7391:1078:1;;-1:-1:-1;7391:1078:1;;;;8322:87;;-1:-1:-1;;;7391:1078:1:o;8474:154::-;-1:-1:-1;;;;;8553:5:1;8549:54;8542:5;8539:65;8529:93;;8618:1;8615;8608:12;8633:247;8692:6;8745:2;8733:9;8724:7;8720:23;8716:32;8713:52;;;8761:1;8758;8751:12;8713:52;8800:9;8787:23;8819:31;8844:5;8819:31;:::i;8885:1126::-;9021:6;9029;9037;9045;9053;9061;9069;9077;9130:3;9118:9;9109:7;9105:23;9101:33;9098:53;;;9147:1;9144;9137:12;9098:53;9183:9;9170:23;9160:33;;9244:2;9233:9;9229:18;9216:32;9267:18;9308:2;9300:6;9297:14;9294:34;;;9324:1;9321;9314:12;9294:34;9363:59;9414:7;9405:6;9394:9;9390:22;9363:59;:::i;:::-;9441:8;;-1:-1:-1;9337:85:1;-1:-1:-1;9529:2:1;9514:18;;9501:32;;-1:-1:-1;9545:16:1;;;9542:36;;;9574:1;9571;9564:12;9542:36;9613:61;9666:7;9655:8;9644:9;9640:24;9613:61;:::i;:::-;9693:8;;-1:-1:-1;9587:87:1;-1:-1:-1;9775:2:1;9760:18;;9747:32;;-1:-1:-1;9832:3:1;9817:19;;9804:33;;-1:-1:-1;9849:16:1;;;9846:36;;;9878:1;9875;9868:12;9846:36;;9901:52;9945:7;9934:8;9923:9;9919:24;9901:52;:::i;:::-;9891:62;;;10000:3;9989:9;9985:19;9972:33;9962:43;;8885:1126;;;;;;;;;;;:::o;10465:1193::-;10601:6;10609;10617;10625;10633;10641;10649;10657;10710:3;10698:9;10689:7;10685:23;10681:33;10678:53;;;10727:1;10724;10717:12;10678:53;10763:9;10750:23;10740:33;;10823:2;10812:9;10808:18;10795:32;10836:31;10861:5;10836:31;:::i;:::-;10886:5;-1:-1:-1;10942:2:1;10927:18;;10914:32;10965:18;10995:14;;;10992:34;;;11022:1;11019;11012:12;10992:34;11061:59;11112:7;11103:6;11092:9;11088:22;11061:59;:::i;:::-;11139:8;;-1:-1:-1;11035:85:1;-1:-1:-1;11227:2:1;11212:18;;11199:32;;-1:-1:-1;11243:16:1;;;11240:36;;;11272:1;11269;11262:12;11240:36;11295:52;11339:7;11328:8;11317:9;11313:24;11295:52;:::i;:::-;11285:62;;11394:3;11383:9;11379:19;11366:33;11356:43;;11452:3;11441:9;11437:19;11424:33;11408:49;;11482:2;11472:8;11469:16;11466:36;;;11498:1;11495;11488:12;11466:36;;11537:61;11590:7;11579:8;11568:9;11564:24;11537:61;:::i;:::-;10465:1193;;;;-1:-1:-1;10465:1193:1;;-1:-1:-1;10465:1193:1;;;;;;11617:8;-1:-1:-1;;;10465:1193:1:o;12030:1009::-;12142:6;12150;12158;12166;12174;12182;12235:2;12223:9;12214:7;12210:23;12206:32;12203:52;;;12251:1;12248;12241:12;12203:52;12291:9;12278:23;12320:18;12361:2;12353:6;12350:14;12347:34;;;12377:1;12374;12367:12;12347:34;12416:59;12467:7;12458:6;12447:9;12443:22;12416:59;:::i;:::-;12494:8;;-1:-1:-1;12390:85:1;-1:-1:-1;12582:2:1;12567:18;;12554:32;;-1:-1:-1;12598:16:1;;;12595:36;;;12627:1;12624;12617:12;12595:36;12666:61;12719:7;12708:8;12697:9;12693:24;12666:61;:::i;:::-;12746:8;;-1:-1:-1;12640:87:1;-1:-1:-1;12834:2:1;12819:18;;12806:32;;-1:-1:-1;12850:16:1;;;12847:36;;;12879:1;12876;12869:12;12847:36;;12918:61;12971:7;12960:8;12949:9;12945:24;12918:61;:::i;:::-;12030:1009;;;;-1:-1:-1;12030:1009:1;;-1:-1:-1;12030:1009:1;;12998:8;;12030:1009;-1:-1:-1;;;12030:1009:1:o;13044:1217::-;13184:6;13192;13200;13208;13216;13224;13232;13240;13248;13301:3;13289:9;13280:7;13276:23;13272:33;13269:53;;;13318:1;13315;13308:12;13269:53;13354:9;13341:23;13331:33;;13415:2;13404:9;13400:18;13387:32;13438:18;13479:2;13471:6;13468:14;13465:34;;;13495:1;13492;13485:12;13465:34;13534:59;13585:7;13576:6;13565:9;13561:22;13534:59;:::i;:::-;13612:8;;-1:-1:-1;13508:85:1;-1:-1:-1;13700:2:1;13685:18;;13672:32;;-1:-1:-1;13716:16:1;;;13713:36;;;13745:1;13742;13735:12;13713:36;13784:61;13837:7;13826:8;13815:9;13811:24;13784:61;:::i;:::-;13864:8;;-1:-1:-1;13758:87:1;-1:-1:-1;13946:2:1;13931:18;;13918:32;;-1:-1:-1;14003:3:1;13988:19;;13975:33;;-1:-1:-1;14020:16:1;;;14017:36;;;14049:1;14046;14039:12;14017:36;;14088:61;14141:7;14130:8;14119:9;14115:24;14088:61;:::i;:::-;13044:1217;;;;-1:-1:-1;13044:1217:1;;;;;;;;14168:8;14250:3;14235:19;14222:33;;13044:1217;-1:-1:-1;;;;13044:1217:1:o;14266:156::-;14332:20;;14392:4;14381:16;;14371:27;;14361:55;;14412:1;14409;14402:12;14427:317;14493:6;14501;14554:2;14542:9;14533:7;14529:23;14525:32;14522:52;;;14570:1;14567;14560:12;14522:52;14609:9;14596:23;14628:31;14653:5;14628:31;:::i;:::-;14678:5;-1:-1:-1;14702:36:1;14734:2;14719:18;;14702:36;:::i;:::-;14692:46;;14427:317;;;;;:::o;14749:157::-;14831:20;;14880:1;14870:12;;14860:40;;14896:1;14893;14886:12;14911:967;15050:6;15058;15066;15074;15082;15090;15098;15151:3;15139:9;15130:7;15126:23;15122:33;15119:53;;;15168:1;15165;15158:12;15119:53;15204:9;15191:23;15181:33;;15265:2;15254:9;15250:18;15237:32;15288:18;15329:2;15321:6;15318:14;15315:34;;;15345:1;15342;15335:12;15315:34;15384:59;15435:7;15426:6;15415:9;15411:22;15384:59;:::i;:::-;15462:8;;-1:-1:-1;15358:85:1;-1:-1:-1;15358:85:1;;-1:-1:-1;15516:52:1;15564:2;15549:18;;15516:52;:::i;:::-;15506:62;;15621:2;15610:9;15606:18;15593:32;15577:48;;15650:2;15640:8;15637:16;15634:36;;;15666:1;15663;15656:12;15634:36;;15705:61;15758:7;15747:8;15736:9;15732:24;15705:61;:::i;:::-;14911:967;;;;-1:-1:-1;14911:967:1;;;;;;15867:3;15852:19;;;15839:33;;14911:967;-1:-1:-1;;;;14911:967:1:o;15883:410::-;15953:6;15961;16014:2;16002:9;15993:7;15989:23;15985:32;15982:52;;;16030:1;16027;16020:12;15982:52;16070:9;16057:23;16103:18;16095:6;16092:30;16089:50;;;16135:1;16132;16125:12;16089:50;16174:59;16225:7;16216:6;16205:9;16201:22;16174:59;:::i;:::-;16252:8;;16148:85;;-1:-1:-1;15883:410:1;-1:-1:-1;;;;15883:410:1:o;16298:543::-;16386:6;16394;16447:2;16435:9;16426:7;16422:23;16418:32;16415:52;;;16463:1;16460;16453:12;16415:52;16503:9;16490:23;16532:18;16573:2;16565:6;16562:14;16559:34;;;16589:1;16586;16579:12;16559:34;16612:50;16654:7;16645:6;16634:9;16630:22;16612:50;:::i;:::-;16602:60;;16715:2;16704:9;16700:18;16687:32;16671:48;;16744:2;16734:8;16731:16;16728:36;;;16760:1;16757;16750:12;16728:36;;16783:52;16827:7;16816:8;16805:9;16801:24;16783:52;:::i;:::-;16773:62;;;16298:543;;;;;:::o;16846:613::-;16934:6;16942;16950;16958;17011:2;16999:9;16990:7;16986:23;16982:32;16979:52;;;17027:1;17024;17017:12;16979:52;17066:9;17053:23;17085:31;17110:5;17085:31;:::i;:::-;17135:5;-1:-1:-1;17187:2:1;17172:18;;17159:32;;-1:-1:-1;17242:2:1;17227:18;;17214:32;17269:18;17258:30;;17255:50;;;17301:1;17298;17291:12;17255:50;17340:59;17391:7;17382:6;17371:9;17367:22;17340:59;:::i;17464:315::-;17532:6;17540;17593:2;17581:9;17572:7;17568:23;17564:32;17561:52;;;17609:1;17606;17599:12;17561:52;17648:9;17635:23;17667:31;17692:5;17667:31;:::i;:::-;17717:5;17769:2;17754:18;;;;17741:32;;-1:-1:-1;;;17464:315:1:o;17784:448::-;17881:6;17889;17942:2;17930:9;17921:7;17917:23;17913:32;17910:52;;;17958:1;17955;17948:12;17910:52;17998:9;17985:23;18031:18;18023:6;18020:30;18017:50;;;18063:1;18060;18053:12;18017:50;18102:70;18164:7;18155:6;18144:9;18140:22;18102:70;:::i;18237:801::-;18397:4;18426:2;18466;18455:9;18451:18;18496:2;18485:9;18478:21;18519:6;18554;18548:13;18585:6;18577;18570:22;18623:2;18612:9;18608:18;18601:25;;18685:2;18675:6;18672:1;18668:14;18657:9;18653:30;18649:39;18635:53;;18723:2;18715:6;18711:15;18744:1;18754:255;18768:6;18765:1;18762:13;18754:255;;;18861:2;18857:7;18845:9;18837:6;18833:22;18829:36;18824:3;18817:49;18889:40;18922:6;18913;18907:13;18889:40;:::i;:::-;18879:50;-1:-1:-1;18987:12:1;;;;18952:15;;;;18790:1;18783:9;18754:255;;;-1:-1:-1;19026:6:1;;18237:801;-1:-1:-1;;;;;;;18237:801:1:o;19043:118::-;19129:5;19122:13;19115:21;19108:5;19105:32;19095:60;;19151:1;19148;19141:12;19166:241;19222:6;19275:2;19263:9;19254:7;19250:23;19246:32;19243:52;;;19291:1;19288;19281:12;19243:52;19330:9;19317:23;19349:28;19371:5;19349:28;:::i;19412:721::-;19504:6;19512;19520;19528;19581:2;19569:9;19560:7;19556:23;19552:32;19549:52;;;19597:1;19594;19587:12;19549:52;19637:9;19624:23;19666:18;19707:2;19699:6;19696:14;19693:34;;;19723:1;19720;19713:12;19693:34;19762:59;19813:7;19804:6;19793:9;19789:22;19762:59;:::i;:::-;19840:8;;-1:-1:-1;19736:85:1;-1:-1:-1;19928:2:1;19913:18;;19900:32;;-1:-1:-1;19944:16:1;;;19941:36;;;19973:1;19970;19963:12;19941:36;;20012:61;20065:7;20054:8;20043:9;20039:24;20012:61;:::i;20138:858::-;20248:6;20256;20264;20272;20280;20288;20341:3;20329:9;20320:7;20316:23;20312:33;20309:53;;;20358:1;20355;20348:12;20309:53;20394:9;20381:23;20371:33;;20455:2;20444:9;20440:18;20427:32;20478:18;20519:2;20511:6;20508:14;20505:34;;;20535:1;20532;20525:12;20505:34;20574:59;20625:7;20616:6;20605:9;20601:22;20574:59;:::i;:::-;20652:8;;-1:-1:-1;20548:85:1;-1:-1:-1;20740:2:1;20725:18;;20712:32;;-1:-1:-1;20756:16:1;;;20753:36;;;20785:1;20782;20775:12;20753:36;;20824:61;20877:7;20866:8;20855:9;20851:24;20824:61;:::i;:::-;20138:858;;;;-1:-1:-1;20138:858:1;;;;;20986:2;20971:18;;;20958:32;;20138:858;-1:-1:-1;;;;20138:858:1:o;22403:1241::-;22555:6;22563;22571;22579;22587;22595;22603;22611;22664:3;22652:9;22643:7;22639:23;22635:33;22632:53;;;22681:1;22678;22671:12;22632:53;22717:9;22704:23;22694:33;;22778:2;22767:9;22763:18;22750:32;22801:18;22842:2;22834:6;22831:14;22828:34;;;22858:1;22855;22848:12;22828:34;22897:59;22948:7;22939:6;22928:9;22924:22;22897:59;:::i;:::-;22975:8;;-1:-1:-1;22871:85:1;-1:-1:-1;23063:2:1;23048:18;;23035:32;;-1:-1:-1;23079:16:1;;;23076:36;;;23108:1;23105;23098:12;23076:36;23131:52;23175:7;23164:8;23153:9;23149:24;23131:52;:::i;:::-;23121:62;;23236:2;23225:9;23221:18;23208:32;23192:48;;23265:2;23255:8;23252:16;23249:36;;;23281:1;23278;23271:12;23249:36;23304:52;23348:7;23337:8;23326:9;23322:24;23304:52;:::i;:::-;23294:62;;23375:37;23407:3;23396:9;23392:19;23375:37;:::i;:::-;23365:47;;23465:3;23454:9;23450:19;23437:33;23421:49;;23495:2;23485:8;23482:16;23479:36;;;23511:1;23508;23501:12;23479:36;;23534:52;23578:7;23567:8;23556:9;23552:24;23534:52;:::i;:::-;23524:62;;;23633:3;23622:9;23618:19;23605:33;23595:43;;22403:1241;;;;;;;;;;;:::o;23649:251::-;23719:6;23772:2;23760:9;23751:7;23747:23;23743:32;23740:52;;;23788:1;23785;23778:12;23740:52;23820:9;23814:16;23839:31;23864:5;23839:31;:::i;23905:184::-;-1:-1:-1;;;23954:1:1;23947:88;24054:4;24051:1;24044:15;24078:4;24075:1;24068:15;24403:184;-1:-1:-1;;;24452:1:1;24445:88;24552:4;24549:1;24542:15;24576:4;24573:1;24566:15;24592:289;24631:3;24652:17;;;24649:197;;-1:-1:-1;;;24699:1:1;24692:88;24803:4;24800:1;24793:15;24831:4;24828:1;24821:15;24649:197;-1:-1:-1;24873:1:1;24862:13;;24592:289::o;24886:271::-;25069:6;25061;25056:3;25043:33;25025:3;25095:16;;25120:13;;;25095:16;24886:271;-1:-1:-1;24886:271:1:o;25162:267::-;25251:6;25246:3;25239:19;25303:6;25296:5;25289:4;25284:3;25280:14;25267:43;-1:-1:-1;25355:1:1;25330:16;;;25348:4;25326:27;;;25319:38;;;;25411:2;25390:15;;;-1:-1:-1;;25386:29:1;25377:39;;;25373:50;;25162:267::o;25434:581::-;25707:6;25696:9;25689:25;25750:3;25745:2;25734:9;25730:18;25723:31;25670:4;25777:63;25835:3;25824:9;25820:19;25812:6;25804;25777:63;:::i;:::-;25888:9;25880:6;25876:22;25871:2;25860:9;25856:18;25849:50;25916;25959:6;25951;25943;25916:50;:::i;:::-;25908:58;;;26002:6;25997:2;25986:9;25982:18;25975:34;25434:581;;;;;;;;;:::o;26020:245::-;26087:6;26140:2;26128:9;26119:7;26115:23;26111:32;26108:52;;;26156:1;26153;26146:12;26108:52;26188:9;26182:16;26207:28;26229:5;26207:28;:::i;26270:508::-;26515:2;26504:9;26497:21;26478:4;26541:62;26599:2;26588:9;26584:18;26576:6;26568;26541:62;:::i;:::-;26651:9;26643:6;26639:22;26634:2;26623:9;26619:18;26612:50;26679;26722:6;26714;26706;26679:50;:::i;:::-;26671:58;;;26765:6;26760:2;26749:9;26745:18;26738:34;26270:508;;;;;;;;:::o;26783:526::-;26878:6;26886;26894;26902;26955:3;26943:9;26934:7;26930:23;26926:33;26923:53;;;26972:1;26969;26962:12;26923:53;27008:9;26995:23;26985:33;;27065:2;27054:9;27050:18;27037:32;27027:42;;27120:2;27109:9;27105:18;27092:32;27147:18;27139:6;27136:30;27133:50;;;27179:1;27176;27169:12;27133:50;27202;27244:7;27235:6;27224:9;27220:22;27202:50;:::i;:::-;26783:526;;;;-1:-1:-1;27192:60:1;;27299:2;27284:18;27271:32;;-1:-1:-1;;;26783:526:1:o;27314:301::-;27402:1;27395:5;27392:12;27382:200;;-1:-1:-1;;;27435:1:1;27428:88;27539:4;27536:1;27529:15;27567:4;27564:1;27557:15;27382:200;27591:18;;27314:301::o;27620:222::-;27773:2;27758:18;;27785:51;27762:9;27818:6;27785:51;:::i;27847:184::-;27917:6;27970:2;27958:9;27949:7;27945:23;27941:32;27938:52;;;27986:1;27983;27976:12;27938:52;-1:-1:-1;28009:16:1;;27847:184;-1:-1:-1;27847:184:1:o;28036:245::-;28193:2;28182:9;28175:21;28156:4;28213:62;28271:2;28260:9;28256:18;28248:6;28240;28213:62;:::i;28286:287::-;28415:3;28453:6;28447:13;28469:66;28528:6;28523:3;28516:4;28508:6;28504:17;28469:66;:::i;:::-;28551:16;;;;;28286:287;-1:-1:-1;;28286:287:1:o;28951:521::-;29028:4;29034:6;29094:11;29081:25;29188:2;29184:7;29173:8;29157:14;29153:29;29149:43;29129:18;29125:68;29115:96;;29207:1;29204;29197:12;29115:96;29234:33;;29286:20;;;-1:-1:-1;29329:18:1;29318:30;;29315:50;;;29361:1;29358;29351:12;29315:50;29394:4;29382:17;;-1:-1:-1;29425:14:1;29421:27;;;29411:38;;29408:58;;;29462:1;29459;29452:12;29666:338;29841:2;29830:9;29823:21;29804:4;29861:45;29902:2;29891:9;29887:18;29879:6;29861:45;:::i;:::-;29853:53;;-1:-1:-1;;;;;29946:6:1;29942:55;29937:2;29926:9;29922:18;29915:83;29666:338;;;;;:::o;30009:437::-;30088:1;30084:12;;;;30131;;;30152:61;;30206:4;30198:6;30194:17;30184:27;;30152:61;30259:2;30251:6;30248:14;30228:18;30225:38;30222:218;;-1:-1:-1;;;30293:1:1;30286:88;30397:4;30394:1;30387:15;30425:4;30422:1;30415:15;30222:218;;30009:437;;;:::o;30451:291::-;30628:6;30617:9;30610:25;30671:2;30666;30655:9;30651:18;30644:30;30591:4;30691:45;30732:2;30721:9;30717:18;30709:6;30691:45;:::i;30747:947::-;30878:6;30886;30894;30902;30910;30918;30971:3;30959:9;30950:7;30946:23;30942:33;30939:53;;;30988:1;30985;30978:12;30939:53;31024:9;31011:23;31001:33;;31081:2;31070:9;31066:18;31053:32;31043:42;;31136:2;31125:9;31121:18;31108:32;31159:18;31200:2;31192:6;31189:14;31186:34;;;31216:1;31213;31206:12;31186:34;31239:50;31281:7;31272:6;31261:9;31257:22;31239:50;:::i;:::-;31229:60;;31342:2;31331:9;31327:18;31314:32;31298:48;;31371:2;31361:8;31358:16;31355:36;;;31387:1;31384;31377:12;31355:36;31410:52;31454:7;31443:8;31432:9;31428:24;31410:52;:::i;:::-;31400:62;;31509:3;31498:9;31494:19;31481:33;31471:43;;31567:3;31556:9;31552:19;31539:33;31523:49;;31597:2;31587:8;31584:16;31581:36;;;31613:1;31610;31603:12;31581:36;;31636:52;31680:7;31669:8;31658:9;31654:24;31636:52;:::i;:::-;31626:62;;;30747:947;;;;;;;;:::o;31699:552::-;31960:3;31949:9;31942:22;31923:4;31987:63;32045:3;32034:9;32030:19;32022:6;32014;31987:63;:::i;:::-;32098:9;32090:6;32086:22;32081:2;32070:9;32066:18;32059:50;32126:33;32152:6;32144;32126:33;:::i;:::-;32190:2;32175:18;;32168:34;;;;-1:-1:-1;;32233:2:1;32218:18;32211:34;32118:41;31699:552;-1:-1:-1;;;31699:552:1:o;32256:907::-;32619:6;32608:9;32601:25;32662:3;32657:2;32646:9;32642:18;32635:31;32582:4;32689:63;32747:3;32736:9;32732:19;32724:6;32716;32689:63;:::i;:::-;32800:9;32792:6;32788:22;32783:2;32772:9;32768:18;32761:50;32834:33;32860:6;32852;32834:33;:::i;:::-;32820:47;;32915:9;32907:6;32903:22;32898:2;32887:9;32883:18;32876:50;32943:33;32969:6;32961;32943:33;:::i;:::-;33007:3;32992:19;;32985:35;;;;-1:-1:-1;;;;;;;33057:55:1;;;;33051:3;33036:19;;33029:84;33144:3;33129:19;;;33122:35;32935:41;32256:907;-1:-1:-1;;;;;32256:907:1:o;33168:567::-;33284:6;33292;33300;33308;33361:3;33349:9;33340:7;33336:23;33332:33;33329:53;;;33378:1;33375;33368:12;33329:53;33414:9;33401:23;33391:33;;33471:2;33460:9;33456:18;33443:32;33433:42;;33494:52;33542:2;33531:9;33527:18;33494:52;:::i;:::-;33484:62;;33597:2;33586:9;33582:18;33569:32;33624:18;33616:6;33613:30;33610:50;;;33656:1;33653;33646:12;33610:50;33679;33721:7;33712:6;33701:9;33697:22;33679:50;:::i;:::-;33669:60;;;33168:567;;;;;;;:::o;33740:951::-;33871:6;33879;33887;33895;33903;33911;33964:3;33952:9;33943:7;33939:23;33935:33;33932:53;;;33981:1;33978;33971:12;33932:53;34017:9;34004:23;33994:33;;34074:2;34063:9;34059:18;34046:32;34036:42;;34129:2;34118:9;34114:18;34101:32;34152:18;34193:2;34185:6;34182:14;34179:34;;;34209:1;34206;34199:12;34179:34;34232:50;34274:7;34265:6;34254:9;34250:22;34232:50;:::i;:::-;34222:60;;34335:2;34324:9;34320:18;34307:32;34291:48;;34364:2;34354:8;34351:16;34348:36;;;34380:1;34377;34370:12;34348:36;34403:52;34447:7;34436:8;34425:9;34421:24;34403:52;:::i;:::-;34393:62;;34474:37;34506:3;34495:9;34491:19;34474:37;:::i;:::-;34464:47;;34564:3;34553:9;34549:19;34536:33;34520:49;;34594:2;34584:8;34581:16;34578:36;;;34610:1;34607;34600:12;34696:312;34775:6;34783;34836:2;34824:9;34815:7;34811:23;34807:32;34804:52;;;34852:1;34849;34842:12;34804:52;34881:9;34875:16;34865:26;;34934:2;34923:9;34919:18;34913:25;34947:31;34972:5;34947:31;:::i;:::-;34997:5;34987:15;;;34696:312;;;;;:::o;36124:479::-;36357:2;36346:9;36339:21;36320:4;36383:62;36441:2;36430:9;36426:18;36418:6;36410;36383:62;:::i;:::-;36493:9;36485:6;36481:22;36476:2;36465:9;36461:18;36454:50;36521:33;36547:6;36539;36521:33;:::i;:::-;36513:41;;;36590:6;36585:2;36574:9;36570:18;36563:34;36124:479;;;;;;;:::o;36608:757::-;36931:6;36920:9;36913:25;36974:6;36969:2;36958:9;36954:18;36947:34;37017:3;37012:2;37001:9;36997:18;36990:31;36894:4;37044:46;37085:3;37074:9;37070:19;37062:6;37044:46;:::i;:::-;37138:9;37130:6;37126:22;37121:2;37110:9;37106:18;37099:50;37172:33;37198:6;37190;37172:33;:::i;:::-;37158:47;;37242:6;37236:3;37225:9;37221:19;37214:35;37298:9;37290:6;37286:22;37280:3;37269:9;37265:19;37258:51;37326:33;37352:6;37344;37326:33;:::i;:::-;37318:41;36608:757;-1:-1:-1;;;;;;;;;36608:757:1:o;37370:331::-;37475:9;37486;37528:8;37516:10;37513:24;37510:44;;;37550:1;37547;37540:12;37510:44;37579:6;37569:8;37566:20;37563:40;;;37599:1;37596;37589:12;37563:40;-1:-1:-1;;37625:23:1;;;37670:25;;;;;-1:-1:-1;37370:331:1:o;37706:369::-;-1:-1:-1;;;;;;37826:19:1;;37948:11;;;;37979:1;37971:10;;37968:101;;;38056:2;38050;38043:3;38040:1;38036:11;38033:1;38029:19;38025:28;38021:2;38017:37;38013:46;38004:55;;37968:101;;;37706:369;;;;:::o;38277:916::-;38664:6;38653:9;38646:25;38707:6;38702:2;38691:9;38687:18;38680:34;38750:3;38745:2;38734:9;38730:18;38723:31;38627:4;38777:63;38835:3;38824:9;38820:19;38812:6;38804;38777:63;:::i;:::-;38888:9;38880:6;38876:22;38871:2;38860:9;38856:18;38849:50;38922;38965:6;38957;38949;38922:50;:::i;:::-;38908:64;;39009:6;39003:3;38992:9;38988:19;38981:35;39065:9;39057:6;39053:22;39047:3;39036:9;39032:19;39025:51;39093:50;39136:6;39128;39120;39093:50;:::i;:::-;39085:58;;;39180:6;39174:3;39163:9;39159:19;39152:35;38277:916;;;;;;;;;;;;;:::o;39198:405::-;39420:6;39409:9;39402:25;39436:60;39492:2;39481:9;39477:18;39469:6;39436:60;:::i;:::-;39532:2;39527;39516:9;39512:18;39505:30;39383:4;39552:45;39593:2;39582:9;39578:18;39570:6;39552:45;:::i;:::-;39544:53;39198:405;-1:-1:-1;;;;;39198:405:1:o;39608:338::-;-1:-1:-1;;;;;39787:6:1;39783:55;39772:9;39765:74;39875:2;39870;39859:9;39855:18;39848:30;39746:4;39895:45;39936:2;39925:9;39921:18;39913:6;39895:45;:::i;39951:408::-;40156:2;40145:9;40138:21;40119:4;40182:62;40240:2;40229:9;40225:18;40217:6;40209;40182:62;:::i;:::-;40292:9;40284:6;40280:22;40275:2;40264:9;40260:18;40253:50;40320:33;40346:6;40338;40320:33;:::i;:::-;40312:41;39951:408;-1:-1:-1;;;;;;39951:408:1:o;40364:478::-;40614:6;40603:9;40596:25;40657:6;40652:2;40641:9;40637:18;40630:34;40673:60;40729:2;40718:9;40714:18;40706:6;40673:60;:::i;:::-;40769:3;40764:2;40753:9;40749:18;40742:31;40577:4;40790:46;40831:3;40820:9;40816:19;40808:6;40790:46;:::i;40847:943::-;40900:5;40953:3;40946:4;40938:6;40934:17;40930:27;40920:55;;40971:1;40968;40961:12;40920:55;41007:6;40994:20;41033:4;41056:18;41093:2;41089;41086:10;41083:36;;;41099:18;;:::i;:::-;41145:2;41142:1;41138:10;41168:28;41192:2;41188;41184:11;41168:28;:::i;:::-;41230:15;;;41300;;;41296:24;;;41261:12;;;;41332:15;;;41329:35;;;41360:1;41357;41350:12;41329:35;41396:2;41388:6;41384:15;41373:26;;41408:353;41424:6;41419:3;41416:15;41408:353;;;41510:3;41497:17;41546:2;41533:11;41530:19;41527:109;;;41590:1;41619:2;41615;41608:14;41527:109;41661:57;41714:3;41709:2;41695:11;41687:6;41683:24;41679:33;41661:57;:::i;:::-;41649:70;;-1:-1:-1;41441:12:1;;;;41739;;;;41408:353;;;41779:5;40847:943;-1:-1:-1;;;;;;;;40847:943:1:o;41795:957::-;41969:6;41977;41985;41993;42046:3;42034:9;42025:7;42021:23;42017:33;42014:53;;;42063:1;42060;42053:12;42014:53;42102:9;42089:23;42121:31;42146:5;42121:31;:::i;:::-;42171:5;-1:-1:-1;42227:2:1;42212:18;;42199:32;42250:18;42280:14;;;42277:34;;;42307:1;42304;42297:12;42277:34;42330:50;42372:7;42363:6;42352:9;42348:22;42330:50;:::i;:::-;42320:60;;42433:2;42422:9;42418:18;42405:32;42389:48;;42462:2;42452:8;42449:16;42446:36;;;42478:1;42475;42468:12;42446:36;42501:62;42555:7;42544:8;42533:9;42529:24;42501:62;:::i;:::-;42491:72;;42616:2;42605:9;42601:18;42588:32;42572:48;;42645:2;42635:8;42632:16;42629:36;;;42661:1;42658;42651:12;42629:36;;42684:62;42738:7;42727:8;42716:9;42712:24;42684:62;:::i;42757:383::-;42954:2;42943:9;42936:21;42917:4;42980:45;43021:2;43010:9;43006:18;42998:6;42980:45;:::i;:::-;43073:9;43065:6;43061:22;43056:2;43045:9;43041:18;43034:50;43101:33;43127:6;43119;43101:33;:::i;43145:653::-;43446:6;43435:9;43428:25;43489:6;43484:2;43473:9;43469:18;43462:34;43532:3;43527:2;43516:9;43512:18;43505:31;43409:4;43559:63;43617:3;43606:9;43602:19;43594:6;43586;43559:63;:::i;:::-;43670:9;43662:6;43658:22;43653:2;43642:9;43638:18;43631:50;43698;43741:6;43733;43725;43698:50;:::i;:::-;43690:58;;;43785:6;43779:3;43768:9;43764:19;43757:35;43145:653;;;;;;;;;;:::o;43803:727::-;44108:6;44097:9;44090:25;44151:6;44146:2;44135:9;44131:18;44124:34;-1:-1:-1;;;;;44198:6:1;44194:55;44189:2;44178:9;44174:18;44167:83;44286:3;44281:2;44270:9;44266:18;44259:31;44071:4;44313:46;44354:3;44343:9;44339:19;44331:6;44313:46;:::i;:::-;44408:9;44400:6;44396:22;44390:3;44379:9;44375:19;44368:51;44436:33;44462:6;44454;44436:33;:::i;:::-;44428:41;;;44518:4;44510:6;44506:17;44500:3;44489:9;44485:19;44478:46;43803:727;;;;;;;;;:::o;44535:583::-;-1:-1:-1;;;;;44788:6:1;44784:55;44773:9;44766:74;44876:3;44871:2;44860:9;44856:18;44849:31;44747:4;44903:46;44944:3;44933:9;44929:19;44921:6;44903:46;:::i;:::-;44997:9;44989:6;44985:22;44980:2;44969:9;44965:18;44958:50;45025:33;45051:6;45043;45025:33;:::i;:::-;45017:41;;;45106:4;45098:6;45094:17;45089:2;45078:9;45074:18;45067:45;44535:583;;;;;;;:::o;45123:815::-;45448:3;45437:9;45430:22;45411:4;45475:46;45516:3;45505:9;45501:19;45493:6;45475:46;:::i;:::-;45569:9;45561:6;45557:22;45552:2;45541:9;45537:18;45530:50;45603:33;45629:6;45621;45603:33;:::i;:::-;45589:47;;45684:4;45676:6;45672:17;45667:2;45656:9;45652:18;45645:45;45738:9;45730:6;45726:22;45721:2;45710:9;45706:18;45699:50;45772:33;45798:6;45790;45772:33;:::i;:::-;45758:47;;45854:9;45846:6;45842:22;45836:3;45825:9;45821:19;45814:51;45882:50;45925:6;45917;45909;45882:50;:::i;45943:768::-;46266:6;46255:9;46248:25;46309:6;46304:2;46293:9;46289:18;46282:34;46352:3;46347:2;46336:9;46332:18;46325:31;46229:4;46379:46;46420:3;46409:9;46405:19;46397:6;46379:46;:::i;:::-;46473:9;46465:6;46461:22;46456:2;46445:9;46441:18;46434:50;46507:33;46533:6;46525;46507:33;:::i;:::-;46493:47;;46589:4;46581:6;46577:17;46571:3;46560:9;46556:19;46549:46;46644:9;46636:6;46632:22;46626:3;46615:9;46611:19;46604:51;46672:33;46698:6;46690;46672:33;:::i;48458:795::-;48730:4;-1:-1:-1;;;;;48840:2:1;48832:6;48828:15;48817:9;48810:34;48880:3;48875:2;48864:9;48860:18;48853:31;48907:63;48965:3;48954:9;48950:19;48942:6;48934;48907:63;:::i;:::-;49018:9;49010:6;49006:22;49001:2;48990:9;48986:18;48979:50;49052:33;49078:6;49070;49052:33;:::i;:::-;49038:47;;49133:9;49125:6;49121:22;49116:2;49105:9;49101:18;49094:50;49161:33;49187:6;49179;49161:33;:::i;:::-;49153:41;;;49243:2;49235:6;49231:15;49225:3;49214:9;49210:19;49203:44;;48458:795;;;;;;;;;:::o;49258:571::-;49511:2;49500:9;49493:21;49474:4;49537:62;49595:2;49584:9;49580:18;49572:6;49564;49537:62;:::i;:::-;49647:9;49639:6;49635:22;49630:2;49619:9;49615:18;49608:50;49681:33;49707:6;49699;49681:33;:::i;:::-;49667:47;;49762:9;49754:6;49750:22;49745:2;49734:9;49730:18;49723:50;49790:33;49816:6;49808;49790:33;:::i;:::-;49782:41;49258:571;-1:-1:-1;;;;;;;49258:571:1:o;49960:545::-;50062:2;50057:3;50054:11;50051:448;;;50098:1;50123:5;50119:2;50112:17;50168:4;50164:2;50154:19;50238:2;50226:10;50222:19;50219:1;50215:27;50209:4;50205:38;50274:4;50262:10;50259:20;50256:47;;;-1:-1:-1;50297:4:1;50256:47;50352:2;50347:3;50343:12;50340:1;50336:20;50330:4;50326:31;50316:41;;50407:82;50425:2;50418:5;50415:13;50407:82;;;50470:17;;;50451:1;50440:13;50407:82;;50681:1352;50807:3;50801:10;50834:18;50826:6;50823:30;50820:56;;;50856:18;;:::i;:::-;50885:97;50975:6;50935:38;50967:4;50961:11;50935:38;:::i;:::-;50929:4;50885:97;:::i;:::-;51037:4;;51101:2;51090:14;;51118:1;51113:663;;;;51820:1;51837:6;51834:89;;;-1:-1:-1;51889:19:1;;;51883:26;51834:89;-1:-1:-1;;50638:1:1;50634:11;;;50630:24;50626:29;50616:40;50662:1;50658:11;;;50613:57;51936:81;;51083:944;;51113:663;49907:1;49900:14;;;49944:4;49931:18;;-1:-1:-1;;51149:20:1;;;51267:236;51281:7;51278:1;51275:14;51267:236;;;51370:19;;;51364:26;51349:42;;51462:27;;;;51430:1;51418:14;;;;51297:19;;51267:236;;;51271:3;51531:6;51522:7;51519:19;51516:201;;;51592:19;;;51586:26;-1:-1:-1;;51675:1:1;51671:14;;;51687:3;51667:24;51663:37;51659:42;51644:58;51629:74;;51516:201;-1:-1:-1;;;;;51763:1:1;51747:14;;;51743:22;51730:36;;-1:-1:-1;50681:1352:1:o
Swarm Source
ipfs://94780ce55d28f1d568f4e0ab1b9dc230b96e952b73d2e06456fbff2289fa27f4
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in FRAX
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.