creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts/access/AccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n    struct RoleData {\n        mapping(address => bool) members;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with a standardized message including the required role.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     *\n     * _Available since v4.1._\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n        return _roles[role].members[account];\n    }\n\n    /**\n     * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n     * Overriding this function changes the behavior of the {onlyRole} modifier.\n     *\n     * Format of the revert message is described in {_checkRole}.\n     *\n     * _Available since v4.6._\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Revert with a standard message if `account` is missing `role`.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert(\n                string(\n                    abi.encodePacked(\n                        \"AccessControl: account \",\n                        Strings.toHexString(account),\n                        \" is missing role \",\n                        Strings.toHexString(uint256(role), 32)\n                    )\n                )\n            );\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override {\n        require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event. Note that unlike {grantRole}, this function doesn't perform any\n     * checks on the calling account.\n     *\n     * May emit a {RoleGranted} event.\n     *\n     * [WARNING]\n     * ====\n     * This function should only be called from the constructor when setting\n     * up the initial roles for the system.\n     *\n     * Using this function in any other way is effectively circumventing the admin\n     * system imposed by {AccessControl}.\n     * ====\n     *\n     * NOTE: This function is deprecated in favor of {_grantRole}.\n     */\n    function _setupRole(bytes32 role, address account) internal virtual {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual {\n        if (!hasRole(role, account)) {\n            _roles[role].members[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n        }\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual {\n        if (hasRole(role, account)) {\n            _roles[role].members[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/access/IAccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     *\n     * _Available since v3.1._\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) external;\n}\n"
      },
      "@openzeppelin/contracts/access/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20.sol\";\nimport \"../../../utils/Context.sol\";\n\n/**\n * @dev Extension of {ERC20} that allows token holders to destroy both their own\n * tokens and those that they have an allowance for, in a way that can be\n * recognized off-chain (via event analysis).\n */\nabstract contract ERC20Burnable is Context, ERC20 {\n    /**\n     * @dev Destroys `amount` tokens from the caller.\n     *\n     * See {ERC20-_burn}.\n     */\n    function burn(uint256 amount) public virtual {\n        _burn(_msgSender(), amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, deducting from the caller's\n     * allowance.\n     *\n     * See {ERC20-_burn} and {ERC20-allowance}.\n     *\n     * Requirements:\n     *\n     * - the caller must have allowance for ``accounts``'s tokens of at least\n     * `amount`.\n     */\n    function burnFrom(address account, uint256 amount) public virtual {\n        _spendAllowance(account, _msgSender(), amount);\n        _burn(account, amount);\n    }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"
      },
      "@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/introspection/ERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "@openzeppelin/contracts/utils/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/math/SignedMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Strings.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = Math.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toString(int256 value) internal pure returns (string memory) {\n        return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, Math.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"
      },
      "contracts/libraries/BytesLib.sol": {
        "content": "// SPDX-License-Identifier: Unlicense\n/*\n * @title Solidity Bytes Arrays Utils\n * @author Gonçalo Sá <goncalo.sa@consensys.net>\n *\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\n *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\n */\npragma solidity >=0.8.0 <0.9.0;\n\nlibrary BytesLib {\n  function concat(\n    bytes memory _preBytes,\n    bytes memory _postBytes\n  ) internal pure returns (bytes memory) {\n    bytes memory tempBytes;\n\n    assembly {\n      // Get a location of some free memory and store it in tempBytes as\n      // Solidity does for memory variables.\n      tempBytes := mload(0x40)\n\n      // Store the length of the first bytes array at the beginning of\n      // the memory for tempBytes.\n      let length := mload(_preBytes)\n      mstore(tempBytes, length)\n\n      // Maintain a memory counter for the current write location in the\n      // temp bytes array by adding the 32 bytes for the array length to\n      // the starting location.\n      let mc := add(tempBytes, 0x20)\n      // Stop copying when the memory counter reaches the length of the\n      // first bytes array.\n      let end := add(mc, length)\n\n      for {\n        // Initialize a copy counter to the start of the _preBytes data,\n        // 32 bytes into its memory.\n        let cc := add(_preBytes, 0x20)\n      } lt(mc, end) {\n        // Increase both counters by 32 bytes each iteration.\n        mc := add(mc, 0x20)\n        cc := add(cc, 0x20)\n      } {\n        // Write the _preBytes data into the tempBytes memory 32 bytes\n        // at a time.\n        mstore(mc, mload(cc))\n      }\n\n      // Add the length of _postBytes to the current length of tempBytes\n      // and store it as the new length in the first 32 bytes of the\n      // tempBytes memory.\n      length := mload(_postBytes)\n      mstore(tempBytes, add(length, mload(tempBytes)))\n\n      // Move the memory counter back from a multiple of 0x20 to the\n      // actual end of the _preBytes data.\n      mc := end\n      // Stop copying when the memory counter reaches the new combined\n      // length of the arrays.\n      end := add(mc, length)\n\n      for {\n        let cc := add(_postBytes, 0x20)\n      } lt(mc, end) {\n        mc := add(mc, 0x20)\n        cc := add(cc, 0x20)\n      } {\n        mstore(mc, mload(cc))\n      }\n\n      // Update the free-memory pointer by padding our last write location\n      // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\n      // next 32 byte block, then round down to the nearest multiple of\n      // 32. If the sum of the length of the two arrays is zero then add\n      // one before rounding down to leave a blank 32 bytes (the length block with 0).\n      mstore(\n        0x40,\n        and(\n          add(add(end, iszero(add(length, mload(_preBytes)))), 31),\n          not(31) // Round down to the nearest 32 bytes.\n        )\n      )\n    }\n\n    return tempBytes;\n  }\n\n  function concatStorage(\n    bytes storage _preBytes,\n    bytes memory _postBytes\n  ) internal {\n    assembly {\n      // Read the first 32 bytes of _preBytes storage, which is the length\n      // of the array. (We don't need to use the offset into the slot\n      // because arrays use the entire slot.)\n      let fslot := sload(_preBytes.slot)\n      // Arrays of 31 bytes or less have an even value in their slot,\n      // while longer arrays have an odd value. The actual length is\n      // the slot divided by two for odd values, and the lowest order\n      // byte divided by two for even values.\n      // If the slot is even, bitwise and the slot with 255 and divide by\n      // two to get the length. If the slot is odd, bitwise and the slot\n      // with -1 and divide by two.\n      let slength := div(\n        and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)),\n        2\n      )\n      let mlength := mload(_postBytes)\n      let newlength := add(slength, mlength)\n      // slength can contain both the length and contents of the array\n      // if length < 32 bytes so let's prepare for that\n      // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n      switch add(lt(slength, 32), lt(newlength, 32))\n      case 2 {\n        // Since the new array still fits in the slot, we just need to\n        // update the contents of the slot.\n        // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\n        sstore(\n          _preBytes.slot,\n          // all the modifications to the slot are inside this\n          // next block\n          add(\n            // we can just add to the slot contents because the\n            // bytes we want to change are the LSBs\n            fslot,\n            add(\n              mul(\n                div(\n                  // load the bytes from memory\n                  mload(add(_postBytes, 0x20)),\n                  // zero all bytes to the right\n                  exp(0x100, sub(32, mlength))\n                ),\n                // and now shift left the number of bytes to\n                // leave space for the length in the slot\n                exp(0x100, sub(32, newlength))\n              ),\n              // increase length by the double of the memory\n              // bytes length\n              mul(mlength, 2)\n            )\n          )\n        )\n      }\n      case 1 {\n        // The stored value fits in the slot, but the combined value\n        // will exceed it.\n        // get the keccak hash to get the contents of the array\n        mstore(0x0, _preBytes.slot)\n        let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n        // save new length\n        sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n        // The contents of the _postBytes array start 32 bytes into\n        // the structure. Our first read should obtain the `submod`\n        // bytes that can fit into the unused space in the last word\n        // of the stored array. To get this, we read 32 bytes starting\n        // from `submod`, so the data we read overlaps with the array\n        // contents by `submod` bytes. Masking the lowest-order\n        // `submod` bytes allows us to add that value directly to the\n        // stored value.\n\n        let submod := sub(32, slength)\n        let mc := add(_postBytes, submod)\n        let end := add(_postBytes, mlength)\n        let mask := sub(exp(0x100, submod), 1)\n\n        sstore(\n          sc,\n          add(\n            and(\n              fslot,\n              0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\n            ),\n            and(mload(mc), mask)\n          )\n        )\n\n        for {\n          mc := add(mc, 0x20)\n          sc := add(sc, 1)\n        } lt(mc, end) {\n          sc := add(sc, 1)\n          mc := add(mc, 0x20)\n        } {\n          sstore(sc, mload(mc))\n        }\n\n        mask := exp(0x100, sub(mc, end))\n\n        sstore(sc, mul(div(mload(mc), mask), mask))\n      }\n      default {\n        // get the keccak hash to get the contents of the array\n        mstore(0x0, _preBytes.slot)\n        // Start copying to the last used word of the stored array.\n        let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n        // save new length\n        sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n        // Copy over the first `submod` bytes of the new data as in\n        // case 1 above.\n        let slengthmod := mod(slength, 32)\n        let mlengthmod := mod(mlength, 32)\n        let submod := sub(32, slengthmod)\n        let mc := add(_postBytes, submod)\n        let end := add(_postBytes, mlength)\n        let mask := sub(exp(0x100, submod), 1)\n\n        sstore(sc, add(sload(sc), and(mload(mc), mask)))\n\n        for {\n          sc := add(sc, 1)\n          mc := add(mc, 0x20)\n        } lt(mc, end) {\n          sc := add(sc, 1)\n          mc := add(mc, 0x20)\n        } {\n          sstore(sc, mload(mc))\n        }\n\n        mask := exp(0x100, sub(mc, end))\n\n        sstore(sc, mul(div(mload(mc), mask), mask))\n      }\n    }\n  }\n\n  function slice(\n    bytes memory _bytes,\n    uint _start,\n    uint _length\n  ) internal pure returns (bytes memory) {\n    require(_length + 31 >= _length, \"slice_overflow\");\n    require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n\n    bytes memory tempBytes;\n\n    assembly {\n      switch iszero(_length)\n      case 0 {\n        // Get a location of some free memory and store it in tempBytes as\n        // Solidity does for memory variables.\n        tempBytes := mload(0x40)\n\n        // The first word of the slice result is potentially a partial\n        // word read from the original array. To read it, we calculate\n        // the length of that partial word and start copying that many\n        // bytes into the array. The first word we copy will start with\n        // data we don't care about, but the last `lengthmod` bytes will\n        // land at the beginning of the contents of the new array. When\n        // we're done copying, we overwrite the full first word with\n        // the actual length of the slice.\n        let lengthmod := and(_length, 31)\n\n        // The multiplication in the next line is necessary\n        // because when slicing multiples of 32 bytes (lengthmod == 0)\n        // the following copy loop was copying the origin's length\n        // and then ending prematurely not copying everything it should.\n        let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n        let end := add(mc, _length)\n\n        for {\n          // The multiplication in the next line has the same exact purpose\n          // as the one above.\n          let cc := add(\n            add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))),\n            _start\n          )\n        } lt(mc, end) {\n          mc := add(mc, 0x20)\n          cc := add(cc, 0x20)\n        } {\n          mstore(mc, mload(cc))\n        }\n\n        mstore(tempBytes, _length)\n\n        //update free-memory pointer\n        //allocating the array padded to 32 bytes like the compiler does now\n        mstore(0x40, and(add(mc, 31), not(31)))\n      }\n      //if we want a zero-length slice let's just return a zero-length array\n      default {\n        tempBytes := mload(0x40)\n        //zero out the 32 bytes slice we are about to return\n        //we need to do it because Solidity does not garbage collect\n        mstore(tempBytes, 0)\n\n        mstore(0x40, add(tempBytes, 0x20))\n      }\n    }\n\n    return tempBytes;\n  }\n\n  function toAddress(\n    bytes memory _bytes,\n    uint _start\n  ) internal pure returns (address) {\n    require(_bytes.length >= _start + 20, \"toAddress_outOfBounds\");\n    address tempAddress;\n\n    assembly {\n      tempAddress := div(\n        mload(add(add(_bytes, 0x20), _start)),\n        0x1000000000000000000000000\n      )\n    }\n\n    return tempAddress;\n  }\n\n  function toUint8(\n    bytes memory _bytes,\n    uint _start\n  ) internal pure returns (uint8) {\n    require(_bytes.length >= _start + 1, \"toUint8_outOfBounds\");\n    uint8 tempUint;\n\n    assembly {\n      tempUint := mload(add(add(_bytes, 0x1), _start))\n    }\n\n    return tempUint;\n  }\n\n  function toUint16(\n    bytes memory _bytes,\n    uint _start\n  ) internal pure returns (uint16) {\n    require(_bytes.length >= _start + 2, \"toUint16_outOfBounds\");\n    uint16 tempUint;\n\n    assembly {\n      tempUint := mload(add(add(_bytes, 0x2), _start))\n    }\n\n    return tempUint;\n  }\n\n  function toUint32(\n    bytes memory _bytes,\n    uint _start\n  ) internal pure returns (uint32) {\n    require(_bytes.length >= _start + 4, \"toUint32_outOfBounds\");\n    uint32 tempUint;\n\n    assembly {\n      tempUint := mload(add(add(_bytes, 0x4), _start))\n    }\n\n    return tempUint;\n  }\n\n  function toUint64(\n    bytes memory _bytes,\n    uint _start\n  ) internal pure returns (uint64) {\n    require(_bytes.length >= _start + 8, \"toUint64_outOfBounds\");\n    uint64 tempUint;\n\n    assembly {\n      tempUint := mload(add(add(_bytes, 0x8), _start))\n    }\n\n    return tempUint;\n  }\n\n  function toUint96(\n    bytes memory _bytes,\n    uint _start\n  ) internal pure returns (uint96) {\n    require(_bytes.length >= _start + 12, \"toUint96_outOfBounds\");\n    uint96 tempUint;\n\n    assembly {\n      tempUint := mload(add(add(_bytes, 0xc), _start))\n    }\n\n    return tempUint;\n  }\n\n  function toUint128(\n    bytes memory _bytes,\n    uint _start\n  ) internal pure returns (uint128) {\n    require(_bytes.length >= _start + 16, \"toUint128_outOfBounds\");\n    uint128 tempUint;\n\n    assembly {\n      tempUint := mload(add(add(_bytes, 0x10), _start))\n    }\n\n    return tempUint;\n  }\n\n  function toUint256(\n    bytes memory _bytes,\n    uint _start\n  ) internal pure returns (uint) {\n    require(_bytes.length >= _start + 32, \"toUint256_outOfBounds\");\n    uint tempUint;\n\n    assembly {\n      tempUint := mload(add(add(_bytes, 0x20), _start))\n    }\n\n    return tempUint;\n  }\n\n  function toBytes32(\n    bytes memory _bytes,\n    uint _start\n  ) internal pure returns (bytes32) {\n    require(_bytes.length >= _start + 32, \"toBytes32_outOfBounds\");\n    bytes32 tempBytes32;\n\n    assembly {\n      tempBytes32 := mload(add(add(_bytes, 0x20), _start))\n    }\n\n    return tempBytes32;\n  }\n\n  function equal(\n    bytes memory _preBytes,\n    bytes memory _postBytes\n  ) internal pure returns (bool) {\n    bool success = true;\n\n    assembly {\n      let length := mload(_preBytes)\n\n      // if lengths don't match the arrays are not equal\n      switch eq(length, mload(_postBytes))\n      case 1 {\n        // cb is a circuit breaker in the for loop since there's\n        //  no said feature for inline assembly loops\n        // cb = 1 - don't breaker\n        // cb = 0 - break\n        let cb := 1\n\n        let mc := add(_preBytes, 0x20)\n        let end := add(mc, length)\n\n        for {\n          let cc := add(_postBytes, 0x20)\n          // the next line is the loop condition:\n          // while(uint256(mc < end) + cb == 2)\n        } eq(add(lt(mc, end), cb), 2) {\n          mc := add(mc, 0x20)\n          cc := add(cc, 0x20)\n        } {\n          // if any of these checks fails then arrays are not equal\n          if iszero(eq(mload(mc), mload(cc))) {\n            // unsuccess:\n            success := 0\n            cb := 0\n          }\n        }\n      }\n      default {\n        // unsuccess:\n        success := 0\n      }\n    }\n\n    return success;\n  }\n\n  function equalStorage(\n    bytes storage _preBytes,\n    bytes memory _postBytes\n  ) internal view returns (bool) {\n    bool success = true;\n\n    assembly {\n      // we know _preBytes_offset is 0\n      let fslot := sload(_preBytes.slot)\n      // Decode the length of the stored array like in concatStorage().\n      let slength := div(\n        and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)),\n        2\n      )\n      let mlength := mload(_postBytes)\n\n      // if lengths don't match the arrays are not equal\n      switch eq(slength, mlength)\n      case 1 {\n        // slength can contain both the length and contents of the array\n        // if length < 32 bytes so let's prepare for that\n        // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n        if iszero(iszero(slength)) {\n          switch lt(slength, 32)\n          case 1 {\n            // blank the last byte which is the length\n            fslot := mul(div(fslot, 0x100), 0x100)\n\n            if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\n              // unsuccess:\n              success := 0\n            }\n          }\n          default {\n            // cb is a circuit breaker in the for loop since there's\n            //  no said feature for inline assembly loops\n            // cb = 1 - don't breaker\n            // cb = 0 - break\n            let cb := 1\n\n            // get the keccak hash to get the contents of the array\n            mstore(0x0, _preBytes.slot)\n            let sc := keccak256(0x0, 0x20)\n\n            let mc := add(_postBytes, 0x20)\n            let end := add(mc, mlength)\n\n            // the next line is the loop condition:\n            // while(uint256(mc < end) + cb == 2)\n            for {\n\n            } eq(add(lt(mc, end), cb), 2) {\n              sc := add(sc, 1)\n              mc := add(mc, 0x20)\n            } {\n              if iszero(eq(sload(sc), mload(mc))) {\n                // unsuccess:\n                success := 0\n                cb := 0\n              }\n            }\n          }\n        }\n      }\n      default {\n        // unsuccess:\n        success := 0\n      }\n    }\n\n    return success;\n  }\n}\n"
      },
      "contracts/libraries/ExcessivelySafeCall.sol": {
        "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.7.6;\n\nlibrary ExcessivelySafeCall {\n  uint constant LOW_28_MASK =\n    0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n\n  /// @notice Use when you _really_ really _really_ don't trust the called\n  /// contract. This prevents the called contract from causing reversion of\n  /// the caller in as many ways as we can.\n  /// @dev The main difference between this and a solidity low-level call is\n  /// that we limit the number of bytes that the callee can cause to be\n  /// copied to caller memory. This prevents stupid things like malicious\n  /// contracts returning 10,000,000 bytes causing a local OOG when copying\n  /// to memory.\n  /// @param _target The address to call\n  /// @param _gas The amount of gas to forward to the remote contract\n  /// @param _maxCopy The maximum number of bytes of returndata to copy\n  /// to memory.\n  /// @param _calldata The data to send to the remote contract\n  /// @return success and returndata, as `.call()`. Returndata is capped to\n  /// `_maxCopy` bytes.\n  function excessivelySafeCall(\n    address _target,\n    uint _gas,\n    uint16 _maxCopy,\n    bytes memory _calldata\n  ) internal returns (bool, bytes memory) {\n    // set up for assembly call\n    uint _toCopy;\n    bool _success;\n    bytes memory _returnData = new bytes(_maxCopy);\n    // dispatch message to recipient\n    // by assembly calling \"handle\" function\n    // we call via assembly to avoid memcopying a very large returndata\n    // returned by a malicious contract\n    assembly {\n      _success := call(\n        _gas, // gas\n        _target, // recipient\n        0, // ether value\n        add(_calldata, 0x20), // inloc\n        mload(_calldata), // inlen\n        0, // outloc\n        0 // outlen\n      )\n      // limit our copy to 256 bytes\n      _toCopy := returndatasize()\n      if gt(_toCopy, _maxCopy) {\n        _toCopy := _maxCopy\n      }\n      // Store the length of the copied bytes\n      mstore(_returnData, _toCopy)\n      // copy the bytes from returndata[0:_toCopy]\n      returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n    }\n    return (_success, _returnData);\n  }\n\n  /// @notice Use when you _really_ really _really_ don't trust the called\n  /// contract. This prevents the called contract from causing reversion of\n  /// the caller in as many ways as we can.\n  /// @dev The main difference between this and a solidity low-level call is\n  /// that we limit the number of bytes that the callee can cause to be\n  /// copied to caller memory. This prevents stupid things like malicious\n  /// contracts returning 10,000,000 bytes causing a local OOG when copying\n  /// to memory.\n  /// @param _target The address to call\n  /// @param _gas The amount of gas to forward to the remote contract\n  /// @param _maxCopy The maximum number of bytes of returndata to copy\n  /// to memory.\n  /// @param _calldata The data to send to the remote contract\n  /// @return success and returndata, as `.call()`. Returndata is capped to\n  /// `_maxCopy` bytes.\n  function excessivelySafeStaticCall(\n    address _target,\n    uint _gas,\n    uint16 _maxCopy,\n    bytes memory _calldata\n  ) internal view returns (bool, bytes memory) {\n    // set up for assembly call\n    uint _toCopy;\n    bool _success;\n    bytes memory _returnData = new bytes(_maxCopy);\n    // dispatch message to recipient\n    // by assembly calling \"handle\" function\n    // we call via assembly to avoid memcopying a very large returndata\n    // returned by a malicious contract\n    assembly {\n      _success := staticcall(\n        _gas, // gas\n        _target, // recipient\n        add(_calldata, 0x20), // inloc\n        mload(_calldata), // inlen\n        0, // outloc\n        0 // outlen\n      )\n      // limit our copy to 256 bytes\n      _toCopy := returndatasize()\n      if gt(_toCopy, _maxCopy) {\n        _toCopy := _maxCopy\n      }\n      // Store the length of the copied bytes\n      mstore(_returnData, _toCopy)\n      // copy the bytes from returndata[0:_toCopy]\n      returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n    }\n    return (_success, _returnData);\n  }\n\n  /**\n   * @notice Swaps function selectors in encoded contract calls\n   * @dev Allows reuse of encoded calldata for functions with identical\n   * argument types but different names. It simply swaps out the first 4 bytes\n   * for the new selector. This function modifies memory in place, and should\n   * only be used with caution.\n   * @param _newSelector The new 4-byte selector\n   * @param _buf The encoded contract args\n   */\n  function swapSelector(bytes4 _newSelector, bytes memory _buf) internal pure {\n    require(_buf.length >= 4);\n    uint _mask = LOW_28_MASK;\n    assembly {\n      // load the first word of\n      let _word := mload(add(_buf, 0x20))\n      // mask out the top 4 bytes\n      // /x\n      _word := and(_word, _mask)\n      _word := or(_newSelector, _word)\n      mstore(add(_buf, 0x20), _word)\n    }\n  }\n}\n"
      },
      "contracts/lzApp/interfaces/ILayerZeroEndpoint.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n  // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n  // @param _dstChainId - the destination chain identifier\n  // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n  // @param _payload - a custom bytes payload to send to the destination contract\n  // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n  // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n  // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n  function send(\n    uint16 _dstChainId,\n    bytes calldata _destination,\n    bytes calldata _payload,\n    address payable _refundAddress,\n    address _zroPaymentAddress,\n    bytes calldata _adapterParams\n  ) external payable;\n\n  // @notice used by the messaging library to publish verified payload\n  // @param _srcChainId - the source chain identifier\n  // @param _srcAddress - the source contract (as bytes) at the source chain\n  // @param _dstAddress - the address on destination chain\n  // @param _nonce - the unbound message ordering nonce\n  // @param _gasLimit - the gas limit for external contract execution\n  // @param _payload - verified payload to send to the destination contract\n  function receivePayload(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress,\n    address _dstAddress,\n    uint64 _nonce,\n    uint _gasLimit,\n    bytes calldata _payload\n  ) external;\n\n  // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n  // @param _srcChainId - the source chain identifier\n  // @param _srcAddress - the source chain contract address\n  function getInboundNonce(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress\n  ) external view returns (uint64);\n\n  // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n  // @param _srcAddress - the source chain contract address\n  function getOutboundNonce(\n    uint16 _dstChainId,\n    address _srcAddress\n  ) external view returns (uint64);\n\n  // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n  // @param _dstChainId - the destination chain identifier\n  // @param _userApplication - the user app address on this EVM chain\n  // @param _payload - the custom message to send over LayerZero\n  // @param _payInZRO - if false, user app pays the protocol fee in native token\n  // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n  function estimateFees(\n    uint16 _dstChainId,\n    address _userApplication,\n    bytes calldata _payload,\n    bool _payInZRO,\n    bytes calldata _adapterParam\n  ) external view returns (uint nativeFee, uint zroFee);\n\n  // @notice get this Endpoint's immutable source identifier\n  function getChainId() external view returns (uint16);\n\n  // @notice the interface to retry failed message on this Endpoint destination\n  // @param _srcChainId - the source chain identifier\n  // @param _srcAddress - the source chain contract address\n  // @param _payload - the payload to be retried\n  function retryPayload(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress,\n    bytes calldata _payload\n  ) external;\n\n  // @notice query if any STORED payload (message blocking) at the endpoint.\n  // @param _srcChainId - the source chain identifier\n  // @param _srcAddress - the source chain contract address\n  function hasStoredPayload(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress\n  ) external view returns (bool);\n\n  // @notice query if the _libraryAddress is valid for sending msgs.\n  // @param _userApplication - the user app address on this EVM chain\n  function getSendLibraryAddress(\n    address _userApplication\n  ) external view returns (address);\n\n  // @notice query if the _libraryAddress is valid for receiving msgs.\n  // @param _userApplication - the user app address on this EVM chain\n  function getReceiveLibraryAddress(\n    address _userApplication\n  ) external view returns (address);\n\n  // @notice query if the non-reentrancy guard for send() is on\n  // @return true if the guard is on. false otherwise\n  function isSendingPayload() external view returns (bool);\n\n  // @notice query if the non-reentrancy guard for receive() is on\n  // @return true if the guard is on. false otherwise\n  function isReceivingPayload() external view returns (bool);\n\n  // @notice get the configuration of the LayerZero messaging library of the specified version\n  // @param _version - messaging library version\n  // @param _chainId - the chainId for the pending config change\n  // @param _userApplication - the contract address of the user application\n  // @param _configType - type of configuration. every messaging library has its own convention.\n  function getConfig(\n    uint16 _version,\n    uint16 _chainId,\n    address _userApplication,\n    uint _configType\n  ) external view returns (bytes memory);\n\n  // @notice get the send() LayerZero messaging library version\n  // @param _userApplication - the contract address of the user application\n  function getSendVersion(\n    address _userApplication\n  ) external view returns (uint16);\n\n  // @notice get the lzReceive() LayerZero messaging library version\n  // @param _userApplication - the contract address of the user application\n  function getReceiveVersion(\n    address _userApplication\n  ) external view returns (uint16);\n}\n"
      },
      "contracts/lzApp/interfaces/ILayerZeroReceiver.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n  // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n  // @param _srcChainId - the source endpoint identifier\n  // @param _srcAddress - the source sending contract address from the source chain\n  // @param _nonce - the ordered message nonce\n  // @param _payload - the signed payload is the UA bytes has encoded to be sent\n  function lzReceive(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress,\n    uint64 _nonce,\n    bytes calldata _payload\n  ) external;\n}\n"
      },
      "contracts/lzApp/interfaces/ILayerZeroUserApplicationConfig.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n  // @notice set the configuration of the LayerZero messaging library of the specified version\n  // @param _version - messaging library version\n  // @param _chainId - the chainId for the pending config change\n  // @param _configType - type of configuration. every messaging library has its own convention.\n  // @param _config - configuration in the bytes. can encode arbitrary content.\n  function setConfig(\n    uint16 _version,\n    uint16 _chainId,\n    uint _configType,\n    bytes calldata _config\n  ) external;\n\n  // @notice set the send() LayerZero messaging library version to _version\n  // @param _version - new messaging library version\n  function setSendVersion(uint16 _version) external;\n\n  // @notice set the lzReceive() LayerZero messaging library version to _version\n  // @param _version - new messaging library version\n  function setReceiveVersion(uint16 _version) external;\n\n  // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n  // @param _srcChainId - the chainId of the source chain\n  // @param _srcAddress - the contract address of the source contract at the source chain\n  function forceResumeReceive(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress\n  ) external;\n}\n"
      },
      "contracts/lzApp/LzApp.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./interfaces/ILayerZeroReceiver.sol\";\nimport \"./interfaces/ILayerZeroUserApplicationConfig.sol\";\nimport \"./interfaces/ILayerZeroEndpoint.sol\";\nimport \"../libraries/BytesLib.sol\";\n\n/*\n * a generic LzReceiver implementation\n */\nabstract contract LzApp is\n  Ownable,\n  ILayerZeroReceiver,\n  ILayerZeroUserApplicationConfig\n{\n  using BytesLib for bytes;\n\n  // ua can not send payload larger than this by default, but it can be changed by the ua owner\n  uint public constant DEFAULT_PAYLOAD_SIZE_LIMIT = 10000;\n\n  ILayerZeroEndpoint public immutable lzEndpoint;\n  mapping(uint16 => bytes) public trustedRemoteLookup;\n  mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;\n  mapping(uint16 => uint) public payloadSizeLimitLookup;\n  address public precrime;\n\n  event SetPrecrime(address precrime);\n  event SetTrustedRemote(uint16 _remoteChainId, bytes _path);\n  event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);\n  event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);\n\n  constructor(address _endpoint) {\n    lzEndpoint = ILayerZeroEndpoint(_endpoint);\n  }\n\n  function lzReceive(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress,\n    uint64 _nonce,\n    bytes calldata _payload\n  ) public virtual override {\n    // lzReceive must be called by the endpoint for security\n    require(\n      _msgSender() == address(lzEndpoint),\n      \"LzApp: invalid endpoint caller\"\n    );\n\n    bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n    // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n    require(\n      _srcAddress.length == trustedRemote.length &&\n        trustedRemote.length > 0 &&\n        keccak256(_srcAddress) == keccak256(trustedRemote),\n      \"LzApp: invalid source sending contract\"\n    );\n\n    _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n  }\n\n  // abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging\n  function _blockingLzReceive(\n    uint16 _srcChainId,\n    bytes memory _srcAddress,\n    uint64 _nonce,\n    bytes memory _payload\n  ) internal virtual;\n\n  function _lzSend(\n    uint16 _dstChainId,\n    bytes memory _payload,\n    address payable _refundAddress,\n    address _zroPaymentAddress,\n    bytes memory _adapterParams,\n    uint _nativeFee\n  ) internal virtual {\n    bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n    require(\n      trustedRemote.length != 0,\n      \"LzApp: destination chain is not a trusted source\"\n    );\n    _checkPayloadSize(_dstChainId, _payload.length);\n    lzEndpoint.send{value: _nativeFee}(\n      _dstChainId,\n      trustedRemote,\n      _payload,\n      _refundAddress,\n      _zroPaymentAddress,\n      _adapterParams\n    );\n  }\n\n  function _checkGasLimit(\n    uint16 _dstChainId,\n    uint16 _type,\n    bytes memory _adapterParams,\n    uint _extraGas\n  ) internal view virtual {\n    uint providedGasLimit = _getGasLimit(_adapterParams);\n    uint minGasLimit = minDstGasLookup[_dstChainId][_type];\n    require(minGasLimit > 0, \"LzApp: minGasLimit not set\");\n    require(\n      providedGasLimit >= minGasLimit + _extraGas,\n      \"LzApp: gas limit is too low\"\n    );\n  }\n\n  function _getGasLimit(\n    bytes memory _adapterParams\n  ) internal pure virtual returns (uint gasLimit) {\n    require(_adapterParams.length >= 34, \"LzApp: invalid adapterParams\");\n    assembly {\n      gasLimit := mload(add(_adapterParams, 34))\n    }\n  }\n\n  function _checkPayloadSize(\n    uint16 _dstChainId,\n    uint _payloadSize\n  ) internal view virtual {\n    uint payloadSizeLimit = payloadSizeLimitLookup[_dstChainId];\n    if (payloadSizeLimit == 0) {\n      // use default if not set\n      payloadSizeLimit = DEFAULT_PAYLOAD_SIZE_LIMIT;\n    }\n    require(\n      _payloadSize <= payloadSizeLimit,\n      \"LzApp: payload size is too large\"\n    );\n  }\n\n  //---------------------------UserApplication config----------------------------------------\n  function getConfig(\n    uint16 _version,\n    uint16 _chainId,\n    address,\n    uint _configType\n  ) external view returns (bytes memory) {\n    return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n  }\n\n  // generic config for LayerZero user Application\n  function setConfig(\n    uint16 _version,\n    uint16 _chainId,\n    uint _configType,\n    bytes calldata _config\n  ) external override onlyOwner {\n    lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n  }\n\n  function setSendVersion(uint16 _version) external override onlyOwner {\n    lzEndpoint.setSendVersion(_version);\n  }\n\n  function setReceiveVersion(uint16 _version) external override onlyOwner {\n    lzEndpoint.setReceiveVersion(_version);\n  }\n\n  function forceResumeReceive(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress\n  ) external override onlyOwner {\n    lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n  }\n\n  // _path = abi.encodePacked(remoteAddress, localAddress)\n  // this function set the trusted path for the cross-chain communication\n  function setTrustedRemote(\n    uint16 _remoteChainId,\n    bytes calldata _path\n  ) external onlyOwner {\n    trustedRemoteLookup[_remoteChainId] = _path;\n    emit SetTrustedRemote(_remoteChainId, _path);\n  }\n\n  function setTrustedRemoteAddress(\n    uint16 _remoteChainId,\n    bytes calldata _remoteAddress\n  ) external onlyOwner {\n    trustedRemoteLookup[_remoteChainId] = abi.encodePacked(\n      _remoteAddress,\n      address(this)\n    );\n    emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);\n  }\n\n  function getTrustedRemoteAddress(\n    uint16 _remoteChainId\n  ) external view returns (bytes memory) {\n    bytes memory path = trustedRemoteLookup[_remoteChainId];\n    require(path.length != 0, \"LzApp: no trusted path record\");\n    return path.slice(0, path.length - 20); // the last 20 bytes should be address(this)\n  }\n\n  function setPrecrime(address _precrime) external onlyOwner {\n    precrime = _precrime;\n    emit SetPrecrime(_precrime);\n  }\n\n  function setMinDstGas(\n    uint16 _dstChainId,\n    uint16 _packetType,\n    uint _minGas\n  ) external onlyOwner {\n    minDstGasLookup[_dstChainId][_packetType] = _minGas;\n    emit SetMinDstGas(_dstChainId, _packetType, _minGas);\n  }\n\n  // if the size is 0, it means default size limit\n  function setPayloadSizeLimit(\n    uint16 _dstChainId,\n    uint _size\n  ) external onlyOwner {\n    payloadSizeLimitLookup[_dstChainId] = _size;\n  }\n\n  //--------------------------- VIEW FUNCTION ----------------------------------------\n  function isTrustedRemote(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress\n  ) external view returns (bool) {\n    bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n    return keccak256(trustedSource) == keccak256(_srcAddress);\n  }\n}\n"
      },
      "contracts/lzApp/NonblockingLzApp.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./LzApp.sol\";\nimport \"../libraries/ExcessivelySafeCall.sol\";\n\n/*\n * the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel\n * this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking\n * NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress)\n */\nabstract contract NonblockingLzApp is LzApp {\n  using ExcessivelySafeCall for address;\n\n  constructor(address _endpoint) LzApp(_endpoint) {}\n\n  mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32)))\n    public failedMessages;\n\n  event MessageFailed(\n    uint16 _srcChainId,\n    bytes _srcAddress,\n    uint64 _nonce,\n    bytes _payload,\n    bytes _reason\n  );\n  event RetryMessageSuccess(\n    uint16 _srcChainId,\n    bytes _srcAddress,\n    uint64 _nonce,\n    bytes32 _payloadHash\n  );\n\n  // overriding the virtual function in LzReceiver\n  function _blockingLzReceive(\n    uint16 _srcChainId,\n    bytes memory _srcAddress,\n    uint64 _nonce,\n    bytes memory _payload\n  ) internal virtual override {\n    (bool success, bytes memory reason) = address(this).excessivelySafeCall(\n      gasleft(),\n      150,\n      abi.encodeWithSelector(\n        this.nonblockingLzReceive.selector,\n        _srcChainId,\n        _srcAddress,\n        _nonce,\n        _payload\n      )\n    );\n    if (!success) {\n      _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);\n    }\n  }\n\n  function _storeFailedMessage(\n    uint16 _srcChainId,\n    bytes memory _srcAddress,\n    uint64 _nonce,\n    bytes memory _payload,\n    bytes memory _reason\n  ) internal virtual {\n    failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n    emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);\n  }\n\n  function nonblockingLzReceive(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress,\n    uint64 _nonce,\n    bytes calldata _payload\n  ) public virtual {\n    // only internal transaction\n    require(\n      _msgSender() == address(this),\n      \"NonblockingLzApp: caller must be LzApp\"\n    );\n    _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n  }\n\n  //@notice override this function\n  function _nonblockingLzReceive(\n    uint16 _srcChainId,\n    bytes memory _srcAddress,\n    uint64 _nonce,\n    bytes memory _payload\n  ) internal virtual;\n\n  function retryMessage(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress,\n    uint64 _nonce,\n    bytes calldata _payload\n  ) public payable virtual {\n    // assert there is message to retry\n    bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n    require(payloadHash != bytes32(0), \"NonblockingLzApp: no stored message\");\n    require(\n      keccak256(_payload) == payloadHash,\n      \"NonblockingLzApp: invalid payload\"\n    );\n    // clear the stored message\n    failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n    // execute the message. revert if it fails again\n    _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n    emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);\n  }\n}\n"
      },
      "contracts/src/BaseOFTV2.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./OFTCoreV2.sol\";\nimport \"./interfaces/IOFTV2.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\nabstract contract BaseOFTV2 is OFTCoreV2, ERC165, IOFTV2 {\n  constructor(\n    uint8 _sharedDecimals,\n    address _lzEndpoint\n  ) OFTCoreV2(_sharedDecimals, _lzEndpoint) {}\n\n  /************************************************************************\n   * public functions\n   ************************************************************************/\n  function sendFrom(\n    address _from,\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount,\n    LzCallParams calldata _callParams\n  ) public payable virtual override {\n    _send(\n      _from,\n      _dstChainId,\n      _toAddress,\n      _amount,\n      _callParams.refundAddress,\n      _callParams.zroPaymentAddress,\n      _callParams.adapterParams\n    );\n  }\n\n  function sendAndCall(\n    address _from,\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount,\n    bytes calldata _payload,\n    uint64 _dstGasForCall,\n    LzCallParams calldata _callParams\n  ) public payable virtual override {\n    _sendAndCall(\n      _from,\n      _dstChainId,\n      _toAddress,\n      _amount,\n      _payload,\n      _dstGasForCall,\n      _callParams.refundAddress,\n      _callParams.zroPaymentAddress,\n      _callParams.adapterParams\n    );\n  }\n\n  /************************************************************************\n   * public view functions\n   ************************************************************************/\n  function supportsInterface(\n    bytes4 interfaceId\n  ) public view virtual override(ERC165, IERC165) returns (bool) {\n    return\n      interfaceId == type(IOFTV2).interfaceId ||\n      super.supportsInterface(interfaceId);\n  }\n\n  function estimateSendFee(\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount,\n    bool _useZro,\n    bytes calldata _adapterParams\n  ) public view virtual override returns (uint nativeFee, uint zroFee) {\n    return\n      _estimateSendFee(\n        _dstChainId,\n        _toAddress,\n        _amount,\n        _useZro,\n        _adapterParams\n      );\n  }\n\n  function estimateSendAndCallFee(\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount,\n    bytes calldata _payload,\n    uint64 _dstGasForCall,\n    bool _useZro,\n    bytes calldata _adapterParams\n  ) public view virtual override returns (uint nativeFee, uint zroFee) {\n    return\n      _estimateSendAndCallFee(\n        _dstChainId,\n        _toAddress,\n        _amount,\n        _payload,\n        _dstGasForCall,\n        _useZro,\n        _adapterParams\n      );\n  }\n\n  function circulatingSupply() public view virtual override returns (uint);\n\n  function token() public view virtual override returns (address);\n}\n"
      },
      "contracts/src/interfaces/ICommonOFT.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n */\ninterface ICommonOFT is IERC165 {\n  struct LzCallParams {\n    address payable refundAddress;\n    address zroPaymentAddress;\n    bytes adapterParams;\n  }\n\n  /**\n   * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n   * _dstChainId - L0 defined chain id to send tokens too\n   * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n   * _amount - amount of the tokens to transfer\n   * _useZro - indicates to use zro to pay L0 fees\n   * _adapterParam - flexible bytes array to indicate messaging adapter services in L0\n   */\n  function estimateSendFee(\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount,\n    bool _useZro,\n    bytes calldata _adapterParams\n  ) external view returns (uint nativeFee, uint zroFee);\n\n  function estimateSendAndCallFee(\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount,\n    bytes calldata _payload,\n    uint64 _dstGasForCall,\n    bool _useZro,\n    bytes calldata _adapterParams\n  ) external view returns (uint nativeFee, uint zroFee);\n\n  /**\n   * @dev returns the circulating amount of tokens on current chain\n   */\n  function circulatingSupply() external view returns (uint);\n\n  /**\n   * @dev returns the address of the ERC20 token\n   */\n  function token() external view returns (address);\n}\n"
      },
      "contracts/src/interfaces/IOFTReceiverV2.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.5.0;\n\ninterface IOFTReceiverV2 {\n  /**\n   * @dev Called by the OFT contract when tokens are received from source chain.\n   * @param _srcChainId The chain id of the source chain.\n   * @param _srcAddress The address of the OFT token contract on the source chain.\n   * @param _nonce The nonce of the transaction on the source chain.\n   * @param _from The address of the account who calls the sendAndCall() on the source chain.\n   * @param _amount The amount of tokens to transfer.\n   * @param _payload Additional data with no specified format.\n   */\n  function onOFTReceived(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress,\n    uint64 _nonce,\n    bytes32 _from,\n    uint _amount,\n    bytes calldata _payload\n  ) external;\n}\n"
      },
      "contracts/src/interfaces/IOFTV2.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ICommonOFT.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n */\ninterface IOFTV2 is ICommonOFT {\n  /**\n   * @dev send `_amount` amount of token to (`_dstChainId`, `_toAddress`) from `_from`\n   * `_from` the owner of token\n   * `_dstChainId` the destination chain identifier\n   * `_toAddress` can be any size depending on the `dstChainId`.\n   * `_amount` the quantity of tokens in wei\n   * `_refundAddress` the address LayerZero refunds if too much message fee is sent\n   * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)\n   * `_adapterParams` is a flexible bytes array to indicate messaging adapter services\n   */\n  function sendFrom(\n    address _from,\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount,\n    LzCallParams calldata _callParams\n  ) external payable;\n\n  function sendAndCall(\n    address _from,\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount,\n    bytes calldata _payload,\n    uint64 _dstGasForCall,\n    LzCallParams calldata _callParams\n  ) external payable;\n}\n"
      },
      "contracts/src/OFTCoreV2.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../lzApp/NonblockingLzApp.sol\";\nimport \"../libraries/ExcessivelySafeCall.sol\";\nimport \"./interfaces/ICommonOFT.sol\";\nimport \"./interfaces/IOFTReceiverV2.sol\";\n\nabstract contract OFTCoreV2 is NonblockingLzApp {\n  using BytesLib for bytes;\n  using ExcessivelySafeCall for address;\n\n  uint public constant NO_EXTRA_GAS = 0;\n\n  // packet type\n  uint8 public constant PT_SEND = 0;\n  uint8 public constant PT_SEND_AND_CALL = 1;\n\n  uint8 public immutable sharedDecimals;\n\n  mapping(uint16 => mapping(bytes => mapping(uint64 => bool)))\n    public creditedPackets;\n\n  /**\n   * @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n   * `_nonce` is the outbound nonce\n   */\n  event SendToChain(\n    uint16 indexed _dstChainId,\n    address indexed _from,\n    bytes32 indexed _toAddress,\n    uint _amount\n  );\n\n  /**\n   * @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n   * `_nonce` is the inbound nonce.\n   */\n  event ReceiveFromChain(\n    uint16 indexed _srcChainId,\n    address indexed _to,\n    uint _amount\n  );\n\n  event CallOFTReceivedSuccess(\n    uint16 indexed _srcChainId,\n    bytes _srcAddress,\n    uint64 _nonce,\n    bytes32 _hash\n  );\n\n  event NonContractAddress(address _address);\n\n  // _sharedDecimals should be the minimum decimals on all chains\n  constructor(\n    uint8 _sharedDecimals,\n    address _lzEndpoint\n  ) NonblockingLzApp(_lzEndpoint) {\n    sharedDecimals = _sharedDecimals;\n  }\n\n  /************************************************************************\n   * public functions\n   ************************************************************************/\n  function callOnOFTReceived(\n    uint16 _srcChainId,\n    bytes calldata _srcAddress,\n    uint64 _nonce,\n    bytes32 _from,\n    address _to,\n    uint _amount,\n    bytes calldata _payload,\n    uint _gasForCall\n  ) public virtual {\n    require(_msgSender() == address(this), \"OFTCore: caller must be OFTCore\");\n\n    // send\n    _amount = _transferFrom(address(this), _to, _amount);\n    emit ReceiveFromChain(_srcChainId, _to, _amount);\n\n    // call\n    IOFTReceiverV2(_to).onOFTReceived{gas: _gasForCall}(\n      _srcChainId,\n      _srcAddress,\n      _nonce,\n      _from,\n      _amount,\n      _payload\n    );\n  }\n\n  /************************************************************************\n   * internal functions\n   ************************************************************************/\n  function _estimateSendFee(\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount,\n    bool _useZro,\n    bytes memory _adapterParams\n  ) internal view virtual returns (uint nativeFee, uint zroFee) {\n    // mock the payload for sendFrom()\n    bytes memory payload = _encodeSendPayload(_toAddress, _ld2sd(_amount));\n    return\n      lzEndpoint.estimateFees(\n        _dstChainId,\n        address(this),\n        payload,\n        _useZro,\n        _adapterParams\n      );\n  }\n\n  function _estimateSendAndCallFee(\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount,\n    bytes memory _payload,\n    uint64 _dstGasForCall,\n    bool _useZro,\n    bytes memory _adapterParams\n  ) internal view virtual returns (uint nativeFee, uint zroFee) {\n    // mock the payload for sendAndCall()\n    bytes memory payload = _encodeSendAndCallPayload(\n      msg.sender,\n      _toAddress,\n      _ld2sd(_amount),\n      _payload,\n      _dstGasForCall\n    );\n    return\n      lzEndpoint.estimateFees(\n        _dstChainId,\n        address(this),\n        payload,\n        _useZro,\n        _adapterParams\n      );\n  }\n\n  function _nonblockingLzReceive(\n    uint16 _srcChainId,\n    bytes memory _srcAddress,\n    uint64 _nonce,\n    bytes memory _payload\n  ) internal virtual override {\n    uint8 packetType = _payload.toUint8(0);\n\n    if (packetType == PT_SEND) {\n      _sendAck(_srcChainId, _srcAddress, _nonce, _payload);\n    } else if (packetType == PT_SEND_AND_CALL) {\n      _sendAndCallAck(_srcChainId, _srcAddress, _nonce, _payload);\n    } else {\n      revert(\"OFTCore: unknown packet type\");\n    }\n  }\n\n  function _send(\n    address _from,\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount,\n    address payable _refundAddress,\n    address _zroPaymentAddress,\n    bytes memory _adapterParams\n  ) internal virtual returns (uint amount) {\n    _checkGasLimit(_dstChainId, PT_SEND, _adapterParams, NO_EXTRA_GAS);\n\n    (amount, ) = _removeDust(_amount);\n    amount = _debitFrom(_from, _dstChainId, _toAddress, amount); // amount returned should not have dust\n    require(amount > 0, \"OFTCore: amount too small\");\n\n    bytes memory lzPayload = _encodeSendPayload(_toAddress, _ld2sd(amount));\n    _lzSend(\n      _dstChainId,\n      lzPayload,\n      _refundAddress,\n      _zroPaymentAddress,\n      _adapterParams,\n      msg.value\n    );\n\n    emit SendToChain(_dstChainId, _from, _toAddress, amount);\n  }\n\n  function _sendAck(\n    uint16 _srcChainId,\n    bytes memory,\n    uint64,\n    bytes memory _payload\n  ) internal virtual {\n    (address to, uint64 amountSD) = _decodeSendPayload(_payload);\n    if (to == address(0)) {\n      to = address(0xdead);\n    }\n\n    uint amount = _sd2ld(amountSD);\n    amount = _creditTo(_srcChainId, to, amount);\n\n    emit ReceiveFromChain(_srcChainId, to, amount);\n  }\n\n  function _sendAndCall(\n    address _from,\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount,\n    bytes memory _payload,\n    uint64 _dstGasForCall,\n    address payable _refundAddress,\n    address _zroPaymentAddress,\n    bytes memory _adapterParams\n  ) internal virtual returns (uint amount) {\n    _checkGasLimit(\n      _dstChainId,\n      PT_SEND_AND_CALL,\n      _adapterParams,\n      _dstGasForCall\n    );\n\n    (amount, ) = _removeDust(_amount);\n    amount = _debitFrom(_from, _dstChainId, _toAddress, amount);\n    require(amount > 0, \"OFTCore: amount too small\");\n\n    // encode the msg.sender into the payload instead of _from\n    bytes memory lzPayload = _encodeSendAndCallPayload(\n      msg.sender,\n      _toAddress,\n      _ld2sd(amount),\n      _payload,\n      _dstGasForCall\n    );\n    _lzSend(\n      _dstChainId,\n      lzPayload,\n      _refundAddress,\n      _zroPaymentAddress,\n      _adapterParams,\n      msg.value\n    );\n\n    emit SendToChain(_dstChainId, _from, _toAddress, amount);\n  }\n\n  function _sendAndCallAck(\n    uint16 _srcChainId,\n    bytes memory _srcAddress,\n    uint64 _nonce,\n    bytes memory _payload\n  ) internal virtual {\n    (\n      bytes32 from,\n      address to,\n      uint64 amountSD,\n      bytes memory payloadForCall,\n      uint64 gasForCall\n    ) = _decodeSendAndCallPayload(_payload);\n\n    bool credited = creditedPackets[_srcChainId][_srcAddress][_nonce];\n    uint amount = _sd2ld(amountSD);\n\n    // credit to this contract first, and then transfer to receiver only if callOnOFTReceived() succeeds\n    if (!credited) {\n      amount = _creditTo(_srcChainId, address(this), amount);\n      creditedPackets[_srcChainId][_srcAddress][_nonce] = true;\n    }\n\n    if (!_isContract(to)) {\n      emit NonContractAddress(to);\n      return;\n    }\n\n    // workaround for stack too deep\n    uint16 srcChainId = _srcChainId;\n    bytes memory srcAddress = _srcAddress;\n    uint64 nonce = _nonce;\n    bytes memory payload = _payload;\n    bytes32 from_ = from;\n    address to_ = to;\n    uint amount_ = amount;\n    bytes memory payloadForCall_ = payloadForCall;\n\n    // no gas limit for the call if retry\n    uint gas = credited ? gasleft() : gasForCall;\n    (bool success, bytes memory reason) = address(this).excessivelySafeCall(\n      gasleft(),\n      150,\n      abi.encodeWithSelector(\n        this.callOnOFTReceived.selector,\n        srcChainId,\n        srcAddress,\n        nonce,\n        from_,\n        to_,\n        amount_,\n        payloadForCall_,\n        gas\n      )\n    );\n\n    if (success) {\n      bytes32 hash = keccak256(payload);\n      emit CallOFTReceivedSuccess(srcChainId, srcAddress, nonce, hash);\n    } else {\n      // store the failed message into the nonblockingLzApp\n      _storeFailedMessage(srcChainId, srcAddress, nonce, payload, reason);\n    }\n  }\n\n  function _isContract(address _account) internal view returns (bool) {\n    return _account.code.length > 0;\n  }\n\n  function _ld2sd(uint _amount) internal view virtual returns (uint64) {\n    uint amountSD = _amount / _ld2sdRate();\n    require(amountSD <= type(uint64).max, \"OFTCore: amountSD overflow\");\n    return uint64(amountSD);\n  }\n\n  function _sd2ld(uint64 _amountSD) internal view virtual returns (uint) {\n    return _amountSD * _ld2sdRate();\n  }\n\n  function _removeDust(\n    uint _amount\n  ) internal view virtual returns (uint amountAfter, uint dust) {\n    dust = _amount % _ld2sdRate();\n    amountAfter = _amount - dust;\n  }\n\n  function _encodeSendPayload(\n    bytes32 _toAddress,\n    uint64 _amountSD\n  ) internal view virtual returns (bytes memory) {\n    return abi.encodePacked(PT_SEND, _toAddress, _amountSD);\n  }\n\n  function _decodeSendPayload(\n    bytes memory _payload\n  ) internal view virtual returns (address to, uint64 amountSD) {\n    require(\n      _payload.toUint8(0) == PT_SEND && _payload.length == 41,\n      \"OFTCore: invalid payload\"\n    );\n\n    to = _payload.toAddress(13); // drop the first 12 bytes of bytes32\n    amountSD = _payload.toUint64(33);\n  }\n\n  function _encodeSendAndCallPayload(\n    address _from,\n    bytes32 _toAddress,\n    uint64 _amountSD,\n    bytes memory _payload,\n    uint64 _dstGasForCall\n  ) internal view virtual returns (bytes memory) {\n    return\n      abi.encodePacked(\n        PT_SEND_AND_CALL,\n        _toAddress,\n        _amountSD,\n        _addressToBytes32(_from),\n        _dstGasForCall,\n        _payload\n      );\n  }\n\n  function _decodeSendAndCallPayload(\n    bytes memory _payload\n  )\n    internal\n    view\n    virtual\n    returns (\n      bytes32 from,\n      address to,\n      uint64 amountSD,\n      bytes memory payload,\n      uint64 dstGasForCall\n    )\n  {\n    require(\n      _payload.toUint8(0) == PT_SEND_AND_CALL,\n      \"OFTCore: invalid payload\"\n    );\n\n    to = _payload.toAddress(13); // drop the first 12 bytes of bytes32\n    amountSD = _payload.toUint64(33);\n    from = _payload.toBytes32(41);\n    dstGasForCall = _payload.toUint64(73);\n    payload = _payload.slice(81, _payload.length - 81);\n  }\n\n  function _addressToBytes32(\n    address _address\n  ) internal pure virtual returns (bytes32) {\n    return bytes32(uint(uint160(_address)));\n  }\n\n  function _debitFrom(\n    address _from,\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint _amount\n  ) internal virtual returns (uint);\n\n  function _creditTo(\n    uint16 _srcChainId,\n    address _toAddress,\n    uint _amount\n  ) internal virtual returns (uint);\n\n  function _transferFrom(\n    address _from,\n    address _to,\n    uint _amount\n  ) internal virtual returns (uint);\n\n  function _ld2sdRate() internal view virtual returns (uint);\n}\n"
      },
      "contracts/src/OFTV2.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"./BaseOFTV2.sol\";\n\ncontract OFTV2 is BaseOFTV2, ERC20 {\n  uint internal immutable ld2sdRate;\n\n  constructor(\n    string memory _name,\n    string memory _symbol,\n    uint8 _sharedDecimals,\n    address _lzEndpoint\n  ) ERC20(_name, _symbol) BaseOFTV2(_sharedDecimals, _lzEndpoint) {\n    uint8 decimals = decimals();\n    require(\n      _sharedDecimals <= decimals,\n      \"OFT: sharedDecimals must be <= decimals\"\n    );\n    ld2sdRate = 10 ** (decimals - _sharedDecimals);\n  }\n\n  /************************************************************************\n   * public functions\n   ************************************************************************/\n  function circulatingSupply() public view virtual override returns (uint) {\n    return totalSupply();\n  }\n\n  function token() public view virtual override returns (address) {\n    return address(this);\n  }\n\n  /************************************************************************\n   * internal functions\n   ************************************************************************/\n  function _debitFrom(\n    address _from,\n    uint16,\n    bytes32,\n    uint _amount\n  ) internal virtual override returns (uint) {\n    address spender = _msgSender();\n    if (_from != spender) _spendAllowance(_from, spender, _amount);\n    _burn(_from, _amount);\n    return _amount;\n  }\n\n  function _creditTo(\n    uint16,\n    address _toAddress,\n    uint _amount\n  ) internal virtual override returns (uint) {\n    _mint(_toAddress, _amount);\n    return _amount;\n  }\n\n  function _transferFrom(\n    address _from,\n    address _to,\n    uint _amount\n  ) internal virtual override returns (uint) {\n    address spender = _msgSender();\n    // if transfer from this contract, no need to check allowance\n    if (_from != address(this) && _from != spender)\n      _spendAllowance(_from, spender, _amount);\n    _transfer(_from, _to, _amount);\n    return _amount;\n  }\n\n  function _ld2sdRate() internal view virtual override returns (uint) {\n    return ld2sdRate;\n  }\n}\n"
      },
      "contracts/src/tokens/XArcadeToken.sol": {
        "content": "// SPDX-License-Identifier: CC-BY-NC-4.0\npragma solidity 0.8.17;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol\";\nimport \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport \"../OFTV2.sol\";\n\ncontract XArcadeToken is OFTV2, ERC20Burnable {\n  /**\n   * @notice The Arcade Swap Contract is set as the only address that is\n   *      allowed to mint or burn tokens after contract creation\n   */\n  address public ArcadeSwapContractAddress;\n\n  /**\n   * @notice The max supply of XArcade token allowed\n   */\n  uint256 private constant MAX_SUPPLY = 800_000_000 * 10 ** 18;\n\n  /**\n   * @notice Boolean for vaults being minted to\n   */\n  bool public vaultsMinted;\n\n  /**\n   * @notice The contract administrator address\n   */\n  address public contractAdmin;\n\n  /**\n   * @notice Initialize the contract\n   *\n   * @param _layerZeroEndpoint The Layer Zero endpoint network address deployed\n   * @param _sharedDecimals The number of decimals to use for the token\n   */\n  constructor(\n    address _layerZeroEndpoint,\n    uint8 _sharedDecimals\n  ) OFTV2(\"xArcade Token\", \"xARC\", _sharedDecimals, _layerZeroEndpoint) {\n    contractAdmin = msg.sender;\n  }\n\n  /**\n   * @notice Modifier that requires msg.sender to be Arcade Swap contract\n   * @dev Required in mint and burn functions\n   */\n  modifier isArcadeSwapContract() {\n    require(\n      msg.sender == ArcadeSwapContractAddress,\n      \"Caller must be Arcade Swap contract\"\n    );\n    _;\n  }\n\n  /**\n   * @dev Fired in mintXArcade()\n   *\n   * @param amount the amount of $xARC tokens minted\n   */\n  event XArcadeMinted(uint256 amount);\n\n  /**\n   * @dev Fired in burnXArcade()\n   *\n   * @param amount the amount of $xARC tokens burned\n   */\n  event XArcadeBurned(uint256 amount);\n\n  /**\n   * @dev Fired in updateArcadeSwapContract()\n   *\n   * @param newAddress the new address of Arcade Swap contract\n   */\n  event ArcadeSwapContractUpdated(address indexed newAddress);\n\n  /**\n   * @dev Fired in updateVaultsMinted()\n   *\n   */\n  event VaultsMinted();\n\n  /**\n   * @notice Mint and deposit `amount` $xARC tokens to message sender\n   *\n   * @dev Throws on the following restriction errors:\n   *      * Caller is not Arcade Swap contract\n   *      * Mint exceeds MAX_SUPPLY\n   *\n   * @param _amount The amount of tokens to be minted\n   */\n  function mintXArcade(uint256 _amount) public isArcadeSwapContract {\n    require(\n      totalSupply() + _amount <= MAX_SUPPLY,\n      \"Amount to mint will exceed total supply\"\n    );\n    _mint(ArcadeSwapContractAddress, _amount);\n\n    emit XArcadeMinted(_amount);\n  }\n\n  /**\n   * @notice Burn and destroy `amount` $xARC tokens from message sender\n   *\n   * @dev Throws on the following restriction errors:\n   *      * Caller is not Arcade Swap contract\n   *      * Total supply cannot be less than 0\n   *\n   * @param _amount The amount of tokens to be burned\n   */\n  function burnXArcade(uint256 _amount) public isArcadeSwapContract {\n    require(totalSupply() - _amount >= 0, \"Cannot burn tokens below 0\");\n    _burn(address(msg.sender), _amount);\n\n    emit XArcadeBurned(_amount);\n  }\n\n  /**\n   * @notice Update the address of Arcade Swap contract\n   *\n   * @dev Throws on the following restriction errors:\n   *      * Caller is not the Contract Admin\n   *\n   * @param _ArcadeSwapContractAddress address of the Arcade Swap contract\n   */\n  function updateArcadeSwapContract(\n    address _ArcadeSwapContractAddress\n  ) public onlyContractAdmin {\n    ArcadeSwapContractAddress = _ArcadeSwapContractAddress;\n\n    emit ArcadeSwapContractUpdated(_ArcadeSwapContractAddress);\n  }\n\n  /**\n   * @notice Mint tokens to a specified vault\n   * @param _vaultAddress Address of the vault to mint tokens to\n   */\n  function mintToVault(\n    address _vaultAddress,\n    uint256 _amount\n  ) public onlyContractAdmin {\n    require(\n      totalSupply() + _amount <= MAX_SUPPLY,\n      \"Amount to mint will exceed total supply\"\n    );\n    require(!vaultsMinted, \"Vaults have already been minted\");\n    require(_vaultAddress != address(0), \"Vault address cannot be 0x0\");\n    _mint(_vaultAddress, _amount);\n\n    emit XArcadeMinted(_amount);\n  }\n\n  /**\n   * @notice Update all vaults have been minted\n   */\n  function updateVaultsMinted() public onlyContractAdmin {\n    vaultsMinted = true;\n\n    emit VaultsMinted();\n  }\n\n  /**\n   * @notice Update the contract administrator\n   */\n  function updateContractAdmin(\n    address _contractAdmin\n  ) public onlyContractAdmin {\n    contractAdmin = _contractAdmin;\n  }\n\n  /**\n   * @notice Modifier that requires msg.sender to be contract admin\n   */\n  modifier onlyContractAdmin() {\n    require(msg.sender == contractAdmin, \"Caller must be contract admin\");\n    _;\n  }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 999999
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}