creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/synths/Synth.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\nimport \"@openzeppelin/contracts/proxy/Clones.sol\";\r\nimport \"../lib/layerzero/token/oft/v2/OFTV2Upgradeable.sol\";\r\nimport \"../interfaces/IOnDemandOracle.sol\";\r\nimport \"../interfaces/IController.sol\";\r\nimport \"../interfaces/IBaseVault.sol\";\r\nimport \"../pools/SavingsPool.sol\";\r\nimport \"./TwapPrice.sol\";\r\n\r\n\r\n/** @notice Synth token\r\n  * @dev Can only  be minted by collateral vaults or through layer zero inbound transfer\r\n  */\r\ncontract Synth is OFTV2Upgradeable {\r\n  using SafeERC20Upgradeable for ERC20Upgradeable;\r\n  \r\n  /// @notice Price oracle\r\n  address public oracle;\r\n  /// @notice Authorized minter vaults\r\n  address[] public mintVaults;\r\n  /// @notice Savings pool\r\n  address payable public savingsPool;\r\n  /// @notice Controller address\r\n  address private controller;\r\n  \r\n  /// @notice Current savings yield X4\r\n  uint private savingsYield;\r\n  /// @notice Last saving yield update:\r\n  /// Because it is update several times a day by each collateral, the adjustment speed needs \r\n  /// to be weighted by the time elapsed since last update\r\n  uint private savingYieldUpdateTime;\r\n  \r\n\r\n  // The collateral vaults should ultimately be dynamic, ie allow cloning one of the authorized (eg, list in configurator)\r\n  // If a collateral is added later, anyone could then create a clone for this particular synth.\r\n  function initialize(string memory name, string memory symbol, address _oracle, address lzEndpoint, address _savingPoolLogic) initializer public {\r\n    __OFTV2Upgradeable_init(name, symbol, 8, lzEndpoint);\r\n    savingsYield = 5000;\r\n    controller = msg.sender;\r\n    oracle = _oracle;\r\n    bytes memory spName = abi.encodePacked(name, \" Savings Pool\");\r\n\r\n    address _savingsPool = Clones.cloneDeterministic(_savingPoolLogic, keccak256(spName));\r\n    SavingsPool(payable(_savingsPool)).initialize(address(this), string(spName), string(abi.encodePacked(symbol, \"-SP\")));\r\n    savingsPool = payable(_savingsPool);\r\n    cloneVaults();\r\n  }\r\n  \r\n  \r\n  /// @notice Create local vault clones for each controller-listed vault\r\n  /// @dev Can be called anytime by anyone to add newly listed vaults\r\n  function cloneVaults() public {\r\n    address _controller = controller;\r\n    uint vaultsLength = IController(_controller).getVaultsLength();\r\n    uint v = mintVaults.length;\r\n    if (v < vaultsLength){\r\n      for(uint k = v; k < vaultsLength; k++){\r\n        address vault = IController(_controller).vaults(k);\r\n        address vaultClone = Clones.clone(vault);\r\n        address collateralAsset = IBaseVault(vault).collateralAsset();\r\n        address _oracle = IBaseVault(vault).oracle();\r\n        // after cloning need to re-initialize storage with the values from original vault\r\n        IBaseVault(vaultClone).initialize(address(this), _oracle, collateralAsset,  _controller,  ERC20Upgradeable(collateralAsset).symbol());\r\n        mintVaults.push(vaultClone);\r\n        SavingsPool(savingsPool).addOracle(collateralAsset, _oracle);\r\n      }\r\n    }\r\n  }\r\n  \r\n  \r\n  /// @notice Get target price of the synth, 1e8 in case of USD synth\r\n  /// @dev Override with a call to the oracle for a non USD synth\r\n  function getPrice() public virtual view returns (uint priceX8){\r\n    priceX8 = 1e8;\r\n    if (oracle != address(0)) priceX8 = uint(IOnDemandOracle(oracle).latestAnswer());\r\n  }\r\n  \r\n  \r\n  /// @notice Update the layer zero endpoint: allows deploying on a chain and only become omnichain later\r\n  /// @dev Synth isnt ownable so the update function will query the value from the controller permissionlessly\r\n  function updateLzEndpoint(address _lzEndpoint) public {\r\n    lzEndpoint = ILayerZeroEndpoint(IController(controller).lzEndpoint());\r\n  }\r\n  \r\n  /// @notice Require to be a minter vault\r\n  /// @dev Function rather than modifer to save contract space\r\n  function onlyMintVault() internal {\r\n    bool isMinter;\r\n    for (uint k; k < mintVaults.length; k++)\r\n      if (mintVaults[k] == msg.sender) isMinter = true;\r\n    require(isMinter, \"ST: Unauthorized Minter\");\r\n  }\r\n  \r\n  // Collateral vaults can mint and burn \r\n  function mint(address _recipient, uint256 _amount) public  {\r\n    onlyMintVault();\r\n    _mint(_recipient, _amount);\r\n  }\r\n  function burn(address _recipient, uint256 _amount) public  {\r\n    onlyMintVault();\r\n    _burn(_recipient, _amount);\r\n  }\r\n  \r\n  /// @notice Get LSD income and auction it, proceeds go to the savings pool\r\n  function collectSavingsIncome(address asset, uint amount) public  {\r\n    onlyMintVault();\r\n    ERC20Upgradeable(asset).safeTransferFrom(msg.sender, savingsPool, amount);\r\n    SavingsPool(savingsPool).startAuction(asset);\r\n  }\r\n  \r\n  \r\n  /// @notice Get savings yield X4\r\n  /// @dev More rewards are allocated to Synth to incentivize demand if price is low\r\n  /// More rewards are given to LSD depositors if price is too high (demand > supply)\r\n  /// We use a Uniswap v3 TWAP oracle, as it is purely decentralized but tracks the price well\r\n  /// enough and oracle manipulation isnt really a concern here\r\n  /// Using fixed TwapPrice contract deployment address rather than going thru foundry hoop to link create2 libs\r\n  function getSavingsYield() public returns (uint savingsYieldX4) {\r\n    uint timeSinceLastUpdate = block.timestamp - savingYieldUpdateTime;\r\n    if (timeSinceLastUpdate > 3600) timeSinceLastUpdate = 3600;\r\n    \r\n    (address uniswapFactory, address quoteToken, uint8 quoteDecimals, uint32 twapDuration, uint16 priceBoundsX4, uint16 yieldAdjustmentSpeedX4) \r\n        = IController(controller).getUniswapParams();\r\n    \r\n    uint twapPriceX8 = TwapPrice.getTwapPrice(uniswapFactory, address(this), decimals(), quoteToken, quoteDecimals, twapDuration);\r\n    if (twapPriceX8 > 0){\r\n      int priceDistanceX4 = (int(twapPriceX8) - int(getPrice())) * 10_000 / int(twapPriceX8);\r\n      priceDistanceX4 = priceDistanceX4 > 0 ? \r\n        int(min(uint(priceDistanceX4), uint(priceBoundsX4)))\r\n        : -int(min(uint(-priceDistanceX4), uint(priceBoundsX4)));\r\n\r\n      int adjustment = priceDistanceX4 * int(uint(yieldAdjustmentSpeedX4)) / 10_000;\r\n      if (adjustment > 0) savingsYieldX4 = savingsYield + uint(adjustment) * timeSinceLastUpdate / 3600;\r\n      else savingsYieldX4 = savingsYield - uint(-adjustment) * timeSinceLastUpdate / 3600;\r\n      \r\n      savingsYield = savingsYieldX4;\r\n    }\r\n    else savingsYieldX4 = savingsYield;\r\n    \r\n    savingYieldUpdateTime = block.timestamp;\r\n  }\r\n  \r\n  // Min(uint,uint)\r\n  function min(uint a, uint b) internal pure returns (uint m) {\r\n    m = a < b ? a : b;\r\n  }\r\n}"
      },
      "node_modules/@openzeppelin/contracts/proxy/Clones.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n    /**\n     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n     *\n     * This function uses the create opcode, which should never revert.\n     */\n    function clone(address implementation) internal returns (address instance) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n            // of the `implementation` address with the bytecode before the address.\n            mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n            // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n            mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n            instance := create(0, 0x09, 0x37)\n        }\n        require(instance != address(0), \"ERC1167: create failed\");\n    }\n\n    /**\n     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n     *\n     * This function uses the create2 opcode and a `salt` to deterministically deploy\n     * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n     * the clones cannot be deployed twice at the same address.\n     */\n    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n            // of the `implementation` address with the bytecode before the address.\n            mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n            // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n            mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n            instance := create2(0, 0x09, 0x37, salt)\n        }\n        require(instance != address(0), \"ERC1167: create2 failed\");\n    }\n\n    /**\n     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n     */\n    function predictDeterministicAddress(\n        address implementation,\n        bytes32 salt,\n        address deployer\n    ) internal pure returns (address predicted) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40)\n            mstore(add(ptr, 0x38), deployer)\n            mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\n            mstore(add(ptr, 0x14), implementation)\n            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\n            mstore(add(ptr, 0x58), salt)\n            mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\n            predicted := keccak256(add(ptr, 0x43), 0x55)\n        }\n    }\n\n    /**\n     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n     */\n    function predictDeterministicAddress(\n        address implementation,\n        bytes32 salt\n    ) internal view returns (address predicted) {\n        return predictDeterministicAddress(implementation, salt, address(this));\n    }\n}\n"
      },
      "contracts/lib/layerzero/token/oft/v2/OFTV2Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\nimport \"./BaseOFTV2Upgradeable.sol\";\n\ncontract OFTV2Upgradeable is BaseOFTV2Upgradeable, ERC20Upgradeable {\n    uint internal ld2sdRate;\n\n    function __OFTV2Upgradeable_init(\n        string memory _name,\n        string memory _symbol,\n        uint8 _sharedDecimals,\n        address _lzEndpoint\n    ) internal {\n        __ERC20_init(_name, _symbol);\n        __BaseOFTV2_init(_sharedDecimals, _lzEndpoint);\n        uint8 decimals = decimals();\n        require(_sharedDecimals <= decimals, \"OFT: sharedDecimals must be <= decimals\");\n        ld2sdRate = 10**(decimals - _sharedDecimals);\n    }\n\n    /************************************************************************\n     * public functions\n     ************************************************************************/\n    function circulatingSupply() public view virtual override returns (uint) {\n        return totalSupply();\n    }\n\n    function token() public view virtual override returns (address) {\n        return address(this);\n    }\n\n    /************************************************************************\n     * internal functions\n     ************************************************************************/\n    function _debitFrom(\n        address _from,\n        uint16,\n        bytes32,\n        uint _amount\n    ) internal virtual override returns (uint) {\n        address spender = _msgSender();\n        if (_from != spender) _spendAllowance(_from, spender, _amount);\n        _burn(_from, _amount);\n        return _amount;\n    }\n\n    function _creditTo(\n        uint16,\n        address _toAddress,\n        uint _amount\n    ) internal virtual override returns (uint) {\n        _mint(_toAddress, _amount);\n        return _amount;\n    }\n\n    function _transferFrom(\n        address _from,\n        address _to,\n        uint _amount\n    ) internal virtual override returns (uint) {\n        address spender = _msgSender();\n        // if transfer from this contract, no need to check allowance\n        if (_from != address(this) && _from != spender) _spendAllowance(_from, spender, _amount);\n        _transfer(_from, _to, _amount);\n        return _amount;\n    }\n\n    function _ld2sdRate() internal view virtual override returns (uint) {\n        return ld2sdRate;\n    }\n}\n"
      },
      "contracts/interfaces/IOnDemandOracle.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\n/// @notice IOnDemandOracle used for oracles that get their value from offchain signed data\r\n/// https://github.com/MonroeProtocol/OnDemandOracle\r\ninterface IOnDemandOracle {\r\n  /// @notice Get latest oracle answer (may be stale)\r\n  function latestAnswer() external view returns (int256);\r\n  \r\n  /// @notice Update and get latest oracle answer based on signed offchain data\r\n  /// Reverts on bad priceUpdateData\r\n  function updateAnswer(bytes calldata priceUpdateData) external payable returns (int256);\r\n  \r\n  function decimals() external view returns (uint256);\r\n  \r\n  function lastUpdate() external view returns (uint256);\r\n  \r\n  function isStale() external view returns (bool);\r\n}"
      },
      "contracts/interfaces/IController.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\n\r\ninterface IController {\r\n  function getVaultsLength() external view returns (uint);\r\n  function vaults(uint vaultId) external view returns (address);\r\n  function getUniswapParams() external view \r\n    returns (address uniswapFactory, address quoteToken, uint8 tokenDecimals, uint32 twapDuration, uint16 priceBoundsX4, uint16 yieldAdjustmentSpeedX4);\r\n    \r\n  function treasury() external view returns (address);\r\n  function treasuryFee() external view returns (uint16);\r\n  function emergencyPoolShare() external view returns (uint16);\r\n  function setTreasury(address _treasury, uint16 _treasuryFee) external;\r\n  function setParameters(uint16 _emergencyPoolShare, uint16 _priceBounds, uint16 _yieldAdjustmentSpeed) external;\r\n  function setAddresses(address _synth, address _savingsPool, address _lzEndpoint, address _uniswapV3Factory, address _usdc) external;\r\n  function lzEndpoint() external returns (address);\r\n  \r\n  function getLiquidationThresholds(address collateral) external view returns (uint16 liquidationThreshold, uint16 hardLiquidationThreshold);\r\n  function setLiquidationThresholds(address collateral, uint16 _liquidationThreshold, uint16 _hardLiquidationThreshold) external;\r\n}"
      },
      "contracts/interfaces/IBaseVault.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\n\r\ninterface IBaseVault {\r\n  function depositAndMint(uint256 collateralAmount, uint256 burnAmount, bytes calldata priceUpdateData) external payable;\r\n  function withdrawAndBurn(uint256 collateralAmount, uint256 burnAmount, bytes calldata priceUpdateData) external payable;\r\n  function balanceOf(address owner) external view returns (uint);\r\n  function initialize(address _synth, address _oracle, address _collateralAsset, address _controller, string memory symbol) external;\r\n  function collateralAsset() external pure returns (address);\r\n  function oracle() external view returns (address);\r\n  function updatePrice(bytes calldata priceUpdateData) external payable returns (uint price);\r\n  function latestPrice() external view returns (uint price);\r\n}"
      },
      "contracts/pools/SavingsPool.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\n\r\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC4626Upgradeable.sol\";\r\nimport \"../interfaces/IOnDemandOracle.sol\";\r\n\r\n\r\n/// @notice Saving pool where a synthetic asset can be deposited to earn a share of LSD yield.\r\n/// @notice Implements a ducth auction and streams fees to users to prevent sniping\r\n/// @author \r\ncontract SavingsPool is ERC4626Upgradeable {\r\n  using SafeERC20Upgradeable for ERC20Upgradeable;\r\n\r\n  event BoughtAuctionedAsset(address indexed buyer, address indexed auctionedAsset, uint boughtAmount, address paidAsset, uint paidAmount);\r\n\r\n  /// @notice Period over which fees are streamed (1d)\r\n  uint internal constant STREAMING_PERIOD = 86400;\r\n  /// @notice Fees accumated at a given period\r\n  mapping(uint => uint) internal periodToFees;\r\n  /// @notice Auction start date of an asset\r\n  mapping(address => uint) internal auctionStartDates;\r\n  /// @notice Oracles mapping for asset auction\r\n  mapping(address => IOnDemandOracle) public assetOracles;\r\n\r\n\r\n  function initialize(address underlying, string memory name_, string memory symbol_) public initializer {\r\n    __ERC4626_init(IERC20Upgradeable(underlying));\r\n    __ERC20_init(name_, symbol_);\r\n  }\r\n  \r\n  \r\n  /// @notice Add a new oracle feed matching an existing vault\r\n  function addOracle(address _asset, address oracle) public {\r\n    require(msg.sender == asset(), \"SSP: Unauthorized Call\");\r\n    assetOracles[_asset] = IOnDemandOracle(oracle);\r\n  }\r\n\r\n  \r\n  /// @notice Returns the underlying assets\r\n  function totalAssets() public view override returns (uint256){\r\n    return ERC20Upgradeable(asset()).balanceOf(address(this)) - pendingFees();\r\n  }\r\n  \r\n\r\n  /// @notice Auction earned assets for synth underlying to avoid expensive swaps\r\n  /// @dev Protected to prevent griefing (offering rewards to reset auction)\r\n  function startAuction(address rewardAsset) public {\r\n    require(msg.sender == asset(), \"SSP: Caller Not Synth\");\r\n    // asset is already transfered by the synth contract who has the allowance\r\n    auctionStartDates[rewardAsset] = block.timestamp;\r\n  }\r\n  \r\n  \r\n  /// @notice Get Dutch auction price discount in percent\r\n  /// @dev 1% every 30mn from auction start, max 50% discount\r\n  function getDutchAuctionPriceDiscount(address _asset) public view returns (uint discount){\r\n    if (auctionStartDates[_asset] > 0) discount = (block.timestamp - auctionStartDates[_asset]) / 1800;\r\n    if (discount > 50) discount = 50;\r\n  }\r\n  \r\n  receive() external payable { revert(); }\r\n  fallback() external payable { revert(); }\r\n  \r\n  /// @notice Buy auctioned off assets at current oracle price minus dutch auction discount\r\n  function buyAssets(address auctionedAsset, uint boughtAmount, bytes calldata priceUpdateData) external payable returns (uint paidAmount) {\r\n    // Update oracle if needed\r\n    IOnDemandOracle oracle = assetOracles[auctionedAsset];\r\n    uint price = uint(oracle.updateAnswer{value: msg.value}(priceUpdateData));\r\n    uint discount = getDutchAuctionPriceDiscount(auctionedAsset);\r\n    paidAmount = boughtAmount * 1e18 * price * (100 - discount ) / 100e8 / 10**ERC20Upgradeable(auctionedAsset).decimals();\r\n    if (paidAmount > 0){\r\n      ERC20Upgradeable(asset()).safeTransferFrom(msg.sender, address(this), paidAmount);\r\n      reserveFees(paidAmount);\r\n      ERC20Upgradeable(auctionedAsset).transfer(msg.sender, boughtAmount);\r\n      emit BoughtAuctionedAsset(msg.sender, auctionedAsset, boughtAmount, asset(), paidAmount);\r\n    }\r\n  }\r\n  \r\n  \r\n  /// @notice Add fees to the current period\r\n  function reserveFees(uint amount) internal {\r\n    uint period = block.timestamp / STREAMING_PERIOD;\r\n    if(amount > 0) periodToFees[period] += amount;\r\n  }\r\n  \r\n  /// @notice Returns amount of fees reserved, pending streaming\r\n  function pendingFees() public view returns (uint _pendingFees) {\r\n    // time elapsed in past period:\r\n    uint currentPeriod = block.timestamp / STREAMING_PERIOD;\r\n    uint remainingTime = STREAMING_PERIOD - block.timestamp % STREAMING_PERIOD;\r\n    _pendingFees = periodToFees[currentPeriod] + periodToFees[currentPeriod-1] * remainingTime / STREAMING_PERIOD;\r\n  }\r\n}"
      },
      "contracts/synths/TwapPrice.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\nimport \"../interfaces/IUniswapV3Pool.sol\";\r\nimport \"../interfaces/IUniswapV3Factory.sol\";\r\nimport \"../lib/TickMath.sol\";\r\nimport { sqrtPriceX96ToUint } from \"../lib/RangeOrderUtils.sol\";\r\n\r\n\r\nlibrary TwapPrice {\r\n  /// @notice Fetch time-weighted average price in ticks from Uniswap pool\r\n  function getTwapPrice(address uniswapFactory, address baseToken, uint8 baseDecimals, address quoteToken, uint8 quoteDecimals, uint32 twapDuration) \r\n    internal view returns (uint twapPriceX8) \r\n  {\r\n    address uniswapPool = IUniswapV3Factory(uniswapFactory).getPool(baseToken, quoteToken, 500);\r\n    if (uniswapPool != address(0)){\r\n      bool synthIsToken0 = baseToken < quoteToken;\r\n      uint8 token0Decimals = synthIsToken0 ? baseDecimals : quoteDecimals;\r\n      \r\n      // Get twap tick from https://github.com/Uniswap/v3-periphery/blob/main/contracts/libraries/OracleLibrary.sol\r\n      uint32[] memory secondsAgo = new uint32[](2);\r\n      secondsAgo[0] = twapDuration;\r\n      // secondsAgo[1] = 0; // redundant\r\n      (int56[] memory tickCumulatives, ) = IUniswapV3Pool(uniswapPool).observe(secondsAgo);\r\n      int24 twapTick = int24((tickCumulatives[1] - tickCumulatives[0]) / int56(int32(twapDuration)));\r\n      \r\n      // convert tick to price (underlying/collateral token in collateral decimals)\r\n      uint256 twapPrice = sqrtPriceX96ToUint(TickMath.getSqrtRatioAtTick(twapTick), token0Decimals);\r\n\r\n      uint256 token1DecimalsExp = 10**(synthIsToken0 ? quoteDecimals : baseDecimals);\r\n      if (synthIsToken0) twapPriceX8 = twapPrice * 10**8 / token1DecimalsExp;\r\n      else twapPriceX8 = 10**8 * token1DecimalsExp / twapPrice;\r\n    }\r\n  }\r\n}"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n        __ERC20_init_unchained(name_, symbol_);\n    }\n\n    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[45] private __gap;\n}\n"
      },
      "contracts/lib/layerzero/token/oft/v2/BaseOFTV2Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./OFTCoreV2Upgradeable.sol\";\nimport \"./interfaces/IOFTV2.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\nabstract contract BaseOFTV2Upgradeable is OFTCoreV2Upgradeable, ERC165, IOFTV2 {\n    function __BaseOFTV2_init(uint8 _sharedDecimals, address _lzEndpoint) internal {\n      __OFTCoreV2_init(_sharedDecimals, _lzEndpoint);\n    }\n\n    /************************************************************************\n     * public functions\n     ************************************************************************/\n    function sendFrom(\n        address _from,\n        uint16 _dstChainId,\n        bytes32 _toAddress,\n        uint _amount,\n        LzCallParams calldata _callParams\n    ) public payable virtual override {\n        _send(_from, _dstChainId, _toAddress, _amount, _callParams.refundAddress, _callParams.zroPaymentAddress, _callParams.adapterParams);\n    }\n\n    function sendAndCall(\n        address _from,\n        uint16 _dstChainId,\n        bytes32 _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        LzCallParams calldata _callParams\n    ) public payable virtual override {\n        _sendAndCall(\n            _from,\n            _dstChainId,\n            _toAddress,\n            _amount,\n            _payload,\n            _dstGasForCall,\n            _callParams.refundAddress,\n            _callParams.zroPaymentAddress,\n            _callParams.adapterParams\n        );\n    }\n\n    /************************************************************************\n     * public view functions\n     ************************************************************************/\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n        return interfaceId == type(IOFTV2).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    function estimateSendFee(\n        uint16 _dstChainId,\n        bytes32 _toAddress,\n        uint _amount,\n        bool _useZro,\n        bytes calldata _adapterParams\n    ) public view virtual override returns (uint nativeFee, uint zroFee) {\n        return _estimateSendFee(_dstChainId, _toAddress, _amount, _useZro, _adapterParams);\n    }\n\n    function estimateSendAndCallFee(\n        uint16 _dstChainId,\n        bytes32 _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        bool _useZro,\n        bytes calldata _adapterParams\n    ) public view virtual override returns (uint nativeFee, uint zroFee) {\n        return _estimateSendAndCallFee(_dstChainId, _toAddress, _amount, _payload, _dstGasForCall, _useZro, _adapterParams);\n    }\n\n    function circulatingSupply() public view virtual override returns (uint);\n\n    function token() public view virtual override returns (address);\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC4626Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC4626.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../utils/SafeERC20Upgradeable.sol\";\nimport \"../../../interfaces/IERC4626Upgradeable.sol\";\nimport \"../../../utils/math/MathUpgradeable.sol\";\nimport {Initializable} from \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC4626 \"Tokenized Vault Standard\" as defined in\n * https://eips.ethereum.org/EIPS/eip-4626[EIP-4626].\n *\n * This extension allows the minting and burning of \"shares\" (represented using the ERC20 inheritance) in exchange for\n * underlying \"assets\" through standardized {deposit}, {mint}, {redeem} and {burn} workflows. This contract extends\n * the ERC20 standard. Any additional extensions included along it would affect the \"shares\" token represented by this\n * contract and not the \"assets\" token which is an independent contract.\n *\n * [CAUTION]\n * ====\n * In empty (or nearly empty) ERC-4626 vaults, deposits are at high risk of being stolen through frontrunning\n * with a \"donation\" to the vault that inflates the price of a share. This is variously known as a donation or inflation\n * attack and is essentially a problem of slippage. Vault deployers can protect against this attack by making an initial\n * deposit of a non-trivial amount of the asset, such that price manipulation becomes infeasible. Withdrawals may\n * similarly be affected by slippage. Users can protect against this attack as well as unexpected slippage in general by\n * verifying the amount received is as expected, using a wrapper that performs these checks such as\n * https://github.com/fei-protocol/ERC4626#erc4626router-and-base[ERC4626Router].\n *\n * Since v4.9, this implementation uses virtual assets and shares to mitigate that risk. The `_decimalsOffset()`\n * corresponds to an offset in the decimal representation between the underlying asset's decimals and the vault\n * decimals. This offset also determines the rate of virtual shares to virtual assets in the vault, which itself\n * determines the initial exchange rate. While not fully preventing the attack, analysis shows that the default offset\n * (0) makes it non-profitable, as a result of the value being captured by the virtual shares (out of the attacker's\n * donation) matching the attacker's expected gains. With a larger offset, the attack becomes orders of magnitude more\n * expensive than it is profitable. More details about the underlying math can be found\n * xref:erc4626.adoc#inflation-attack[here].\n *\n * The drawback of this approach is that the virtual shares do capture (a very small) part of the value being accrued\n * to the vault. Also, if the vault experiences losses, the users try to exit the vault, the virtual shares and assets\n * will cause the first user to exit to experience reduced losses in detriment to the last users that will experience\n * bigger losses. Developers willing to revert back to the pre-v4.9 behavior just need to override the\n * `_convertToShares` and `_convertToAssets` functions.\n *\n * To learn more, check out our xref:ROOT:erc4626.adoc[ERC-4626 guide].\n * ====\n *\n * _Available since v4.7._\n */\nabstract contract ERC4626Upgradeable is Initializable, ERC20Upgradeable, IERC4626Upgradeable {\n    using MathUpgradeable for uint256;\n\n    IERC20Upgradeable private _asset;\n    uint8 private _underlyingDecimals;\n\n    /**\n     * @dev Set the underlying asset contract. This must be an ERC20-compatible contract (ERC20 or ERC777).\n     */\n    function __ERC4626_init(IERC20Upgradeable asset_) internal onlyInitializing {\n        __ERC4626_init_unchained(asset_);\n    }\n\n    function __ERC4626_init_unchained(IERC20Upgradeable asset_) internal onlyInitializing {\n        (bool success, uint8 assetDecimals) = _tryGetAssetDecimals(asset_);\n        _underlyingDecimals = success ? assetDecimals : 18;\n        _asset = asset_;\n    }\n\n    /**\n     * @dev Attempts to fetch the asset decimals. A return value of false indicates that the attempt failed in some way.\n     */\n    function _tryGetAssetDecimals(IERC20Upgradeable asset_) private view returns (bool, uint8) {\n        (bool success, bytes memory encodedDecimals) = address(asset_).staticcall(\n            abi.encodeWithSelector(IERC20MetadataUpgradeable.decimals.selector)\n        );\n        if (success && encodedDecimals.length >= 32) {\n            uint256 returnedDecimals = abi.decode(encodedDecimals, (uint256));\n            if (returnedDecimals <= type(uint8).max) {\n                return (true, uint8(returnedDecimals));\n            }\n        }\n        return (false, 0);\n    }\n\n    /**\n     * @dev Decimals are computed by adding the decimal offset on top of the underlying asset's decimals. This\n     * \"original\" value is cached during construction of the vault contract. If this read operation fails (e.g., the\n     * asset has not been created yet), a default of 18 is used to represent the underlying asset's decimals.\n     *\n     * See {IERC20Metadata-decimals}.\n     */\n    function decimals() public view virtual override(IERC20MetadataUpgradeable, ERC20Upgradeable) returns (uint8) {\n        return _underlyingDecimals + _decimalsOffset();\n    }\n\n    /** @dev See {IERC4626-asset}. */\n    function asset() public view virtual override returns (address) {\n        return address(_asset);\n    }\n\n    /** @dev See {IERC4626-totalAssets}. */\n    function totalAssets() public view virtual override returns (uint256) {\n        return _asset.balanceOf(address(this));\n    }\n\n    /** @dev See {IERC4626-convertToShares}. */\n    function convertToShares(uint256 assets) public view virtual override returns (uint256) {\n        return _convertToShares(assets, MathUpgradeable.Rounding.Down);\n    }\n\n    /** @dev See {IERC4626-convertToAssets}. */\n    function convertToAssets(uint256 shares) public view virtual override returns (uint256) {\n        return _convertToAssets(shares, MathUpgradeable.Rounding.Down);\n    }\n\n    /** @dev See {IERC4626-maxDeposit}. */\n    function maxDeposit(address) public view virtual override returns (uint256) {\n        return type(uint256).max;\n    }\n\n    /** @dev See {IERC4626-maxMint}. */\n    function maxMint(address) public view virtual override returns (uint256) {\n        return type(uint256).max;\n    }\n\n    /** @dev See {IERC4626-maxWithdraw}. */\n    function maxWithdraw(address owner) public view virtual override returns (uint256) {\n        return _convertToAssets(balanceOf(owner), MathUpgradeable.Rounding.Down);\n    }\n\n    /** @dev See {IERC4626-maxRedeem}. */\n    function maxRedeem(address owner) public view virtual override returns (uint256) {\n        return balanceOf(owner);\n    }\n\n    /** @dev See {IERC4626-previewDeposit}. */\n    function previewDeposit(uint256 assets) public view virtual override returns (uint256) {\n        return _convertToShares(assets, MathUpgradeable.Rounding.Down);\n    }\n\n    /** @dev See {IERC4626-previewMint}. */\n    function previewMint(uint256 shares) public view virtual override returns (uint256) {\n        return _convertToAssets(shares, MathUpgradeable.Rounding.Up);\n    }\n\n    /** @dev See {IERC4626-previewWithdraw}. */\n    function previewWithdraw(uint256 assets) public view virtual override returns (uint256) {\n        return _convertToShares(assets, MathUpgradeable.Rounding.Up);\n    }\n\n    /** @dev See {IERC4626-previewRedeem}. */\n    function previewRedeem(uint256 shares) public view virtual override returns (uint256) {\n        return _convertToAssets(shares, MathUpgradeable.Rounding.Down);\n    }\n\n    /** @dev See {IERC4626-deposit}. */\n    function deposit(uint256 assets, address receiver) public virtual override returns (uint256) {\n        require(assets <= maxDeposit(receiver), \"ERC4626: deposit more than max\");\n\n        uint256 shares = previewDeposit(assets);\n        _deposit(_msgSender(), receiver, assets, shares);\n\n        return shares;\n    }\n\n    /** @dev See {IERC4626-mint}.\n     *\n     * As opposed to {deposit}, minting is allowed even if the vault is in a state where the price of a share is zero.\n     * In this case, the shares will be minted without requiring any assets to be deposited.\n     */\n    function mint(uint256 shares, address receiver) public virtual override returns (uint256) {\n        require(shares <= maxMint(receiver), \"ERC4626: mint more than max\");\n\n        uint256 assets = previewMint(shares);\n        _deposit(_msgSender(), receiver, assets, shares);\n\n        return assets;\n    }\n\n    /** @dev See {IERC4626-withdraw}. */\n    function withdraw(uint256 assets, address receiver, address owner) public virtual override returns (uint256) {\n        require(assets <= maxWithdraw(owner), \"ERC4626: withdraw more than max\");\n\n        uint256 shares = previewWithdraw(assets);\n        _withdraw(_msgSender(), receiver, owner, assets, shares);\n\n        return shares;\n    }\n\n    /** @dev See {IERC4626-redeem}. */\n    function redeem(uint256 shares, address receiver, address owner) public virtual override returns (uint256) {\n        require(shares <= maxRedeem(owner), \"ERC4626: redeem more than max\");\n\n        uint256 assets = previewRedeem(shares);\n        _withdraw(_msgSender(), receiver, owner, assets, shares);\n\n        return assets;\n    }\n\n    /**\n     * @dev Internal conversion function (from assets to shares) with support for rounding direction.\n     */\n    function _convertToShares(uint256 assets, MathUpgradeable.Rounding rounding) internal view virtual returns (uint256) {\n        return assets.mulDiv(totalSupply() + 10 ** _decimalsOffset(), totalAssets() + 1, rounding);\n    }\n\n    /**\n     * @dev Internal conversion function (from shares to assets) with support for rounding direction.\n     */\n    function _convertToAssets(uint256 shares, MathUpgradeable.Rounding rounding) internal view virtual returns (uint256) {\n        return shares.mulDiv(totalAssets() + 1, totalSupply() + 10 ** _decimalsOffset(), rounding);\n    }\n\n    /**\n     * @dev Deposit/mint common workflow.\n     */\n    function _deposit(address caller, address receiver, uint256 assets, uint256 shares) internal virtual {\n        // If _asset is ERC777, `transferFrom` can trigger a reentrancy BEFORE the transfer happens through the\n        // `tokensToSend` hook. On the other hand, the `tokenReceived` hook, that is triggered after the transfer,\n        // calls the vault, which is assumed not malicious.\n        //\n        // Conclusion: we need to do the transfer before we mint so that any reentrancy would happen before the\n        // assets are transferred and before the shares are minted, which is a valid state.\n        // slither-disable-next-line reentrancy-no-eth\n        SafeERC20Upgradeable.safeTransferFrom(_asset, caller, address(this), assets);\n        _mint(receiver, shares);\n\n        emit Deposit(caller, receiver, assets, shares);\n    }\n\n    /**\n     * @dev Withdraw/redeem common workflow.\n     */\n    function _withdraw(\n        address caller,\n        address receiver,\n        address owner,\n        uint256 assets,\n        uint256 shares\n    ) internal virtual {\n        if (caller != owner) {\n            _spendAllowance(owner, caller, shares);\n        }\n\n        // If _asset is ERC777, `transfer` can trigger a reentrancy AFTER the transfer happens through the\n        // `tokensReceived` hook. On the other hand, the `tokensToSend` hook, that is triggered before the transfer,\n        // calls the vault, which is assumed not malicious.\n        //\n        // Conclusion: we need to do the transfer after the burn so that any reentrancy would happen after the\n        // shares are burned and after the assets are transferred, which is a valid state.\n        _burn(owner, shares);\n        SafeERC20Upgradeable.safeTransfer(_asset, receiver, assets);\n\n        emit Withdraw(caller, receiver, owner, assets, shares);\n    }\n\n    function _decimalsOffset() internal view virtual returns (uint8) {\n        return 0;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "contracts/interfaces/IUniswapV3Pool.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\r\npragma solidity >=0.5.0;\r\n\r\ninterface IUniswapV3Pool{\r\n    /// @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp\r\n    /// @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing\r\n    /// the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick,\r\n    /// you must call it with secondsAgos = [3600, 0].\r\n    /// @dev The time weighted average tick represents the geometric time weighted average price of the pool, in\r\n    /// log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio.\r\n    /// @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned\r\n    /// @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp\r\n    /// @return secondsPerLiquidityCumulativeX128s Cumulative seconds per liquidity-in-range value as of each `secondsAgos` from the current block\r\n    /// timestamp\r\n    function observe(uint32[] calldata secondsAgos)\r\n        external\r\n        view\r\n        returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);\r\n    \r\n}"
      },
      "contracts/interfaces/IUniswapV3Factory.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\n/// @notice Single Uniswap v3 factory function needed\r\ninterface IUniswapV3Factory {\r\n  function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool);\r\n}"
      },
      "contracts/lib/TickMath.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.0;\n\n/// @title Math library for computing sqrt prices from ticks and vice versa\n/// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports\n/// prices between 2**-128 and 2**128\nlibrary TickMath {\n    error T();\n    error R();\n\n    /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128\n    int24 internal constant MIN_TICK = -887272;\n    /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128\n    int24 internal constant MAX_TICK = -MIN_TICK;\n\n    /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK)\n    uint160 internal constant MIN_SQRT_RATIO = 4295128739;\n    /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK)\n    uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;\n\n    /// @notice Calculates sqrt(1.0001^tick) * 2^96\n    /// @dev Throws if |tick| > max tick\n    /// @param tick The input tick for the above formula\n    /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)\n    /// at the given tick\n    function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {\n        unchecked {\n            uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));\n            if (absTick > uint256(int256(MAX_TICK))) revert T();\n\n            uint256 ratio = absTick & 0x1 != 0\n                ? 0xfffcb933bd6fad37aa2d162d1a594001\n                : 0x100000000000000000000000000000000;\n            if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;\n            if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;\n            if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;\n            if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;\n            if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;\n            if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;\n            if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;\n            if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;\n            if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;\n            if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;\n            if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;\n            if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;\n            if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;\n            if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;\n            if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;\n            if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;\n            if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;\n            if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;\n            if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;\n\n            if (tick > 0) ratio = type(uint256).max / ratio;\n\n            // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96.\n            // we then downcast because we know the result always fits within 160 bits due to our tick input constraint\n            // we round up in the division so getTickAtSqrtRatio of the output price is always consistent\n            sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));\n        }\n    }\n\n    /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio\n    /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may\n    /// ever return.\n    /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96\n    /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio\n    function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) {\n        unchecked {\n            // second inequality must be < because the price can never reach the price at the max tick\n            if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R();\n            uint256 ratio = uint256(sqrtPriceX96) << 32;\n\n            uint256 r = ratio;\n            uint256 msb = 0;\n\n            assembly {\n                let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n                msb := or(msb, f)\n                r := shr(f, r)\n            }\n            assembly {\n                let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF))\n                msb := or(msb, f)\n                r := shr(f, r)\n            }\n            assembly {\n                let f := shl(5, gt(r, 0xFFFFFFFF))\n                msb := or(msb, f)\n                r := shr(f, r)\n            }\n            assembly {\n                let f := shl(4, gt(r, 0xFFFF))\n                msb := or(msb, f)\n                r := shr(f, r)\n            }\n            assembly {\n                let f := shl(3, gt(r, 0xFF))\n                msb := or(msb, f)\n                r := shr(f, r)\n            }\n            assembly {\n                let f := shl(2, gt(r, 0xF))\n                msb := or(msb, f)\n                r := shr(f, r)\n            }\n            assembly {\n                let f := shl(1, gt(r, 0x3))\n                msb := or(msb, f)\n                r := shr(f, r)\n            }\n            assembly {\n                let f := gt(r, 0x1)\n                msb := or(msb, f)\n            }\n\n            if (msb >= 128) r = ratio >> (msb - 127);\n            else r = ratio << (127 - msb);\n\n            int256 log_2 = (int256(msb) - 128) << 64;\n\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(63, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(62, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(61, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(60, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(59, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(58, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(57, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(56, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(55, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(54, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(53, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(52, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(51, f))\n                r := shr(f, r)\n            }\n            assembly {\n                r := shr(127, mul(r, r))\n                let f := shr(128, r)\n                log_2 := or(log_2, shl(50, f))\n            }\n\n            int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number\n\n            int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128);\n            int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128);\n\n            tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;\n        }\n    }\n}"
      },
      "contracts/lib/RangeOrderUtils.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\nimport {FullMath} from \"./FullMath.sol\";\n\n\n/* Function imported from Rysk Finance:  https://github.com/rysk-finance/dynamic-hedging/blob/f53509267a5d42006baa26a1f495b5c9819452af/packages/contracts/contracts/vendor/uniswap/RangeOrderUtils.sol\n*/\nuint256 constant Q96 = 0x1000000000000000000000000;\n\n/**\n * @param sqrtPriceX96 the sqrt price of token0/token1\n * @param token0Decimals the decimals of token0\n * @return the price as token0/token1 in token1 decimals\n */\nfunction sqrtPriceX96ToUint(uint160 sqrtPriceX96, uint8 token0Decimals)\n    pure\n    returns (uint256)\n{\n    uint256 sqrtPrice = uint256(sqrtPriceX96);\n    if (sqrtPrice > Q96) {\n        uint256 sqrtP = FullMath.mulDiv(sqrtPrice, 10 ** token0Decimals, Q96);\n        return FullMath.mulDiv(sqrtP, sqrtP, 10 ** token0Decimals);\n    } else {\n        uint256 numerator1 = FullMath.mulDiv(sqrtPrice, sqrtPrice, 1);\n        uint256 numerator2 = 10 ** token0Decimals;\n        return FullMath.mulDiv(numerator1, numerator2, 1 << 192);\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\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 ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\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     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n     * constructor.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\n        );\n        _initialized = 1;\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: setting the version to 255 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n        _initialized = version;\n        _initializing = true;\n        _;\n        _initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized != type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint8) {\n        return _initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _initializing;\n    }\n}\n"
      },
      "contracts/lib/layerzero/token/oft/v2/OFTCoreV2Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../../lzApp/NonblockingLzAppUpgradeable.sol\";\nimport \"../../../libraries/ExcessivelySafeCall.sol\";\nimport \"./interfaces/ICommonOFT.sol\";\nimport \"./interfaces/IOFTReceiverV2.sol\";\n\nabstract contract OFTCoreV2Upgradeable is NonblockingLzAppUpgradeable {\n    using BytesLib for bytes;\n    using ExcessivelySafeCall for address;\n\n    uint public constant NO_EXTRA_GAS = 0;\n\n    // packet type\n    uint8 public constant PT_SEND = 0;\n    uint8 public constant PT_SEND_AND_CALL = 1;\n\n    uint8 public sharedDecimals;\n\n    mapping(uint16 => mapping(bytes => mapping(uint64 => bool))) 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(uint16 indexed _dstChainId, address indexed _from, bytes32 indexed _toAddress, uint _amount);\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(uint16 indexed _srcChainId, address indexed _to, uint _amount);\n\n    event CallOFTReceivedSuccess(uint16 indexed _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _hash);\n\n    event NonContractAddress(address _address);\n\n    // _sharedDecimals should be the minimum decimals on all chains\n    function __OFTCoreV2_init(uint8 _sharedDecimals, address _lzEndpoint) internal {\n        __NonblockingLzApp_init(_lzEndpoint);\n        sharedDecimals = _sharedDecimals;\n    }\n\n    /************************************************************************\n     * public functions\n     ************************************************************************/\n    function callOnOFTReceived(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes32 _from,\n        address _to,\n        uint _amount,\n        bytes calldata _payload,\n        uint _gasForCall\n    ) public virtual {\n        require(_msgSender() == address(this), \"OFTCore: caller must be OFTCore\");\n\n        // send\n        _amount = _transferFrom(address(this), _to, _amount);\n        emit ReceiveFromChain(_srcChainId, _to, _amount);\n\n        // call\n        IOFTReceiverV2(_to).onOFTReceived{gas: _gasForCall}(_srcChainId, _srcAddress, _nonce, _from, _amount, _payload);\n    }\n\n    /************************************************************************\n     * internal functions\n     ************************************************************************/\n    function _estimateSendFee(\n        uint16 _dstChainId,\n        bytes32 _toAddress,\n        uint _amount,\n        bool _useZro,\n        bytes memory _adapterParams\n    ) internal view virtual returns (uint nativeFee, uint zroFee) {\n        // mock the payload for sendFrom()\n        bytes memory payload = _encodeSendPayload(_toAddress, _ld2sd(_amount));\n        return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n    }\n\n    function _estimateSendAndCallFee(\n        uint16 _dstChainId,\n        bytes32 _toAddress,\n        uint _amount,\n        bytes memory _payload,\n        uint64 _dstGasForCall,\n        bool _useZro,\n        bytes memory _adapterParams\n    ) internal view virtual returns (uint nativeFee, uint zroFee) {\n        // mock the payload for sendAndCall()\n        bytes memory payload = _encodeSendAndCallPayload(msg.sender, _toAddress, _ld2sd(_amount), _payload, _dstGasForCall);\n        return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n    }\n\n    function _nonblockingLzReceive(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload\n    ) internal virtual override {\n        uint8 packetType = _payload.toUint8(0);\n\n        if (packetType == PT_SEND) {\n            _sendAck(_srcChainId, _srcAddress, _nonce, _payload);\n        } else if (packetType == PT_SEND_AND_CALL) {\n            _sendAndCallAck(_srcChainId, _srcAddress, _nonce, _payload);\n        } else {\n            revert(\"OFTCore: unknown packet type\");\n        }\n    }\n\n    function _send(\n        address _from,\n        uint16 _dstChainId,\n        bytes32 _toAddress,\n        uint _amount,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes memory _adapterParams\n    ) internal virtual returns (uint amount) {\n        _checkGasLimit(_dstChainId, PT_SEND, _adapterParams, NO_EXTRA_GAS);\n\n        (amount, ) = _removeDust(_amount);\n        amount = _debitFrom(_from, _dstChainId, _toAddress, amount); // amount returned should not have dust\n        require(amount > 0, \"OFTCore: amount too small\");\n\n        bytes memory lzPayload = _encodeSendPayload(_toAddress, _ld2sd(amount));\n        _lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);\n\n        emit SendToChain(_dstChainId, _from, _toAddress, amount);\n    }\n\n    function _sendAck(\n        uint16 _srcChainId,\n        bytes memory,\n        uint64,\n        bytes memory _payload\n    ) internal virtual {\n        (address to, uint64 amountSD) = _decodeSendPayload(_payload);\n        if (to == address(0)) {\n            to = address(0xdead);\n        }\n\n        uint amount = _sd2ld(amountSD);\n        amount = _creditTo(_srcChainId, to, amount);\n\n        emit ReceiveFromChain(_srcChainId, to, amount);\n    }\n\n    function _sendAndCall(\n        address _from,\n        uint16 _dstChainId,\n        bytes32 _toAddress,\n        uint _amount,\n        bytes memory _payload,\n        uint64 _dstGasForCall,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes memory _adapterParams\n    ) internal virtual returns (uint amount) {\n        _checkGasLimit(_dstChainId, PT_SEND_AND_CALL, _adapterParams, _dstGasForCall);\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(msg.sender, _toAddress, _ld2sd(amount), _payload, _dstGasForCall);\n        _lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);\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        (bytes32 from, address to, uint64 amountSD, bytes memory payloadForCall, uint64 gasForCall) = _decodeSendAndCallPayload(_payload);\n\n        bool credited = creditedPackets[_srcChainId][_srcAddress][_nonce];\n        uint amount = _sd2ld(amountSD);\n\n        // credit to this contract first, and then transfer to receiver only if callOnOFTReceived() succeeds\n        if (!credited) {\n            amount = _creditTo(_srcChainId, address(this), amount);\n            creditedPackets[_srcChainId][_srcAddress][_nonce] = true;\n        }\n\n        if (!_isContract(to)) {\n            emit NonContractAddress(to);\n            return;\n        }\n\n        // workaround for stack too deep\n        uint16 srcChainId = _srcChainId;\n        bytes memory srcAddress = _srcAddress;\n        uint64 nonce = _nonce;\n        bytes memory payload = _payload;\n        bytes32 from_ = from;\n        address to_ = to;\n        uint amount_ = amount;\n        bytes memory payloadForCall_ = payloadForCall;\n\n        // no gas limit for the call if retry\n        uint gas = credited ? gasleft() : gasForCall;\n        (bool success, bytes memory reason) = address(this).excessivelySafeCall(\n            gasleft(),\n            150,\n            abi.encodeWithSelector(this.callOnOFTReceived.selector, srcChainId, srcAddress, nonce, from_, to_, amount_, payloadForCall_, gas)\n        );\n\n        if (success) {\n            bytes32 hash = keccak256(payload);\n            emit CallOFTReceivedSuccess(srcChainId, srcAddress, nonce, hash);\n        } else {\n            // store the failed message into the nonblockingLzApp\n            _storeFailedMessage(srcChainId, srcAddress, nonce, payload, reason);\n        }\n    }\n\n    function _isContract(address _account) internal view returns (bool) {\n        return _account.code.length > 0;\n    }\n\n    function _ld2sd(uint _amount) internal view virtual returns (uint64) {\n        uint amountSD = _amount / _ld2sdRate();\n        require(amountSD <= type(uint64).max, \"OFTCore: amountSD overflow\");\n        return uint64(amountSD);\n    }\n\n    function _sd2ld(uint64 _amountSD) internal view virtual returns (uint) {\n        return _amountSD * _ld2sdRate();\n    }\n\n    function _removeDust(uint _amount) internal view virtual returns (uint amountAfter, uint dust) {\n        dust = _amount % _ld2sdRate();\n        amountAfter = _amount - dust;\n    }\n\n    function _encodeSendPayload(bytes32 _toAddress, uint64 _amountSD) internal view virtual returns (bytes memory) {\n        return abi.encodePacked(PT_SEND, _toAddress, _amountSD);\n    }\n\n    function _decodeSendPayload(bytes memory _payload) internal view virtual returns (address to, uint64 amountSD) {\n        require(_payload.toUint8(0) == PT_SEND && _payload.length == 41, \"OFTCore: invalid payload\");\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 abi.encodePacked(PT_SEND_AND_CALL, _toAddress, _amountSD, _addressToBytes32(_from), _dstGasForCall, _payload);\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(_payload.toUint8(0) == PT_SEND_AND_CALL, \"OFTCore: invalid payload\");\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) internal pure virtual returns (bytes32) {\n        return bytes32(uint(uint160(_address)));\n    }\n\n    function _debitFrom(\n        address _from,\n        uint16 _dstChainId,\n        bytes32 _toAddress,\n        uint _amount\n    ) internal virtual returns (uint);\n\n    function _creditTo(\n        uint16 _srcChainId,\n        address _toAddress,\n        uint _amount\n    ) internal virtual returns (uint);\n\n    function _transferFrom(\n        address _from,\n        address _to,\n        uint _amount\n    ) internal virtual returns (uint);\n\n    function _ld2sdRate() internal view virtual returns (uint);\n}\n"
      },
      "contracts/lib/layerzero/token/oft/v2/interfaces/IOFTV2.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ICommonOFT.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n */\ninterface IOFTV2 is ICommonOFT {\n\n    /**\n     * @dev send `_amount` amount of token to (`_dstChainId`, `_toAddress`) from `_from`\n     * `_from` the owner of token\n     * `_dstChainId` the destination chain identifier\n     * `_toAddress` can be any size depending on the `dstChainId`.\n     * `_amount` the quantity of tokens in wei\n     * `_refundAddress` the address LayerZero refunds if too much message fee is sent\n     * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)\n     * `_adapterParams` is a flexible bytes array to indicate messaging adapter services\n     */\n    function sendFrom(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, LzCallParams calldata _callParams) external payable;\n\n    function sendAndCall(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, bytes calldata _payload, uint64 _dstGasForCall, LzCallParams calldata _callParams) external payable;\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/introspection/ERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/IERC20PermitUpgradeable.sol\";\nimport \"../../../utils/AddressUpgradeable.sol\";\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 SafeERC20Upgradeable {\n    using AddressUpgradeable 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(IERC20Upgradeable token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\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(IERC20Upgradeable token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\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(IERC20Upgradeable token, address spender, uint256 value) 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(token, abi.encodeWithSelector(token.approve.selector, spender, value));\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(IERC20Upgradeable token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\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(IERC20Upgradeable token, address spender, uint256 value) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\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(IERC20Upgradeable token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\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        IERC20PermitUpgradeable 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(IERC20Upgradeable 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(data, \"SafeERC20: low-level call failed\");\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation 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     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\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 && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/interfaces/IERC4626Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4626.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20Upgradeable.sol\";\nimport \"../token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\n\n/**\n * @dev Interface of the ERC4626 \"Tokenized Vault Standard\", as defined in\n * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].\n *\n * _Available since v4.7._\n */\ninterface IERC4626Upgradeable is IERC20Upgradeable, IERC20MetadataUpgradeable {\n    event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);\n\n    event Withdraw(\n        address indexed sender,\n        address indexed receiver,\n        address indexed owner,\n        uint256 assets,\n        uint256 shares\n    );\n\n    /**\n     * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.\n     *\n     * - MUST be an ERC-20 token contract.\n     * - MUST NOT revert.\n     */\n    function asset() external view returns (address assetTokenAddress);\n\n    /**\n     * @dev Returns the total amount of the underlying asset that is “managed” by Vault.\n     *\n     * - SHOULD include any compounding that occurs from yield.\n     * - MUST be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT revert.\n     */\n    function totalAssets() external view returns (uint256 totalManagedAssets);\n\n    /**\n     * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal\n     * scenario where all the conditions are met.\n     *\n     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT show any variations depending on the caller.\n     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\n     * - MUST NOT revert.\n     *\n     * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the\n     * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and\n     * from.\n     */\n    function convertToShares(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal\n     * scenario where all the conditions are met.\n     *\n     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\n     * - MUST NOT show any variations depending on the caller.\n     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\n     * - MUST NOT revert.\n     *\n     * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the\n     * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and\n     * from.\n     */\n    function convertToAssets(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,\n     * through a deposit call.\n     *\n     * - MUST return a limited value if receiver is subject to some deposit limit.\n     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.\n     * - MUST NOT revert.\n     */\n    function maxDeposit(address receiver) external view returns (uint256 maxAssets);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given\n     * current on-chain conditions.\n     *\n     * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit\n     *   call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called\n     *   in the same transaction.\n     * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the\n     *   deposit would be accepted, regardless if the user has enough tokens approved, etc.\n     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by depositing.\n     */\n    function previewDeposit(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.\n     *\n     * - MUST emit the Deposit event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   deposit execution, and are accounted for during deposit.\n     * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not\n     *   approving enough underlying tokens to the Vault contract, etc).\n     *\n     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.\n     */\n    function deposit(uint256 assets, address receiver) external returns (uint256 shares);\n\n    /**\n     * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.\n     * - MUST return a limited value if receiver is subject to some mint limit.\n     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.\n     * - MUST NOT revert.\n     */\n    function maxMint(address receiver) external view returns (uint256 maxShares);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given\n     * current on-chain conditions.\n     *\n     * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call\n     *   in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the\n     *   same transaction.\n     * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint\n     *   would be accepted, regardless if the user has enough tokens approved, etc.\n     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by minting.\n     */\n    function previewMint(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.\n     *\n     * - MUST emit the Deposit event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint\n     *   execution, and are accounted for during mint.\n     * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not\n     *   approving enough underlying tokens to the Vault contract, etc).\n     *\n     * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.\n     */\n    function mint(uint256 shares, address receiver) external returns (uint256 assets);\n\n    /**\n     * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the\n     * Vault, through a withdraw call.\n     *\n     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\n     * - MUST NOT revert.\n     */\n    function maxWithdraw(address owner) external view returns (uint256 maxAssets);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,\n     * given current on-chain conditions.\n     *\n     * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw\n     *   call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if\n     *   called\n     *   in the same transaction.\n     * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though\n     *   the withdrawal would be accepted, regardless if the user has enough shares, etc.\n     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by depositing.\n     */\n    function previewWithdraw(uint256 assets) external view returns (uint256 shares);\n\n    /**\n     * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.\n     *\n     * - MUST emit the Withdraw event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   withdraw execution, and are accounted for during withdraw.\n     * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner\n     *   not having enough shares, etc).\n     *\n     * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\n     * Those methods should be performed separately.\n     */\n    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);\n\n    /**\n     * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,\n     * through a redeem call.\n     *\n     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\n     * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.\n     * - MUST NOT revert.\n     */\n    function maxRedeem(address owner) external view returns (uint256 maxShares);\n\n    /**\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,\n     * given current on-chain conditions.\n     *\n     * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call\n     *   in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the\n     *   same transaction.\n     * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the\n     *   redemption would be accepted, regardless if the user has enough shares, etc.\n     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\n     * - MUST NOT revert.\n     *\n     * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in\n     * share price or some other type of condition, meaning the depositor will lose assets by redeeming.\n     */\n    function previewRedeem(uint256 shares) external view returns (uint256 assets);\n\n    /**\n     * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.\n     *\n     * - MUST emit the Withdraw event.\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\n     *   redeem execution, and are accounted for during redeem.\n     * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner\n     *   not having enough shares, etc).\n     *\n     * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\n     * Those methods should be performed separately.\n     */\n    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"
      },
      "contracts/lib/FullMath.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.4;\n\n/// @title Contains 512-bit math functions\n/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision\n/// @dev Handles \"phantom overflow\" i.e., allows multiplication and division where an intermediate value overflows 256 bits\nlibrary FullMath {\n    /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n    /// @param a The multiplicand\n    /// @param b The multiplier\n    /// @param denominator The divisor\n    /// @return result The 256-bit result\n    /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv\n    function mulDiv(\n        uint256 a,\n        uint256 b,\n        uint256 denominator\n    ) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = a * b\n            // Compute the product mod 2**256 and mod 2**256 - 1\n            // then use the Chinese Remainder Theorem to reconstruct\n            // the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2**256 + prod0\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(a, b, not(0))\n                prod0 := mul(a, b)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division\n            if (prod1 == 0) {\n                require(denominator > 0);\n                assembly {\n                    result := div(prod0, denominator)\n                }\n                return result;\n            }\n\n            // Make sure the result is less than 2**256.\n            // Also prevents denominator == 0\n            require(denominator > prod1);\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0]\n            // Compute remainder using mulmod\n            uint256 remainder;\n            assembly {\n                remainder := mulmod(a, b, denominator)\n            }\n            // Subtract 256 bit number from 512 bit number\n            assembly {\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator\n            // Compute largest power of two divisor of denominator.\n            // Always >= 1.\n            // EDIT for 0.8 compatibility:\n            // see: https://ethereum.stackexchange.com/questions/96642/unary-operator-cannot-be-applied-to-type-uint256\n            uint256 twos = denominator & (~denominator + 1);\n\n            // Divide denominator by power of two\n            assembly {\n                denominator := div(denominator, twos)\n            }\n\n            // Divide [prod1 prod0] by the factors of two\n            assembly {\n                prod0 := div(prod0, twos)\n            }\n            // Shift in bits from prod1 into prod0. For this we need\n            // to flip `twos` such that it is 2**256 / twos.\n            // If twos is zero, then it becomes one\n            assembly {\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2**256\n            // Now that denominator is an odd number, it has an inverse\n            // modulo 2**256 such that denominator * inv = 1 mod 2**256.\n            // Compute the inverse by starting with a seed that is correct\n            // correct for four bits. That is, denominator * inv = 1 mod 2**4\n            uint256 inv = (3 * denominator) ^ 2;\n            // Now use Newton-Raphson iteration to improve the precision.\n            // Thanks to Hensel's lifting lemma, this also works in modular\n            // arithmetic, doubling the correct bits in each step.\n            inv *= 2 - denominator * inv; // inverse mod 2**8\n            inv *= 2 - denominator * inv; // inverse mod 2**16\n            inv *= 2 - denominator * inv; // inverse mod 2**32\n            inv *= 2 - denominator * inv; // inverse mod 2**64\n            inv *= 2 - denominator * inv; // inverse mod 2**128\n            inv *= 2 - denominator * inv; // inverse mod 2**256\n\n            // Because the division is now exact we can divide by multiplying\n            // with the modular inverse of denominator. This will give us the\n            // correct result modulo 2**256. Since the precoditions guarantee\n            // that the outcome is less than 2**256, this is the final result.\n            // We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inv;\n            return result;\n        }\n    }\n\n    /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n    /// @param a The multiplicand\n    /// @param b The multiplier\n    /// @param denominator The divisor\n    /// @return result The 256-bit result\n    function mulDivRoundingUp(\n        uint256 a,\n        uint256 b,\n        uint256 denominator\n    ) internal pure returns (uint256 result) {\n        result = mulDiv(a, b, denominator);\n        if (mulmod(a, b, denominator) > 0) {\n            require(result < type(uint256).max);\n            result++;\n        }\n    }\n}"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
        "content": "// 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 AddressUpgradeable {\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(success, \"Address: unable to send value, recipient may have reverted\");\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) internal returns (bytes memory) {\n        return 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(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\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(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return 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) internal view returns (bytes memory) {\n        return 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 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) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\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 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) private pure {\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"
      },
      "contracts/lib/layerzero/lzApp/NonblockingLzAppUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./LzAppUpgradeable.sol\";\nimport \"../libraries/ExcessivelySafeCall.sol\";\n\n/*\n * the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel\n * this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking\n * NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress)\n */\nabstract contract NonblockingLzAppUpgradeable is LzAppUpgradeable {\n    using ExcessivelySafeCall for address;\n\n    function __NonblockingLzApp_init(address _endpoint) internal {\n      __LzApp_init(_endpoint);\n    }\n\n    mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n    event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);\n    event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);\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(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload)\n        );\n        if (!success) {\n            _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);\n        }\n    }\n\n    function _storeFailedMessage(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload,\n        bytes memory _reason\n    ) internal virtual {\n        failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n        emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);\n    }\n\n    function nonblockingLzReceive(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _payload\n    ) public virtual {\n        // only internal transaction\n        require(_msgSender() == address(this), \"NonblockingLzApp: caller must be LzApp\");\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(keccak256(_payload) == payloadHash, \"NonblockingLzApp: invalid payload\");\n        // clear the stored message\n        failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n        // execute the message. revert if it fails again\n        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n        emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);\n    }\n}\n"
      },
      "contracts/lib/layerzero/libraries/ExcessivelySafeCall.sol": {
        "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.7.6;\n\nlibrary ExcessivelySafeCall {\n    uint constant LOW_28_MASK = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n\n    /// @notice Use when you _really_ really _really_ don't trust the called\n    /// contract. This prevents the called contract from causing reversion of\n    /// the caller in as many ways as we can.\n    /// @dev The main difference between this and a solidity low-level call is\n    /// that we limit the number of bytes that the callee can cause to be\n    /// copied to caller memory. This prevents stupid things like malicious\n    /// contracts returning 10,000,000 bytes causing a local OOG when copying\n    /// to memory.\n    /// @param _target The address to call\n    /// @param _gas The amount of gas to forward to the remote contract\n    /// @param _maxCopy The maximum number of bytes of returndata to copy\n    /// to memory.\n    /// @param _calldata The data to send to the remote contract\n    /// @return success and returndata, as `.call()`. Returndata is capped to\n    /// `_maxCopy` bytes.\n    function excessivelySafeCall(\n        address _target,\n        uint _gas,\n        uint16 _maxCopy,\n        bytes memory _calldata\n    ) internal returns (bool, bytes memory) {\n        // set up for assembly call\n        uint _toCopy;\n        bool _success;\n        bytes memory _returnData = new bytes(_maxCopy);\n        // dispatch message to recipient\n        // by assembly calling \"handle\" function\n        // we call via assembly to avoid memcopying a very large returndata\n        // returned by a malicious contract\n        assembly {\n            _success := call(\n                _gas, // gas\n                _target, // recipient\n                0, // ether value\n                add(_calldata, 0x20), // inloc\n                mload(_calldata), // inlen\n                0, // outloc\n                0 // outlen\n            )\n            // limit our copy to 256 bytes\n            _toCopy := returndatasize()\n            if gt(_toCopy, _maxCopy) {\n                _toCopy := _maxCopy\n            }\n            // Store the length of the copied bytes\n            mstore(_returnData, _toCopy)\n            // copy the bytes from returndata[0:_toCopy]\n            returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n        }\n        return (_success, _returnData);\n    }\n\n    /// @notice Use when you _really_ really _really_ don't trust the called\n    /// contract. This prevents the called contract from causing reversion of\n    /// the caller in as many ways as we can.\n    /// @dev The main difference between this and a solidity low-level call is\n    /// that we limit the number of bytes that the callee can cause to be\n    /// copied to caller memory. This prevents stupid things like malicious\n    /// contracts returning 10,000,000 bytes causing a local OOG when copying\n    /// to memory.\n    /// @param _target The address to call\n    /// @param _gas The amount of gas to forward to the remote contract\n    /// @param _maxCopy The maximum number of bytes of returndata to copy\n    /// to memory.\n    /// @param _calldata The data to send to the remote contract\n    /// @return success and returndata, as `.call()`. Returndata is capped to\n    /// `_maxCopy` bytes.\n    function excessivelySafeStaticCall(\n        address _target,\n        uint _gas,\n        uint16 _maxCopy,\n        bytes memory _calldata\n    ) internal view returns (bool, bytes memory) {\n        // set up for assembly call\n        uint _toCopy;\n        bool _success;\n        bytes memory _returnData = new bytes(_maxCopy);\n        // dispatch message to recipient\n        // by assembly calling \"handle\" function\n        // we call via assembly to avoid memcopying a very large returndata\n        // returned by a malicious contract\n        assembly {\n            _success := staticcall(\n                _gas, // gas\n                _target, // recipient\n                add(_calldata, 0x20), // inloc\n                mload(_calldata), // inlen\n                0, // outloc\n                0 // outlen\n            )\n            // limit our copy to 256 bytes\n            _toCopy := returndatasize()\n            if gt(_toCopy, _maxCopy) {\n                _toCopy := _maxCopy\n            }\n            // Store the length of the copied bytes\n            mstore(_returnData, _toCopy)\n            // copy the bytes from returndata[0:_toCopy]\n            returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n        }\n        return (_success, _returnData);\n    }\n\n    /**\n     * @notice Swaps function selectors in encoded contract calls\n     * @dev Allows reuse of encoded calldata for functions with identical\n     * argument types but different names. It simply swaps out the first 4 bytes\n     * for the new selector. This function modifies memory in place, and should\n     * only be used with caution.\n     * @param _newSelector The new 4-byte selector\n     * @param _buf The encoded contract args\n     */\n    function swapSelector(bytes4 _newSelector, bytes memory _buf) internal pure {\n        require(_buf.length >= 4);\n        uint _mask = LOW_28_MASK;\n        assembly {\n            // load the first word of\n            let _word := mload(add(_buf, 0x20))\n            // mask out the top 4 bytes\n            // /x\n            _word := and(_word, _mask)\n            _word := or(_newSelector, _word)\n            mstore(add(_buf, 0x20), _word)\n        }\n    }\n}\n"
      },
      "contracts/lib/layerzero/token/oft/v2/interfaces/ICommonOFT.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n */\ninterface ICommonOFT is IERC165 {\n\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(uint16 _dstChainId, bytes32 _toAddress, uint _amount, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);\n\n    function estimateSendAndCallFee(uint16 _dstChainId, bytes32 _toAddress, uint _amount, bytes calldata _payload, uint64 _dstGasForCall, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);\n\n    /**\n     * @dev returns the circulating amount of tokens on current chain\n     */\n    function circulatingSupply() external view returns (uint);\n\n    /**\n     * @dev returns the address of the ERC20 token\n     */\n    function token() external view returns (address);\n}\n"
      },
      "contracts/lib/layerzero/token/oft/v2/interfaces/IOFTReceiverV2.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.5.0;\n\ninterface IOFTReceiverV2 {\n    /**\n     * @dev Called by the OFT contract when tokens are received from source chain.\n     * @param _srcChainId The chain id of the source chain.\n     * @param _srcAddress The address of the OFT token contract on the source chain.\n     * @param _nonce The nonce of the transaction on the source chain.\n     * @param _from The address of the account who calls the sendAndCall() on the source chain.\n     * @param _amount The amount of tokens to transfer.\n     * @param _payload Additional data with no specified format.\n     */\n    function onOFTReceived(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes32 _from, uint _amount, bytes calldata _payload) external;\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol": {
        "content": "// 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 IERC20PermitUpgradeable {\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"
      },
      "contracts/lib/layerzero/lzApp/LzAppUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"./interfaces/ILayerZeroReceiver.sol\";\nimport \"./interfaces/ILayerZeroUserApplicationConfig.sol\";\nimport \"./interfaces/ILayerZeroEndpoint.sol\";\nimport \"../libraries/BytesLib.sol\";\n\n/*\n * a generic LzReceiver implementation\n */\nabstract contract LzAppUpgradeable is OwnableUpgradeable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n    using BytesLib for bytes;\n\n    // ua can not send payload larger than this by default, but it can be changed by the ua owner\n    uint public constant DEFAULT_PAYLOAD_SIZE_LIMIT = 10000;\n\n    ILayerZeroEndpoint public lzEndpoint;\n    mapping(uint16 => bytes) public trustedRemoteLookup;\n    mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;\n    mapping(uint16 => uint) public payloadSizeLimitLookup;\n    address public precrime;\n\n    event SetPrecrime(address precrime);\n    event SetTrustedRemote(uint16 _remoteChainId, bytes _path);\n    event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);\n    event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);\n\n    function __LzApp_init(address _endpoint) internal {\n        __Ownable_init();\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(_msgSender() == address(lzEndpoint), \"LzApp: invalid endpoint caller\");\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 && trustedRemote.length > 0 && keccak256(_srcAddress) == keccak256(trustedRemote),\n            \"LzApp: invalid source sending contract\"\n        );\n\n        _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n    }\n\n    // abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging\n    function _blockingLzReceive(\n        uint16 _srcChainId,\n        bytes memory _srcAddress,\n        uint64 _nonce,\n        bytes memory _payload\n    ) internal virtual;\n\n    function _lzSend(\n        uint16 _dstChainId,\n        bytes memory _payload,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes memory _adapterParams,\n        uint _nativeFee\n    ) internal virtual {\n        bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n        require(trustedRemote.length != 0, \"LzApp: destination chain is not a trusted source\");\n        _checkPayloadSize(_dstChainId, _payload.length);\n        lzEndpoint.send{value: _nativeFee}(_dstChainId, trustedRemote, _payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n    }\n\n    function _checkGasLimit(\n        uint16 _dstChainId,\n        uint16 _type,\n        bytes memory _adapterParams,\n        uint _extraGas\n    ) internal view virtual {\n        uint providedGasLimit = _getGasLimit(_adapterParams);\n        uint minGasLimit = minDstGasLookup[_dstChainId][_type];\n        require(minGasLimit > 0, \"LzApp: minGasLimit not set\");\n        require(providedGasLimit >= minGasLimit + _extraGas, \"LzApp: gas limit is too low\");\n    }\n\n    function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) {\n        require(_adapterParams.length >= 34, \"LzApp: invalid adapterParams\");\n        assembly {\n            gasLimit := mload(add(_adapterParams, 34))\n        }\n    }\n\n    function _checkPayloadSize(uint16 _dstChainId, uint _payloadSize) internal view virtual {\n        uint payloadSizeLimit = payloadSizeLimitLookup[_dstChainId];\n        if (payloadSizeLimit == 0) {\n            // use default if not set\n            payloadSizeLimit = DEFAULT_PAYLOAD_SIZE_LIMIT;\n        }\n        require(_payloadSize <= payloadSizeLimit, \"LzApp: payload size is too large\");\n    }\n\n    //---------------------------UserApplication config----------------------------------------\n    function getConfig(\n        uint16 _version,\n        uint16 _chainId,\n        address,\n        uint _configType\n    ) external view returns (bytes memory) {\n        return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n    }\n\n    // generic config for LayerZero user Application\n    function setConfig(\n        uint16 _version,\n        uint16 _chainId,\n        uint _configType,\n        bytes calldata _config\n    ) external override onlyOwner {\n        lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n    }\n\n    function setSendVersion(uint16 _version) external override onlyOwner {\n        lzEndpoint.setSendVersion(_version);\n    }\n\n    function setReceiveVersion(uint16 _version) external override onlyOwner {\n        lzEndpoint.setReceiveVersion(_version);\n    }\n\n    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {\n        lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n    }\n\n    // _path = abi.encodePacked(remoteAddress, localAddress)\n    // this function set the trusted path for the cross-chain communication\n    function setTrustedRemote(uint16 _remoteChainId, bytes calldata _path) external onlyOwner {\n        trustedRemoteLookup[_remoteChainId] = _path;\n        emit SetTrustedRemote(_remoteChainId, _path);\n    }\n\n    function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner {\n        trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));\n        emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);\n    }\n\n    function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) {\n        bytes memory path = trustedRemoteLookup[_remoteChainId];\n        require(path.length != 0, \"LzApp: no trusted path record\");\n        return path.slice(0, path.length - 20); // the last 20 bytes should be address(this)\n    }\n\n    function setPrecrime(address _precrime) external onlyOwner {\n        precrime = _precrime;\n        emit SetPrecrime(_precrime);\n    }\n\n    function setMinDstGas(\n        uint16 _dstChainId,\n        uint16 _packetType,\n        uint _minGas\n    ) external onlyOwner {\n        minDstGasLookup[_dstChainId][_packetType] = _minGas;\n        emit SetMinDstGas(_dstChainId, _packetType, _minGas);\n    }\n\n    // if the size is 0, it means default size limit\n    function setPayloadSizeLimit(uint16 _dstChainId, uint _size) external onlyOwner {\n        payloadSizeLimitLookup[_dstChainId] = _size;\n    }\n\n    //--------------------------- VIEW FUNCTION ----------------------------------------\n    function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n        bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n        return keccak256(trustedSource) == keccak256(_srcAddress);\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    function __Ownable_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal onlyInitializing {\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     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "contracts/lib/layerzero/lzApp/interfaces/ILayerZeroReceiver.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n    // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n    // @param _srcChainId - the source endpoint identifier\n    // @param _srcAddress - the source sending contract address from the source chain\n    // @param _nonce - the ordered message nonce\n    // @param _payload - the signed payload is the UA bytes has encoded to be sent\n    function lzReceive(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _payload\n    ) external;\n}\n"
      },
      "contracts/lib/layerzero/lzApp/interfaces/ILayerZeroUserApplicationConfig.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n    // @notice set the configuration of the LayerZero messaging library of the specified version\n    // @param _version - messaging library version\n    // @param _chainId - the chainId for the pending config change\n    // @param _configType - type of configuration. every messaging library has its own convention.\n    // @param _config - configuration in the bytes. can encode arbitrary content.\n    function setConfig(\n        uint16 _version,\n        uint16 _chainId,\n        uint _configType,\n        bytes calldata _config\n    ) external;\n\n    // @notice set the send() LayerZero messaging library version to _version\n    // @param _version - new messaging library version\n    function setSendVersion(uint16 _version) external;\n\n    // @notice set the lzReceive() LayerZero messaging library version to _version\n    // @param _version - new messaging library version\n    function setReceiveVersion(uint16 _version) external;\n\n    // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n    // @param _srcChainId - the chainId of the source chain\n    // @param _srcAddress - the contract address of the source contract at the source chain\n    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n"
      },
      "contracts/lib/layerzero/lzApp/interfaces/ILayerZeroEndpoint.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n    // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n    // @param _dstChainId - the destination chain identifier\n    // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n    // @param _payload - a custom bytes payload to send to the destination contract\n    // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n    // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n    // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n    function send(\n        uint16 _dstChainId,\n        bytes calldata _destination,\n        bytes calldata _payload,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes calldata _adapterParams\n    ) external payable;\n\n    // @notice used by the messaging library to publish verified payload\n    // @param _srcChainId - the source chain identifier\n    // @param _srcAddress - the source contract (as bytes) at the source chain\n    // @param _dstAddress - the address on destination chain\n    // @param _nonce - the unbound message ordering nonce\n    // @param _gasLimit - the gas limit for external contract execution\n    // @param _payload - verified payload to send to the destination contract\n    function receivePayload(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        address _dstAddress,\n        uint64 _nonce,\n        uint _gasLimit,\n        bytes calldata _payload\n    ) external;\n\n    // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n    // @param _srcChainId - the source chain identifier\n    // @param _srcAddress - the source chain contract address\n    function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n    // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n    // @param _srcAddress - the source chain contract address\n    function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n    // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n    // @param _dstChainId - the destination chain identifier\n    // @param _userApplication - the user app address on this EVM chain\n    // @param _payload - the custom message to send over LayerZero\n    // @param _payInZRO - if false, user app pays the protocol fee in native token\n    // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n    function estimateFees(\n        uint16 _dstChainId,\n        address _userApplication,\n        bytes calldata _payload,\n        bool _payInZRO,\n        bytes calldata _adapterParam\n    ) external view returns (uint nativeFee, uint zroFee);\n\n    // @notice get this Endpoint's immutable source identifier\n    function getChainId() external view returns (uint16);\n\n    // @notice the interface to retry failed message on this Endpoint destination\n    // @param _srcChainId - the source chain identifier\n    // @param _srcAddress - the source chain contract address\n    // @param _payload - the payload to be retried\n    function retryPayload(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        bytes calldata _payload\n    ) external;\n\n    // @notice query if any STORED payload (message blocking) at the endpoint.\n    // @param _srcChainId - the source chain identifier\n    // @param _srcAddress - the source chain contract address\n    function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n    // @notice query if the _libraryAddress is valid for sending msgs.\n    // @param _userApplication - the user app address on this EVM chain\n    function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n    // @notice query if the _libraryAddress is valid for receiving msgs.\n    // @param _userApplication - the user app address on this EVM chain\n    function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n    // @notice query if the non-reentrancy guard for send() is on\n    // @return true if the guard is on. false otherwise\n    function isSendingPayload() external view returns (bool);\n\n    // @notice query if the non-reentrancy guard for receive() is on\n    // @return true if the guard is on. false otherwise\n    function isReceivingPayload() external view returns (bool);\n\n    // @notice get the configuration of the LayerZero messaging library of the specified version\n    // @param _version - messaging library version\n    // @param _chainId - the chainId for the pending config change\n    // @param _userApplication - the contract address of the user application\n    // @param _configType - type of configuration. every messaging library has its own convention.\n    function getConfig(\n        uint16 _version,\n        uint16 _chainId,\n        address _userApplication,\n        uint _configType\n    ) external view returns (bytes memory);\n\n    // @notice get the send() LayerZero messaging library version\n    // @param _userApplication - the contract address of the user application\n    function getSendVersion(address _userApplication) external view returns (uint16);\n\n    // @notice get the lzReceive() LayerZero messaging library version\n    // @param _userApplication - the contract address of the user application\n    function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n"
      },
      "contracts/lib/layerzero/libraries/BytesLib.sol": {
        "content": "// SPDX-License-Identifier: Unlicense\n/*\n * @title Solidity Bytes Arrays Utils\n * @author Gonçalo Sá <goncalo.sa@consensys.net>\n *\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\n *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\n */\npragma solidity >=0.8.0 <0.9.0;\n\nlibrary BytesLib {\n    function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes memory) {\n        bytes memory tempBytes;\n\n        assembly {\n            // Get a location of some free memory and store it in tempBytes as\n            // Solidity does for memory variables.\n            tempBytes := mload(0x40)\n\n            // Store the length of the first bytes array at the beginning of\n            // the memory for tempBytes.\n            let length := mload(_preBytes)\n            mstore(tempBytes, length)\n\n            // Maintain a memory counter for the current write location in the\n            // temp bytes array by adding the 32 bytes for the array length to\n            // the starting location.\n            let mc := add(tempBytes, 0x20)\n            // Stop copying when the memory counter reaches the length of the\n            // first bytes array.\n            let end := add(mc, length)\n\n            for {\n                // Initialize a copy counter to the start of the _preBytes data,\n                // 32 bytes into its memory.\n                let cc := add(_preBytes, 0x20)\n            } lt(mc, end) {\n                // Increase both counters by 32 bytes each iteration.\n                mc := add(mc, 0x20)\n                cc := add(cc, 0x20)\n            } {\n                // Write the _preBytes data into the tempBytes memory 32 bytes\n                // at a time.\n                mstore(mc, mload(cc))\n            }\n\n            // Add the length of _postBytes to the current length of tempBytes\n            // and store it as the new length in the first 32 bytes of the\n            // tempBytes memory.\n            length := mload(_postBytes)\n            mstore(tempBytes, add(length, mload(tempBytes)))\n\n            // Move the memory counter back from a multiple of 0x20 to the\n            // actual end of the _preBytes data.\n            mc := end\n            // Stop copying when the memory counter reaches the new combined\n            // length of the arrays.\n            end := add(mc, length)\n\n            for {\n                let cc := add(_postBytes, 0x20)\n            } lt(mc, end) {\n                mc := add(mc, 0x20)\n                cc := add(cc, 0x20)\n            } {\n                mstore(mc, mload(cc))\n            }\n\n            // Update the free-memory pointer by padding our last write location\n            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\n            // next 32 byte block, then round down to the nearest multiple of\n            // 32. If the sum of the length of the two arrays is zero then add\n            // one before rounding down to leave a blank 32 bytes (the length block with 0).\n            mstore(\n                0x40,\n                and(\n                    add(add(end, iszero(add(length, mload(_preBytes)))), 31),\n                    not(31) // Round down to the nearest 32 bytes.\n                )\n            )\n        }\n\n        return tempBytes;\n    }\n\n    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\n        assembly {\n            // Read the first 32 bytes of _preBytes storage, which is the length\n            // of the array. (We don't need to use the offset into the slot\n            // because arrays use the entire slot.)\n            let fslot := sload(_preBytes.slot)\n            // Arrays of 31 bytes or less have an even value in their slot,\n            // while longer arrays have an odd value. The actual length is\n            // the slot divided by two for odd values, and the lowest order\n            // byte divided by two for even values.\n            // If the slot is even, bitwise and the slot with 255 and divide by\n            // two to get the length. If the slot is odd, bitwise and the slot\n            // with -1 and divide by two.\n            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\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(sc, add(and(fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00), and(mload(mc), mask)))\n\n                for {\n                    mc := add(mc, 0x20)\n                    sc := add(sc, 1)\n                } lt(mc, end) {\n                    sc := add(sc, 1)\n                    mc := add(mc, 0x20)\n                } {\n                    sstore(sc, mload(mc))\n                }\n\n                mask := exp(0x100, sub(mc, end))\n\n                sstore(sc, mul(div(mload(mc), mask), mask))\n            }\n            default {\n                // get the keccak hash to get the contents of the array\n                mstore(0x0, _preBytes.slot)\n                // Start copying to the last used word of the stored array.\n                let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n                // save new length\n                sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n                // Copy over the first `submod` bytes of the new data as in\n                // case 1 above.\n                let slengthmod := mod(slength, 32)\n                let mlengthmod := mod(mlength, 32)\n                let submod := sub(32, slengthmod)\n                let mc := add(_postBytes, submod)\n                let end := add(_postBytes, mlength)\n                let mask := sub(exp(0x100, submod), 1)\n\n                sstore(sc, add(sload(sc), and(mload(mc), mask)))\n\n                for {\n                    sc := add(sc, 1)\n                    mc := add(mc, 0x20)\n                } lt(mc, end) {\n                    sc := add(sc, 1)\n                    mc := add(mc, 0x20)\n                } {\n                    sstore(sc, mload(mc))\n                }\n\n                mask := exp(0x100, sub(mc, end))\n\n                sstore(sc, mul(div(mload(mc), mask), mask))\n            }\n        }\n    }\n\n    function slice(\n        bytes memory _bytes,\n        uint _start,\n        uint _length\n    ) internal pure returns (bytes memory) {\n        require(_length + 31 >= _length, \"slice_overflow\");\n        require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n\n        bytes memory tempBytes;\n\n        assembly {\n            switch iszero(_length)\n            case 0 {\n                // Get a location of some free memory and store it in tempBytes as\n                // Solidity does for memory variables.\n                tempBytes := mload(0x40)\n\n                // The first word of the slice result is potentially a partial\n                // word read from the original array. To read it, we calculate\n                // the length of that partial word and start copying that many\n                // bytes into the array. The first word we copy will start with\n                // data we don't care about, but the last `lengthmod` bytes will\n                // land at the beginning of the contents of the new array. When\n                // we're done copying, we overwrite the full first word with\n                // the actual length of the slice.\n                let lengthmod := and(_length, 31)\n\n                // The multiplication in the next line is necessary\n                // because when slicing multiples of 32 bytes (lengthmod == 0)\n                // the following copy loop was copying the origin's length\n                // and then ending prematurely not copying everything it should.\n                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n                let end := add(mc, _length)\n\n                for {\n                    // The multiplication in the next line has the same exact purpose\n                    // as the one above.\n                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\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, uint _start) internal pure returns (address) {\n        require(_bytes.length >= _start + 20, \"toAddress_outOfBounds\");\n        address tempAddress;\n\n        assembly {\n            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n        }\n\n        return tempAddress;\n    }\n\n    function toUint8(bytes memory _bytes, uint _start) internal pure returns (uint8) {\n        require(_bytes.length >= _start + 1, \"toUint8_outOfBounds\");\n        uint8 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0x1), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toUint16(bytes memory _bytes, uint _start) internal pure returns (uint16) {\n        require(_bytes.length >= _start + 2, \"toUint16_outOfBounds\");\n        uint16 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0x2), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toUint32(bytes memory _bytes, uint _start) internal pure returns (uint32) {\n        require(_bytes.length >= _start + 4, \"toUint32_outOfBounds\");\n        uint32 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0x4), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toUint64(bytes memory _bytes, uint _start) internal pure returns (uint64) {\n        require(_bytes.length >= _start + 8, \"toUint64_outOfBounds\");\n        uint64 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0x8), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toUint96(bytes memory _bytes, uint _start) internal pure returns (uint96) {\n        require(_bytes.length >= _start + 12, \"toUint96_outOfBounds\");\n        uint96 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0xc), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toUint128(bytes memory _bytes, uint _start) internal pure returns (uint128) {\n        require(_bytes.length >= _start + 16, \"toUint128_outOfBounds\");\n        uint128 tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0x10), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toUint256(bytes memory _bytes, uint _start) internal pure returns (uint) {\n        require(_bytes.length >= _start + 32, \"toUint256_outOfBounds\");\n        uint tempUint;\n\n        assembly {\n            tempUint := mload(add(add(_bytes, 0x20), _start))\n        }\n\n        return tempUint;\n    }\n\n    function toBytes32(bytes memory _bytes, uint _start) internal pure returns (bytes32) {\n        require(_bytes.length >= _start + 32, \"toBytes32_outOfBounds\");\n        bytes32 tempBytes32;\n\n        assembly {\n            tempBytes32 := mload(add(add(_bytes, 0x20), _start))\n        }\n\n        return tempBytes32;\n    }\n\n    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\n        bool success = true;\n\n        assembly {\n            let length := mload(_preBytes)\n\n            // if lengths don't match the arrays are not equal\n            switch eq(length, mload(_postBytes))\n            case 1 {\n                // cb is a circuit breaker in the for loop since there's\n                //  no said feature for inline assembly loops\n                // cb = 1 - don't breaker\n                // cb = 0 - break\n                let cb := 1\n\n                let mc := add(_preBytes, 0x20)\n                let end := add(mc, length)\n\n                for {\n                    let cc := add(_postBytes, 0x20)\n                    // the next line is the loop condition:\n                    // while(uint256(mc < end) + cb == 2)\n                } eq(add(lt(mc, end), cb), 2) {\n                    mc := add(mc, 0x20)\n                    cc := add(cc, 0x20)\n                } {\n                    // if any of these checks fails then arrays are not equal\n                    if iszero(eq(mload(mc), mload(cc))) {\n                        // unsuccess:\n                        success := 0\n                        cb := 0\n                    }\n                }\n            }\n            default {\n                // unsuccess:\n                success := 0\n            }\n        }\n\n        return success;\n    }\n\n    function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) {\n        bool success = true;\n\n        assembly {\n            // we know _preBytes_offset is 0\n            let fslot := sload(_preBytes.slot)\n            // Decode the length of the stored array like in concatStorage().\n            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\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"
      }
    },
    "settings": {
      "remappings": [
        "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
        "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/",
        "@uniswap/v3-periphery/=node_modules/@uniswap/v3-periphery/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "forge-std/=lib/forge-std/src/",
        "layerzero/=node_modules/@layerzerolabs/solidity-examples/contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": false,
      "libraries": {}
    }
  }}