creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/BFT_TokenProxyOFT.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1 AND MIT AND Unlicense\n\n// File @layerzerolabs/solidity-examples/contracts/interfaces/ILayerZeroUserApplicationConfig.sol@v0.0.7\n\n// Original license: 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    uint256 _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(uint16 _srcChainId, bytes calldata _srcAddress)\n    external;\n}\n\n// File @layerzerolabs/solidity-examples/contracts/interfaces/ILayerZeroEndpoint.sol@v0.0.7\n\n// Original license: SPDX_License_Identifier: MIT\n\npragma solidity >=0.5.0;\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    uint256 _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(uint16 _srcChainId, bytes calldata _srcAddress)\n    external\n    view\n    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(uint16 _dstChainId, address _srcAddress)\n    external\n    view\n    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 (uint256 nativeFee, uint256 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(uint16 _srcChainId, bytes calldata _srcAddress)\n    external\n    view\n    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(address _userApplication)\n    external\n    view\n    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(address _userApplication)\n    external\n    view\n    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    uint256 _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(address _userApplication)\n    external\n    view\n    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(address _userApplication)\n    external\n    view\n    returns (uint16);\n}\n\n// File @layerzerolabs/solidity-examples/contracts/interfaces/ILayerZeroReceiver.sol@v0.0.7\n\n// Original license: 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\n// File @layerzerolabs/solidity-examples/contracts/util/BytesLib.sol@v0.0.7\n\n// Original license: 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(bytes memory _preBytes, bytes memory _postBytes)\n    internal\n    pure\n    returns (bytes memory)\n  {\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(bytes storage _preBytes, bytes memory _postBytes)\n    internal\n  {\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    uint256 _start,\n    uint256 _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(bytes memory _bytes, uint256 _start)\n    internal\n    pure\n    returns (address)\n  {\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(bytes memory _bytes, uint256 _start)\n    internal\n    pure\n    returns (uint8)\n  {\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(bytes memory _bytes, uint256 _start)\n    internal\n    pure\n    returns (uint16)\n  {\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(bytes memory _bytes, uint256 _start)\n    internal\n    pure\n    returns (uint32)\n  {\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(bytes memory _bytes, uint256 _start)\n    internal\n    pure\n    returns (uint64)\n  {\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(bytes memory _bytes, uint256 _start)\n    internal\n    pure\n    returns (uint96)\n  {\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(bytes memory _bytes, uint256 _start)\n    internal\n    pure\n    returns (uint128)\n  {\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(bytes memory _bytes, uint256 _start)\n    internal\n    pure\n    returns (uint256)\n  {\n    require(_bytes.length >= _start + 32, \"toUint256_outOfBounds\");\n    uint256 tempUint;\n\n    assembly {\n      tempUint := mload(add(add(_bytes, 0x20), _start))\n    }\n\n    return tempUint;\n  }\n\n  function toBytes32(bytes memory _bytes, uint256 _start)\n    internal\n    pure\n    returns (bytes32)\n  {\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(bytes memory _preBytes, bytes memory _postBytes)\n    internal\n    pure\n    returns (bool)\n  {\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(bytes storage _preBytes, bytes memory _postBytes)\n    internal\n    view\n    returns (bool)\n  {\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\n// File @openzeppelin/contracts/utils/Context.sol@v4.9.6\n\n// Original license: SPDX_License_Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (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  function _contextSuffixLength() internal view virtual returns (uint256) {\n    return 0;\n  }\n}\n\n// File @openzeppelin/contracts/access/Ownable.sol@v4.9.6\n\n// Original license: SPDX_License_Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\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(\n    address indexed previousOwner,\n    address indexed newOwner\n  );\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\n// File @layerzerolabs/solidity-examples/contracts/lzApp/LzApp.sol@v0.0.7\n\n// Original license: SPDX_License_Identifier: MIT\n\npragma solidity ^0.8.0;\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  ILayerZeroEndpoint public immutable lzEndpoint;\n  mapping(uint16 => bytes) public trustedRemoteLookup;\n  mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup;\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, uint256 _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    uint256 _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    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    uint256 _extraGas\n  ) internal view virtual {\n    uint256 providedGasLimit = _getGasLimit(_adapterParams);\n    uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n    require(minGasLimit > 0, \"LzApp: minGasLimit not set\");\n    require(providedGasLimit >= minGasLimit, \"LzApp: gas limit is too low\");\n  }\n\n  function _getGasLimit(bytes memory _adapterParams)\n    internal\n    pure\n    virtual\n    returns (uint256 gasLimit)\n  {\n    require(_adapterParams.length >= 34, \"LzApp: invalid adapterParams\");\n    assembly {\n      gasLimit := mload(add(_adapterParams, 34))\n    }\n  }\n\n  //---------------------------UserApplication config----------------------------------------\n  function getConfig(\n    uint16 _version,\n    uint16 _chainId,\n    address,\n    uint256 _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    uint256 _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(uint16 _srcChainId, bytes calldata _srcAddress)\n    external\n    override\n    onlyOwner\n  {\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(uint16 _srcChainId, bytes calldata _path)\n    external\n    onlyOwner\n  {\n    trustedRemoteLookup[_srcChainId] = _path;\n    emit SetTrustedRemote(_srcChainId, _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(uint16 _remoteChainId)\n    external\n    view\n    returns (bytes memory)\n  {\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    uint256 _minGas\n  ) external onlyOwner {\n    require(_minGas > 0, \"LzApp: invalid minGas\");\n    minDstGasLookup[_dstChainId][_packetType] = _minGas;\n    emit SetMinDstGas(_dstChainId, _packetType, _minGas);\n  }\n\n  //--------------------------- VIEW FUNCTION ----------------------------------------\n  function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress)\n    external\n    view\n    returns (bool)\n  {\n    bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n    return keccak256(trustedSource) == keccak256(_srcAddress);\n  }\n}\n\n// File @layerzerolabs/solidity-examples/contracts/util/ExcessivelySafeCall.sol@v0.0.7\n\n// Original license: SPDX_License_Identifier: MIT\npragma solidity >=0.7.6;\n\nlibrary ExcessivelySafeCall {\n  uint256 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    uint256 _gas,\n    uint16 _maxCopy,\n    bytes memory _calldata\n  ) internal returns (bool, bytes memory) {\n    // set up for assembly call\n    uint256 _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    uint256 _gas,\n    uint16 _maxCopy,\n    bytes memory _calldata\n  ) internal view returns (bool, bytes memory) {\n    // set up for assembly call\n    uint256 _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    uint256 _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\n// File @layerzerolabs/solidity-examples/contracts/lzApp/NonblockingLzApp.sol@v0.0.7\n\n// Original license: SPDX_License_Identifier: MIT\n\npragma solidity ^0.8.0;\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    // try-catch all errors/exceptions\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\n// File @layerzerolabs/solidity-examples/contracts/token/oft/v2/fee/Fee.sol@v0.0.7\n\n// Original license: SPDX_License_Identifier: MIT\n\npragma solidity ^0.8.0;\n\nabstract contract Fee is Ownable {\n  uint256 public constant BP_DENOMINATOR = 10000;\n\n  mapping(uint16 => FeeConfig) public chainIdToFeeBps;\n  uint16 public defaultFeeBp;\n  address public feeOwner; // defaults to owner\n\n  struct FeeConfig {\n    uint16 feeBP;\n    bool enabled;\n  }\n\n  event SetFeeBp(uint16 dstchainId, bool enabled, uint16 feeBp);\n  event SetDefaultFeeBp(uint16 feeBp);\n  event SetFeeOwner(address feeOwner);\n\n  constructor() {\n    feeOwner = owner();\n  }\n\n  function setDefaultFeeBp(uint16 _feeBp) public virtual onlyOwner {\n    require(_feeBp <= BP_DENOMINATOR, \"Fee: fee bp must be <= BP_DENOMINATOR\");\n    defaultFeeBp = _feeBp;\n    emit SetDefaultFeeBp(defaultFeeBp);\n  }\n\n  function setFeeBp(\n    uint16 _dstChainId,\n    bool _enabled,\n    uint16 _feeBp\n  ) public virtual onlyOwner {\n    require(_feeBp <= BP_DENOMINATOR, \"Fee: fee bp must be <= BP_DENOMINATOR\");\n    chainIdToFeeBps[_dstChainId] = FeeConfig(_feeBp, _enabled);\n    emit SetFeeBp(_dstChainId, _enabled, _feeBp);\n  }\n\n  function setFeeOwner(address _feeOwner) public virtual onlyOwner {\n    require(_feeOwner != address(0x0), \"Fee: feeOwner cannot be 0x\");\n    feeOwner = _feeOwner;\n    emit SetFeeOwner(_feeOwner);\n  }\n\n  function quoteOFTFee(uint16 _dstChainId, uint256 _amount)\n    public\n    view\n    virtual\n    returns (uint256 fee)\n  {\n    FeeConfig memory config = chainIdToFeeBps[_dstChainId];\n    if (config.enabled) {\n      fee = (_amount * config.feeBP) / BP_DENOMINATOR;\n    } else if (defaultFeeBp > 0) {\n      fee = (_amount * defaultFeeBp) / BP_DENOMINATOR;\n    } else {\n      fee = 0;\n    }\n  }\n\n  function _payOFTFee(\n    address _from,\n    uint16 _dstChainId,\n    uint256 _amount\n  ) internal virtual returns (uint256 amount, uint256 fee) {\n    fee = quoteOFTFee(_dstChainId, _amount);\n    amount = _amount - fee;\n    if (fee > 0) {\n      _transferFrom(_from, feeOwner, fee);\n    }\n  }\n\n  function _transferFrom(\n    address _from,\n    address _to,\n    uint256 _amount\n  ) internal virtual returns (uint256);\n}\n\n// File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.9.6\n\n// Original license: 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\n// File @layerzerolabs/solidity-examples/contracts/token/oft/v2/ICommonOFT.sol@v0.0.7\n\n// Original license: SPDX_License_Identifier: MIT\n\npragma solidity >=0.5.0;\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    uint256 _amount,\n    bool _useZro,\n    bytes calldata _adapterParams\n  ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n  function estimateSendAndCallFee(\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint256 _amount,\n    bytes calldata _payload,\n    uint64 _dstGasForCall,\n    bool _useZro,\n    bytes calldata _adapterParams\n  ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n  /**\n   * @dev returns the circulating amount of tokens on current chain\n   */\n  function circulatingSupply() external view returns (uint256);\n\n  /**\n   * @dev returns the address of the ERC20 token\n   */\n  function token() external view returns (address);\n}\n\n// File @layerzerolabs/solidity-examples/contracts/token/oft/v2/fee/IOFTWithFee.sol@v0.0.7\n\n// Original license: SPDX_License_Identifier: MIT\n\npragma solidity >=0.5.0;\n\n/**\n * @dev Interface of the IOFT core standard\n */\ninterface IOFTWithFee 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   * `_minAmount` the minimum amount of tokens to receive on dstChain\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    uint256 _amount,\n    uint256 _minAmount,\n    LzCallParams calldata _callParams\n  ) external payable;\n\n  function sendAndCall(\n    address _from,\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint256 _amount,\n    uint256 _minAmount,\n    bytes calldata _payload,\n    uint64 _dstGasForCall,\n    LzCallParams calldata _callParams\n  ) external payable;\n}\n\n// File @layerzerolabs/solidity-examples/contracts/token/oft/v2/IOFTReceiverV2.sol@v0.0.7\n\n// Original license: 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    uint256 _amount,\n    bytes calldata _payload\n  ) external;\n}\n\n// File @layerzerolabs/solidity-examples/contracts/token/oft/v2/OFTCoreV2.sol@v0.0.7\n\n// Original license: SPDX_License_Identifier: MIT\n\npragma solidity ^0.8.0;\n\nabstract contract OFTCoreV2 is NonblockingLzApp {\n  using BytesLib for bytes;\n  using ExcessivelySafeCall for address;\n\n  uint256 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  bool public useCustomAdapterParams;\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    uint256 _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    uint256 _amount\n  );\n\n  event SetUseCustomAdapterParams(bool _useCustomAdapterParams);\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(uint8 _sharedDecimals, address _lzEndpoint)\n    NonblockingLzApp(_lzEndpoint)\n  {\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    uint256 _amount,\n    bytes calldata _payload,\n    uint256 _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  function setUseCustomAdapterParams(bool _useCustomAdapterParams)\n    public\n    virtual\n    onlyOwner\n  {\n    useCustomAdapterParams = _useCustomAdapterParams;\n    emit SetUseCustomAdapterParams(_useCustomAdapterParams);\n  }\n\n  /************************************************************************\n   * internal functions\n   ************************************************************************/\n  function _estimateSendFee(\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint256 _amount,\n    bool _useZro,\n    bytes memory _adapterParams\n  ) internal view virtual returns (uint256 nativeFee, uint256 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    uint256 _amount,\n    bytes memory _payload,\n    uint64 _dstGasForCall,\n    bool _useZro,\n    bytes memory _adapterParams\n  ) internal view virtual returns (uint256 nativeFee, uint256 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    uint256 _amount,\n    address payable _refundAddress,\n    address _zroPaymentAddress,\n    bytes memory _adapterParams\n  ) internal virtual returns (uint256 amount) {\n    _checkAdapterParams(_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    uint256 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    uint256 _amount,\n    bytes memory _payload,\n    uint64 _dstGasForCall,\n    address payable _refundAddress,\n    address _zroPaymentAddress,\n    bytes memory _adapterParams\n  ) internal virtual returns (uint256 amount) {\n    _checkAdapterParams(\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    uint256 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    uint256 amount_ = amount;\n    bytes memory payloadForCall_ = payloadForCall;\n\n    // no gas limit for the call if retry\n    uint256 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 _checkAdapterParams(\n    uint16 _dstChainId,\n    uint16 _pkType,\n    bytes memory _adapterParams,\n    uint256 _extraGas\n  ) internal virtual {\n    if (useCustomAdapterParams) {\n      _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n    } else {\n      require(\n        _adapterParams.length == 0,\n        \"OFTCore: _adapterParams must be empty.\"\n      );\n    }\n  }\n\n  function _ld2sd(uint256 _amount) internal view virtual returns (uint64) {\n    uint256 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 (uint256) {\n    return _amountSD * _ld2sdRate();\n  }\n\n  function _removeDust(uint256 _amount)\n    internal\n    view\n    virtual\n    returns (uint256 amountAfter, uint256 dust)\n  {\n    dust = _amount % _ld2sdRate();\n    amountAfter = _amount - dust;\n  }\n\n  function _encodeSendPayload(bytes32 _toAddress, uint64 _amountSD)\n    internal\n    view\n    virtual\n    returns (bytes memory)\n  {\n    return abi.encodePacked(PT_SEND, _toAddress, _amountSD);\n  }\n\n  function _decodeSendPayload(bytes memory _payload)\n    internal\n    view\n    virtual\n    returns (address to, uint64 amountSD)\n  {\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(bytes memory _payload)\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(address _address)\n    internal\n    pure\n    virtual\n    returns (bytes32)\n  {\n    return bytes32(uint256(uint160(_address)));\n  }\n\n  function _debitFrom(\n    address _from,\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint256 _amount\n  ) internal virtual returns (uint256);\n\n  function _creditTo(\n    uint16 _srcChainId,\n    address _toAddress,\n    uint256 _amount\n  ) internal virtual returns (uint256);\n\n  function _transferFrom(\n    address _from,\n    address _to,\n    uint256 _amount\n  ) internal virtual returns (uint256);\n\n  function _ld2sdRate() internal view virtual returns (uint256);\n}\n\n// File @openzeppelin/contracts/utils/introspection/ERC165.sol@v4.9.6\n\n// Original license: SPDX_License_Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\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)\n    public\n    view\n    virtual\n    override\n    returns (bool)\n  {\n    return interfaceId == type(IERC165).interfaceId;\n  }\n}\n\n// File @layerzerolabs/solidity-examples/contracts/token/oft/v2/fee/BaseOFTWithFee.sol@v0.0.7\n\n// Original license: SPDX_License_Identifier: MIT\n\npragma solidity ^0.8.0;\n\nabstract contract BaseOFTWithFee is OFTCoreV2, Fee, ERC165, IOFTWithFee {\n  constructor(uint8 _sharedDecimals, address _lzEndpoint)\n    OFTCoreV2(_sharedDecimals, _lzEndpoint)\n  {}\n\n  /************************************************************************\n   * public functions\n   ************************************************************************/\n  function sendFrom(\n    address _from,\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint256 _amount,\n    uint256 _minAmount,\n    LzCallParams calldata _callParams\n  ) public payable virtual override {\n    (_amount, ) = _payOFTFee(_from, _dstChainId, _amount);\n    _amount = _send(\n      _from,\n      _dstChainId,\n      _toAddress,\n      _amount,\n      _callParams.refundAddress,\n      _callParams.zroPaymentAddress,\n      _callParams.adapterParams\n    );\n    require(\n      _amount >= _minAmount,\n      \"BaseOFTWithFee: amount is less than minAmount\"\n    );\n  }\n\n  function sendAndCall(\n    address _from,\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint256 _amount,\n    uint256 _minAmount,\n    bytes calldata _payload,\n    uint64 _dstGasForCall,\n    LzCallParams calldata _callParams\n  ) public payable virtual override {\n    (_amount, ) = _payOFTFee(_from, _dstChainId, _amount);\n    _amount = _sendAndCall(\n      _from,\n      _dstChainId,\n      _toAddress,\n      _amount,\n      _payload,\n      _dstGasForCall,\n      _callParams.refundAddress,\n      _callParams.zroPaymentAddress,\n      _callParams.adapterParams\n    );\n    require(\n      _amount >= _minAmount,\n      \"BaseOFTWithFee: amount is less than minAmount\"\n    );\n  }\n\n  /************************************************************************\n   * public view functions\n   ************************************************************************/\n  function supportsInterface(bytes4 interfaceId)\n    public\n    view\n    virtual\n    override(ERC165, IERC165)\n    returns (bool)\n  {\n    return\n      interfaceId == type(IOFTWithFee).interfaceId ||\n      super.supportsInterface(interfaceId);\n  }\n\n  function estimateSendFee(\n    uint16 _dstChainId,\n    bytes32 _toAddress,\n    uint256 _amount,\n    bool _useZro,\n    bytes calldata _adapterParams\n  ) public view virtual override returns (uint256 nativeFee, uint256 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    uint256 _amount,\n    bytes calldata _payload,\n    uint64 _dstGasForCall,\n    bool _useZro,\n    bytes calldata _adapterParams\n  ) public view virtual override returns (uint256 nativeFee, uint256 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 (uint256);\n\n  function token() public view virtual override returns (address);\n\n  function _transferFrom(\n    address _from,\n    address _to,\n    uint256 _amount\n  ) internal virtual override(Fee, OFTCoreV2) returns (uint256);\n}\n\n// File @openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol@v4.9.6\n\n// Original license: SPDX_License_Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n *     doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n *     token.safeTransferFrom(msg.sender, address(this), value);\n *     ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\n */\ninterface IERC20Permit {\n  /**\n   * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n   * given ``owner``'s signed approval.\n   *\n   * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n   * ordering also apply here.\n   *\n   * Emits an {Approval} event.\n   *\n   * Requirements:\n   *\n   * - `spender` cannot be the zero address.\n   * - `deadline` must be a timestamp in the future.\n   * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n   * over the EIP712-formatted function arguments.\n   * - the signature must use ``owner``'s current nonce (see {nonces}).\n   *\n   * For more information on the signature format, see the\n   * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n   * section].\n   *\n   * CAUTION: See Security Considerations above.\n   */\n  function permit(\n    address owner,\n    address spender,\n    uint256 value,\n    uint256 deadline,\n    uint8 v,\n    bytes32 r,\n    bytes32 s\n  ) external;\n\n  /**\n   * @dev Returns the current nonce for `owner`. This value must be\n   * included whenever a signature is generated for {permit}.\n   *\n   * Every successful call to {permit} increases ``owner``'s nonce by one. This\n   * prevents a signature from being used multiple times.\n   */\n  function nonces(address owner) external view returns (uint256);\n\n  /**\n   * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n   */\n  // solhint-disable-next-line func-name-mixedcase\n  function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n\n// File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.9.6\n\n// Original license: 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)\n    external\n    view\n    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(\n    address from,\n    address to,\n    uint256 amount\n  ) external returns (bool);\n}\n\n// File @openzeppelin/contracts/utils/Address.sol@v4.9.6\n\n// Original license: SPDX_License_Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n  /**\n   * @dev Returns true if `account` is a contract.\n   *\n   * [IMPORTANT]\n   * ====\n   * It is unsafe to assume that an address for which this function returns\n   * false is an externally-owned account (EOA) and not a contract.\n   *\n   * Among others, `isContract` will return false for the following\n   * types of addresses:\n   *\n   *  - an externally-owned account\n   *  - a contract in construction\n   *  - an address where a contract will be created\n   *  - an address where a contract lived, but was destroyed\n   *\n   * Furthermore, `isContract` will also return true if the target contract within\n   * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n   * which only has an effect at the end of a transaction.\n   * ====\n   *\n   * [IMPORTANT]\n   * ====\n   * You shouldn't rely on `isContract` to protect against flash loan attacks!\n   *\n   * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n   * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n   * constructor.\n   * ====\n   */\n  function isContract(address account) internal view returns (bool) {\n    // This method relies on extcodesize/address.code.length, which returns 0\n    // for contracts in construction, since the code is only stored at the end\n    // of the constructor execution.\n\n    return account.code.length > 0;\n  }\n\n  /**\n   * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n   * `recipient`, forwarding all available gas and reverting on errors.\n   *\n   * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n   * of certain opcodes, possibly making contracts go over the 2300 gas limit\n   * imposed by `transfer`, making them unable to receive funds via\n   * `transfer`. {sendValue} removes this limitation.\n   *\n   * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n   *\n   * IMPORTANT: because control is transferred to `recipient`, care must be\n   * taken to not create reentrancy vulnerabilities. Consider using\n   * {ReentrancyGuard} or the\n   * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n   */\n  function sendValue(address payable recipient, uint256 amount) internal {\n    require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n    (bool success, ) = recipient.call{ value: amount }(\"\");\n    require(\n      success,\n      \"Address: unable to send value, recipient may have reverted\"\n    );\n  }\n\n  /**\n   * @dev Performs a Solidity function call using a low level `call`. A\n   * plain `call` is an unsafe replacement for a function call: use this\n   * function instead.\n   *\n   * If `target` reverts with a revert reason, it is bubbled up by this\n   * function (like regular Solidity function calls).\n   *\n   * Returns the raw returned data. To convert to the expected return value,\n   * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n   *\n   * Requirements:\n   *\n   * - `target` must be a contract.\n   * - calling `target` with `data` must not revert.\n   *\n   * _Available since v3.1._\n   */\n  function functionCall(address target, bytes memory data)\n    internal\n    returns (bytes memory)\n  {\n    return\n      functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n  }\n\n  /**\n   * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n   * `errorMessage` as a fallback revert reason when `target` reverts.\n   *\n   * _Available since v3.1._\n   */\n  function functionCall(\n    address target,\n    bytes memory data,\n    string memory errorMessage\n  ) internal returns (bytes memory) {\n    return functionCallWithValue(target, data, 0, errorMessage);\n  }\n\n  /**\n   * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n   * but also transferring `value` wei to `target`.\n   *\n   * Requirements:\n   *\n   * - the calling contract must have an ETH balance of at least `value`.\n   * - the called Solidity function must be `payable`.\n   *\n   * _Available since v3.1._\n   */\n  function functionCallWithValue(\n    address target,\n    bytes memory data,\n    uint256 value\n  ) internal returns (bytes memory) {\n    return\n      functionCallWithValue(\n        target,\n        data,\n        value,\n        \"Address: low-level call with value failed\"\n      );\n  }\n\n  /**\n   * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n   * with `errorMessage` as a fallback revert reason when `target` reverts.\n   *\n   * _Available since v3.1._\n   */\n  function functionCallWithValue(\n    address target,\n    bytes memory data,\n    uint256 value,\n    string memory errorMessage\n  ) internal returns (bytes memory) {\n    require(\n      address(this).balance >= value,\n      \"Address: insufficient balance for call\"\n    );\n    (bool success, bytes memory returndata) = target.call{ value: value }(data);\n    return\n      verifyCallResultFromTarget(target, success, returndata, errorMessage);\n  }\n\n  /**\n   * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n   * but performing a static call.\n   *\n   * _Available since v3.3._\n   */\n  function functionStaticCall(address target, bytes memory data)\n    internal\n    view\n    returns (bytes memory)\n  {\n    return\n      functionStaticCall(target, data, \"Address: low-level static call failed\");\n  }\n\n  /**\n   * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n   * but performing a static call.\n   *\n   * _Available since v3.3._\n   */\n  function functionStaticCall(\n    address target,\n    bytes memory data,\n    string memory errorMessage\n  ) internal view returns (bytes memory) {\n    (bool success, bytes memory returndata) = target.staticcall(data);\n    return\n      verifyCallResultFromTarget(target, success, returndata, errorMessage);\n  }\n\n  /**\n   * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n   * but performing a delegate call.\n   *\n   * _Available since v3.4._\n   */\n  function functionDelegateCall(address target, bytes memory data)\n    internal\n    returns (bytes memory)\n  {\n    return\n      functionDelegateCall(\n        target,\n        data,\n        \"Address: low-level delegate call failed\"\n      );\n  }\n\n  /**\n   * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n   * but performing a delegate call.\n   *\n   * _Available since v3.4._\n   */\n  function functionDelegateCall(\n    address target,\n    bytes memory data,\n    string memory errorMessage\n  ) internal returns (bytes memory) {\n    (bool success, bytes memory returndata) = target.delegatecall(data);\n    return\n      verifyCallResultFromTarget(target, success, returndata, errorMessage);\n  }\n\n  /**\n   * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n   * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n   *\n   * _Available since v4.8._\n   */\n  function verifyCallResultFromTarget(\n    address target,\n    bool success,\n    bytes memory returndata,\n    string memory errorMessage\n  ) internal view returns (bytes memory) {\n    if (success) {\n      if (returndata.length == 0) {\n        // only check isContract if the call was successful and the return data is empty\n        // otherwise we already know that it was a contract\n        require(isContract(target), \"Address: call to non-contract\");\n      }\n      return returndata;\n    } else {\n      _revert(returndata, errorMessage);\n    }\n  }\n\n  /**\n   * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n   * revert reason or using the provided one.\n   *\n   * _Available since v4.3._\n   */\n  function verifyCallResult(\n    bool success,\n    bytes memory returndata,\n    string memory errorMessage\n  ) internal pure returns (bytes memory) {\n    if (success) {\n      return returndata;\n    } else {\n      _revert(returndata, errorMessage);\n    }\n  }\n\n  function _revert(bytes memory returndata, string memory errorMessage)\n    private\n    pure\n  {\n    // Look for revert reason and bubble it up if present\n    if (returndata.length > 0) {\n      // The easiest way to bubble the revert reason is using memory via assembly\n      /// @solidity memory-safe-assembly\n      assembly {\n        let returndata_size := mload(returndata)\n        revert(add(32, returndata), returndata_size)\n      }\n    } else {\n      revert(errorMessage);\n    }\n  }\n}\n\n// File @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol@v4.9.6\n\n// Original license: SPDX_License_Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n  using Address for address;\n\n  /**\n   * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n   * non-reverting calls are assumed to be successful.\n   */\n  function safeTransfer(\n    IERC20 token,\n    address to,\n    uint256 value\n  ) internal {\n    _callOptionalReturn(\n      token,\n      abi.encodeWithSelector(token.transfer.selector, to, value)\n    );\n  }\n\n  /**\n   * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n   * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n   */\n  function safeTransferFrom(\n    IERC20 token,\n    address from,\n    address to,\n    uint256 value\n  ) internal {\n    _callOptionalReturn(\n      token,\n      abi.encodeWithSelector(token.transferFrom.selector, from, to, value)\n    );\n  }\n\n  /**\n   * @dev Deprecated. This function has issues similar to the ones found in\n   * {IERC20-approve}, and its usage is discouraged.\n   *\n   * Whenever possible, use {safeIncreaseAllowance} and\n   * {safeDecreaseAllowance} instead.\n   */\n  function safeApprove(\n    IERC20 token,\n    address spender,\n    uint256 value\n  ) internal {\n    // safeApprove should only be called when setting an initial allowance,\n    // or when resetting it to zero. To increase and decrease it, use\n    // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n    require(\n      (value == 0) || (token.allowance(address(this), spender) == 0),\n      \"SafeERC20: approve from non-zero to non-zero allowance\"\n    );\n    _callOptionalReturn(\n      token,\n      abi.encodeWithSelector(token.approve.selector, spender, value)\n    );\n  }\n\n  /**\n   * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n   * non-reverting calls are assumed to be successful.\n   */\n  function safeIncreaseAllowance(\n    IERC20 token,\n    address spender,\n    uint256 value\n  ) internal {\n    uint256 oldAllowance = token.allowance(address(this), spender);\n    _callOptionalReturn(\n      token,\n      abi.encodeWithSelector(\n        token.approve.selector,\n        spender,\n        oldAllowance + value\n      )\n    );\n  }\n\n  /**\n   * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n   * non-reverting calls are assumed to be successful.\n   */\n  function safeDecreaseAllowance(\n    IERC20 token,\n    address spender,\n    uint256 value\n  ) internal {\n    unchecked {\n      uint256 oldAllowance = token.allowance(address(this), spender);\n      require(\n        oldAllowance >= value,\n        \"SafeERC20: decreased allowance below zero\"\n      );\n      _callOptionalReturn(\n        token,\n        abi.encodeWithSelector(\n          token.approve.selector,\n          spender,\n          oldAllowance - value\n        )\n      );\n    }\n  }\n\n  /**\n   * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n   * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n   * to be set to zero before setting it to a non-zero value, such as USDT.\n   */\n  function forceApprove(\n    IERC20 token,\n    address spender,\n    uint256 value\n  ) internal {\n    bytes memory approvalCall = abi.encodeWithSelector(\n      token.approve.selector,\n      spender,\n      value\n    );\n\n    if (!_callOptionalReturnBool(token, approvalCall)) {\n      _callOptionalReturn(\n        token,\n        abi.encodeWithSelector(token.approve.selector, spender, 0)\n      );\n      _callOptionalReturn(token, approvalCall);\n    }\n  }\n\n  /**\n   * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n   * Revert on invalid signature.\n   */\n  function safePermit(\n    IERC20Permit token,\n    address owner,\n    address spender,\n    uint256 value,\n    uint256 deadline,\n    uint8 v,\n    bytes32 r,\n    bytes32 s\n  ) internal {\n    uint256 nonceBefore = token.nonces(owner);\n    token.permit(owner, spender, value, deadline, v, r, s);\n    uint256 nonceAfter = token.nonces(owner);\n    require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n  }\n\n  /**\n   * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n   * on the return value: the return value is optional (but if data is returned, it must not be false).\n   * @param token The token targeted by the call.\n   * @param data The call data (encoded using abi.encode or one of its variants).\n   */\n  function _callOptionalReturn(IERC20 token, bytes memory data) private {\n    // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n    // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n    // the target address contains contract code and also asserts for success in the low-level call.\n\n    bytes memory returndata = address(token).functionCall(\n      data,\n      \"SafeERC20: low-level call failed\"\n    );\n    require(\n      returndata.length == 0 || abi.decode(returndata, (bool)),\n      \"SafeERC20: ERC20 operation did not succeed\"\n    );\n  }\n\n  /**\n   * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n   * on the return value: the return value is optional (but if data is returned, it must not be false).\n   * @param token The token targeted by the call.\n   * @param data The call data (encoded using abi.encode or one of its variants).\n   *\n   * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n   */\n  function _callOptionalReturnBool(IERC20 token, bytes memory data)\n    private\n    returns (bool)\n  {\n    // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n    // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n    // and not revert is the subcall reverts.\n\n    (bool success, bytes memory returndata) = address(token).call(data);\n    return\n      success &&\n      (returndata.length == 0 || abi.decode(returndata, (bool))) &&\n      Address.isContract(address(token));\n  }\n}\n\n// File @layerzerolabs/solidity-examples/contracts/token/oft/v2/fee/ProxyOFTWithFee.sol@v0.0.7\n\n// Original license: SPDX_License_Identifier: MIT\n\npragma solidity ^0.8.0;\n\ncontract ProxyOFTWithFee is BaseOFTWithFee {\n  using SafeERC20 for IERC20;\n\n  IERC20 internal immutable innerToken;\n  uint256 internal immutable ld2sdRate;\n\n  // total amount is transferred from this chain to other chains, ensuring the total is less than uint64.max in sd\n  uint256 public outboundAmount;\n\n  constructor(\n    address _token,\n    uint8 _sharedDecimals,\n    address _lzEndpoint\n  ) BaseOFTWithFee(_sharedDecimals, _lzEndpoint) {\n    innerToken = IERC20(_token);\n\n    (bool success, bytes memory data) = _token.staticcall(\n      abi.encodeWithSignature(\"decimals()\")\n    );\n    require(success, \"ProxyOFTWithFee: failed to get token decimals\");\n    uint8 decimals = abi.decode(data, (uint8));\n\n    require(\n      _sharedDecimals <= decimals,\n      \"ProxyOFTWithFee: 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 (uint256) {\n    return innerToken.totalSupply() - outboundAmount;\n  }\n\n  function token() public view virtual override returns (address) {\n    return address(innerToken);\n  }\n\n  /************************************************************************\n   * internal functions\n   ************************************************************************/\n  function _debitFrom(\n    address _from,\n    uint16,\n    bytes32,\n    uint256 _amount\n  ) internal virtual override returns (uint256) {\n    require(_from == _msgSender(), \"ProxyOFTWithFee: owner is not send caller\");\n\n    _amount = _transferFrom(_from, address(this), _amount);\n\n    // _amount still may have dust if the token has transfer fee, then give the dust back to the sender\n    (uint256 amount, uint256 dust) = _removeDust(_amount);\n    if (dust > 0) innerToken.safeTransfer(_from, dust);\n\n    // check total outbound amount\n    outboundAmount += amount;\n    uint256 cap = _sd2ld(type(uint64).max);\n    require(cap >= outboundAmount, \"ProxyOFTWithFee: outboundAmount overflow\");\n\n    return amount;\n  }\n\n  function _creditTo(\n    uint16,\n    address _toAddress,\n    uint256 _amount\n  ) internal virtual override returns (uint256) {\n    outboundAmount -= _amount;\n\n    // tokens are already in this contract, so no need to transfer\n    if (_toAddress == address(this)) {\n      return _amount;\n    }\n\n    return _transferFrom(address(this), _toAddress, _amount);\n  }\n\n  function _transferFrom(\n    address _from,\n    address _to,\n    uint256 _amount\n  ) internal virtual override returns (uint256) {\n    uint256 before = innerToken.balanceOf(_to);\n    if (_from == address(this)) {\n      innerToken.safeTransfer(_to, _amount);\n    } else {\n      innerToken.safeTransferFrom(_from, _to, _amount);\n    }\n    return innerToken.balanceOf(_to) - before;\n  }\n\n  function _ld2sdRate() internal view virtual override returns (uint256) {\n    return ld2sdRate;\n  }\n}\n\n// File contracts/TokenProxyOFT.sol\n\n// Original license: SPDX_License_Identifier: MIT\npragma solidity ^0.8.0;\n\ncontract BIG_FOOT_Proxy is ProxyOFTWithFee {\n  constructor(address _token, address _lzEndpoint)\n    ProxyOFTWithFee(_token, 4, _lzEndpoint)\n  {}\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}