{
  "address": "0x0596Dd13e29Ea4573eefC64530a4395718Fb0A17",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "contract ITaskTreasury",
          "name": "_oldTreasury",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "FundsDeposited",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "receiver",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "initiator",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "FundsWithdrawn",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "user",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "executor",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "token",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "fees",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "service",
          "type": "address"
        }
      ],
      "name": "LogDeductFees",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "maxFee",
          "type": "uint256"
        }
      ],
      "name": "UpdatedMaxFee",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "service",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "bool",
          "name": "add",
          "type": "bool"
        }
      ],
      "name": "UpdatedService",
      "type": "event"
    },
    {
      "inputs": [],
      "name": "MIN_SHARES_IN_TREASURY",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_receiver",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_token",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_amount",
          "type": "uint256"
        }
      ],
      "name": "depositFunds",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_user",
          "type": "address"
        }
      ],
      "name": "getCreditTokensByUser",
      "outputs": [
        {
          "internalType": "address[]",
          "name": "",
          "type": "address[]"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_user",
          "type": "address"
        }
      ],
      "name": "getTotalCreditTokensByUser",
      "outputs": [
        {
          "internalType": "address[]",
          "name": "",
          "type": "address[]"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "getWhitelistedServices",
      "outputs": [
        {
          "internalType": "address[]",
          "name": "",
          "type": "address[]"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "_maxFee",
          "type": "uint256"
        }
      ],
      "name": "initialize",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "maxFee",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "oldTreasury",
      "outputs": [
        {
          "internalType": "contract ITaskTreasury",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "name": "shares",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "name": "totalShares",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_user",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_token",
          "type": "address"
        }
      ],
      "name": "totalUserTokenBalance",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "_newMaxFee",
          "type": "uint256"
        }
      ],
      "name": "updateMaxFee",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_service",
          "type": "address"
        },
        {
          "internalType": "bool",
          "name": "_add",
          "type": "bool"
        }
      ],
      "name": "updateWhitelistedService",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_user",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_token",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_amount",
          "type": "uint256"
        }
      ],
      "name": "useFunds",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_user",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_token",
          "type": "address"
        }
      ],
      "name": "userTokenBalance",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address payable",
          "name": "_receiver",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "_token",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_amount",
          "type": "uint256"
        }
      ],
      "name": "withdrawFunds",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "stateMutability": "payable",
      "type": "receive"
    }
  ],
  "transactionHash": "0x3f971f63e9d24bbeed52c5fd5865e64b57b7f4f1820ddc778a7cd1be52972fa4",
  "receipt": {
    "to": null,
    "from": "0xF1108379d71ff2A785899F4C36010f841F1Fea04",
    "contractAddress": "0x0596Dd13e29Ea4573eefC64530a4395718Fb0A17",
    "transactionIndex": 42,
    "gasUsed": "3324571",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0x000306c90000103a73526a875cc390e81973116d372253fe1f3b9f58bd677a3a",
    "transactionHash": "0x3f971f63e9d24bbeed52c5fd5865e64b57b7f4f1820ddc778a7cd1be52972fa4",
    "logs": [],
    "blockNumber": 57969002,
    "cumulativeGasUsed": "11299578",
    "status": 1,
    "byzantium": true
  },
  "args": ["0x0000000000000000000000000000000000000000"],
  "numDeployments": 1,
  "solcInputHash": "77f620c289a408fcb75c281cb93af647",
  "metadata": "{\"compiler\":{\"version\":\"0.8.14+commit.80d49f37\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"_oldTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"}],\"name\":\"LogDeductFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedMaxFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"UpdatedService\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_SHARES_IN_TREASURY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getTotalCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"shares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"totalUserTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"updateMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"}],\"name\":\"updateWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"getTotalCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"totalUserTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"updateMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"updateWhitelistedService(address,bool)\":{\"params\":{\"_add\":\"Add to whitelist if true, else remove from whitelist\",\"_service\":\"Service to add or remove from whitelist\"}},\"useFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"userTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"stateVariables\":{\"_tokens\":{\"details\":\"tracks the tokens deposited by users\"},\"shares\":{\"details\":\"tracks token shares of users\"},\"totalShares\":{\"details\":\"tracks total shares of tokens\"}},\"version\":1},\"userdoc\":{\"events\":{\"FundsDeposited(address,address,uint256)\":{\"notice\":\"Events ///\"}},\"kind\":\"user\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user.\"},\"getTotalCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user across treasuries.\"},\"getWhitelistedServices()\":{\"notice\":\"Get list of services that can call useFunds.\"},\"totalUserTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user across treasuries\"},\"updateMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"updateWhitelistedService(address,bool)\":{\"notice\":\"Add or remove service that can call useFunds. Gelato Governance\"},\"useFunds(address,address,uint256)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Gelato Automate\"},\"userTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":\"TaskTreasuryUpgradable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have 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 * 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 initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n    /**\\n     * @dev Indicates that the contract has been initialized.\\n     */\\n    bool 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 Modifier to protect an initializer function from being invoked twice.\\n     */\\n    modifier initializer() {\\n        // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n        // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n        // contract may have been reentered.\\n        require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n        bool isTopLevelCall = !_initializing;\\n        if (isTopLevelCall) {\\n            _initializing = true;\\n            _initialized = true;\\n        }\\n\\n        _;\\n\\n        if (isTopLevelCall) {\\n            _initializing = false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n     * {initializer} modifier, directly or indirectly.\\n     */\\n    modifier onlyInitializing() {\\n        require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n        _;\\n    }\\n\\n    function _isConstructor() private view returns (bool) {\\n        return !AddressUpgradeable.isContract(address(this));\\n    }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n    // Booleans are more expensive than uint256 or any type that takes up a full\\n    // word because each write operation emits an extra SLOAD to first read the\\n    // slot's contents, replace the bits taken up by the boolean, and then write\\n    // back. This is the compiler's defense against contract upgrades and\\n    // pointer aliasing, and it cannot be disabled.\\n\\n    // The values being non-zero value makes deployment a bit more expensive,\\n    // but in exchange the refund on every call to nonReentrant will be lower in\\n    // amount. Since refunds are capped to a percentage of the total\\n    // transaction's gas, it is best to keep them low in cases like this one, to\\n    // increase the likelihood of the full refund coming into effect.\\n    uint256 private constant _NOT_ENTERED = 1;\\n    uint256 private constant _ENTERED = 2;\\n\\n    uint256 private _status;\\n\\n    function __ReentrancyGuard_init() internal onlyInitializing {\\n        __ReentrancyGuard_init_unchained();\\n    }\\n\\n    function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n        _status = _NOT_ENTERED;\\n    }\\n\\n    /**\\n     * @dev Prevents a contract from calling itself, directly or indirectly.\\n     * Calling a `nonReentrant` function from another `nonReentrant`\\n     * function is not supported. It is possible to prevent this from happening\\n     * by making the `nonReentrant` function external, and making it call a\\n     * `private` function that does the actual work.\\n     */\\n    modifier nonReentrant() {\\n        // On the first call to nonReentrant, _notEntered will be true\\n        require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n        // Any calls to nonReentrant after this point will fail\\n        _status = _ENTERED;\\n\\n        _;\\n\\n        // By storing the original value once again, a refund is triggered (see\\n        // https://eips.ethereum.org/EIPS/eip-2200)\\n        _status = _NOT_ENTERED;\\n    }\\n    uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf3a9b766b0d0456f79d9402db4b49bb16c414f3f9d65244475c0704b6c66dcf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n    /**\\n     * @dev Returns true if `account` is a contract.\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * It is unsafe to assume that an address for which this function returns\\n     * false is an externally-owned account (EOA) and not a contract.\\n     *\\n     * Among others, `isContract` will return false for the following\\n     * types of addresses:\\n     *\\n     *  - an externally-owned account\\n     *  - a contract in construction\\n     *  - an address where a contract will be created\\n     *  - an address where a contract lived, but was destroyed\\n     * ====\\n     */\\n    function isContract(address account) internal view returns (bool) {\\n        // This method relies on extcodesize, which returns 0 for contracts in\\n        // construction, since the code is only stored at the end of the\\n        // constructor execution.\\n\\n        uint256 size;\\n        assembly {\\n            size := extcodesize(account)\\n        }\\n        return size > 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 functionCall(target, data, \\\"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        require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\\n        return verifyCallResult(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        require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.staticcall(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n     * revert reason 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            // 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\\n                assembly {\\n                    let returndata_size := mload(returndata)\\n                    revert(add(32, returndata), returndata_size)\\n                }\\n            } else {\\n                revert(errorMessage);\\n            }\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.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 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    /**\\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\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.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    /**\\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\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.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 functionCall(target, data, \\\"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        require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\\n        return verifyCallResult(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        require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.staticcall(data);\\n        return verifyCallResult(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        require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n        (bool success, bytes memory returndata) = target.delegatecall(data);\\n        return verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n     * revert reason 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            // 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\\n                assembly {\\n                    let returndata_size := mload(returndata)\\n                    revert(add(32, returndata), returndata_size)\\n                }\\n            } else {\\n                revert(errorMessage);\\n            }\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n *     // Add the library methods\\n *     using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n *     // Declare a set state variable\\n *     EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n    // To implement this library for multiple types with as little code\\n    // repetition as possible, we write it in terms of a generic Set type with\\n    // bytes32 values.\\n    // The Set implementation uses private functions, and user-facing\\n    // implementations (such as AddressSet) are just wrappers around the\\n    // underlying Set.\\n    // This means that we can only create new EnumerableSets for types that fit\\n    // in bytes32.\\n\\n    struct Set {\\n        // Storage of set values\\n        bytes32[] _values;\\n        // Position of the value in the `values` array, plus 1 because index 0\\n        // means a value is not in the set.\\n        mapping(bytes32 => uint256) _indexes;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function _add(Set storage set, bytes32 value) private returns (bool) {\\n        if (!_contains(set, value)) {\\n            set._values.push(value);\\n            // The value is stored at length-1, but we add 1 to all indexes\\n            // and use 0 as a sentinel value\\n            set._indexes[value] = set._values.length;\\n            return true;\\n        } else {\\n            return false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\\n        // We read and store the value's index to prevent multiple reads from the same storage slot\\n        uint256 valueIndex = set._indexes[value];\\n\\n        if (valueIndex != 0) {\\n            // Equivalent to contains(set, value)\\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\\n            // This modifies the order of the array, as noted in {at}.\\n\\n            uint256 toDeleteIndex = valueIndex - 1;\\n            uint256 lastIndex = set._values.length - 1;\\n\\n            if (lastIndex != toDeleteIndex) {\\n                bytes32 lastvalue = set._values[lastIndex];\\n\\n                // Move the last value to the index where the value to delete is\\n                set._values[toDeleteIndex] = lastvalue;\\n                // Update the index for the moved value\\n                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n            }\\n\\n            // Delete the slot where the moved value was stored\\n            set._values.pop();\\n\\n            // Delete the index for the deleted slot\\n            delete set._indexes[value];\\n\\n            return true;\\n        } else {\\n            return false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n        return set._indexes[value] != 0;\\n    }\\n\\n    /**\\n     * @dev Returns the number of values on the set. O(1).\\n     */\\n    function _length(Set storage set) private view returns (uint256) {\\n        return set._values.length;\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n        return set._values[index];\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function _values(Set storage set) private view returns (bytes32[] memory) {\\n        return set._values;\\n    }\\n\\n    // Bytes32Set\\n\\n    struct Bytes32Set {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n        return _add(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n        return _remove(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n        return _contains(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(Bytes32Set storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n        return _at(set._inner, index);\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n        return _values(set._inner);\\n    }\\n\\n    // AddressSet\\n\\n    struct AddressSet {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(AddressSet storage set, address value) internal returns (bool) {\\n        return _add(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(AddressSet storage set, address value) internal returns (bool) {\\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(AddressSet storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n        return address(uint160(uint256(_at(set._inner, index))));\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(AddressSet storage set) internal view returns (address[] memory) {\\n        bytes32[] memory store = _values(set._inner);\\n        address[] memory result;\\n\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n\\n    // UintSet\\n\\n    struct UintSet {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\\n        return _add(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n        return _remove(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n        return _contains(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Returns the number of values on the set. O(1).\\n     */\\n    function length(UintSet storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n    /**\\n     * @dev Returns the value stored at position `index` in the set. O(1).\\n     *\\n     * Note that there are no guarantees on the ordering of values inside the\\n     * array, and it may change when more values are added or removed.\\n     *\\n     * Requirements:\\n     *\\n     * - `index` must be strictly less than {length}.\\n     */\\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n        return uint256(_at(set._inner, index));\\n    }\\n\\n    /**\\n     * @dev Return the entire set in an array\\n     *\\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n     */\\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\\n        bytes32[] memory store = _values(set._inner);\\n        uint256[] memory result;\\n\\n        assembly {\\n            result := store\\n        }\\n\\n        return result;\\n    }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/functions/FUtils.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n    SafeERC20,\\n    IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n    address payable _to,\\n    address _paymentToken,\\n    uint256 _amount\\n) {\\n    if (_paymentToken == ETH) {\\n        (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n        require(success, \\\"_transfer: ETH transfer failed\\\");\\n    } else {\\n        SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n    }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/IERC20Extended.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.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 IERC20Extended {\\n    function decimals() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves `amount` tokens from the caller's account to `to`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address to, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender)\\n        external\\n        view\\n        returns (uint256);\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Moves `amount` tokens from `from` to `to` using the\\n     * allowance mechanism. `amount` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(\\n        address from,\\n        address to,\\n        uint256 amount\\n    ) external returns (bool);\\n\\n    /**\\n     * @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(\\n        address indexed owner,\\n        address indexed spender,\\n        uint256 value\\n    );\\n}\\n\",\"keccak256\":\"0xdfa1185ee541ba2ef0ef3cfe61fc277233ae557a90d2cb013546e01df7364695\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasury {\\n    /// @notice Events ///\\n    event FundsDeposited(\\n        address indexed sender,\\n        address indexed token,\\n        uint256 indexed amount\\n    );\\n\\n    event FundsWithdrawn(\\n        address indexed receiver,\\n        address indexed initiator,\\n        address indexed token,\\n        uint256 amount\\n    );\\n\\n    /// @notice External functions ///\\n\\n    function depositFunds(\\n        address receiver,\\n        address token,\\n        uint256 amount\\n    ) external payable;\\n\\n    function withdrawFunds(\\n        address payable receiver,\\n        address token,\\n        uint256 amount\\n    ) external;\\n\\n    function useFunds(\\n        address token,\\n        uint256 amount,\\n        address user\\n    ) external;\\n\\n    function addWhitelistedService(address service) external;\\n\\n    function removeWhitelistedService(address service) external;\\n\\n    /// @notice External view functions ///\\n\\n    function gelato() external view returns (address);\\n\\n    function getCreditTokensByUser(address user)\\n        external\\n        view\\n        returns (address[] memory);\\n\\n    function getWhitelistedServices() external view returns (address[] memory);\\n\\n    function userTokenBalance(address user, address token)\\n        external\\n        view\\n        returns (uint256);\\n}\\n\",\"keccak256\":\"0xd3a9a4df2a2cb7b86802e1e7e31803283199e98955733c2744873e943497b1c4\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n    /// @notice Events ///\\n\\n    event FundsDeposited(\\n        address indexed sender,\\n        address indexed token,\\n        uint256 indexed amount\\n    );\\n\\n    event FundsWithdrawn(\\n        address indexed receiver,\\n        address indexed initiator,\\n        address indexed token,\\n        uint256 amount\\n    );\\n\\n    event LogDeductFees(\\n        address indexed user,\\n        address indexed executor,\\n        address indexed token,\\n        uint256 fees,\\n        address service\\n    );\\n\\n    event UpdatedService(address indexed service, bool add);\\n\\n    event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n    /// @notice External functions ///\\n\\n    function depositFunds(\\n        address receiver,\\n        address token,\\n        uint256 amount\\n    ) external payable;\\n\\n    function withdrawFunds(\\n        address payable receiver,\\n        address token,\\n        uint256 amount\\n    ) external;\\n\\n    function useFunds(\\n        address user,\\n        address token,\\n        uint256 amount\\n    ) external;\\n\\n    function updateMaxFee(uint256 _newMaxFee) external;\\n\\n    function updateWhitelistedService(address service, bool isWhitelist)\\n        external;\\n\\n    /// @notice External view functions ///\\n\\n    function getCreditTokensByUser(address user)\\n        external\\n        view\\n        returns (address[] memory);\\n\\n    function getTotalCreditTokensByUser(address user)\\n        external\\n        view\\n        returns (address[] memory);\\n\\n    function getWhitelistedServices() external view returns (address[] memory);\\n\\n    function totalUserTokenBalance(address user, address token)\\n        external\\n        view\\n        returns (uint256);\\n\\n    function userTokenBalance(address user, address token)\\n        external\\n        view\\n        returns (uint256);\\n}\\n\",\"keccak256\":\"0x4b692a8a7e0e365cbed8f03704a97d7ffa06736a96f1a2206983bb4e8ead9b75\",\"license\":\"MIT\"},\"contracts/libraries/LibShares.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\nimport {ETH} from \\\"../functions/FUtils.sol\\\";\\nimport {IERC20Extended} from \\\"../interfaces/IERC20Extended.sol\\\";\\n\\nlibrary LibShares {\\n    function contractBalance(address _token) internal view returns (uint256) {\\n        if (_token == ETH) {\\n            return address(this).balance;\\n        } else {\\n            return IERC20Extended(_token).balanceOf(address(this));\\n        }\\n    }\\n\\n    function tokenToShares(\\n        address _token,\\n        uint256 _tokenAmount,\\n        uint256 _totalShares,\\n        uint256 _totalBalance\\n    ) internal view returns (uint256) {\\n        uint256 sharesOfToken;\\n\\n        uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\\n        uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\\n\\n        // credit shares equivalent to token amount\\n        if (_totalShares == 0 || _totalBalance == 0) {\\n            sharesOfToken = tokenIn18Dp;\\n        } else {\\n            sharesOfToken = divCeil(\\n                tokenIn18Dp * _totalShares,\\n                totalBalanceIn18Dp\\n            );\\n        }\\n\\n        return sharesOfToken;\\n    }\\n\\n    function to18Dp(address _token, uint256 _amount)\\n        internal\\n        view\\n        returns (uint256)\\n    {\\n        if (_token == ETH) return _amount;\\n        uint256 decimals = IERC20Extended(_token).decimals();\\n\\n        if (decimals < 18) {\\n            return _amount * 10**(18 - decimals);\\n        } else {\\n            return _amount / 10**(decimals - 18);\\n        }\\n    }\\n\\n    function sharesToToken(\\n        uint256 _shares,\\n        uint256 _totalShares,\\n        uint256 _totalBalance\\n    ) internal pure returns (uint256) {\\n        uint256 tokenOfShares;\\n\\n        if (_totalShares == 0 || _totalBalance == 0) {\\n            tokenOfShares = 0;\\n        } else {\\n            tokenOfShares = (_shares * _totalBalance) / _totalShares;\\n        }\\n\\n        return tokenOfShares;\\n    }\\n\\n    function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\\n        uint256 remainder = x % y;\\n        uint256 result;\\n\\n        if (remainder == 0) {\\n            result = x / y;\\n        } else {\\n            result = ((x - remainder) + y) / y;\\n        }\\n\\n        return result;\\n    }\\n}\\n\",\"keccak256\":\"0x77587737bfa126a9d0830b2e73e27d15d75dd7aaebefc851b237166e0eb1745f\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n    EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n    IERC20,\\n    SafeERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n    ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport {\\n    Initializable\\n} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {_transfer, ETH} from \\\"../functions/FUtils.sol\\\";\\nimport {Proxied} from \\\"../vendor/proxy/EIP173/Proxied.sol\\\";\\nimport {ITaskTreasury} from \\\"../interfaces/ITaskTreasury.sol\\\";\\nimport {\\n    ITaskTreasuryUpgradable\\n} from \\\"../interfaces/ITaskTreasuryUpgradable.sol\\\";\\nimport {LibShares} from \\\"../libraries/LibShares.sol\\\";\\n\\ncontract TaskTreasuryUpgradable is\\n    ITaskTreasuryUpgradable,\\n    Proxied,\\n    Initializable,\\n    ReentrancyGuardUpgradeable\\n{\\n    using EnumerableSet for EnumerableSet.AddressSet;\\n    using SafeERC20 for IERC20;\\n\\n    ITaskTreasury public immutable oldTreasury;\\n    uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\\n    uint256 public maxFee;\\n\\n    ///@dev tracks token shares of users\\n    mapping(address => mapping(address => uint256)) public shares;\\n\\n    ///@dev tracks total shares of tokens\\n    mapping(address => uint256) public totalShares;\\n\\n    ///@dev tracks the tokens deposited by users\\n    mapping(address => EnumerableSet.AddressSet) internal _tokens;\\n\\n    EnumerableSet.AddressSet internal _whitelistedServices;\\n\\n    modifier onlyWhitelistedServices() {\\n        require(\\n            _whitelistedServices.contains(msg.sender),\\n            \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n        );\\n        _;\\n    }\\n\\n    constructor(ITaskTreasury _oldTreasury) {\\n        oldTreasury = _oldTreasury;\\n    }\\n\\n    receive() external payable {\\n        depositFunds(msg.sender, ETH, msg.value);\\n    }\\n\\n    function initialize(uint256 _maxFee) external initializer {\\n        maxFee = _maxFee;\\n        __ReentrancyGuard_init();\\n    }\\n\\n    /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Automate\\n    /// @param _user Address of user whose balance will be deducted\\n    /// @param _token Token to be used for payment by users\\n    /// @param _amount Amount to be deducted\\n    function useFunds(\\n        address _user,\\n        address _token,\\n        uint256 _amount\\n    ) external override onlyWhitelistedServices {\\n        if (maxFee != 0)\\n            require(maxFee >= _amount, \\\"TaskTreasury: Overcharged\\\");\\n\\n        uint256 balanceInOld = _oldTreasuryUserTokenBalance(_user, _token);\\n\\n        if (_amount <= balanceInOld) {\\n            oldTreasury.useFunds(_token, _amount, _user);\\n        } else {\\n            if (balanceInOld > 0)\\n                oldTreasury.useFunds(_token, balanceInOld, _user);\\n\\n            _pay(_user, _token, _amount - balanceInOld);\\n        }\\n\\n        emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\\n    }\\n\\n    /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n    /// @param _newMaxFee New Max Fee to charge\\n    function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\\n        maxFee = _newMaxFee;\\n\\n        emit UpdatedMaxFee(_newMaxFee);\\n    }\\n\\n    /// @notice Add or remove service that can call useFunds. Gelato Governance\\n    /// @param _service Service to add or remove from whitelist\\n    /// @param _add Add to whitelist if true, else remove from whitelist\\n    function updateWhitelistedService(address _service, bool _add)\\n        external\\n        override\\n        onlyProxyAdmin\\n    {\\n        if (_add) {\\n            _whitelistedServices.add(_service);\\n        } else {\\n            _whitelistedServices.remove(_service);\\n        }\\n\\n        emit UpdatedService(_service, _add);\\n    }\\n\\n    /// @notice Get list of services that can call useFunds.\\n    function getWhitelistedServices()\\n        external\\n        view\\n        override\\n        returns (address[] memory)\\n    {\\n        return _whitelistedServices.values();\\n    }\\n\\n    // solhint-disable max-line-length\\n    /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n    /// @param _receiver Address receiving the credits\\n    /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n    /// @param _amount Amount to be credited\\n    function depositFunds(\\n        address _receiver,\\n        address _token,\\n        uint256 _amount\\n    ) public payable override nonReentrant {\\n        uint256 depositAmount;\\n        uint256 totalBalance;\\n        if (_token == ETH) {\\n            depositAmount = msg.value;\\n        } else {\\n            require(msg.value == 0, \\\"TaskTreasury: No ETH\\\");\\n            IERC20 token = IERC20(_token);\\n\\n            uint256 preBalance = token.balanceOf(address(this));\\n            token.safeTransferFrom(msg.sender, address(this), _amount);\\n            uint256 postBalance = token.balanceOf(address(this));\\n\\n            depositAmount = postBalance - preBalance;\\n        }\\n\\n        totalBalance = LibShares.contractBalance(_token) - depositAmount;\\n\\n        _creditUser(_receiver, _token, depositAmount, totalBalance);\\n\\n        emit FundsDeposited(_receiver, _token, depositAmount);\\n    }\\n\\n    /// @notice Function to withdraw Funds back to the _receiver\\n    /// @param _receiver Address receiving the credits\\n    /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n    /// @param _amount Amount to be credited\\n    function withdrawFunds(\\n        address payable _receiver,\\n        address _token,\\n        uint256 _amount\\n    ) public override nonReentrant {\\n        _deductUser(msg.sender, _token, _amount);\\n\\n        _transfer(_receiver, _token, _amount);\\n\\n        emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\\n    }\\n\\n    /// @notice Helper func to get all deposited tokens by a user.\\n    /// @param _user User to get the balances from\\n    function getCreditTokensByUser(address _user)\\n        public\\n        view\\n        override\\n        returns (address[] memory)\\n    {\\n        return _tokens[_user].values();\\n    }\\n\\n    /// @notice Helper func to get all deposited tokens by a user across treasuries.\\n    /// @param _user User to get the balances from\\n    function getTotalCreditTokensByUser(address _user)\\n        public\\n        view\\n        override\\n        returns (address[] memory)\\n    {\\n        address[] memory tokensInNew = _tokens[_user].values();\\n        address[] memory tokensInOld = _oldTreasuryGetCreditTokensByUser(_user);\\n\\n        uint256 tokensInOldOnlyLength;\\n        for (uint256 i; i < tokensInOld.length; i++) {\\n            if (!_tokens[_user].contains(tokensInOld[i])) {\\n                tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\\n                tokensInOldOnlyLength++;\\n            }\\n        }\\n\\n        uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\\n        address[] memory tokens = new address[](uniqTokensLength);\\n\\n        for (uint256 i; i < uniqTokensLength; i++) {\\n            if (i < tokensInNew.length) {\\n                tokens[i] = tokensInNew[i];\\n            } else {\\n                uint256 j = i - tokensInNew.length;\\n                tokens[i] = tokensInOld[j];\\n            }\\n        }\\n\\n        return tokens;\\n    }\\n\\n    /// @notice Get balance of a token owned by user\\n    /// @param _user User to get balance from\\n    /// @param _token Token to check balance of\\n    function userTokenBalance(address _user, address _token)\\n        public\\n        view\\n        override\\n        returns (uint256)\\n    {\\n        uint256 totalBalance = LibShares.contractBalance(_token);\\n        return\\n            LibShares.sharesToToken(\\n                shares[_user][_token],\\n                totalShares[_token],\\n                totalBalance\\n            );\\n    }\\n\\n    /// @notice Get balance of a token owned by user across treasuries\\n    /// @param _user User to get balance from\\n    /// @param _token Token to check balance of\\n    function totalUserTokenBalance(address _user, address _token)\\n        public\\n        view\\n        override\\n        returns (uint256)\\n    {\\n        uint256 balanceInNew = userTokenBalance(_user, _token);\\n        uint256 balanceInOld = _oldTreasuryUserTokenBalance(_user, _token);\\n\\n        uint256 balance = balanceInNew + balanceInOld;\\n\\n        return balance;\\n    }\\n\\n    function _creditUser(\\n        address _user,\\n        address _token,\\n        uint256 _amount,\\n        uint256 _totalBalance\\n    ) internal {\\n        uint256 sharesTotal = totalShares[_token];\\n        uint256 sharesToCredit = LibShares.tokenToShares(\\n            _token,\\n            _amount,\\n            sharesTotal,\\n            _totalBalance\\n        );\\n\\n        if (sharesTotal == 0)\\n            require(\\n                sharesToCredit >= MIN_SHARES_IN_TREASURY,\\n                \\\"TaskTreasury: Require MIN_SHARES_IN_TREASURY\\\"\\n            );\\n\\n        require(sharesToCredit > 0, \\\"TaskTreasury: Zero shares to credit\\\");\\n\\n        shares[_user][_token] += sharesToCredit;\\n        totalShares[_token] = sharesTotal + sharesToCredit;\\n\\n        _tokens[_user].add(_token);\\n    }\\n\\n    function _deductUser(\\n        address _user,\\n        address _token,\\n        uint256 _amount\\n    ) internal {\\n        uint256 totalBalance = LibShares.contractBalance(_token);\\n        uint256 sharesTotal = totalShares[_token];\\n        uint256 sharesToCharge = LibShares.tokenToShares(\\n            _token,\\n            _amount,\\n            sharesTotal,\\n            totalBalance\\n        );\\n\\n        require(\\n            sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\\n            \\\"TaskTreasury: Below MIN_SHARES_IN_TREASURY\\\"\\n        );\\n\\n        uint256 sharesOfUser = shares[_user][_token];\\n\\n        shares[_user][_token] = sharesOfUser - sharesToCharge;\\n        totalShares[_token] = sharesTotal - sharesToCharge;\\n\\n        if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\\n    }\\n\\n    function _pay(\\n        address _user,\\n        address _token,\\n        uint256 _amount\\n    ) internal {\\n        address admin = _proxyAdmin();\\n        require(_user != admin, \\\"TaskTreasury: No proxy admin\\\");\\n\\n        uint256 totalBalance = LibShares.contractBalance(_token);\\n        uint256 sharesToPay = LibShares.tokenToShares(\\n            _token,\\n            _amount,\\n            totalShares[_token],\\n            totalBalance\\n        );\\n\\n        require(\\n            shares[_user][_token] >= sharesToPay,\\n            \\\"TaskTreasury: Not enough funds\\\"\\n        );\\n        shares[_user][_token] -= sharesToPay;\\n        shares[admin][_token] += sharesToPay;\\n    }\\n\\n    function _oldTreasuryGetCreditTokensByUser(address _user)\\n        private\\n        view\\n        returns (address[] memory)\\n    {\\n        if (address(oldTreasury) != address(0)) {\\n            return oldTreasury.getCreditTokensByUser(_user);\\n        }\\n\\n        return new address[](0);\\n    }\\n\\n    function _oldTreasuryUserTokenBalance(address _user, address _token)\\n        private\\n        view\\n        returns (uint256)\\n    {\\n        if (address(oldTreasury) != address(0)) {\\n            return oldTreasury.userTokenBalance(_user, _token);\\n        }\\n\\n        return 0;\\n    }\\n}\\n\",\"keccak256\":\"0x2ad0227526640b04ea2475a16d7335fb00f6175bd246ea2615c9894389100ad6\",\"license\":\"UNLICENSED\"},\"contracts/vendor/proxy/EIP173/Proxied.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nabstract contract Proxied {\\n    /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\\n    /// It also allows these functions to be called inside a contructor\\n    /// even if the contract is meant to be used without proxy\\n    modifier proxied() {\\n        address proxyAdminAddress = _proxyAdmin();\\n        // With hardhat-deploy proxies\\n        // the proxyAdminAddress is zero only for the implementation contract\\n        // if the implementation contract want to be used as a standalone/immutable contract\\n        // it simply has to execute the `proxied` function\\n        // This ensure the proxyAdminAddress is never zero post deployment\\n        // And allow you to keep the same code for both proxied contract and immutable contract\\n        if (proxyAdminAddress == address(0)) {\\n            // ensure can not be called twice when used outside of proxy : no admin\\n            // solhint-disable-next-line security/no-inline-assembly\\n            assembly {\\n                sstore(\\n                    0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n                    0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\\n                )\\n            }\\n        } else {\\n            require(msg.sender == proxyAdminAddress);\\n        }\\n        _;\\n    }\\n\\n    modifier onlyProxyAdmin() {\\n        require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n        _;\\n    }\\n\\n    function _proxyAdmin() internal view returns (address adminAddress) {\\n        // solhint-disable-next-line security/no-inline-assembly\\n        assembly {\\n            adminAddress := sload(\\n                0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n            )\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x428ced1961d42c505a3e49d90498f92f4b0df8537e5ffa59f14ba375d99150a1\",\"license\":\"GPL-3.0\"}},\"version\":1}",
  "bytecode": "[encoded data, 31106 characters]",
  "deployedBytecode": "[encoded data, 30386 characters]",
  "devdoc": {
    "kind": "dev",
    "methods": {
      "depositFunds(address,address,uint256)": {
        "params": {
          "_amount": "Amount to be credited",
          "_receiver": "Address receiving the credits",
          "_token": "Token to be credited, use \"0xeeee....\" for ETH"
        }
      },
      "getCreditTokensByUser(address)": {
        "params": {
          "_user": "User to get the balances from"
        }
      },
      "getTotalCreditTokensByUser(address)": {
        "params": {
          "_user": "User to get the balances from"
        }
      },
      "totalUserTokenBalance(address,address)": {
        "params": {
          "_token": "Token to check balance of",
          "_user": "User to get balance from"
        }
      },
      "updateMaxFee(uint256)": {
        "params": {
          "_newMaxFee": "New Max Fee to charge"
        }
      },
      "updateWhitelistedService(address,bool)": {
        "params": {
          "_add": "Add to whitelist if true, else remove from whitelist",
          "_service": "Service to add or remove from whitelist"
        }
      },
      "useFunds(address,address,uint256)": {
        "params": {
          "_amount": "Amount to be deducted",
          "_token": "Token to be used for payment by users",
          "_user": "Address of user whose balance will be deducted"
        }
      },
      "userTokenBalance(address,address)": {
        "params": {
          "_token": "Token to check balance of",
          "_user": "User to get balance from"
        }
      },
      "withdrawFunds(address,address,uint256)": {
        "params": {
          "_amount": "Amount to be credited",
          "_receiver": "Address receiving the credits",
          "_token": "Token to be credited, use \"0xeeee....\" for ETH"
        }
      }
    },
    "stateVariables": {
      "_tokens": {
        "details": "tracks the tokens deposited by users"
      },
      "shares": {
        "details": "tracks token shares of users"
      },
      "totalShares": {
        "details": "tracks total shares of tokens"
      }
    },
    "version": 1
  },
  "userdoc": {
    "events": {
      "FundsDeposited(address,address,uint256)": {
        "notice": "Events ///"
      }
    },
    "kind": "user",
    "methods": {
      "depositFunds(address,address,uint256)": {
        "notice": "Function to deposit Funds which will be used to execute transactions on various services"
      },
      "getCreditTokensByUser(address)": {
        "notice": "Helper func to get all deposited tokens by a user."
      },
      "getTotalCreditTokensByUser(address)": {
        "notice": "Helper func to get all deposited tokens by a user across treasuries."
      },
      "getWhitelistedServices()": {
        "notice": "Get list of services that can call useFunds."
      },
      "totalUserTokenBalance(address,address)": {
        "notice": "Get balance of a token owned by user across treasuries"
      },
      "updateMaxFee(uint256)": {
        "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)"
      },
      "updateWhitelistedService(address,bool)": {
        "notice": "Add or remove service that can call useFunds. Gelato Governance"
      },
      "useFunds(address,address,uint256)": {
        "notice": "Function called by whitelisted services to handle payments, e.g. Gelato Automate"
      },
      "userTokenBalance(address,address)": {
        "notice": "Get balance of a token owned by user"
      },
      "withdrawFunds(address,address,uint256)": {
        "notice": "Function to withdraw Funds back to the _receiver"
      }
    },
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 6,
        "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable",
        "label": "_initialized",
        "offset": 0,
        "slot": "0",
        "type": "t_bool"
      },
      {
        "astId": 9,
        "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable",
        "label": "_initializing",
        "offset": 1,
        "slot": "0",
        "type": "t_bool"
      },
      {
        "astId": 87,
        "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable",
        "label": "_status",
        "offset": 0,
        "slot": "1",
        "type": "t_uint256"
      },
      {
        "astId": 130,
        "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable",
        "label": "__gap",
        "offset": 0,
        "slot": "2",
        "type": "t_array(t_uint256)49_storage"
      },
      {
        "astId": 9316,
        "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable",
        "label": "maxFee",
        "offset": 0,
        "slot": "51",
        "type": "t_uint256"
      },
      {
        "astId": 9323,
        "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable",
        "label": "shares",
        "offset": 0,
        "slot": "52",
        "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
      },
      {
        "astId": 9328,
        "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable",
        "label": "totalShares",
        "offset": 0,
        "slot": "53",
        "type": "t_mapping(t_address,t_uint256)"
      },
      {
        "astId": 9334,
        "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable",
        "label": "_tokens",
        "offset": 0,
        "slot": "54",
        "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)"
      },
      {
        "astId": 9337,
        "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable",
        "label": "_whitelistedServices",
        "offset": 0,
        "slot": "55",
        "type": "t_struct(AddressSet)1540_storage"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_array(t_bytes32)dyn_storage": {
        "base": "t_bytes32",
        "encoding": "dynamic_array",
        "label": "bytes32[]",
        "numberOfBytes": "32"
      },
      "t_array(t_uint256)49_storage": {
        "base": "t_uint256",
        "encoding": "inplace",
        "label": "uint256[49]",
        "numberOfBytes": "1568"
      },
      "t_bool": {
        "encoding": "inplace",
        "label": "bool",
        "numberOfBytes": "1"
      },
      "t_bytes32": {
        "encoding": "inplace",
        "label": "bytes32",
        "numberOfBytes": "32"
      },
      "t_mapping(t_address,t_mapping(t_address,t_uint256))": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => mapping(address => uint256))",
        "numberOfBytes": "32",
        "value": "t_mapping(t_address,t_uint256)"
      },
      "t_mapping(t_address,t_struct(AddressSet)1540_storage)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => struct EnumerableSet.AddressSet)",
        "numberOfBytes": "32",
        "value": "t_struct(AddressSet)1540_storage"
      },
      "t_mapping(t_address,t_uint256)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => uint256)",
        "numberOfBytes": "32",
        "value": "t_uint256"
      },
      "t_mapping(t_bytes32,t_uint256)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => uint256)",
        "numberOfBytes": "32",
        "value": "t_uint256"
      },
      "t_struct(AddressSet)1540_storage": {
        "encoding": "inplace",
        "label": "struct EnumerableSet.AddressSet",
        "members": [
          {
            "astId": 1539,
            "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable",
            "label": "_inner",
            "offset": 0,
            "slot": "0",
            "type": "t_struct(Set)1239_storage"
          }
        ],
        "numberOfBytes": "64"
      },
      "t_struct(Set)1239_storage": {
        "encoding": "inplace",
        "label": "struct EnumerableSet.Set",
        "members": [
          {
            "astId": 1234,
            "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable",
            "label": "_values",
            "offset": 0,
            "slot": "0",
            "type": "t_array(t_bytes32)dyn_storage"
          },
          {
            "astId": 1238,
            "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable",
            "label": "_indexes",
            "offset": 0,
            "slot": "1",
            "type": "t_mapping(t_bytes32,t_uint256)"
          }
        ],
        "numberOfBytes": "64"
      },
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      }
    }
  }
}
