{
  "address": "0x991660133a987F21c6225027C33B9B5680272850",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_fSushi",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_restaurant",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_kitchen",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_flashStrategyFactory",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [],
      "name": "BillCreated",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "Forbidden",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidKitchen",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidRestaurant",
      "type": "error"
    },
    {
      "anonymous": false,
      "inputs": [],
      "name": "Checkpoint",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "pid",
          "type": "uint256"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "bill",
          "type": "address"
        }
      ],
      "name": "CreateBill",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "previousOwner",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "OwnershipTransferred",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "kitchen",
          "type": "address"
        }
      ],
      "name": "UpdateKitchen",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "restaurant",
          "type": "address"
        }
      ],
      "name": "UpdateRestaurant",
      "type": "event"
    },
    {
      "inputs": [],
      "name": "checkpoint",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "pid",
          "type": "uint256"
        }
      ],
      "name": "createBill",
      "outputs": [
        {
          "internalType": "address",
          "name": "bill",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "fSushi",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "flashStrategyFactory",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "name": "getBill",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "kitchen",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "lastCheckpoint",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "pid",
          "type": "uint256"
        },
        {
          "internalType": "address",
          "name": "to",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "mintFSushi",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "pid",
          "type": "uint256"
        }
      ],
      "name": "predictBillAddress",
      "outputs": [
        {
          "internalType": "address",
          "name": "bill",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "renounceOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "restaurant",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "startWeek",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "transferOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_kitchen",
          "type": "address"
        }
      ],
      "name": "updateKitchen",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_restaurant",
          "type": "address"
        }
      ],
      "name": "updateRestaurant",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "name": "weeklyRewards",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
  ],
  "transactionHash": "0xd568f91ce95df43f9f418ab36144dbec0628157fe39645f68b6276caaaaa5c2d",
  "receipt": {
    "to": null,
    "from": "0x612ef87bfcd858687160294b0eFFACA0CBA342E2",
    "contractAddress": "0x991660133a987F21c6225027C33B9B5680272850",
    "transactionIndex": 126,
    "gasUsed": "2802607",
    "logsBloom": "0x000000000000000040000000000900000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000200000000000000000008000000800000000000000000000000084000000000000000000000000000000000000000000000a0000000000000000000000000000002000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000020000000000000000000000000000001000000000000000000000000000002000000",
    "blockHash": "0x4b1209d72ca9f72b56fa39db24eb0bdac43e862322285d1c6ae5441e45409d23",
    "transactionHash": "0xd568f91ce95df43f9f418ab36144dbec0628157fe39645f68b6276caaaaa5c2d",
    "logs": [
      {
        "transactionIndex": 126,
        "blockNumber": 16351287,
        "transactionHash": "0xd568f91ce95df43f9f418ab36144dbec0628157fe39645f68b6276caaaaa5c2d",
        "address": "0x991660133a987F21c6225027C33B9B5680272850",
        "topics": [
          "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x000000000000000000000000612ef87bfcd858687160294b0effaca0cba342e2"
        ],
        "data": "0x",
        "logIndex": 286,
        "blockHash": "0x4b1209d72ca9f72b56fa39db24eb0bdac43e862322285d1c6ae5441e45409d23"
      },
      {
        "transactionIndex": 126,
        "blockNumber": 16351287,
        "transactionHash": "0xd568f91ce95df43f9f418ab36144dbec0628157fe39645f68b6276caaaaa5c2d",
        "address": "0x92066b9FA5cd5d890FC67E28619c07b10c5e2AA5",
        "topics": [
          "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"
        ],
        "data": "0x0000000000000000000000000000000000000000000000000000000000000001",
        "logIndex": 287,
        "blockHash": "0x4b1209d72ca9f72b56fa39db24eb0bdac43e862322285d1c6ae5441e45409d23"
      }
    ],
    "blockNumber": 16351287,
    "cumulativeGasUsed": "16316044",
    "status": 1,
    "byzantium": true
  },
  "args": [
    "0xA24390c62186A8D265344e914F0Fd962B81b5F13",
    "0x8f77a1f6D36c6F3005B33E4071733C7057463Ca5",
    "0xe4CC24Fa7bbcCD83cF10a20760B1b842Cb750421",
    "0x77b8E6e577fd3e90553dbF205D3854a649414741"
  ],
  "numDeployments": 3,
  "solcInputHash": "5fa9b4677f0dd6b8fed89c830d246fe8",
  "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_fSushi\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_restaurant\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_kitchen\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_flashStrategyFactory\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BillCreated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Forbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidKitchen\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRestaurant\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Checkpoint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"pid\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bill\",\"type\":\"address\"}],\"name\":\"CreateBill\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"kitchen\",\"type\":\"address\"}],\"name\":\"UpdateKitchen\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"restaurant\",\"type\":\"address\"}],\"name\":\"UpdateRestaurant\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"checkpoint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pid\",\"type\":\"uint256\"}],\"name\":\"createBill\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"bill\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fSushi\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"flashStrategyFactory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"getBill\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"kitchen\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastCheckpoint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pid\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mintFSushi\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pid\",\"type\":\"uint256\"}],\"name\":\"predictBillAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"bill\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"restaurant\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"startWeek\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_kitchen\",\"type\":\"address\"}],\"name\":\"updateKitchen\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_restaurant\",\"type\":\"address\"}],\"name\":\"updateRestaurant\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"weeklyRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"checkpoint()\":{\"details\":\"if this function doesn't get called for 512 weeks (around 9.8 years) this contract breaks\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"kitchen()\":{\"notice\":\"address of IFSushiKitchen\"},\"lastCheckpoint()\":{\"notice\":\"weeklyRewards is guaranteed to be correct before this week (exclusive)\"},\"restaurant()\":{\"notice\":\"address of IFSushiRestaurant\"},\"weeklyRewards(uint256)\":{\"notice\":\"how much rewards to be minted at the week\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SousChef.sol\":\"SousChef\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[],\"viaIR\":true},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n    address private _owner;\\n\\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n    /**\\n     * @dev Initializes the contract setting the deployer as the initial owner.\\n     */\\n    constructor() {\\n        _transferOwnership(_msgSender());\\n    }\\n\\n    /**\\n     * @dev Throws if called by any account other than the owner.\\n     */\\n    modifier onlyOwner() {\\n        _checkOwner();\\n        _;\\n    }\\n\\n    /**\\n     * @dev Returns the address of the current owner.\\n     */\\n    function owner() public view virtual returns (address) {\\n        return _owner;\\n    }\\n\\n    /**\\n     * @dev Throws if the sender is not the owner.\\n     */\\n    function _checkOwner() internal view virtual {\\n        require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n    }\\n\\n    /**\\n     * @dev Leaves the contract without owner. It will not be possible to call\\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\\n     *\\n     * NOTE: Renouncing ownership will leave the contract without an owner,\\n     * thereby removing 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\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Clones.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.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(address implementation, bytes32 salt)\\n        internal\\n        view\\n        returns (address predicted)\\n    {\\n        return predictDeterministicAddress(implementation, salt, address(this));\\n    }\\n}\\n\",\"keccak256\":\"0x888d64d221d52c31d015b76e50ca1af5ef8ff076550810b49cea6b01d8267a10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/Address.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 * ```\\n * contract MyToken is ERC20Upgradeable {\\n *     function initialize() initializer public {\\n *         __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\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) || (!Address.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 Internal function that returns the initialized version. Returns `_initialized`\\n     */\\n    function _getInitializedVersion() internal view returns (uint8) {\\n        return _initialized;\\n    }\\n\\n    /**\\n     * @dev Internal function that returns the initialized version. Returns `_initializing`\\n     */\\n    function _isInitializing() internal view returns (bool) {\\n        return _initializing;\\n    }\\n}\\n\",\"keccak256\":\"0xcee5467d5d873fb75dae6f98c01a8d25dd609f9d0374c7d39217bd5f9539a2d6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n    /**\\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n     * another (`to`).\\n     *\\n     * Note that `value` may be zero.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    /**\\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n     * a call to {approve}. `value` is the new allowance.\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n    /**\\n     * @dev Returns the amount of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves `amount` tokens from the caller's account to `to`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address to, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Moves `amount` tokens from `from` to `to` using the\\n     * allowance mechanism. `amount` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(\\n        address from,\\n        address to,\\n        uint256 amount\\n    ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n    /**\\n     * @dev Returns the name of the token.\\n     */\\n    function name() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the symbol of the token.\\n     */\\n    function symbol() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the decimals places of the token.\\n     */\\n    function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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 */\\ninterface IERC20Permit {\\n    /**\\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n     * given ``owner``'s signed approval.\\n     *\\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n     * ordering also apply here.\\n     *\\n     * Emits an {Approval} event.\\n     *\\n     * Requirements:\\n     *\\n     * - `spender` cannot be the zero address.\\n     * - `deadline` must be a timestamp in the future.\\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n     * over the EIP712-formatted function arguments.\\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\\n     *\\n     * For more information on the signature format, see the\\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n     * section].\\n     */\\n    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\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.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 SafeERC20 {\\n    using Address for address;\\n\\n    function safeTransfer(\\n        IERC20 token,\\n        address to,\\n        uint256 value\\n    ) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n    }\\n\\n    function safeTransferFrom(\\n        IERC20 token,\\n        address from,\\n        address to,\\n        uint256 value\\n    ) 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(\\n        IERC20 token,\\n        address spender,\\n        uint256 value\\n    ) internal {\\n        // safeApprove should only be called when setting an initial allowance,\\n        // or when resetting it to zero. To increase and decrease it, use\\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n        require(\\n            (value == 0) || (token.allowance(address(this), spender) == 0),\\n            \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n        );\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n    }\\n\\n    function safeIncreaseAllowance(\\n        IERC20 token,\\n        address spender,\\n        uint256 value\\n    ) internal {\\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n    }\\n\\n    function safeDecreaseAllowance(\\n        IERC20 token,\\n        address spender,\\n        uint256 value\\n    ) internal {\\n        unchecked {\\n            uint256 oldAllowance = token.allowance(address(this), spender);\\n            require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n            uint256 newAllowance = oldAllowance - value;\\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n        }\\n    }\\n\\n    function safePermit(\\n        IERC20Permit token,\\n        address owner,\\n        address spender,\\n        uint256 value,\\n        uint256 deadline,\\n        uint8 v,\\n        bytes32 r,\\n        bytes32 s\\n    ) internal {\\n        uint256 nonceBefore = token.nonces(owner);\\n        token.permit(owner, spender, value, deadline, v, r, s);\\n        uint256 nonceAfter = token.nonces(owner);\\n        require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n    }\\n\\n    /**\\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\\n     * @param token The token targeted by the call.\\n     * @param data The call data (encoded using abi.encode or one of its variants).\\n     */\\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n        // the target address contains contract code and also asserts for success in the low-level call.\\n\\n        bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n        if (returndata.length > 0) {\\n            // Return data is optional\\n            require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x9b72f93be69ca894d8492c244259615c4a742afc8d63720dbc8bb81087d9b238\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n    /**\\n     * @dev Returns true if `account` is a contract.\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * It is unsafe to assume that an address for which this function returns\\n     * false is an externally-owned account (EOA) and not a contract.\\n     *\\n     * Among others, `isContract` will return false for the following\\n     * types of addresses:\\n     *\\n     *  - an externally-owned account\\n     *  - a contract in construction\\n     *  - an address where a contract will be created\\n     *  - an address where a contract lived, but was destroyed\\n     * ====\\n     *\\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://diligence.consensys.net/posts/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.5.11/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(\\n        address target,\\n        bytes memory data,\\n        uint256 value\\n    ) 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\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n    function _msgSender() internal view virtual returns (address) {\\n        return msg.sender;\\n    }\\n\\n    function _msgData() internal view virtual returns (bytes calldata) {\\n        return msg.data;\\n    }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n    bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n    uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n     */\\n    function toString(uint256 value) internal pure returns (string memory) {\\n        unchecked {\\n            uint256 length = Math.log10(value) + 1;\\n            string memory buffer = new string(length);\\n            uint256 ptr;\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                ptr := add(buffer, add(32, length))\\n            }\\n            while (true) {\\n                ptr--;\\n                /// @solidity memory-safe-assembly\\n                assembly {\\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n                }\\n                value /= 10;\\n                if (value == 0) break;\\n            }\\n            return buffer;\\n        }\\n    }\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n     */\\n    function toHexString(uint256 value) internal pure returns (string memory) {\\n        unchecked {\\n            return toHexString(value, Math.log256(value) + 1);\\n        }\\n    }\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n     */\\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n        bytes memory buffer = new bytes(2 * length + 2);\\n        buffer[0] = \\\"0\\\";\\n        buffer[1] = \\\"x\\\";\\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\\n            buffer[i] = _SYMBOLS[value & 0xf];\\n            value >>= 4;\\n        }\\n        require(value == 0, \\\"Strings: hex length insufficient\\\");\\n        return string(buffer);\\n    }\\n\\n    /**\\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n     */\\n    function toHexString(address addr) internal pure returns (string memory) {\\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n    }\\n}\\n\",\"keccak256\":\"0xa4d1d62251f8574deb032a35fc948386a9b4de74b812d4f545a1ac120486b48a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n    enum RecoverError {\\n        NoError,\\n        InvalidSignature,\\n        InvalidSignatureLength,\\n        InvalidSignatureS,\\n        InvalidSignatureV // Deprecated in v4.8\\n    }\\n\\n    function _throwError(RecoverError error) private pure {\\n        if (error == RecoverError.NoError) {\\n            return; // no error: do nothing\\n        } else if (error == RecoverError.InvalidSignature) {\\n            revert(\\\"ECDSA: invalid signature\\\");\\n        } else if (error == RecoverError.InvalidSignatureLength) {\\n            revert(\\\"ECDSA: invalid signature length\\\");\\n        } else if (error == RecoverError.InvalidSignatureS) {\\n            revert(\\\"ECDSA: invalid signature 's' value\\\");\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the address that signed a hashed message (`hash`) with\\n     * `signature` or error string. This address can then be used for verification purposes.\\n     *\\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n     * this function rejects them by requiring the `s` value to be in the lower\\n     * half order, and the `v` value to be either 27 or 28.\\n     *\\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n     * verification to be secure: it is possible to craft signatures that\\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n     * this is by receiving a hash of the original message (which may otherwise\\n     * be too long), and then calling {toEthSignedMessageHash} on it.\\n     *\\n     * Documentation for signature generation:\\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n     *\\n     * _Available since v4.3._\\n     */\\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n        if (signature.length == 65) {\\n            bytes32 r;\\n            bytes32 s;\\n            uint8 v;\\n            // ecrecover takes the signature parameters, and the only way to get them\\n            // currently is to use assembly.\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                r := mload(add(signature, 0x20))\\n                s := mload(add(signature, 0x40))\\n                v := byte(0, mload(add(signature, 0x60)))\\n            }\\n            return tryRecover(hash, v, r, s);\\n        } else {\\n            return (address(0), RecoverError.InvalidSignatureLength);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the address that signed a hashed message (`hash`) with\\n     * `signature`. This address can then be used for verification purposes.\\n     *\\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n     * this function rejects them by requiring the `s` value to be in the lower\\n     * half order, and the `v` value to be either 27 or 28.\\n     *\\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n     * verification to be secure: it is possible to craft signatures that\\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n     * this is by receiving a hash of the original message (which may otherwise\\n     * be too long), and then calling {toEthSignedMessageHash} on it.\\n     */\\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n        (address recovered, RecoverError error) = tryRecover(hash, signature);\\n        _throwError(error);\\n        return recovered;\\n    }\\n\\n    /**\\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n     *\\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n     *\\n     * _Available since v4.3._\\n     */\\n    function tryRecover(\\n        bytes32 hash,\\n        bytes32 r,\\n        bytes32 vs\\n    ) internal pure returns (address, RecoverError) {\\n        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n        uint8 v = uint8((uint256(vs) >> 255) + 27);\\n        return tryRecover(hash, v, r, s);\\n    }\\n\\n    /**\\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n     *\\n     * _Available since v4.2._\\n     */\\n    function recover(\\n        bytes32 hash,\\n        bytes32 r,\\n        bytes32 vs\\n    ) internal pure returns (address) {\\n        (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n        _throwError(error);\\n        return recovered;\\n    }\\n\\n    /**\\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n     * `r` and `s` signature fields separately.\\n     *\\n     * _Available since v4.3._\\n     */\\n    function tryRecover(\\n        bytes32 hash,\\n        uint8 v,\\n        bytes32 r,\\n        bytes32 s\\n    ) internal pure returns (address, RecoverError) {\\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n        // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n        //\\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n        // these malleable signatures as well.\\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n            return (address(0), RecoverError.InvalidSignatureS);\\n        }\\n\\n        // If the signature is valid (and not malleable), return the signer address\\n        address signer = ecrecover(hash, v, r, s);\\n        if (signer == address(0)) {\\n            return (address(0), RecoverError.InvalidSignature);\\n        }\\n\\n        return (signer, RecoverError.NoError);\\n    }\\n\\n    /**\\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\\n     * `r` and `s` signature fields separately.\\n     */\\n    function recover(\\n        bytes32 hash,\\n        uint8 v,\\n        bytes32 r,\\n        bytes32 s\\n    ) internal pure returns (address) {\\n        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n        _throwError(error);\\n        return recovered;\\n    }\\n\\n    /**\\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n     * produces hash corresponding to the one signed with the\\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n     * JSON-RPC method as part of EIP-191.\\n     *\\n     * See {recover}.\\n     */\\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n        // 32 is the length in bytes of hash,\\n        // enforced by the type signature above\\n        return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n    }\\n\\n    /**\\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\\n     * produces hash corresponding to the one signed with the\\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n     * JSON-RPC method as part of EIP-191.\\n     *\\n     * See {recover}.\\n     */\\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n        return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n    }\\n\\n    /**\\n     * @dev Returns an Ethereum Signed Typed Data, created from a\\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\\n     * to the one signed with the\\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n     * JSON-RPC method as part of EIP-712.\\n     *\\n     * See {recover}.\\n     */\\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n        return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n    }\\n}\\n\",\"keccak256\":\"0xda898fa084aa1ddfdb346e6a40459e00a59d87071cce7c315a46d648dd71d0ba\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n    enum Rounding {\\n        Down, // Toward negative infinity\\n        Up, // Toward infinity\\n        Zero // Toward zero\\n    }\\n\\n    /**\\n     * @dev Returns the largest of two numbers.\\n     */\\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a > b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the smallest of two numbers.\\n     */\\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a < b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the average of two numbers. The result is rounded towards\\n     * zero.\\n     */\\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b) / 2 can overflow.\\n        return (a & b) + (a ^ b) / 2;\\n    }\\n\\n    /**\\n     * @dev Returns the ceiling of the division of two numbers.\\n     *\\n     * This differs from standard division with `/` in that it rounds up instead\\n     * of rounding down.\\n     */\\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b - 1) / b can overflow on addition, so we distribute.\\n        return a == 0 ? 0 : (a - 1) / b + 1;\\n    }\\n\\n    /**\\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n     * with further edits by Uniswap Labs also under MIT license.\\n     */\\n    function mulDiv(\\n        uint256 x,\\n        uint256 y,\\n        uint256 denominator\\n    ) 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                return prod0 / denominator;\\n            }\\n\\n            // Make sure the result is less than 2^256. 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            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(\\n        uint256 x,\\n        uint256 y,\\n        uint256 denominator,\\n        Rounding rounding\\n    ) 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        // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n        // \\u2192 `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 10, 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 * 8) < value ? 1 : 0);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\\n * easily result in undesired exploitation or bugs, since developers usually\\n * assume that overflows raise errors. `SafeCast` restores this intuition by\\n * reverting the transaction when such an operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n *\\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\\n * all math on `uint256` and `int256` and then downcasting.\\n */\\nlibrary SafeCast {\\n    /**\\n     * @dev Returns the downcasted uint248 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint248).\\n     *\\n     * Counterpart to Solidity's `uint248` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 248 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint248(uint256 value) internal pure returns (uint248) {\\n        require(value <= type(uint248).max, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n        return uint248(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint240 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint240).\\n     *\\n     * Counterpart to Solidity's `uint240` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 240 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint240(uint256 value) internal pure returns (uint240) {\\n        require(value <= type(uint240).max, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n        return uint240(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint232 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint232).\\n     *\\n     * Counterpart to Solidity's `uint232` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 232 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint232(uint256 value) internal pure returns (uint232) {\\n        require(value <= type(uint232).max, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n        return uint232(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint224 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint224).\\n     *\\n     * Counterpart to Solidity's `uint224` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 224 bits\\n     *\\n     * _Available since v4.2._\\n     */\\n    function toUint224(uint256 value) internal pure returns (uint224) {\\n        require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n        return uint224(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint216 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint216).\\n     *\\n     * Counterpart to Solidity's `uint216` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 216 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint216(uint256 value) internal pure returns (uint216) {\\n        require(value <= type(uint216).max, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n        return uint216(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint208 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint208).\\n     *\\n     * Counterpart to Solidity's `uint208` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 208 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint208(uint256 value) internal pure returns (uint208) {\\n        require(value <= type(uint208).max, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n        return uint208(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint200 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint200).\\n     *\\n     * Counterpart to Solidity's `uint200` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 200 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint200(uint256 value) internal pure returns (uint200) {\\n        require(value <= type(uint200).max, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n        return uint200(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint192 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint192).\\n     *\\n     * Counterpart to Solidity's `uint192` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 192 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint192(uint256 value) internal pure returns (uint192) {\\n        require(value <= type(uint192).max, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n        return uint192(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint184 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint184).\\n     *\\n     * Counterpart to Solidity's `uint184` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 184 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint184(uint256 value) internal pure returns (uint184) {\\n        require(value <= type(uint184).max, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n        return uint184(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint176 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint176).\\n     *\\n     * Counterpart to Solidity's `uint176` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 176 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint176(uint256 value) internal pure returns (uint176) {\\n        require(value <= type(uint176).max, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n        return uint176(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint168 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint168).\\n     *\\n     * Counterpart to Solidity's `uint168` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 168 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint168(uint256 value) internal pure returns (uint168) {\\n        require(value <= type(uint168).max, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n        return uint168(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint160 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint160).\\n     *\\n     * Counterpart to Solidity's `uint160` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 160 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint160(uint256 value) internal pure returns (uint160) {\\n        require(value <= type(uint160).max, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n        return uint160(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint152 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint152).\\n     *\\n     * Counterpart to Solidity's `uint152` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 152 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint152(uint256 value) internal pure returns (uint152) {\\n        require(value <= type(uint152).max, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n        return uint152(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint144 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint144).\\n     *\\n     * Counterpart to Solidity's `uint144` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 144 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint144(uint256 value) internal pure returns (uint144) {\\n        require(value <= type(uint144).max, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n        return uint144(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint136 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint136).\\n     *\\n     * Counterpart to Solidity's `uint136` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 136 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint136(uint256 value) internal pure returns (uint136) {\\n        require(value <= type(uint136).max, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n        return uint136(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint128 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint128).\\n     *\\n     * Counterpart to Solidity's `uint128` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 128 bits\\n     *\\n     * _Available since v2.5._\\n     */\\n    function toUint128(uint256 value) internal pure returns (uint128) {\\n        require(value <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n        return uint128(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint120 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint120).\\n     *\\n     * Counterpart to Solidity's `uint120` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 120 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint120(uint256 value) internal pure returns (uint120) {\\n        require(value <= type(uint120).max, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n        return uint120(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint112 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint112).\\n     *\\n     * Counterpart to Solidity's `uint112` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 112 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint112(uint256 value) internal pure returns (uint112) {\\n        require(value <= type(uint112).max, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n        return uint112(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint104 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint104).\\n     *\\n     * Counterpart to Solidity's `uint104` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 104 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint104(uint256 value) internal pure returns (uint104) {\\n        require(value <= type(uint104).max, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n        return uint104(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint96 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint96).\\n     *\\n     * Counterpart to Solidity's `uint96` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 96 bits\\n     *\\n     * _Available since v4.2._\\n     */\\n    function toUint96(uint256 value) internal pure returns (uint96) {\\n        require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n        return uint96(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint88 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint88).\\n     *\\n     * Counterpart to Solidity's `uint88` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 88 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint88(uint256 value) internal pure returns (uint88) {\\n        require(value <= type(uint88).max, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n        return uint88(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint80 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint80).\\n     *\\n     * Counterpart to Solidity's `uint80` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 80 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint80(uint256 value) internal pure returns (uint80) {\\n        require(value <= type(uint80).max, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n        return uint80(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint72 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint72).\\n     *\\n     * Counterpart to Solidity's `uint72` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 72 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint72(uint256 value) internal pure returns (uint72) {\\n        require(value <= type(uint72).max, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n        return uint72(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint64 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint64).\\n     *\\n     * Counterpart to Solidity's `uint64` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 64 bits\\n     *\\n     * _Available since v2.5._\\n     */\\n    function toUint64(uint256 value) internal pure returns (uint64) {\\n        require(value <= type(uint64).max, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n        return uint64(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint56 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint56).\\n     *\\n     * Counterpart to Solidity's `uint56` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 56 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint56(uint256 value) internal pure returns (uint56) {\\n        require(value <= type(uint56).max, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n        return uint56(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint48 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint48).\\n     *\\n     * Counterpart to Solidity's `uint48` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 48 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint48(uint256 value) internal pure returns (uint48) {\\n        require(value <= type(uint48).max, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n        return uint48(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint40 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint40).\\n     *\\n     * Counterpart to Solidity's `uint40` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 40 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint40(uint256 value) internal pure returns (uint40) {\\n        require(value <= type(uint40).max, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n        return uint40(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint32 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint32).\\n     *\\n     * Counterpart to Solidity's `uint32` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 32 bits\\n     *\\n     * _Available since v2.5._\\n     */\\n    function toUint32(uint256 value) internal pure returns (uint32) {\\n        require(value <= type(uint32).max, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n        return uint32(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint24 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint24).\\n     *\\n     * Counterpart to Solidity's `uint24` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 24 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toUint24(uint256 value) internal pure returns (uint24) {\\n        require(value <= type(uint24).max, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n        return uint24(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint16 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint16).\\n     *\\n     * Counterpart to Solidity's `uint16` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 16 bits\\n     *\\n     * _Available since v2.5._\\n     */\\n    function toUint16(uint256 value) internal pure returns (uint16) {\\n        require(value <= type(uint16).max, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n        return uint16(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted uint8 from uint256, reverting on\\n     * overflow (when the input is greater than largest uint8).\\n     *\\n     * Counterpart to Solidity's `uint8` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 8 bits\\n     *\\n     * _Available since v2.5._\\n     */\\n    function toUint8(uint256 value) internal pure returns (uint8) {\\n        require(value <= type(uint8).max, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n        return uint8(value);\\n    }\\n\\n    /**\\n     * @dev Converts a signed int256 into an unsigned uint256.\\n     *\\n     * Requirements:\\n     *\\n     * - input must be greater than or equal to 0.\\n     *\\n     * _Available since v3.0._\\n     */\\n    function toUint256(int256 value) internal pure returns (uint256) {\\n        require(value >= 0, \\\"SafeCast: value must be positive\\\");\\n        return uint256(value);\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int248 from int256, reverting on\\n     * overflow (when the input is less than smallest int248 or\\n     * greater than largest int248).\\n     *\\n     * Counterpart to Solidity's `int248` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 248 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n        downcasted = int248(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 248 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int240 from int256, reverting on\\n     * overflow (when the input is less than smallest int240 or\\n     * greater than largest int240).\\n     *\\n     * Counterpart to Solidity's `int240` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 240 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n        downcasted = int240(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 240 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int232 from int256, reverting on\\n     * overflow (when the input is less than smallest int232 or\\n     * greater than largest int232).\\n     *\\n     * Counterpart to Solidity's `int232` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 232 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n        downcasted = int232(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 232 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int224 from int256, reverting on\\n     * overflow (when the input is less than smallest int224 or\\n     * greater than largest int224).\\n     *\\n     * Counterpart to Solidity's `int224` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 224 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n        downcasted = int224(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int216 from int256, reverting on\\n     * overflow (when the input is less than smallest int216 or\\n     * greater than largest int216).\\n     *\\n     * Counterpart to Solidity's `int216` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 216 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n        downcasted = int216(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 216 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int208 from int256, reverting on\\n     * overflow (when the input is less than smallest int208 or\\n     * greater than largest int208).\\n     *\\n     * Counterpart to Solidity's `int208` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 208 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n        downcasted = int208(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 208 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int200 from int256, reverting on\\n     * overflow (when the input is less than smallest int200 or\\n     * greater than largest int200).\\n     *\\n     * Counterpart to Solidity's `int200` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 200 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n        downcasted = int200(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 200 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int192 from int256, reverting on\\n     * overflow (when the input is less than smallest int192 or\\n     * greater than largest int192).\\n     *\\n     * Counterpart to Solidity's `int192` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 192 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n        downcasted = int192(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 192 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int184 from int256, reverting on\\n     * overflow (when the input is less than smallest int184 or\\n     * greater than largest int184).\\n     *\\n     * Counterpart to Solidity's `int184` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 184 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n        downcasted = int184(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 184 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int176 from int256, reverting on\\n     * overflow (when the input is less than smallest int176 or\\n     * greater than largest int176).\\n     *\\n     * Counterpart to Solidity's `int176` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 176 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n        downcasted = int176(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 176 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int168 from int256, reverting on\\n     * overflow (when the input is less than smallest int168 or\\n     * greater than largest int168).\\n     *\\n     * Counterpart to Solidity's `int168` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 168 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n        downcasted = int168(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 168 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int160 from int256, reverting on\\n     * overflow (when the input is less than smallest int160 or\\n     * greater than largest int160).\\n     *\\n     * Counterpart to Solidity's `int160` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 160 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n        downcasted = int160(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 160 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int152 from int256, reverting on\\n     * overflow (when the input is less than smallest int152 or\\n     * greater than largest int152).\\n     *\\n     * Counterpart to Solidity's `int152` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 152 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n        downcasted = int152(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 152 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int144 from int256, reverting on\\n     * overflow (when the input is less than smallest int144 or\\n     * greater than largest int144).\\n     *\\n     * Counterpart to Solidity's `int144` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 144 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n        downcasted = int144(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 144 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int136 from int256, reverting on\\n     * overflow (when the input is less than smallest int136 or\\n     * greater than largest int136).\\n     *\\n     * Counterpart to Solidity's `int136` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 136 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n        downcasted = int136(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 136 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int128 from int256, reverting on\\n     * overflow (when the input is less than smallest int128 or\\n     * greater than largest int128).\\n     *\\n     * Counterpart to Solidity's `int128` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 128 bits\\n     *\\n     * _Available since v3.1._\\n     */\\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n        downcasted = int128(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int120 from int256, reverting on\\n     * overflow (when the input is less than smallest int120 or\\n     * greater than largest int120).\\n     *\\n     * Counterpart to Solidity's `int120` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 120 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n        downcasted = int120(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 120 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int112 from int256, reverting on\\n     * overflow (when the input is less than smallest int112 or\\n     * greater than largest int112).\\n     *\\n     * Counterpart to Solidity's `int112` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 112 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n        downcasted = int112(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 112 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int104 from int256, reverting on\\n     * overflow (when the input is less than smallest int104 or\\n     * greater than largest int104).\\n     *\\n     * Counterpart to Solidity's `int104` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 104 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n        downcasted = int104(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 104 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int96 from int256, reverting on\\n     * overflow (when the input is less than smallest int96 or\\n     * greater than largest int96).\\n     *\\n     * Counterpart to Solidity's `int96` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 96 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n        downcasted = int96(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int88 from int256, reverting on\\n     * overflow (when the input is less than smallest int88 or\\n     * greater than largest int88).\\n     *\\n     * Counterpart to Solidity's `int88` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 88 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n        downcasted = int88(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 88 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int80 from int256, reverting on\\n     * overflow (when the input is less than smallest int80 or\\n     * greater than largest int80).\\n     *\\n     * Counterpart to Solidity's `int80` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 80 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n        downcasted = int80(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 80 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int72 from int256, reverting on\\n     * overflow (when the input is less than smallest int72 or\\n     * greater than largest int72).\\n     *\\n     * Counterpart to Solidity's `int72` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 72 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n        downcasted = int72(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 72 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int64 from int256, reverting on\\n     * overflow (when the input is less than smallest int64 or\\n     * greater than largest int64).\\n     *\\n     * Counterpart to Solidity's `int64` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 64 bits\\n     *\\n     * _Available since v3.1._\\n     */\\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n        downcasted = int64(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int56 from int256, reverting on\\n     * overflow (when the input is less than smallest int56 or\\n     * greater than largest int56).\\n     *\\n     * Counterpart to Solidity's `int56` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 56 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n        downcasted = int56(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 56 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int48 from int256, reverting on\\n     * overflow (when the input is less than smallest int48 or\\n     * greater than largest int48).\\n     *\\n     * Counterpart to Solidity's `int48` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 48 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n        downcasted = int48(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 48 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int40 from int256, reverting on\\n     * overflow (when the input is less than smallest int40 or\\n     * greater than largest int40).\\n     *\\n     * Counterpart to Solidity's `int40` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 40 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n        downcasted = int40(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 40 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int32 from int256, reverting on\\n     * overflow (when the input is less than smallest int32 or\\n     * greater than largest int32).\\n     *\\n     * Counterpart to Solidity's `int32` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 32 bits\\n     *\\n     * _Available since v3.1._\\n     */\\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n        downcasted = int32(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 32 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int24 from int256, reverting on\\n     * overflow (when the input is less than smallest int24 or\\n     * greater than largest int24).\\n     *\\n     * Counterpart to Solidity's `int24` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 24 bits\\n     *\\n     * _Available since v4.7._\\n     */\\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n        downcasted = int24(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 24 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int16 from int256, reverting on\\n     * overflow (when the input is less than smallest int16 or\\n     * greater than largest int16).\\n     *\\n     * Counterpart to Solidity's `int16` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 16 bits\\n     *\\n     * _Available since v3.1._\\n     */\\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n        downcasted = int16(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 16 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the downcasted int8 from int256, reverting on\\n     * overflow (when the input is less than smallest int8 or\\n     * greater than largest int8).\\n     *\\n     * Counterpart to Solidity's `int8` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - input must fit into 8 bits\\n     *\\n     * _Available since v3.1._\\n     */\\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n        downcasted = int8(value);\\n        require(downcasted == value, \\\"SafeCast: value doesn't fit in 8 bits\\\");\\n    }\\n\\n    /**\\n     * @dev Converts an unsigned uint256 into a signed int256.\\n     *\\n     * Requirements:\\n     *\\n     * - input must be less than or equal to maxInt256.\\n     *\\n     * _Available since v3.0._\\n     */\\n    function toInt256(uint256 value) internal pure returns (int256) {\\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n        require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n        return int256(value);\\n    }\\n}\\n\",\"keccak256\":\"0x52a8cfb0f5239d11b457dcdd1b326992ef672714ca8da71a157255bddd13f3ad\",\"license\":\"MIT\"},\"contracts/FSushiBill.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity ^0.8.17;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"./base/BaseERC20.sol\\\";\\nimport \\\"./interfaces/IFSushiBill.sol\\\";\\nimport \\\"./interfaces/ISousChef.sol\\\";\\nimport \\\"./interfaces/IFSushiKitchen.sol\\\";\\nimport \\\"./libraries/DateUtils.sol\\\";\\n\\ncontract FSushiBill is BaseERC20, IFSushiBill {\\n    using SafeERC20 for IERC20;\\n    using DateUtils for uint256;\\n\\n    address public override sousChef;\\n    uint256 public override pid;\\n    address public override fToken;\\n\\n    /**\\n     * @notice points = \\u222bW(t)dt, where W(t) is the total supply at the week\\n     */\\n    mapping(uint256 => uint256) public override points; // week => points\\n    /**\\n     * @notice points are guaranteed to be correct before this time's week start\\n     */\\n    uint256 public override lastCheckpoint; // timestamp\\n\\n    /**\\n     * @notice userPoints = \\u222bw(t)dt, where a(t) is the balance of account at the week\\n     */\\n    mapping(address => mapping(uint256 => uint256)) public override userPoints; // account => week => points\\n    /**\\n     * @notice userPoints of account is guaranteed to be correct before this week\\n     */\\n    mapping(address => uint256) public override userLastCheckpoint; // account => timestamp\\n    /**\\n     * @notice how much rewards were claimed in total for account\\n     */\\n    mapping(address => uint256) public override claimedRewards; // account => amount\\n    /**\\n     * @notice in the next claim, rewards will be accumulated from this week\\n     */\\n    mapping(address => uint256) public override nextClaimableWeek; // account => week\\n\\n    function initialize(uint256 _pid, address _fToken) external override initializer {\\n        if (_fToken == address(0)) return;\\n\\n        BaseERC20_initialize(\\n            string.concat(\\\"Flash Sushi Bill for \\\", IERC20Metadata(_fToken).name()),\\n            string.concat(\\\"x\\\", IERC20Metadata(_fToken).symbol()),\\n            \\\"1\\\"\\n        );\\n\\n        sousChef = msg.sender;\\n        pid = _pid;\\n        fToken = _fToken;\\n    }\\n\\n    function deposit(uint256 amount, address beneficiary) external override {\\n        userCheckpoint(msg.sender);\\n\\n        if (amount > 0) {\\n            IERC20(fToken).safeTransferFrom(msg.sender, address(this), amount);\\n\\n            uint256 balance = _balanceOf[msg.sender] + amount;\\n            _balanceOf[msg.sender] = balance;\\n            uint256 totalSupply = _totalSupply + amount;\\n            _totalSupply = totalSupply;\\n\\n            _mint(beneficiary, amount);\\n        }\\n\\n        emit Deposit(msg.sender, amount, beneficiary);\\n    }\\n\\n    function withdraw(uint256 amount, address beneficiary) external override {\\n        userCheckpoint(msg.sender);\\n\\n        if (amount > 0) {\\n            uint256 balance = _balanceOf[msg.sender] - amount;\\n            _balanceOf[msg.sender] = balance;\\n            uint256 totalSupply = _totalSupply - amount;\\n            _totalSupply = totalSupply;\\n\\n            _burn(msg.sender, amount);\\n\\n            IERC20(fToken).safeTransfer(beneficiary, amount);\\n        }\\n\\n        emit Withdraw(msg.sender, amount, beneficiary);\\n    }\\n\\n    /**\\n     * @dev if this function doesn't get called for 512 weeks (around 9.8 years) this contract breaks\\n     */\\n    function checkpoint() public override {\\n        ISousChef(sousChef).checkpoint();\\n\\n        uint256 prevCheckpoint = lastCheckpoint;\\n        _updatePoints(points, _totalSupply, prevCheckpoint);\\n        if (prevCheckpoint < block.timestamp) {\\n            lastCheckpoint = block.timestamp;\\n        }\\n\\n        emit Checkpoint();\\n    }\\n\\n    function userCheckpoint(address account) public override {\\n        checkpoint();\\n\\n        uint256 prevCheckpoint = userLastCheckpoint[account];\\n        _updatePoints(userPoints[account], _balanceOf[account], prevCheckpoint);\\n        if (prevCheckpoint < block.timestamp) {\\n            userLastCheckpoint[account] = block.timestamp;\\n        }\\n\\n        emit UserCheckpoint(account);\\n    }\\n\\n    function _updatePoints(\\n        mapping(uint256 => uint256) storage _points,\\n        uint256 balance,\\n        uint256 lastTime\\n    ) internal {\\n        if (balance == 0) return;\\n\\n        if (lastTime == 0) {\\n            uint256 startWeek = ISousChef(sousChef).startWeek();\\n            lastTime = startWeek.toTimestamp();\\n        }\\n\\n        uint256 from = lastTime.toWeekNumber();\\n        for (uint256 i; i < 512; ) {\\n            uint256 week = from + i;\\n            uint256 weekStart = week.toTimestamp();\\n            uint256 weekEnd = weekStart + WEEK;\\n            if (block.timestamp <= weekStart) break;\\n            if (block.timestamp < weekEnd) {\\n                _points[week] += balance * (block.timestamp - Math.max(lastTime, weekStart));\\n                break;\\n            }\\n            if (i == 0) {\\n                _points[week] += balance * (weekEnd - lastTime);\\n            } else {\\n                _points[week] += balance * WEEK;\\n            }\\n\\n            unchecked {\\n                ++i;\\n            }\\n        }\\n    }\\n\\n    function claimRewards(address beneficiary) external {\\n        userCheckpoint(msg.sender);\\n\\n        uint256 from = nextClaimableWeek[msg.sender];\\n        if (from == block.timestamp.toWeekNumber()) return;\\n        if (from == 0) {\\n            from = ISousChef(sousChef).startWeek();\\n        }\\n\\n        (address _sousChef, uint256 _pid) = (sousChef, pid);\\n        address kitchen = ISousChef(_sousChef).kitchen();\\n        IFSushiKitchen(kitchen).checkpoint(_pid);\\n\\n        // add week-by-week rewards until the last week\\n        uint256 totalRewards;\\n        uint256 to = block.timestamp.toWeekNumber(); // exclusive last index\\n        for (uint256 i; i < 512; ) {\\n            uint256 week = from + i;\\n            if (to <= week) break;\\n            uint256 weeklyRewards = ISousChef(_sousChef).weeklyRewards(week);\\n            uint256 weight = IFSushiKitchen(kitchen).relativeWeightAt(_pid, (week + 1).toTimestamp());\\n            uint256 rewards = points[week] == 0\\n                ? 0\\n                : (weeklyRewards * weight * userPoints[msg.sender][week]) / points[week] / 1e18;\\n            totalRewards += rewards;\\n\\n            unchecked {\\n                ++i;\\n            }\\n        }\\n        nextClaimableWeek[msg.sender] = to;\\n\\n        if (totalRewards > 0) {\\n            claimedRewards[msg.sender] += totalRewards;\\n\\n            ISousChef(sousChef).mintFSushi(_pid, beneficiary, totalRewards);\\n\\n            emit ClaimRewards(msg.sender, beneficiary, totalRewards);\\n        }\\n    }\\n\\n    function _transfer(\\n        address from,\\n        address to,\\n        uint256 amount\\n    ) internal override returns (uint256 balanceOfFrom, uint256 balanceOfTo) {\\n        userCheckpoint(from);\\n        userCheckpoint(to);\\n\\n        return super._transfer(from, to, amount);\\n    }\\n}\\n\",\"keccak256\":\"0x392f2f94e39be0e6eb7cb769cd64923d88760613cc9fcd1078e54534f331bf2f\",\"license\":\"BUSL-1.1\"},\"contracts/SousChef.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity ^0.8.17;\\n\\nimport \\\"@openzeppelin/contracts/proxy/Clones.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport \\\"./interfaces/ISousChef.sol\\\";\\nimport \\\"./interfaces/IFSushi.sol\\\";\\nimport \\\"./interfaces/IFSushiRestaurant.sol\\\";\\nimport \\\"./interfaces/IFlashStrategySushiSwapFactory.sol\\\";\\nimport \\\"./interfaces/IFlashStrategySushiSwap.sol\\\";\\nimport \\\"./FSushiBill.sol\\\";\\n\\ncontract SousChef is Ownable, ISousChef {\\n    using SafeERC20 for IERC20;\\n    using SafeCast for uint256;\\n    using SafeCast for int256;\\n    using DateUtils for uint256;\\n\\n    uint256 internal constant BONUS_MULTIPLIER = 10;\\n    uint256 internal constant REWARDS_PER_WEEK = 3000e18;\\n    uint256 internal constant REWARDS_FOR_INITIAL_WEEKS = BONUS_MULTIPLIER * REWARDS_PER_WEEK;\\n\\n    address public immutable override fSushi;\\n    address public immutable override flashStrategyFactory;\\n    uint256 public immutable override startWeek;\\n\\n    address internal immutable _implementation;\\n\\n    /**\\n     * @notice address of IFSushiRestaurant\\n     */\\n    address public override restaurant;\\n\\n    /**\\n     * @notice address of IFSushiKitchen\\n     */\\n    address public override kitchen;\\n\\n    mapping(uint256 => address) public override getBill;\\n    /**\\n     * @notice how much rewards to be minted at the week\\n     */\\n    mapping(uint256 => uint256) public override weeklyRewards; // week => amount\\n    /**\\n     * @notice weeklyRewards is guaranteed to be correct before this week (exclusive)\\n     */\\n    uint256 public override lastCheckpoint; // week\\n\\n    constructor(\\n        address _fSushi,\\n        address _restaurant,\\n        address _kitchen,\\n        address _flashStrategyFactory\\n    ) {\\n        fSushi = _fSushi;\\n        restaurant = _restaurant;\\n        kitchen = _kitchen;\\n        flashStrategyFactory = _flashStrategyFactory;\\n        uint256 thisWeek = block.timestamp.toWeekNumber();\\n        startWeek = thisWeek;\\n        lastCheckpoint = thisWeek + 1;\\n        weeklyRewards[thisWeek] = REWARDS_FOR_INITIAL_WEEKS;\\n\\n        FSushiBill bill = new FSushiBill();\\n        bill.initialize(0, address(0));\\n        _implementation = address(bill);\\n    }\\n\\n    function predictBillAddress(uint256 pid) external view override returns (address bill) {\\n        bill = Clones.predictDeterministicAddress(_implementation, bytes32(pid));\\n    }\\n\\n    function updateRestaurant(address _restaurant) external override onlyOwner {\\n        if (_restaurant == address(0)) revert InvalidRestaurant();\\n\\n        restaurant = _restaurant;\\n\\n        emit UpdateRestaurant(_restaurant);\\n    }\\n\\n    function updateKitchen(address _kitchen) external override onlyOwner {\\n        if (_kitchen == address(0)) revert InvalidKitchen();\\n\\n        kitchen = _kitchen;\\n\\n        emit UpdateKitchen(_kitchen);\\n    }\\n\\n    function createBill(uint256 pid) external override returns (address bill) {\\n        if (getBill[pid] != address(0)) revert BillCreated();\\n\\n        address strategy = IFlashStrategySushiSwapFactory(flashStrategyFactory).getFlashStrategySushiSwap(pid);\\n        if (strategy == address(0))\\n            strategy = IFlashStrategySushiSwapFactory(flashStrategyFactory).createFlashStrategySushiSwap(pid);\\n\\n        bill = Clones.cloneDeterministic(_implementation, bytes32(pid));\\n        FSushiBill(bill).initialize(pid, IFlashStrategySushiSwap(strategy).fToken());\\n\\n        getBill[pid] = bill;\\n\\n        emit CreateBill(pid, bill);\\n    }\\n\\n    /**\\n     * @dev if this function doesn't get called for 512 weeks (around 9.8 years) this contract breaks\\n     */\\n    function checkpoint() external override {\\n        uint256 from = lastCheckpoint;\\n        uint256 until = block.timestamp.toWeekNumber() + 1;\\n        if (until <= from) return;\\n\\n        for (uint256 i; i < 512; ) {\\n            uint256 week = from + i;\\n            if (until <= week) break;\\n            weeklyRewards[week] = _rewards(week);\\n\\n            unchecked {\\n                ++i;\\n            }\\n        }\\n        lastCheckpoint = until;\\n    }\\n\\n    function _rewards(uint256 week) internal returns (uint256) {\\n        if (week < startWeek + 2) return REWARDS_FOR_INITIAL_WEEKS;\\n        if (week == startWeek + 2) return REWARDS_PER_WEEK;\\n\\n        uint256 totalSupply = IFSushi(fSushi).checkpointedTotalSupplyDuring(week - 1);\\n        uint256 lockedAssets = IFSushiRestaurant(restaurant).checkpointedTotalAssetsDuring(week - 1);\\n\\n        uint256 rewards = (totalSupply == 0 || totalSupply < lockedAssets)\\n            ? 0\\n            : (REWARDS_PER_WEEK * (totalSupply - lockedAssets)) / totalSupply;\\n\\n        // emission rate decreases 1% every week from week 3\\n        if (week - startWeek > 2) {\\n            rewards = (rewards * 99) / 100;\\n        }\\n        return rewards;\\n    }\\n\\n    function mintFSushi(\\n        uint256 pid,\\n        address to,\\n        uint256 amount\\n    ) external override {\\n        if (getBill[pid] != msg.sender) revert Forbidden();\\n\\n        IFSushi(fSushi).mint(to, amount);\\n    }\\n}\\n\",\"keccak256\":\"0xdd7d6def8c29bca1d88b582349cdd79f34541a54df5cd726cbb5d5dbac17f8eb\",\"license\":\"BUSL-1.1\"},\"contracts/base/BaseERC20.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity ^0.8.17;\\n\\nimport \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport \\\"@openzeppelin/contracts/proxy/utils/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\nabstract contract BaseERC20 is Initializable, IERC20Metadata {\\n    error Expired();\\n    error InvalidSignature();\\n    error InvalidAccount();\\n    error InvalidSender();\\n    error InvalidReceiver();\\n    error InvalidOwner();\\n    error InvalidSpender();\\n    error NotEnoughBalance();\\n\\n    uint8 public constant override decimals = 18;\\n    bytes32 private _CACHED_DOMAIN_SEPARATOR;\\n    uint256 private _CACHED_CHAIN_ID;\\n    address private _CACHED_THIS;\\n\\n    bytes32 private _HASHED_NAME;\\n    bytes32 private _HASHED_VERSION;\\n    bytes32 private _TYPE_HASH;\\n\\n    string public override name;\\n    string public override symbol;\\n\\n    uint256 internal _totalSupply;\\n    mapping(address => uint256) internal _balanceOf;\\n    mapping(address => mapping(address => uint256)) internal _allowance;\\n    mapping(address => uint256) public nonces;\\n\\n    bytes32 private constant _PERMIT_TYPEHASH =\\n        keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n\\n    function BaseERC20_initialize(\\n        string memory _name,\\n        string memory _symbol,\\n        string memory _version\\n    ) internal onlyInitializing {\\n        name = _name;\\n        symbol = _symbol;\\n\\n        bytes32 hashedName = keccak256(bytes(_name));\\n        bytes32 hashedVersion = keccak256(bytes(_version));\\n        bytes32 typeHash = keccak256(\\n            \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n        );\\n        _HASHED_NAME = hashedName;\\n        _HASHED_VERSION = hashedVersion;\\n        _CACHED_CHAIN_ID = block.chainid;\\n        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n        _CACHED_THIS = address(this);\\n        _TYPE_HASH = typeHash;\\n    }\\n\\n    function DOMAIN_SEPARATOR() external view returns (bytes32) {\\n        return _domainSeparatorV4();\\n    }\\n\\n    function totalSupply() external view virtual returns (uint256) {\\n        return _totalSupply;\\n    }\\n\\n    function balanceOf(address account) external view virtual returns (uint256) {\\n        return _balanceOf[account];\\n    }\\n\\n    function allowance(address owner, address spender) external view virtual returns (uint256) {\\n        return _allowance[owner][spender];\\n    }\\n\\n    function _domainSeparatorV4() internal view returns (bytes32) {\\n        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\\n            return _CACHED_DOMAIN_SEPARATOR;\\n        } else {\\n            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n        }\\n    }\\n\\n    function _buildDomainSeparator(\\n        bytes32 typeHash,\\n        bytes32 nameHash,\\n        bytes32 versionHash\\n    ) private view returns (bytes32) {\\n        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n    }\\n\\n    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n    }\\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    ) public virtual {\\n        if (block.timestamp > deadline) revert Expired();\\n\\n        bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline));\\n\\n        bytes32 hash = _hashTypedDataV4(structHash);\\n\\n        address signer = ECDSA.recover(hash, v, r, s);\\n        if (signer != owner) revert InvalidSignature();\\n\\n        _approve(owner, spender, value);\\n    }\\n\\n    function transferFrom(\\n        address from,\\n        address to,\\n        uint256 amount\\n    ) external returns (bool) {\\n        if (_allowance[from][msg.sender] != type(uint256).max) {\\n            _allowance[from][msg.sender] -= amount;\\n        }\\n        _transfer(from, to, amount);\\n        return true;\\n    }\\n\\n    function transfer(address to, uint256 amount) external override returns (bool) {\\n        _transfer(msg.sender, to, amount);\\n        return true;\\n    }\\n\\n    function _transfer(\\n        address from,\\n        address to,\\n        uint256 amount\\n    ) internal virtual returns (uint256 balanceOfFrom, uint256 balanceOfTo) {\\n        if (from == address(0)) revert InvalidSender();\\n        if (to == address(0)) revert InvalidReceiver();\\n\\n        uint256 balance = _balanceOf[from];\\n        if (balance < amount) revert NotEnoughBalance();\\n        unchecked {\\n            balanceOfFrom = balance - amount;\\n            balanceOfTo = _balanceOf[to] + amount;\\n            _balanceOf[from] = balanceOfFrom;\\n            _balanceOf[to] = balanceOfTo;\\n        }\\n\\n        emit Transfer(from, to, amount);\\n    }\\n\\n    function approve(address spender, uint256 amount) external override returns (bool) {\\n        _approve(msg.sender, spender, amount);\\n        return true;\\n    }\\n\\n    function _approve(\\n        address owner,\\n        address spender,\\n        uint256 amount\\n    ) internal virtual {\\n        if (owner == address(0)) revert InvalidOwner();\\n        if (spender == address(0)) revert InvalidSpender();\\n\\n        _allowance[owner][spender] = amount;\\n        emit Approval(owner, spender, amount);\\n    }\\n\\n    function _mint(address account, uint256 amount) internal virtual {\\n        if (account == address(0)) revert InvalidAccount();\\n\\n        _totalSupply += amount;\\n        unchecked {\\n            _balanceOf[account] += amount;\\n        }\\n\\n        emit Transfer(address(0), account, amount);\\n    }\\n\\n    function _burn(address account, uint256 amount) internal virtual {\\n        if (account == address(0)) revert InvalidAccount();\\n\\n        uint256 balance = _balanceOf[account];\\n        if (balance < amount) revert NotEnoughBalance();\\n        unchecked {\\n            _balanceOf[account] = balance - amount;\\n            _totalSupply -= amount;\\n        }\\n\\n        emit Transfer(account, address(0), amount);\\n    }\\n}\\n\",\"keccak256\":\"0x4b3dc734d2703c5ff91466a26069ac5fddda062c0d08f82d64cab5c4157b28fb\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/IFSushi.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\ninterface IFSushi is IERC20Metadata {\\n    error Forbidden();\\n    error Expired();\\n    error MintersLocked();\\n    error InvalidSignature();\\n\\n    event SetMinter(address indexed account, bool indexed isMinter);\\n    event LockMinters();\\n    event Checkpoint(uint256 lastCheckpoint);\\n\\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\\n\\n    function startWeek() external view returns (uint256);\\n\\n    function isMinter(address account) external view returns (bool);\\n\\n    function mintersLocked() external view returns (bool);\\n\\n    function nonces(address account) external view returns (uint256);\\n\\n    function totalSupplyDuring(uint256 time) external view returns (uint256);\\n\\n    function lastCheckpoint() external view returns (uint256);\\n\\n    function setMinter(address account, bool _isMinter) external;\\n\\n    function lockMinters() external;\\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    function mint(address to, uint256 amount) external;\\n\\n    function checkpointedTotalSupplyDuring(uint256 week) external returns (uint256);\\n\\n    function checkpoint() external;\\n}\\n\",\"keccak256\":\"0xcddcbb7b60b3644005a7c2c9ac10303b73a6e46a316312cd42c1fb393eb2f7e3\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/IFSushiBill.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\ninterface IFSushiBill is IERC20Metadata {\\n    error NoClaimableRewards();\\n\\n    event Deposit(address indexed account, uint256 amount, address indexed beneficiary);\\n    event Withdraw(address indexed account, uint256 amount, address indexed beneficiary);\\n    event Checkpoint();\\n    event UserCheckpoint(address indexed account);\\n    event ClaimRewards(address indexed account, address indexed beneficiary, uint256 amount);\\n\\n    function sousChef() external view returns (address);\\n\\n    function pid() external view returns (uint256);\\n\\n    function fToken() external view returns (address);\\n\\n    function points(uint256 week) external view returns (uint256);\\n\\n    function lastCheckpoint() external view returns (uint256 timestamp);\\n\\n    function userPoints(address account, uint256 week) external view returns (uint256);\\n\\n    function userLastCheckpoint(address account) external view returns (uint256 timestamp);\\n\\n    function claimedRewards(address account) external view returns (uint256);\\n\\n    function nextClaimableWeek(address account) external view returns (uint256);\\n\\n    function initialize(uint256 _pid, address _fToken) external;\\n\\n    function deposit(uint256 amount, address beneficiary) external;\\n\\n    function withdraw(uint256 amount, address beneficiary) external;\\n\\n    function claimRewards(address beneficiary) external;\\n\\n    function checkpoint() external;\\n\\n    function userCheckpoint(address account) external;\\n}\\n\",\"keccak256\":\"0x10aced848e0f105686eb4878940a81f0bceb201a56494c50d6204aef5dc62ec1\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/IFSushiKitchen.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity ^0.8.0;\\n\\ninterface IFSushiKitchen {\\n    error InvalidPid();\\n\\n    event AddPool(uint256 indexed pid);\\n    event UpdateWeight(uint256 indexed pid, uint256 weightPoints, uint256 totalWeightPoints);\\n\\n    function flashStrategyFactory() external view returns (address);\\n\\n    function totalWeightPointsLength() external view returns (uint256);\\n\\n    function weightPointsLength(uint256 pid) external view returns (uint256);\\n\\n    function totalWeightPoints() external view returns (uint256);\\n\\n    function weightPoints(uint256 pid) external view returns (uint256);\\n\\n    function totalWeightPointsAt(uint256 timestamp) external view returns (uint256);\\n\\n    function weightPointsAt(uint256 pid, uint256 timestamp) external view returns (uint256);\\n\\n    function relativeWeight(uint256 pid) external view returns (uint256);\\n\\n    function relativeWeightAt(uint256 pid, uint256 timestamp) external view returns (uint256);\\n\\n    function addPool(uint256 pid, uint256 points) external;\\n\\n    function updateWeight(uint256 pid, uint256 points) external;\\n\\n    function checkpoint(uint256 pid) external;\\n}\\n\",\"keccak256\":\"0xa16545dec947b746ab1a8a7e5d035080c9337e83db409ea38cd1fb10e0eba08d\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/IFSushiRestaurant.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity ^0.8.0;\\n\\ninterface IFSushiRestaurant {\\n    function startWeek() external view returns (uint256);\\n\\n    function totalAssets() external view returns (uint256);\\n\\n    function totalAssetsDuring(uint256 week) external view returns (uint256);\\n\\n    function lastCheckpoint() external view returns (uint256);\\n\\n    function checkpointedTotalAssets() external returns (uint256);\\n\\n    function checkpointedTotalAssetsDuring(uint256 week) external returns (uint256);\\n\\n    function checkpoint() external;\\n}\\n\",\"keccak256\":\"0xc9f77acbb7bd60b62503caf82313069efa9897b846266fa2abe047c3947ebafd\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/IFlashStrategy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IFlashStrategy {\\n    event BurnedFToken(address indexed _address, uint256 _tokenAmount, uint256 _yieldReturned);\\n\\n    // This is how principal will be deposited into the contract\\n    // The Flash protocol allows the strategy to specify how much\\n    // should be registered. This allows the strategy to manipulate (eg take fee)\\n    // on the principal if the strategy requires\\n    function depositPrincipal(uint256 _tokenAmount) external returns (uint256);\\n\\n    // This is how principal will be returned from the contract\\n    function withdrawPrincipal(uint256 _tokenAmount) external;\\n\\n    // Responsible for instant upfront yield. Takes fERC20 tokens specific to this\\n    // strategy. The strategy is responsible for returning some amount of principal tokens\\n    function burnFToken(\\n        uint256 _tokenAmount,\\n        uint256 _minimumReturned,\\n        address _yieldTo\\n    ) external returns (uint256);\\n\\n    // This should return the current total of all principal within the contract\\n    function getPrincipalBalance() external view returns (uint256);\\n\\n    // This should return the current total of all yield generated to date (including bootstrapped tokens)\\n    function getYieldBalance() external view returns (uint256);\\n\\n    // This should return the principal token address (eg DAI)\\n    function getPrincipalAddress() external view returns (address);\\n\\n    // View function which quotes how many principal tokens would be returned if x\\n    // fERC20 tokens are burned\\n    function quoteMintFToken(uint256 _tokenAmount, uint256 duration) external view returns (uint256);\\n\\n    // View function which quotes how many principal tokens would be returned if x\\n    // fERC20 tokens are burned\\n    // IMPORTANT NOTE: This should utilise bootstrap tokens if they exist\\n    // bootstrapped tokens are any principal tokens that exist within the smart contract\\n    function quoteBurnFToken(uint256 _tokenAmount) external view returns (uint256);\\n\\n    // The function to set the fERC20 address within the strategy\\n    function setFTokenAddress(address _fTokenAddress) external;\\n\\n    // This should return what the maximum stake duration is\\n    function getMaxStakeDuration() external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x8c72e893e2c11a247880fbacf8a0f761268797b789d269f7e0714c00efd5b988\",\"license\":\"MIT\"},\"contracts/interfaces/IFlashStrategySushiSwap.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IFlashStrategy.sol\\\";\\n\\ninterface IFlashStrategySushiSwap is IFlashStrategy {\\n    error Forbidden();\\n    error InvalidVault();\\n    error AmountTooLow();\\n    error InsufficientYield();\\n    error InsufficientTotalSupply();\\n\\n    function factory() external view returns (address);\\n\\n    function flashProtocol() external view returns (address);\\n\\n    function fToken() external view returns (address);\\n\\n    function sushi() external view returns (address);\\n\\n    function flpToken() external view returns (address);\\n\\n    function initialize(address _flashProtocol, address _flpToken) external;\\n}\\n\",\"keccak256\":\"0xa533e69b48a4816db0e03fbd23eb39bad5ab23e762602a326619fb92cb94a774\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/IFlashStrategySushiSwapFactory.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity ^0.8.0;\\n\\ninterface IFlashStrategySushiSwapFactory {\\n    error InvalidFee();\\n    error InvalidFeeRecipient();\\n    error FlashStrategySushiSwapCreated();\\n\\n    event UpdateStakeFeeBPS(uint256 fee);\\n    event UpdateFlashStakeFeeBPS(uint256 fee);\\n    event UpdateFeeRecipient(address feeRecipient);\\n    event CreateFlashStrategySushiSwap(uint256 pid, address strategy);\\n\\n    function flashProtocol() external view returns (address);\\n\\n    function flpTokenFactory() external view returns (address);\\n\\n    function feeRecipient() external view returns (address);\\n\\n    function getFlashStrategySushiSwap(uint256 pid) external view returns (address);\\n\\n    function predictFlashStrategySushiSwapAddress(uint256 pid) external view returns (address strategy);\\n\\n    function updateFeeRecipient(address _feeRecipient) external;\\n\\n    function createFlashStrategySushiSwap(uint256 pid) external returns (address strategy);\\n}\\n\",\"keccak256\":\"0xfa2ca9ab0537cf4b0cf915100d292d48201e905162c4ace0d552d3e5c1cec3f1\",\"license\":\"BUSL-1.1\"},\"contracts/interfaces/ISousChef.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity ^0.8.0;\\n\\ninterface ISousChef {\\n    error BillCreated();\\n    error InvalidRestaurant();\\n    error InvalidKitchen();\\n    error Forbidden();\\n\\n    event UpdateRestaurant(address indexed restaurant);\\n    event UpdateKitchen(address indexed kitchen);\\n    event CreateBill(uint256 indexed pid, address indexed bill);\\n    event Checkpoint();\\n\\n    function fSushi() external view returns (address);\\n\\n    function flashStrategyFactory() external view returns (address);\\n\\n    function startWeek() external view returns (uint256);\\n\\n    function restaurant() external view returns (address);\\n\\n    function kitchen() external view returns (address);\\n\\n    function getBill(uint256 pid) external view returns (address);\\n\\n    function weeklyRewards(uint256 week) external view returns (uint256);\\n\\n    function lastCheckpoint() external view returns (uint256);\\n\\n    function predictBillAddress(uint256 pid) external view returns (address bill);\\n\\n    function updateRestaurant(address _restaurant) external;\\n\\n    function updateKitchen(address _kitchen) external;\\n\\n    function createBill(uint256 pid) external returns (address strategy);\\n\\n    function checkpoint() external;\\n\\n    function mintFSushi(\\n        uint256 pid,\\n        address to,\\n        uint256 amount\\n    ) external;\\n}\\n\",\"keccak256\":\"0x005703330171f9ce003fc1cbea84b67d20889e7030d8f1ada00d7217367bba75\",\"license\":\"BUSL-1.1\"},\"contracts/libraries/DateUtils.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\n\\npragma solidity ^0.8.17;\\n\\nuint256 constant WEEK = 1 weeks;\\n\\nlibrary DateUtils {\\n    function toWeekNumber(uint256 timestamp) internal pure returns (uint256) {\\n        return timestamp / WEEK;\\n    }\\n\\n    function toTimestamp(uint256 weekNumber) internal pure returns (uint256) {\\n        return weekNumber * WEEK;\\n    }\\n}\\n\",\"keccak256\":\"0x1f6685854a201369d06bcbaf873bc0a39ac0c4f40a22f06a5ac86b9b2cf5542f\",\"license\":\"BUSL-1.1\"}},\"version\":1}",
  "bytecode": "0x610100346200023357601f620030f938819003918201601f1916830192916001600160401b03918285118486101762000238578160809285926040978852833981010312620002335762000053826200024e565b62000061602084016200024e565b906200007d6060620000758787016200024e565b95016200024e565b60009485549260018060a01b0319913383861617885588519460018060a01b039687938492833391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08d80a3608052168360015416176001551690600254161760025560a05262093a8042048060c052600181018082116200021f576005558452600460205269065a4da25d3016c000008585205561219880820190828210858311176200020b5790829162000f618339039084f0801562000201571691823b15620001fe5783519163da35a26f60e01b8352816004840152816024840152818360448183885af18015620001f457620001cd575b50505060e05251610cfd908162000264823960805181818160f10152818161045b0152610b02015260a0518181816104fb015261060b015260c05181818161020d0152610a95015260e05181818161056601526106650152f35b8211620001e05750825238808062000173565b634e487b7160e01b81526041600452602490fd5b85513d84823e3d90fd5b80fd5b84513d85823e3d90fd5b634e487b7160e01b86526041600452602486fd5b634e487b7160e01b86526011600452602486fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620002335756fe6040608081526004908136101561001557600080fd5b600091823560e01c9081630616752c146108aa5781631c8f0789146105c4578163376370ae1461052a578163654e6d77146104e65781636edb5aed14610417578163715018a6146103bd5781638da5cb5b14610395578163af364c051461036e578163b1cd06e61461033b578163ba0909dd14610312578163c2c4c5c1146102f3578163d32e81a5146102d4578163e87c6b0d14610259578163ed16805814610230578163eddf2d21146101f5578163f2fde38b14610124575063ffe066a0146100de57600080fd5b34610120578160031936011261012057517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5080fd5b9050346101f15760203660031901126101f15761013f610925565b9061014861093b565b6001600160a01b0391821692831561019f575050600054826bffffffffffffffffffffffff60a01b821617600055167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a380f35b906020608492519162461bcd60e51b8352820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152fd5b8280fd5b505034610120578160031936011261012057602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b50503461012057816003193601126101205760015490516001600160a01b039091168152602090f35b9050346101f15760203660031901126101f157610274610925565b61027c61093b565b6001600160a01b03169182156102c7575050600180546001600160a01b031916821790557f9b116eaa3d43b05c40d187b925c7adf53e0f5445bb842937ecd2348adcce3a178280a280f35b51633f78b32f60e11b8152fd5b5050346101205781600319360112610120576020906005549051908152f35b833461030f578060031936011261030f5761030c6109fe565b80f35b80fd5b50503461012057816003193601126101205760025490516001600160a01b039091168152602090f35b9050346101f15760203660031901126101f15735825260036020908152918190205490516001600160a01b039091168152f35b9050346101f15760203660031901126101f157602092818392358252845220549051908152f35b505034610120578160031936011261012057905490516001600160a01b039091168152602090f35b833461030f578060031936011261030f576103d661093b565b600080546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b838334610120576060366003190112610120576024356001600160a01b0381811692918390036104e15784358452600360205280828520541633036104d1579383947f00000000000000000000000000000000000000000000000000000000000000001692833b156104cd576044859283855196879485936340c10f1960e01b8552840152833560248401525af19081156104c457506104b45750f35b6104bd90610993565b61030f5780f35b513d84823e3d90fd5b8480fd5b8151631dd2188d60e31b81528590fd5b600080fd5b505034610120578160031936011261012057517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b82843461030f57602036600319011261030f5750605560436020938351903060388301526f5af43d82803e903d91602b57fd5bf3ff60248301527f00000000000000000000000000000000000000000000000000000000000000006014830152733d602d80600a3d3981f3363d3d373d3d3d363d7382523560588201526037600c8201206078820152012090519060018060a01b03168152f35b82843461030f576020928360031936011261012057803580835260038552838320546001600160a01b039290831661089c578451633750db2960e21b8152818101839052927f000000000000000000000000000000000000000000000000000000000000000081168785602481845afa9485156107d35786918991839761087d575b5083871615610820575b5050506e5af43d82803e903d91602b57fd5bf37f0000000000000000000000000000000000000000000000000000000000000000763d602d80600a3d3981f3363d3d373d3d3d363d7300000062ffffff8260881c1617875260781b17875280836037600988f5169384156107dd578782918489518094819363a8694e5760e01b8352165afa9081156107d35786916107a6575b50843b156107a257865163da35a26f60e01b8152928301849052166024820152838160448183875af1801561079857610765575b507ffe2bb598f3e02fe595703967f99b828e4ad5d5414e67c91f702e33bc4c5cae6d83948284955260038752808620846bffffffffffffffffffffffff60a01b825416179055519480a38152f35b82936107917ffe2bb598f3e02fe595703967f99b828e4ad5d5414e67c91f702e33bc4c5cae6d92610993565b9350610717565b85513d86823e3d90fd5b8580fd5b6107c69150883d8a116107cc575b6107be81836109bd565b8101906109df565b886106e3565b503d6107b4565b87513d88823e3d90fd5b865162461bcd60e51b8152808401899052601760248201527f455243313136373a2063726561746532206661696c65640000000000000000006044820152606490fd5b9091929550602488518094819363a9a00b8b60e01b835288888401525af1908115610873578591610856575b5092848789610650565b61086d9150873d89116107cc576107be81836109bd565b8761084c565b86513d87823e3d90fd5b610895919750823d84116107cc576107be81836109bd565b958a610646565b84516301e39a9760e61b8152fd5b9050346101f15760203660031901126101f1576108c5610925565b6108cd61093b565b6001600160a01b0316918215610918575050600280546001600160a01b031916821790557ff31c4869a9ef8dc42660d3730d22d14c8bb7cee703b1955ff59af6807051131a8280a280f35b5163613f10e760e01b8152fd5b600435906001600160a01b03821682036104e157565b6000546001600160a01b0316330361094f57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b67ffffffffffffffff81116109a757604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff8211176109a757604052565b908160209103126104e157516001600160a01b03811681036104e15790565b60055462093a80420490600190818301809311610a6b5780831115610a815760005b6102008110610a32575b505050600555565b80820190818311610a6b5781851115610a655781610a508593610a93565b90600052600460205260406000205501610a20565b50610a2a565b634e487b7160e01b600052601160045260246000fd5b505050565b91908203918211610a6b57565b7f000000000000000000000000000000000000000000000000000000000000000060028101808211610a6b57808310610cb6578214610ca7576000198201828111610a6b576040516327aecfff60e21b8152600481018290526000916020906001600160a01b038284602481887f000000000000000000000000000000000000000000000000000000000000000086165af1938415610c9c57908592918395610c66575b50906024849260015416916040519485938492636037e00360e01b845260048401525af1918215610c5b578492610c2d575b5050811590818015610c24575b15610bc9575050506002610b8d82935b8495610a86565b11610b9757505090565b909150606382029180830460631490151715610bb557506064900490565b634e487b7160e01b81526011600452602490fd5b610bd39083610a86565b9068a2a15d09519be000009180830292830403610c1057610bfc57600291610b8d910493610b86565b634e487b7160e01b83526012600452602483fd5b634e487b7160e01b84526011600452602484fd5b50808310610b76565b90809250813d8311610c54575b610c4481836109bd565b810103126101f157513880610b69565b503d610c3a565b6040513d86823e3d90fd5b8480929650819394503d8311610c95575b610c8181836109bd565b810103126104cd5751928491906024610b37565b503d610c77565b6040513d87823e3d90fd5b505068a2a15d09519be0000090565b50505069065a4da25d3016c000009056fea2646970667358221220280cef84225da674cf6dfa68abb0b6a37fba69093935e071e1845d0735ec434d64736f6c63430008110033608080604052346100165761217c908161001c8239f35b600080fdfe6040608081526004908136101561001557600080fd5b600091823560e01c908162f714ce14610ad057816306fdde0314610a38578163095ea7b314610a07578163103222a7146109cf57816318160ddd146109b0578163233b25641461098757816323b872dd14610907578163313ce567146108eb5781633644e515146108c75781635fab6541146108865781636e553f651461072257816370a08231146106ea5781637ecebe00146106b257816395d89b41146105d15781639799b4e7146105a95781639f3b598214610571578163a8694e5714610548578163a9059cbb14610515578163b07b709b146104f3578163bd834345146104bb578163c2c4c5c1146104a2578163d32e81a514610483578163d505accf14610304578163da35a26f146101dc57508063dd62ed3e14610194578063ef5cfb8c1461016c5763f10684541461014b57600080fd5b34610168578160031936011261016857602090600e549051908152f35b5080fd5b82346101915760203660031901126101915761018e610189610c41565b611976565b80f35b80fd5b5034610168578060031936011261016857806020926101b1610c41565b6101b9610c26565b6001600160a01b039182168352600b865283832091168252845220549051908152f35b9050346103005781600319360112610300576101f6610c26565b83549160ff8360081c1615928380946102f3575b80156102dc575b156102825760ff198116600117865561023392919084610271575b5035610dfe565b61023b575080f35b60207f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989161ff001984541684555160018152a180f35b61ffff19166101011786553861022c565b845162461bcd60e51b8152602081840152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b50303b1580156102115750600160ff821614610211565b50600160ff82161061020a565b8280fd5b8383346101685760e03660031901126101685761031f610c41565b610327610c26565b906044359260643560843560ff8116810361047f5781421161046f576001600160a01b03848116808952600c6020528489208054919492939290600019831461045c5760018301905585519060208201927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c984528688840152858a1660608401528a608084015260a083015260c082015260c0815260e0810181811067ffffffffffffffff82111761044957865251902061042891610420916103e8611dc6565b91875191602083019361190160f01b8552602284015260428301526042825261041082610cbb565b60c4359260a43592519020611f47565b919091611e2d565b160361043a575061018e9394506120a1565b51638baa579f60e01b81528590fd5b634e487b7160e01b8b5260418c5260248bfd5b634e487b7160e01b8b5260118c5260248bfd5b8251630407b05b60e31b81528890fd5b8680fd5b5050346101685781600319360112610168576020906011549051908152f35b833461019157806003193601126101915761018e6114bf565b5050346101685760203660031901126101685760209181906001600160a01b036104e3610c41565b1681526014845220549051908152f35b83346101915760203660031901126101915761018e610510610c41565b611595565b50503461016857806003193601126101685760209061053f610535610c41565b6024359033611fd6565b50505160018152f35b505034610168578160031936011261016857600f5490516001600160a01b039091168152602090f35b5050346101685760203660031901126101685760209181906001600160a01b03610599610c41565b1681526013845220549051908152f35b9050346103005760203660031901126103005760209282913581526010845220549051908152f35b505034610168578160031936011261016857805190826008546105f381610c57565b8085529160019180831690811561068a575060011461062d575b50505061061f82610629940383610d0f565b5191829182610d54565b0390f35b9450600885527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee35b8286106106725750505061061f826020610629958201019461060d565b80546020878701810191909152909501948101610655565b61062997508693506020925061061f94915060ff191682840152151560051b8201019461060d565b5050346101685760203660031901126101685760209181906001600160a01b036106da610c41565b168152600c845220549051908152f35b5050346101685760203660031901126101685760209181906001600160a01b03610712610c41565b168152600a845220549051908152f35b90503461030057816003193601126103005780359161073f610c26565b9161074933611595565b83610789575b50519182526001600160a01b03169033907fe31c7b8d08ee7db0afa68782e1028ef92305caeea8626633ad44d413e30f6b2f90602090a380f35b600f5482516323b872dd60e01b6020820152336024820152306044820152606480820187905281526001600160a01b0391821660a0820167ffffffffffffffff8111838210176108735785526107df9190611311565b338652600a6020526107f485848820546112ee565b338752600a6020528387205561080c856009546112ee565b908416918215610865575084610821916112ee565b600955808552600a602052818520848154019055847fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60208451878152a33861074f565b8351630da30f6560e31b8152fd5b634e487b7160e01b895260418552602489fd5b50503461016857806003193601126101685760209181906001600160a01b036108ad610c41565b168152601284528181206024358252845220549051908152f35b5050346101685781600319360112610168576020906108e4611dc6565b9051908152f35b5050346101685781600319360112610168576020905160128152f35b5050346101685760603660031901126101685761053f602092610928610c41565b610930610c26565b90846044359360018060a01b038316808252600b895282822033835289526000198383205403610963575b505050611fd6565b8152600b885281812033825288522061097d8482546114b2565b905584388061095b565b505034610168578160031936011261016857600d5490516001600160a01b039091168152602090f35b5050346101685781600319360112610168576020906009549051908152f35b5050346101685760203660031901126101685760209181906001600160a01b036109f7610c41565b1681526015845220549051908152f35b505034610168578060031936011261016857602090610a31610a27610c41565b60243590336120a1565b5160018152f35b50503461016857816003193601126101685780519082600754610a5a81610c57565b8085529160019180831690811561068a5750600114610a855750505061061f82610629940383610d0f565b9450600785526000805160206121278339815191525b828610610ab85750505061061f826020610629958201019461060d565b80546020878701810191909152909501948101610a9b565b905034610300578160031936011261030057803591610aed610c26565b91610af733611595565b83610b37575b50519182526001600160a01b03169033907f56c54ba9bd38d8fd62012e42c7ee564519b09763c426d331b3661b537ead19b290602090a380f35b338552602090600a8252610b4e85848820546114b2565b338752600a835283872055610b65856009546114b2565b6009553315610c1857338652600a82528286205490858210610c0a57509084610c0492338852600a8352038387205584600954036009558583518681527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef833392a3600f54835163a9059cbb60e01b928101929092526001600160a01b0385811660248401526044808401889052835216610bff82610cbb565b611311565b38610afd565b835163569d45cf60e11b8152fd5b8251630da30f6560e31b8152fd5b602435906001600160a01b0382168203610c3c57565b600080fd5b600435906001600160a01b0382168203610c3c57565b90600182811c92168015610c87575b6020831014610c7157565b634e487b7160e01b600052602260045260246000fd5b91607f1691610c66565b67ffffffffffffffff8111610ca557604052565b634e487b7160e01b600052604160045260246000fd5b6080810190811067ffffffffffffffff821117610ca557604052565b6040810190811067ffffffffffffffff821117610ca557604052565b60c0810190811067ffffffffffffffff821117610ca557604052565b90601f8019910116810190811067ffffffffffffffff821117610ca557604052565b60005b838110610d445750506000910152565b8181015183820152602001610d34565b60409160208252610d748151809281602086015260208686019101610d31565b601f01601f1916010190565b67ffffffffffffffff8111610ca557601f01601f191660200190565b602081830312610c3c5780519067ffffffffffffffff8211610c3c570181601f82011215610c3c578051610dcf81610d80565b92610ddd6040519485610d0f565b81845260208284010111610c3c57610dfb9160208085019101610d31565b90565b6001600160a01b039091169081156112ea5760409081516306fdde0360e01b8152600081600481875afa9081156112df576000916112c4575b50610e82603584518093740233630b9b41029bab9b434902134b636103337b91605d1b6020830152610e728151809260208686019101610d31565b8101036015810184520182610d0f565b82516395d89b4160e01b815290600082600481885afa9182156112b957600092611294575b50610ede602185518094600f60fb1b6020830152610ece8151809260208686019101610d31565b8101036001810185520183610d0f565b835191610eea83610cd7565b60018352603160f81b602084015260ff60005460081c161561123c57815167ffffffffffffffff8111610ca557610f22600754610c57565b601f81116111cf575b50806020601f821160011461115c57600091611151575b508160011b916000199060031b1c1916176007555b80519067ffffffffffffffff8211610ca5578190610f76600854610c57565b601f81116110e1575b50602090601f831160011461105b57600092611050575b50508160011b916000199060031b1c1916176008555b60208151910120906020815191012081600455806005554660025583519060208201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f9586855283015260608201524660808201523060a082015260a0815261101581610cf3565b5190206001556bffffffffffffffffffffffff60a01b91308360035416176003556006553382600d541617600d55600e55600f541617600f55565b015190503880610f96565b600860009081527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee39350601f198516905b8181106110c957509084600195949392106110b0575b505050811b01600855610fac565b015160001960f88460031b161c191690553880806110a2565b9293602060018192878601518155019501930161108c565b90915060086000527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3601f840160051c81019160208510611147575b90601f859493920160051c01905b8181106111385750610f7f565b6000815584935060010161112b565b909150819061111d565b905083015138610f42565b915060076000526000805160206121278339815191526000925b601f19831684106111b7576001935082601f1981161061119e575b5050811b01600755610f57565b85015160001960f88460031b161c191690553880611191565b85810151825560209384019360019092019101611176565b6007600052601f820160051c600080516020612127833981519152019060208310611226575b601f0160051c60008051602061212783398151915201905b81811061121a5750610f2b565b6000815560010161120d565b60008051602061212783398151915291506111f5565b845162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b6112b29192503d806000833e6112aa8183610d0f565b810190610d9c565b9038610ea7565b84513d6000823e3d90fd5b6112d991503d806000833e6112aa8183610d0f565b38610e37565b83513d6000823e3d90fd5b5050565b919082018092116112fb57565b634e487b7160e01b600052601160045260246000fd5b60018060a01b03169061138e60405161132981610cd7565b6020938482527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564858301526000808587829751910182855af13d15611419573d9161137383610d80565b926113816040519485610d0f565b83523d868885013e61141d565b80518061139c575b50505050565b81849181010312610168578201519081159182150361019157506113c257808080611396565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b6060915b9192901561147f5750815115611431575090565b3b1561143a5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156114925750805190602001fd5b60405162461bcd60e51b81529081906114ae9060048301610d54565b0390fd5b919082039182116112fb57565b600d546000906001600160a01b0316803b156101685781809160046040518094819363c2c4c5c160e01b83525af1801561158a5761153e575b507f645b050443403fa34bc992a1617954b1b340b2fba133227ee552911014e7fbb39060115461152a8160095461163b565b4211611535575b80a1565b42601155611531565b67ffffffffffffffff8111611576576040527f645b050443403fa34bc992a1617954b1b340b2fba133227ee552911014e7fbb36114f8565b634e487b7160e01b82526041600452602482fd5b6040513d84823e3d90fd5b61159d6114bf565b60018060a01b03167f0103c5dd597c7d8e78094c4dc6d76c405761e7dcd771d4a4826d5e1c484d8c3f60008281526013602052604081205460126020526115f28160408420600a6020526040852054906117e2565b42116115fd575b80a2565b82815260136020524260408220556115f9565b9062093a80918281029281840414901517156112fb57565b818102929181159184041417156112fb57565b9081156112ea57801561175f575b62093a80918282049160005b6102008110611666575b5050505050565b61167081856112ee565b9061167a82611610565b868101908181116112fb57804211156117575781421061170457508390826116d4576116ac600194926116b2926114b2565b86611628565b9060005260106020526116cb60406000209182546112ee565b90555b01611655565b505085840284810487036112fb5760019260005260106020526116fd60406000209182546112ee565b90556116ce565b9150506117259291955061172b945080821160001461175057505b426114b2565b90611628565b90600052601060205261174460406000209182546112ee565b9055388080808061165f565b905061171f565b50505061165f565b50600d5460405163eddf2d2160e01b815290602090829060049082906001600160a01b03165afa80156117d6576000906117a3575b61179e9150611610565b611649565b6020823d82116117ce575b816117bb60209383610d0f565b81010312610191575061179e9051611794565b3d91506117ae565b6040513d6000823e3d90fd5b81156119715782156118f8575b62093a80908184049260005b610200811061180d575b505050505050565b61181781866112ee565b9061182182611610565b858101908181116112fb57804211156118f0578142106118a9575087908261187a5761185360019492611859926114b2565b85611628565b906000528460205261187160406000209182546112ee565b90555b016117fb565b505084830283810486036112fb57600192600052846020526118a260406000209182546112ee565b9055611874565b92979496506118cc955092936117259350919050808211156117505750426114b2565b916000526020526118e360406000209182546112ee565b9055388080808080611805565b505050611805565b600d5460405163eddf2d2160e01b8152919350602090829060049082906001600160a01b03165afa80156117d65760009061193e575b6119389150611610565b916117ef565b6020823d8211611969575b8161195660209383610d0f565b810103126101915750611938905161192e565b3d9150611949565b505050565b61197f33611595565b6000338152601560205260408120549062093a8042048214611971578115611d57575b600d54600e5460405163ba0909dd60e01b81529094909390916001600160a01b031690602085600481855afa948515611d4c578495611d08575b506001600160a01b0385163b15611d04576040516376b25d5960e11b8152600481018790528481602481836001600160a01b038b165af18015611cf957611ce6575b509390839484925b6102008410611b06575b50505050338252601560205262093a804204604083205582611a525750505050565b601460205260408220611a668482546112ee565b9055600d546001600160a01b031693843b15610300578291606483926040519485938492636edb5aed60e01b8452600484015260018060a01b0316988960248401528860448401525af1801561158a57611af2575b50506040519081527f9aa05b3d70a9e3e2f004f039648839560576334fb45c81f91b6db03ad9e2efc960203392a338808080611396565b611afc8291610c91565b6101915780611abb565b90919295611b1487846112ee565b8062093a8042041115611cdf5760405163af364c0560e01b81526004810182905290602082602481895afa918215611cd4578892611ca0575b5060018101808211611c8c578062093a8081020462093a801481151715611c8c576040516336d4a1e160e21b8152600481018c905262093a809190910260248201526020816044816001600160a01b0389165afa908115611c81578991611c4f575b508189526010928360205260408a205415600014611be25750505050611bd860019187906112ee565b9601929190611a26565b90611bec91611628565b91338952611c0f6012938460205260408b20848c5260205260408b205490611628565b9189526020526040882054918215611c3b575091670de0b6b3a7640000611bd8926001940404906112ee565b634e487b7160e01b60005260045260246000fd5b90506020813d602011611c79575b81611c6a60209383610d0f565b81010312610c3c575138611baf565b3d9150611c5d565b6040513d8b823e3d90fd5b634e487b7160e01b89526011600452602489fd5b9091506020813d602011611ccc575b81611cbc60209383610d0f565b81010312610c3c57519038611b4d565b3d9150611caf565b6040513d8a823e3d90fd5b5095611a30565b611cf290949194610c91565b9238611a1e565b6040513d87823e3d90fd5b8380fd5b9094506020813d602011611d44575b81611d2460209383610d0f565b81010312611d0457516001600160a01b0381168103611d045793386119dc565b3d9150611d17565b6040513d86823e3d90fd5b600d5460405163eddf2d2160e01b8152919250602090829060049082906001600160a01b03165afa90811561158a578291611d94575b50906119a2565b90506020813d602011611dbe575b81611daf60209383610d0f565b81010312610168575138611d8d565b3d9150611da2565b6003546001600160a01b0316301480611e22575b15611de55760015490565b6006546004546005546040519160208301938452604083015260608201524660808201523060a082015260a08152611e1c81610cf3565b51902090565b506002544614611dda565b6005811015611f315780611e3e5750565b60018103611e8b5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606490fd5b60028103611ed85760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606490fd5b600314611ee157565b60405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608490fd5b634e487b7160e01b600052602160045260246000fd5b9291907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311611fca5791608094939160ff602094604051948552168484015260408301526060820152600093849182805260015afa15611fbd5781516001600160a01b03811615611fb7579190565b50600190565b50604051903d90823e3d90fd5b50505050600090600390565b929192611fe281611595565b611feb82611595565b6001600160a01b0390811691821561208f5716801561207d57600091808352600a6020526040948584205481811061206c5781877fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef936020930396868152600a84528282822054019981878c93528982822055888152205551908152a39190565b865163569d45cf60e11b8152600490fd5b604051631e4ec46b60e01b8152600490fd5b604051636edaef2f60e11b8152600490fd5b6001600160a01b0390811691821561211457169182156121025760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259183600052600b8252604060002085600052825280604060002055604051908152a3565b604051635461585f60e01b8152600490fd5b6040516349e27cff60e01b8152600490fdfea66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688a2646970667358221220fe7d6ce5186611d1e90b9dbcad6354eaf4b01cc2bc5f477bedd7d200375fdded64736f6c63430008110033",
  "deployedBytecode": "0x6040608081526004908136101561001557600080fd5b600091823560e01c9081630616752c146108aa5781631c8f0789146105c4578163376370ae1461052a578163654e6d77146104e65781636edb5aed14610417578163715018a6146103bd5781638da5cb5b14610395578163af364c051461036e578163b1cd06e61461033b578163ba0909dd14610312578163c2c4c5c1146102f3578163d32e81a5146102d4578163e87c6b0d14610259578163ed16805814610230578163eddf2d21146101f5578163f2fde38b14610124575063ffe066a0146100de57600080fd5b34610120578160031936011261012057517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5080fd5b9050346101f15760203660031901126101f15761013f610925565b9061014861093b565b6001600160a01b0391821692831561019f575050600054826bffffffffffffffffffffffff60a01b821617600055167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a380f35b906020608492519162461bcd60e51b8352820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152fd5b8280fd5b505034610120578160031936011261012057602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b50503461012057816003193601126101205760015490516001600160a01b039091168152602090f35b9050346101f15760203660031901126101f157610274610925565b61027c61093b565b6001600160a01b03169182156102c7575050600180546001600160a01b031916821790557f9b116eaa3d43b05c40d187b925c7adf53e0f5445bb842937ecd2348adcce3a178280a280f35b51633f78b32f60e11b8152fd5b5050346101205781600319360112610120576020906005549051908152f35b833461030f578060031936011261030f5761030c6109fe565b80f35b80fd5b50503461012057816003193601126101205760025490516001600160a01b039091168152602090f35b9050346101f15760203660031901126101f15735825260036020908152918190205490516001600160a01b039091168152f35b9050346101f15760203660031901126101f157602092818392358252845220549051908152f35b505034610120578160031936011261012057905490516001600160a01b039091168152602090f35b833461030f578060031936011261030f576103d661093b565b600080546001600160a01b0319811682556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b838334610120576060366003190112610120576024356001600160a01b0381811692918390036104e15784358452600360205280828520541633036104d1579383947f00000000000000000000000000000000000000000000000000000000000000001692833b156104cd576044859283855196879485936340c10f1960e01b8552840152833560248401525af19081156104c457506104b45750f35b6104bd90610993565b61030f5780f35b513d84823e3d90fd5b8480fd5b8151631dd2188d60e31b81528590fd5b600080fd5b505034610120578160031936011261012057517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b82843461030f57602036600319011261030f5750605560436020938351903060388301526f5af43d82803e903d91602b57fd5bf3ff60248301527f00000000000000000000000000000000000000000000000000000000000000006014830152733d602d80600a3d3981f3363d3d373d3d3d363d7382523560588201526037600c8201206078820152012090519060018060a01b03168152f35b82843461030f576020928360031936011261012057803580835260038552838320546001600160a01b039290831661089c578451633750db2960e21b8152818101839052927f000000000000000000000000000000000000000000000000000000000000000081168785602481845afa9485156107d35786918991839761087d575b5083871615610820575b5050506e5af43d82803e903d91602b57fd5bf37f0000000000000000000000000000000000000000000000000000000000000000763d602d80600a3d3981f3363d3d373d3d3d363d7300000062ffffff8260881c1617875260781b17875280836037600988f5169384156107dd578782918489518094819363a8694e5760e01b8352165afa9081156107d35786916107a6575b50843b156107a257865163da35a26f60e01b8152928301849052166024820152838160448183875af1801561079857610765575b507ffe2bb598f3e02fe595703967f99b828e4ad5d5414e67c91f702e33bc4c5cae6d83948284955260038752808620846bffffffffffffffffffffffff60a01b825416179055519480a38152f35b82936107917ffe2bb598f3e02fe595703967f99b828e4ad5d5414e67c91f702e33bc4c5cae6d92610993565b9350610717565b85513d86823e3d90fd5b8580fd5b6107c69150883d8a116107cc575b6107be81836109bd565b8101906109df565b886106e3565b503d6107b4565b87513d88823e3d90fd5b865162461bcd60e51b8152808401899052601760248201527f455243313136373a2063726561746532206661696c65640000000000000000006044820152606490fd5b9091929550602488518094819363a9a00b8b60e01b835288888401525af1908115610873578591610856575b5092848789610650565b61086d9150873d89116107cc576107be81836109bd565b8761084c565b86513d87823e3d90fd5b610895919750823d84116107cc576107be81836109bd565b958a610646565b84516301e39a9760e61b8152fd5b9050346101f15760203660031901126101f1576108c5610925565b6108cd61093b565b6001600160a01b0316918215610918575050600280546001600160a01b031916821790557ff31c4869a9ef8dc42660d3730d22d14c8bb7cee703b1955ff59af6807051131a8280a280f35b5163613f10e760e01b8152fd5b600435906001600160a01b03821682036104e157565b6000546001600160a01b0316330361094f57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b67ffffffffffffffff81116109a757604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff8211176109a757604052565b908160209103126104e157516001600160a01b03811681036104e15790565b60055462093a80420490600190818301809311610a6b5780831115610a815760005b6102008110610a32575b505050600555565b80820190818311610a6b5781851115610a655781610a508593610a93565b90600052600460205260406000205501610a20565b50610a2a565b634e487b7160e01b600052601160045260246000fd5b505050565b91908203918211610a6b57565b7f000000000000000000000000000000000000000000000000000000000000000060028101808211610a6b57808310610cb6578214610ca7576000198201828111610a6b576040516327aecfff60e21b8152600481018290526000916020906001600160a01b038284602481887f000000000000000000000000000000000000000000000000000000000000000086165af1938415610c9c57908592918395610c66575b50906024849260015416916040519485938492636037e00360e01b845260048401525af1918215610c5b578492610c2d575b5050811590818015610c24575b15610bc9575050506002610b8d82935b8495610a86565b11610b9757505090565b909150606382029180830460631490151715610bb557506064900490565b634e487b7160e01b81526011600452602490fd5b610bd39083610a86565b9068a2a15d09519be000009180830292830403610c1057610bfc57600291610b8d910493610b86565b634e487b7160e01b83526012600452602483fd5b634e487b7160e01b84526011600452602484fd5b50808310610b76565b90809250813d8311610c54575b610c4481836109bd565b810103126101f157513880610b69565b503d610c3a565b6040513d86823e3d90fd5b8480929650819394503d8311610c95575b610c8181836109bd565b810103126104cd5751928491906024610b37565b503d610c77565b6040513d87823e3d90fd5b505068a2a15d09519be0000090565b50505069065a4da25d3016c000009056fea2646970667358221220280cef84225da674cf6dfa68abb0b6a37fba69093935e071e1845d0735ec434d64736f6c63430008110033",
  "devdoc": {
    "kind": "dev",
    "methods": {
      "checkpoint()": {
        "details": "if this function doesn't get called for 512 weeks (around 9.8 years) this contract breaks"
      },
      "owner()": {
        "details": "Returns the address of the current owner."
      },
      "renounceOwnership()": {
        "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
      },
      "transferOwnership(address)": {
        "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
      }
    },
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {
      "kitchen()": {
        "notice": "address of IFSushiKitchen"
      },
      "lastCheckpoint()": {
        "notice": "weeklyRewards is guaranteed to be correct before this week (exclusive)"
      },
      "restaurant()": {
        "notice": "address of IFSushiRestaurant"
      },
      "weeklyRewards(uint256)": {
        "notice": "how much rewards to be minted at the week"
      }
    },
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 7,
        "contract": "contracts/SousChef.sol:SousChef",
        "label": "_owner",
        "offset": 0,
        "slot": "0",
        "type": "t_address"
      },
      {
        "astId": 13710,
        "contract": "contracts/SousChef.sol:SousChef",
        "label": "restaurant",
        "offset": 0,
        "slot": "1",
        "type": "t_address"
      },
      {
        "astId": 13714,
        "contract": "contracts/SousChef.sol:SousChef",
        "label": "kitchen",
        "offset": 0,
        "slot": "2",
        "type": "t_address"
      },
      {
        "astId": 13719,
        "contract": "contracts/SousChef.sol:SousChef",
        "label": "getBill",
        "offset": 0,
        "slot": "3",
        "type": "t_mapping(t_uint256,t_address)"
      },
      {
        "astId": 13725,
        "contract": "contracts/SousChef.sol:SousChef",
        "label": "weeklyRewards",
        "offset": 0,
        "slot": "4",
        "type": "t_mapping(t_uint256,t_uint256)"
      },
      {
        "astId": 13729,
        "contract": "contracts/SousChef.sol:SousChef",
        "label": "lastCheckpoint",
        "offset": 0,
        "slot": "5",
        "type": "t_uint256"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_mapping(t_uint256,t_address)": {
        "encoding": "mapping",
        "key": "t_uint256",
        "label": "mapping(uint256 => address)",
        "numberOfBytes": "32",
        "value": "t_address"
      },
      "t_mapping(t_uint256,t_uint256)": {
        "encoding": "mapping",
        "key": "t_uint256",
        "label": "mapping(uint256 => uint256)",
        "numberOfBytes": "32",
        "value": "t_uint256"
      },
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      }
    }
  }
}