{
  "address": "0x03856b7fD5a166557fA0d33Da91A59d7e3a6e598",
  "abi": [
    {
      "inputs": [],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "loopsLimit",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "requiredLoops",
          "type": "uint256"
        }
      ],
      "name": "MaxLoopsLimitExceeded",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "sender",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "calledContract",
          "type": "address"
        },
        {
          "internalType": "string",
          "name": "methodSignature",
          "type": "string"
        }
      ],
      "name": "Unauthorized",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "VenusERC4626Factory__ERC4626AlreadyExists",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "VenusERC4626Factory__InvalidVToken",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ZeroAddressNotAllowed",
      "type": "error"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "contract VTokenInterface",
          "name": "vToken",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "contract ERC4626Upgradeable",
          "name": "vault",
          "type": "address"
        }
      ],
      "name": "CreateERC4626",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "uint8",
          "name": "version",
          "type": "uint8"
        }
      ],
      "name": "Initialized",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "oldMaxLoopsLimit",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "newmaxLoopsLimit",
          "type": "uint256"
        }
      ],
      "name": "MaxLoopsLimitUpdated",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "oldAccessControlManager",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "newAccessControlManager",
          "type": "address"
        }
      ],
      "name": "NewAccessControlManager",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "previousOwner",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "OwnershipTransferStarted",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "previousOwner",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "OwnershipTransferred",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "oldRecipient",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "newRecipient",
          "type": "address"
        }
      ],
      "name": "RewardRecipientUpdated",
      "type": "event"
    },
    {
      "inputs": [],
      "name": "SALT",
      "outputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "acceptOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "accessControlManager",
      "outputs": [
        {
          "internalType": "contract IAccessControlManagerV8",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "beacon",
      "outputs": [
        {
          "internalType": "contract UpgradeableBeacon",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "vToken",
          "type": "address"
        }
      ],
      "name": "computeVaultAddress",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "vToken",
          "type": "address"
        }
      ],
      "name": "createERC4626",
      "outputs": [
        {
          "internalType": "contract ERC4626Upgradeable",
          "name": "vault",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "vToken",
          "type": "address"
        }
      ],
      "name": "createdVaults",
      "outputs": [
        {
          "internalType": "contract ERC4626Upgradeable",
          "name": "vault",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "accessControlManager",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "poolRegistryAddress",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "rewardRecipientAddress",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "venusERC4626Implementation",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "loopsLimitNumber",
          "type": "uint256"
        }
      ],
      "name": "initialize",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "maxLoopsLimit",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "pendingOwner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "poolRegistry",
      "outputs": [
        {
          "internalType": "contract PoolRegistryInterface",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "renounceOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "rewardRecipient",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "accessControlManager_",
          "type": "address"
        }
      ],
      "name": "setAccessControlManager",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "loopsLimit",
          "type": "uint256"
        }
      ],
      "name": "setMaxLoopsLimit",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "newRecipient",
          "type": "address"
        }
      ],
      "name": "setRewardRecipient",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "transferOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ],
  "transactionHash": "0xfe95cab45cbea3707186e62b72ea43f9fcde09121e65719fba1ddf8eb901008c",
  "receipt": {
    "to": null,
    "from": "0x4c65A0342C8E632209147345c973A18f6A8c1979",
    "contractAddress": "0x03856b7fD5a166557fA0d33Da91A59d7e3a6e598",
    "transactionIndex": 1,
    "gasUsed": "1693464",
    "logsBloom": "0x00000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000040000000000000000000000000000000000000008000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0xd2fd6ae0ddceb46d4145c04c32ef662f93b01821a87b7d72480a716e7d0229ef",
    "transactionHash": "0xfe95cab45cbea3707186e62b72ea43f9fcde09121e65719fba1ddf8eb901008c",
    "logs": [
      {
        "transactionIndex": 1,
        "blockNumber": 64181955,
        "transactionHash": "0xfe95cab45cbea3707186e62b72ea43f9fcde09121e65719fba1ddf8eb901008c",
        "address": "0x03856b7fD5a166557fA0d33Da91A59d7e3a6e598",
        "topics": ["0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498"],
        "data": "0x00000000000000000000000000000000000000000000000000000000000000ff",
        "logIndex": 0,
        "blockHash": "0xd2fd6ae0ddceb46d4145c04c32ef662f93b01821a87b7d72480a716e7d0229ef"
      }
    ],
    "blockNumber": 64181955,
    "cumulativeGasUsed": "1737315",
    "status": 1,
    "byzantium": true
  },
  "args": [],
  "numDeployments": 1,
  "solcInputHash": "b12f8d4761c962054dccd57bfa484d96",
  "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loopsLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredLoops\",\"type\":\"uint256\"}],\"name\":\"MaxLoopsLimitExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"calledContract\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"methodSignature\",\"type\":\"string\"}],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VenusERC4626Factory__ERC4626AlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VenusERC4626Factory__InvalidVToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract VTokenInterface\",\"name\":\"vToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"contract ERC4626Upgradeable\",\"name\":\"vault\",\"type\":\"address\"}],\"name\":\"CreateERC4626\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldMaxLoopsLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newmaxLoopsLimit\",\"type\":\"uint256\"}],\"name\":\"MaxLoopsLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessControlManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessControlManager\",\"type\":\"address\"}],\"name\":\"NewAccessControlManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferStarted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldRecipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newRecipient\",\"type\":\"address\"}],\"name\":\"RewardRecipientUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SALT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accessControlManager\",\"outputs\":[{\"internalType\":\"contract IAccessControlManagerV8\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"beacon\",\"outputs\":[{\"internalType\":\"contract UpgradeableBeacon\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"computeVaultAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"createERC4626\",\"outputs\":[{\"internalType\":\"contract ERC4626Upgradeable\",\"name\":\"vault\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vToken\",\"type\":\"address\"}],\"name\":\"createdVaults\",\"outputs\":[{\"internalType\":\"contract ERC4626Upgradeable\",\"name\":\"vault\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessControlManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"poolRegistryAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rewardRecipientAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"venusERC4626Implementation\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"loopsLimitNumber\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxLoopsLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolRegistry\",\"outputs\":[{\"internalType\":\"contract PoolRegistryInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardRecipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"}],\"name\":\"setAccessControlManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"loopsLimit\",\"type\":\"uint256\"}],\"name\":\"setMaxLoopsLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newRecipient\",\"type\":\"address\"}],\"name\":\"setRewardRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"CreateERC4626(address,address)\":{\"params\":{\"vToken\":\"The vToken used by the vault\",\"vault\":\"The vault that was created\"}},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"RewardRecipientUpdated(address,address)\":{\"params\":{\"newRecipient\":\"The new reward recipient address.\",\"oldRecipient\":\"The previous reward recipient address.\"}}},\"kind\":\"dev\",\"methods\":{\"acceptOwnership()\":{\"details\":\"The new owner accepts the ownership transfer.\"},\"computeVaultAddress(address)\":{\"params\":{\"vToken\":\"The vToken address\"},\"returns\":{\"_0\":\"The precomputed vault address\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createERC4626(address)\":{\"custom:error\":\"ZeroAddressNotAllowed is thrown when the vToken address is zeroVenusERC4626Factory__InvalidVToken is thrown when the provided vToken is not supported by the poolRegistryVenusERC4626Factory__ERC4626AlreadyExists is thrown when this factory already created a VenusERC4626 for the provided vToken\",\"custom:event\":\"CreateERC4626 is emitted when the ERC4626 wrapper is created\",\"params\":{\"vToken\":\"The vToken address to create the vault\"},\"returns\":{\"vault\":\"The deployed VenusERC4626 vault\"}},\"initialize(address,address,address,address,uint256)\":{\"params\":{\"accessControlManager\":\"Address of the ACM contract\",\"loopsLimitNumber\":\"The loops limit for the MaxLoopsLimit helper\",\"poolRegistryAddress\":\"Address of the Pool Registry contract\",\"rewardRecipientAddress\":\"Reward recipient address\",\"venusERC4626Implementation\":\"Address of the VenusERC4626 implementation contract\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pendingOwner()\":{\"details\":\"Returns the address of the pending owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setAccessControlManager(address)\":{\"custom:access\":\"Only Governance\",\"custom:event\":\"Emits NewAccessControlManager event\",\"details\":\"Admin function to set address of AccessControlManager\",\"params\":{\"accessControlManager_\":\"The new address of the AccessControlManager\"}},\"setMaxLoopsLimit(uint256)\":{\"custom:access\":\"Controlled by ACM\",\"custom:event\":\"Emits MaxLoopsLimitUpdated event on success\",\"params\":{\"loopsLimit\":\"Number of loops limit\"}},\"setRewardRecipient(address)\":{\"custom:access\":\"Controlled by ACM\",\"custom:error\":\"ZeroAddressNotAllowed is thrown when the new recipient address is zero\",\"custom:event\":\"RewardRecipientUpdated is emitted when the reward recipient address is updated\",\"params\":{\"newRecipient\":\"The address of the new reward recipient\"}},\"transferOwnership(address)\":{\"details\":\"Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.\"}},\"title\":\"VenusERC4626Factory\",\"version\":1},\"userdoc\":{\"errors\":{\"MaxLoopsLimitExceeded(uint256,uint256)\":[{\"notice\":\"Thrown an error on maxLoopsLimit exceeds for any loop\"}],\"Unauthorized(address,address,string)\":[{\"notice\":\"Thrown when the action is prohibited by AccessControlManager\"}],\"VenusERC4626Factory__ERC4626AlreadyExists()\":[{\"notice\":\"Thrown when a VenusERC4626 already exists for the provided vToken\"}],\"VenusERC4626Factory__InvalidVToken()\":[{\"notice\":\"Thrown when the provided vToken is not registered in PoolRegistry\"}],\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}]},\"events\":{\"CreateERC4626(address,address)\":{\"notice\":\"Emitted when a new ERC4626 vault has been created\"},\"MaxLoopsLimitUpdated(uint256,uint256)\":{\"notice\":\"Emitted when max loops limit is set\"},\"NewAccessControlManager(address,address)\":{\"notice\":\"Emitted when access control manager contract address is changed\"},\"RewardRecipientUpdated(address,address)\":{\"notice\":\"Emitted when the reward recipient address is updated.\"}},\"kind\":\"user\",\"methods\":{\"SALT()\":{\"notice\":\"A constant salt value used for deterministic contract deployment\"},\"accessControlManager()\":{\"notice\":\"Returns the address of the access control manager contract\"},\"beacon()\":{\"notice\":\"The beacon contract for VenusERC4626 proxies\"},\"computeVaultAddress(address)\":{\"notice\":\"Predicts the vault address for a given vToken\"},\"createERC4626(address)\":{\"notice\":\"Creates a VenusERC4626 vault for a given asset and comptroller\"},\"initialize(address,address,address,address,uint256)\":{\"notice\":\"Initializes the contract\"},\"poolRegistry()\":{\"notice\":\"The Pool Registry contract\"},\"rewardRecipient()\":{\"notice\":\"The address that will receive the liquidity mining rewards\"},\"setAccessControlManager(address)\":{\"notice\":\"Sets the address of AccessControlManager\"},\"setMaxLoopsLimit(uint256)\":{\"notice\":\"Set the limit for the loops can iterate to avoid the DOS\"},\"setRewardRecipient(address)\":{\"notice\":\"Sets a new reward recipient address\"}},\"notice\":\"Factory for creating VenusERC4626 contracts\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ERC4626/VenusERC4626Factory.sol\":\"VenusERC4626Factory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./OwnableUpgradeable.sol\\\";\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership} and {acceptOwnership}.\\n *\\n * This module is used through inheritance. It will make available all functions\\n * from parent (Ownable).\\n */\\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\\n    address private _pendingOwner;\\n\\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\\n\\n    function __Ownable2Step_init() internal onlyInitializing {\\n        __Ownable_init_unchained();\\n    }\\n\\n    function __Ownable2Step_init_unchained() internal onlyInitializing {\\n    }\\n    /**\\n     * @dev Returns the address of the pending owner.\\n     */\\n    function pendingOwner() public view virtual returns (address) {\\n        return _pendingOwner;\\n    }\\n\\n    /**\\n     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\\n     * Can only be called by the current owner.\\n     */\\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\\n        _pendingOwner = newOwner;\\n        emit OwnershipTransferStarted(owner(), newOwner);\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\\n     * Internal function without access restriction.\\n     */\\n    function _transferOwnership(address newOwner) internal virtual override {\\n        delete _pendingOwner;\\n        super._transferOwnership(newOwner);\\n    }\\n\\n    /**\\n     * @dev The new owner accepts the ownership transfer.\\n     */\\n    function acceptOwnership() public virtual {\\n        address sender = _msgSender();\\n        require(pendingOwner() == sender, \\\"Ownable2Step: caller is not the new owner\\\");\\n        _transferOwnership(sender);\\n    }\\n\\n    /**\\n     * @dev This empty reserved space is put in place to allow future versions to add new\\n     * variables without shifting down storage in the inheritance chain.\\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n     */\\n    uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x9140dabc466abab21b48b72dbda26736b1183a310d0e677d3719d201df026510\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n    address private _owner;\\n\\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n    /**\\n     * @dev Initializes the contract setting the deployer as the initial owner.\\n     */\\n    function __Ownable_init() internal onlyInitializing {\\n        __Ownable_init_unchained();\\n    }\\n\\n    function __Ownable_init_unchained() internal onlyInitializing {\\n        _transferOwnership(_msgSender());\\n    }\\n\\n    /**\\n     * @dev Throws if called by any account other than the owner.\\n     */\\n    modifier onlyOwner() {\\n        _checkOwner();\\n        _;\\n    }\\n\\n    /**\\n     * @dev Returns the address of the current owner.\\n     */\\n    function owner() public view virtual returns (address) {\\n        return _owner;\\n    }\\n\\n    /**\\n     * @dev Throws if the sender is not the owner.\\n     */\\n    function _checkOwner() internal view virtual {\\n        require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n    }\\n\\n    /**\\n     * @dev Leaves the contract without owner. It will not be possible to call\\n     * `onlyOwner` functions. Can only be called by the current owner.\\n     *\\n     * NOTE: Renouncing ownership will leave the contract without an owner,\\n     * thereby disabling any functionality that is only available to the owner.\\n     */\\n    function renounceOwnership() public virtual onlyOwner {\\n        _transferOwnership(address(0));\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Can only be called by the current owner.\\n     */\\n    function transferOwnership(address newOwner) public virtual onlyOwner {\\n        require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n        _transferOwnership(newOwner);\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Internal function without access restriction.\\n     */\\n    function _transferOwnership(address newOwner) internal virtual {\\n        address oldOwner = _owner;\\n        _owner = newOwner;\\n        emit OwnershipTransferred(oldOwner, newOwner);\\n    }\\n\\n    /**\\n     * @dev This empty reserved space is put in place to allow future versions to add new\\n     * variables without shifting down storage in the inheritance chain.\\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n     */\\n    uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x359a1ab89b46b9aba7bcad3fb651924baf4893d15153049b9976b0fc9be1358e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC4626Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4626.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"../token/ERC20/extensions/IERC20MetadataUpgradeable.sol\\\";\\n\\n/**\\n * @dev Interface of the ERC4626 \\\"Tokenized Vault Standard\\\", as defined in\\n * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].\\n *\\n * _Available since v4.7._\\n */\\ninterface IERC4626Upgradeable is IERC20Upgradeable, IERC20MetadataUpgradeable {\\n    event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);\\n\\n    event Withdraw(\\n        address indexed sender,\\n        address indexed receiver,\\n        address indexed owner,\\n        uint256 assets,\\n        uint256 shares\\n    );\\n\\n    /**\\n     * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.\\n     *\\n     * - MUST be an ERC-20 token contract.\\n     * - MUST NOT revert.\\n     */\\n    function asset() external view returns (address assetTokenAddress);\\n\\n    /**\\n     * @dev Returns the total amount of the underlying asset that is \\u201cmanaged\\u201d by Vault.\\n     *\\n     * - SHOULD include any compounding that occurs from yield.\\n     * - MUST be inclusive of any fees that are charged against assets in the Vault.\\n     * - MUST NOT revert.\\n     */\\n    function totalAssets() external view returns (uint256 totalManagedAssets);\\n\\n    /**\\n     * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal\\n     * scenario where all the conditions are met.\\n     *\\n     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\\n     * - MUST NOT show any variations depending on the caller.\\n     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\\n     * - MUST NOT revert.\\n     *\\n     * NOTE: This calculation MAY NOT reflect the \\u201cper-user\\u201d price-per-share, and instead should reflect the\\n     * \\u201caverage-user\\u2019s\\u201d price-per-share, meaning what the average user should expect to see when exchanging to and\\n     * from.\\n     */\\n    function convertToShares(uint256 assets) external view returns (uint256 shares);\\n\\n    /**\\n     * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal\\n     * scenario where all the conditions are met.\\n     *\\n     * - MUST NOT be inclusive of any fees that are charged against assets in the Vault.\\n     * - MUST NOT show any variations depending on the caller.\\n     * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.\\n     * - MUST NOT revert.\\n     *\\n     * NOTE: This calculation MAY NOT reflect the \\u201cper-user\\u201d price-per-share, and instead should reflect the\\n     * \\u201caverage-user\\u2019s\\u201d price-per-share, meaning what the average user should expect to see when exchanging to and\\n     * from.\\n     */\\n    function convertToAssets(uint256 shares) external view returns (uint256 assets);\\n\\n    /**\\n     * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,\\n     * through a deposit call.\\n     *\\n     * - MUST return a limited value if receiver is subject to some deposit limit.\\n     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.\\n     * - MUST NOT revert.\\n     */\\n    function maxDeposit(address receiver) external view returns (uint256 maxAssets);\\n\\n    /**\\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given\\n     * current on-chain conditions.\\n     *\\n     * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit\\n     *   call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called\\n     *   in the same transaction.\\n     * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the\\n     *   deposit would be accepted, regardless if the user has enough tokens approved, etc.\\n     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\\n     * - MUST NOT revert.\\n     *\\n     * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in\\n     * share price or some other type of condition, meaning the depositor will lose assets by depositing.\\n     */\\n    function previewDeposit(uint256 assets) external view returns (uint256 shares);\\n\\n    /**\\n     * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.\\n     *\\n     * - MUST emit the Deposit event.\\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\\n     *   deposit execution, and are accounted for during deposit.\\n     * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not\\n     *   approving enough underlying tokens to the Vault contract, etc).\\n     *\\n     * NOTE: most implementations will require pre-approval of the Vault with the Vault\\u2019s underlying asset token.\\n     */\\n    function deposit(uint256 assets, address receiver) external returns (uint256 shares);\\n\\n    /**\\n     * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.\\n     * - MUST return a limited value if receiver is subject to some mint limit.\\n     * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.\\n     * - MUST NOT revert.\\n     */\\n    function maxMint(address receiver) external view returns (uint256 maxShares);\\n\\n    /**\\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given\\n     * current on-chain conditions.\\n     *\\n     * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call\\n     *   in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the\\n     *   same transaction.\\n     * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint\\n     *   would be accepted, regardless if the user has enough tokens approved, etc.\\n     * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.\\n     * - MUST NOT revert.\\n     *\\n     * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in\\n     * share price or some other type of condition, meaning the depositor will lose assets by minting.\\n     */\\n    function previewMint(uint256 shares) external view returns (uint256 assets);\\n\\n    /**\\n     * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.\\n     *\\n     * - MUST emit the Deposit event.\\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint\\n     *   execution, and are accounted for during mint.\\n     * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not\\n     *   approving enough underlying tokens to the Vault contract, etc).\\n     *\\n     * NOTE: most implementations will require pre-approval of the Vault with the Vault\\u2019s underlying asset token.\\n     */\\n    function mint(uint256 shares, address receiver) external returns (uint256 assets);\\n\\n    /**\\n     * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the\\n     * Vault, through a withdraw call.\\n     *\\n     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\\n     * - MUST NOT revert.\\n     */\\n    function maxWithdraw(address owner) external view returns (uint256 maxAssets);\\n\\n    /**\\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,\\n     * given current on-chain conditions.\\n     *\\n     * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw\\n     *   call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if\\n     *   called\\n     *   in the same transaction.\\n     * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though\\n     *   the withdrawal would be accepted, regardless if the user has enough shares, etc.\\n     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\\n     * - MUST NOT revert.\\n     *\\n     * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in\\n     * share price or some other type of condition, meaning the depositor will lose assets by depositing.\\n     */\\n    function previewWithdraw(uint256 assets) external view returns (uint256 shares);\\n\\n    /**\\n     * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.\\n     *\\n     * - MUST emit the Withdraw event.\\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\\n     *   withdraw execution, and are accounted for during withdraw.\\n     * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner\\n     *   not having enough shares, etc).\\n     *\\n     * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\\n     * Those methods should be performed separately.\\n     */\\n    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);\\n\\n    /**\\n     * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,\\n     * through a redeem call.\\n     *\\n     * - MUST return a limited value if owner is subject to some withdrawal limit or timelock.\\n     * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.\\n     * - MUST NOT revert.\\n     */\\n    function maxRedeem(address owner) external view returns (uint256 maxShares);\\n\\n    /**\\n     * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,\\n     * given current on-chain conditions.\\n     *\\n     * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call\\n     *   in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the\\n     *   same transaction.\\n     * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the\\n     *   redemption would be accepted, regardless if the user has enough shares, etc.\\n     * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.\\n     * - MUST NOT revert.\\n     *\\n     * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in\\n     * share price or some other type of condition, meaning the depositor will lose assets by redeeming.\\n     */\\n    function previewRedeem(uint256 shares) external view returns (uint256 assets);\\n\\n    /**\\n     * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.\\n     *\\n     * - MUST emit the Withdraw event.\\n     * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the\\n     *   redeem execution, and are accounted for during redeem.\\n     * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner\\n     *   not having enough shares, etc).\\n     *\\n     * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.\\n     * Those methods should be performed separately.\\n     */\\n    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);\\n}\\n\",\"keccak256\":\"0xf867351fb48f5c0e3b45f085ce60f374b785417f84370cb2ffb57f421931e7eb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n *     function initialize() initializer public {\\n *         __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n *     }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n *     function initializeV2() reinitializer(2) public {\\n *         __ERC20Permit_init(\\\"MyToken\\\");\\n *     }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n *     _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n    /**\\n     * @dev Indicates that the contract has been initialized.\\n     * @custom:oz-retyped-from bool\\n     */\\n    uint8 private _initialized;\\n\\n    /**\\n     * @dev Indicates that the contract is in the process of being initialized.\\n     */\\n    bool private _initializing;\\n\\n    /**\\n     * @dev Triggered when the contract has been initialized or reinitialized.\\n     */\\n    event Initialized(uint8 version);\\n\\n    /**\\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n     * `onlyInitializing` functions can be used to initialize parent contracts.\\n     *\\n     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n     * constructor.\\n     *\\n     * Emits an {Initialized} event.\\n     */\\n    modifier initializer() {\\n        bool isTopLevelCall = !_initializing;\\n        require(\\n            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n            \\\"Initializable: contract is already initialized\\\"\\n        );\\n        _initialized = 1;\\n        if (isTopLevelCall) {\\n            _initializing = true;\\n        }\\n        _;\\n        if (isTopLevelCall) {\\n            _initializing = false;\\n            emit Initialized(1);\\n        }\\n    }\\n\\n    /**\\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n     * used to initialize parent contracts.\\n     *\\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n     * are added through upgrades and that require initialization.\\n     *\\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\\n     *\\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n     * a contract, executing them in the right order is up to the developer or operator.\\n     *\\n     * WARNING: setting the version to 255 will prevent any future reinitialization.\\n     *\\n     * Emits an {Initialized} event.\\n     */\\n    modifier reinitializer(uint8 version) {\\n        require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n        _initialized = version;\\n        _initializing = true;\\n        _;\\n        _initializing = false;\\n        emit Initialized(version);\\n    }\\n\\n    /**\\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n     */\\n    modifier onlyInitializing() {\\n        require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n        _;\\n    }\\n\\n    /**\\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n     * through proxies.\\n     *\\n     * Emits an {Initialized} event the first time it is successfully executed.\\n     */\\n    function _disableInitializers() internal virtual {\\n        require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n        if (_initialized != type(uint8).max) {\\n            _initialized = type(uint8).max;\\n            emit Initialized(type(uint8).max);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n     */\\n    function _getInitializedVersion() internal view returns (uint8) {\\n        return _initialized;\\n    }\\n\\n    /**\\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n     */\\n    function _isInitializing() internal view returns (bool) {\\n        return _initializing;\\n    }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport {Initializable} from \\\"../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        _nonReentrantBefore();\\n        _;\\n        _nonReentrantAfter();\\n    }\\n\\n    function _nonReentrantBefore() private {\\n        // On the first call to nonReentrant, _status will be _NOT_ENTERED\\n        require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n        // Any calls to nonReentrant after this point will fail\\n        _status = _ENTERED;\\n    }\\n\\n    function _nonReentrantAfter() private {\\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\\n    /**\\n     * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n     * `nonReentrant` function in the call stack.\\n     */\\n    function _reentrancyGuardEntered() internal view returns (bool) {\\n        return _status == _ENTERED;\\n    }\\n\\n    /**\\n     * @dev This empty reserved space is put in place to allow future versions to add new\\n     * variables without shifting down storage in the inheritance chain.\\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n     */\\n    uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x2025ccf05f6f1f2fd4e078e552836f525a1864e3854ed555047cd732320ab29b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n    mapping(address => uint256) private _balances;\\n\\n    mapping(address => mapping(address => uint256)) private _allowances;\\n\\n    uint256 private _totalSupply;\\n\\n    string private _name;\\n    string private _symbol;\\n\\n    /**\\n     * @dev Sets the values for {name} and {symbol}.\\n     *\\n     * All two of these values are immutable: they can only be set once during\\n     * construction.\\n     */\\n    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n        __ERC20_init_unchained(name_, symbol_);\\n    }\\n\\n    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n        _name = name_;\\n        _symbol = symbol_;\\n    }\\n\\n    /**\\n     * @dev Returns the name of the token.\\n     */\\n    function name() public view virtual override returns (string memory) {\\n        return _name;\\n    }\\n\\n    /**\\n     * @dev Returns the symbol of the token, usually a shorter version of the\\n     * name.\\n     */\\n    function symbol() public view virtual override returns (string memory) {\\n        return _symbol;\\n    }\\n\\n    /**\\n     * @dev Returns the number of decimals used to get its user representation.\\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n     *\\n     * Tokens usually opt for a value of 18, imitating the relationship between\\n     * Ether and Wei. This is the default value returned by this function, unless\\n     * it's overridden.\\n     *\\n     * NOTE: This information is only used for _display_ purposes: it in\\n     * no way affects any of the arithmetic of the contract, including\\n     * {IERC20-balanceOf} and {IERC20-transfer}.\\n     */\\n    function decimals() public view virtual override returns (uint8) {\\n        return 18;\\n    }\\n\\n    /**\\n     * @dev See {IERC20-totalSupply}.\\n     */\\n    function totalSupply() public view virtual override returns (uint256) {\\n        return _totalSupply;\\n    }\\n\\n    /**\\n     * @dev See {IERC20-balanceOf}.\\n     */\\n    function balanceOf(address account) public view virtual override returns (uint256) {\\n        return _balances[account];\\n    }\\n\\n    /**\\n     * @dev See {IERC20-transfer}.\\n     *\\n     * Requirements:\\n     *\\n     * - `to` cannot be the zero address.\\n     * - the caller must have a balance of at least `amount`.\\n     */\\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n        address owner = _msgSender();\\n        _transfer(owner, to, amount);\\n        return true;\\n    }\\n\\n    /**\\n     * @dev See {IERC20-allowance}.\\n     */\\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n        return _allowances[owner][spender];\\n    }\\n\\n    /**\\n     * @dev See {IERC20-approve}.\\n     *\\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\\n     *\\n     * Requirements:\\n     *\\n     * - `spender` cannot be the zero address.\\n     */\\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n        address owner = _msgSender();\\n        _approve(owner, spender, amount);\\n        return true;\\n    }\\n\\n    /**\\n     * @dev See {IERC20-transferFrom}.\\n     *\\n     * Emits an {Approval} event indicating the updated allowance. This is not\\n     * required by the EIP. See the note at the beginning of {ERC20}.\\n     *\\n     * NOTE: Does not update the allowance if the current allowance\\n     * is the maximum `uint256`.\\n     *\\n     * Requirements:\\n     *\\n     * - `from` and `to` cannot be the zero address.\\n     * - `from` must have a balance of at least `amount`.\\n     * - the caller must have allowance for ``from``'s tokens of at least\\n     * `amount`.\\n     */\\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\\n        address spender = _msgSender();\\n        _spendAllowance(from, spender, amount);\\n        _transfer(from, to, amount);\\n        return true;\\n    }\\n\\n    /**\\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\\n     *\\n     * This is an alternative to {approve} that can be used as a mitigation for\\n     * problems described in {IERC20-approve}.\\n     *\\n     * Emits an {Approval} event indicating the updated allowance.\\n     *\\n     * Requirements:\\n     *\\n     * - `spender` cannot be the zero address.\\n     */\\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n        address owner = _msgSender();\\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\\n        return true;\\n    }\\n\\n    /**\\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n     *\\n     * This is an alternative to {approve} that can be used as a mitigation for\\n     * problems described in {IERC20-approve}.\\n     *\\n     * Emits an {Approval} event indicating the updated allowance.\\n     *\\n     * Requirements:\\n     *\\n     * - `spender` cannot be the zero address.\\n     * - `spender` must have allowance for the caller of at least\\n     * `subtractedValue`.\\n     */\\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n        address owner = _msgSender();\\n        uint256 currentAllowance = allowance(owner, spender);\\n        require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n        unchecked {\\n            _approve(owner, spender, currentAllowance - subtractedValue);\\n        }\\n\\n        return true;\\n    }\\n\\n    /**\\n     * @dev Moves `amount` of tokens from `from` to `to`.\\n     *\\n     * This internal function is equivalent to {transfer}, and can be used to\\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\\n     *\\n     * Emits a {Transfer} event.\\n     *\\n     * Requirements:\\n     *\\n     * - `from` cannot be the zero address.\\n     * - `to` cannot be the zero address.\\n     * - `from` must have a balance of at least `amount`.\\n     */\\n    function _transfer(address from, address to, uint256 amount) internal virtual {\\n        require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n        require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n        _beforeTokenTransfer(from, to, amount);\\n\\n        uint256 fromBalance = _balances[from];\\n        require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n        unchecked {\\n            _balances[from] = fromBalance - amount;\\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n            // decrementing then incrementing.\\n            _balances[to] += amount;\\n        }\\n\\n        emit Transfer(from, to, amount);\\n\\n        _afterTokenTransfer(from, to, amount);\\n    }\\n\\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n     * the total supply.\\n     *\\n     * Emits a {Transfer} event with `from` set to the zero address.\\n     *\\n     * Requirements:\\n     *\\n     * - `account` cannot be the zero address.\\n     */\\n    function _mint(address account, uint256 amount) internal virtual {\\n        require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n        _beforeTokenTransfer(address(0), account, amount);\\n\\n        _totalSupply += amount;\\n        unchecked {\\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n            _balances[account] += amount;\\n        }\\n        emit Transfer(address(0), account, amount);\\n\\n        _afterTokenTransfer(address(0), account, amount);\\n    }\\n\\n    /**\\n     * @dev Destroys `amount` tokens from `account`, reducing the\\n     * total supply.\\n     *\\n     * Emits a {Transfer} event with `to` set to the zero address.\\n     *\\n     * Requirements:\\n     *\\n     * - `account` cannot be the zero address.\\n     * - `account` must have at least `amount` tokens.\\n     */\\n    function _burn(address account, uint256 amount) internal virtual {\\n        require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n        _beforeTokenTransfer(account, address(0), amount);\\n\\n        uint256 accountBalance = _balances[account];\\n        require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n        unchecked {\\n            _balances[account] = accountBalance - amount;\\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\\n            _totalSupply -= amount;\\n        }\\n\\n        emit Transfer(account, address(0), amount);\\n\\n        _afterTokenTransfer(account, address(0), amount);\\n    }\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n     *\\n     * This internal function is equivalent to `approve`, and can be used to\\n     * e.g. set automatic allowances for certain subsystems, etc.\\n     *\\n     * Emits an {Approval} event.\\n     *\\n     * Requirements:\\n     *\\n     * - `owner` cannot be the zero address.\\n     * - `spender` cannot be the zero address.\\n     */\\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\\n        require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n        require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n        _allowances[owner][spender] = amount;\\n        emit Approval(owner, spender, amount);\\n    }\\n\\n    /**\\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n     *\\n     * Does not update the allowance amount in case of infinite allowance.\\n     * Revert if not enough allowance is available.\\n     *\\n     * Might emit an {Approval} event.\\n     */\\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n        uint256 currentAllowance = allowance(owner, spender);\\n        if (currentAllowance != type(uint256).max) {\\n            require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n            unchecked {\\n                _approve(owner, spender, currentAllowance - amount);\\n            }\\n        }\\n    }\\n\\n    /**\\n     * @dev Hook that is called before any transfer of tokens. This includes\\n     * minting and burning.\\n     *\\n     * Calling conditions:\\n     *\\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n     * will be transferred to `to`.\\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n     * - `from` and `to` are never both zero.\\n     *\\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n     */\\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n    /**\\n     * @dev Hook that is called after any transfer of tokens. This includes\\n     * minting and burning.\\n     *\\n     * Calling conditions:\\n     *\\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n     * has been transferred to `to`.\\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n     * - `from` and `to` are never both zero.\\n     *\\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n     */\\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n    /**\\n     * @dev This empty reserved space is put in place to allow future versions to add new\\n     * variables without shifting down storage in the inheritance chain.\\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n     */\\n    uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0xa9311aeb22f459e57d4dac77ee76cf43fb28ad3215278456211b5852b0e9e970\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n    /**\\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n     * another (`to`).\\n     *\\n     * Note that `value` may be zero.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    /**\\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n     * a call to {approve}. `value` is the new allowance.\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n    /**\\n     * @dev Returns the amount of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves `amount` tokens from the caller's account to `to`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address to, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Moves `amount` tokens from `from` to `to` using the\\n     * allowance mechanism. `amount` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC4626Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC4626.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../utils/SafeERC20Upgradeable.sol\\\";\\nimport \\\"../../../interfaces/IERC4626Upgradeable.sol\\\";\\nimport \\\"../../../utils/math/MathUpgradeable.sol\\\";\\nimport {Initializable} from \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC4626 \\\"Tokenized Vault Standard\\\" as defined in\\n * https://eips.ethereum.org/EIPS/eip-4626[EIP-4626].\\n *\\n * This extension allows the minting and burning of \\\"shares\\\" (represented using the ERC20 inheritance) in exchange for\\n * underlying \\\"assets\\\" through standardized {deposit}, {mint}, {redeem} and {burn} workflows. This contract extends\\n * the ERC20 standard. Any additional extensions included along it would affect the \\\"shares\\\" token represented by this\\n * contract and not the \\\"assets\\\" token which is an independent contract.\\n *\\n * [CAUTION]\\n * ====\\n * In empty (or nearly empty) ERC-4626 vaults, deposits are at high risk of being stolen through frontrunning\\n * with a \\\"donation\\\" to the vault that inflates the price of a share. This is variously known as a donation or inflation\\n * attack and is essentially a problem of slippage. Vault deployers can protect against this attack by making an initial\\n * deposit of a non-trivial amount of the asset, such that price manipulation becomes infeasible. Withdrawals may\\n * similarly be affected by slippage. Users can protect against this attack as well as unexpected slippage in general by\\n * verifying the amount received is as expected, using a wrapper that performs these checks such as\\n * https://github.com/fei-protocol/ERC4626#erc4626router-and-base[ERC4626Router].\\n *\\n * Since v4.9, this implementation uses virtual assets and shares to mitigate that risk. The `_decimalsOffset()`\\n * corresponds to an offset in the decimal representation between the underlying asset's decimals and the vault\\n * decimals. This offset also determines the rate of virtual shares to virtual assets in the vault, which itself\\n * determines the initial exchange rate. While not fully preventing the attack, analysis shows that the default offset\\n * (0) makes it non-profitable, as a result of the value being captured by the virtual shares (out of the attacker's\\n * donation) matching the attacker's expected gains. With a larger offset, the attack becomes orders of magnitude more\\n * expensive than it is profitable. More details about the underlying math can be found\\n * xref:erc4626.adoc#inflation-attack[here].\\n *\\n * The drawback of this approach is that the virtual shares do capture (a very small) part of the value being accrued\\n * to the vault. Also, if the vault experiences losses, the users try to exit the vault, the virtual shares and assets\\n * will cause the first user to exit to experience reduced losses in detriment to the last users that will experience\\n * bigger losses. Developers willing to revert back to the pre-v4.9 behavior just need to override the\\n * `_convertToShares` and `_convertToAssets` functions.\\n *\\n * To learn more, check out our xref:ROOT:erc4626.adoc[ERC-4626 guide].\\n * ====\\n *\\n * _Available since v4.7._\\n */\\nabstract contract ERC4626Upgradeable is Initializable, ERC20Upgradeable, IERC4626Upgradeable {\\n    using MathUpgradeable for uint256;\\n\\n    IERC20Upgradeable private _asset;\\n    uint8 private _underlyingDecimals;\\n\\n    /**\\n     * @dev Set the underlying asset contract. This must be an ERC20-compatible contract (ERC20 or ERC777).\\n     */\\n    function __ERC4626_init(IERC20Upgradeable asset_) internal onlyInitializing {\\n        __ERC4626_init_unchained(asset_);\\n    }\\n\\n    function __ERC4626_init_unchained(IERC20Upgradeable asset_) internal onlyInitializing {\\n        (bool success, uint8 assetDecimals) = _tryGetAssetDecimals(asset_);\\n        _underlyingDecimals = success ? assetDecimals : 18;\\n        _asset = asset_;\\n    }\\n\\n    /**\\n     * @dev Attempts to fetch the asset decimals. A return value of false indicates that the attempt failed in some way.\\n     */\\n    function _tryGetAssetDecimals(IERC20Upgradeable asset_) private view returns (bool, uint8) {\\n        (bool success, bytes memory encodedDecimals) = address(asset_).staticcall(\\n            abi.encodeWithSelector(IERC20MetadataUpgradeable.decimals.selector)\\n        );\\n        if (success && encodedDecimals.length >= 32) {\\n            uint256 returnedDecimals = abi.decode(encodedDecimals, (uint256));\\n            if (returnedDecimals <= type(uint8).max) {\\n                return (true, uint8(returnedDecimals));\\n            }\\n        }\\n        return (false, 0);\\n    }\\n\\n    /**\\n     * @dev Decimals are computed by adding the decimal offset on top of the underlying asset's decimals. This\\n     * \\\"original\\\" value is cached during construction of the vault contract. If this read operation fails (e.g., the\\n     * asset has not been created yet), a default of 18 is used to represent the underlying asset's decimals.\\n     *\\n     * See {IERC20Metadata-decimals}.\\n     */\\n    function decimals() public view virtual override(IERC20MetadataUpgradeable, ERC20Upgradeable) returns (uint8) {\\n        return _underlyingDecimals + _decimalsOffset();\\n    }\\n\\n    /** @dev See {IERC4626-asset}. */\\n    function asset() public view virtual override returns (address) {\\n        return address(_asset);\\n    }\\n\\n    /** @dev See {IERC4626-totalAssets}. */\\n    function totalAssets() public view virtual override returns (uint256) {\\n        return _asset.balanceOf(address(this));\\n    }\\n\\n    /** @dev See {IERC4626-convertToShares}. */\\n    function convertToShares(uint256 assets) public view virtual override returns (uint256) {\\n        return _convertToShares(assets, MathUpgradeable.Rounding.Down);\\n    }\\n\\n    /** @dev See {IERC4626-convertToAssets}. */\\n    function convertToAssets(uint256 shares) public view virtual override returns (uint256) {\\n        return _convertToAssets(shares, MathUpgradeable.Rounding.Down);\\n    }\\n\\n    /** @dev See {IERC4626-maxDeposit}. */\\n    function maxDeposit(address) public view virtual override returns (uint256) {\\n        return type(uint256).max;\\n    }\\n\\n    /** @dev See {IERC4626-maxMint}. */\\n    function maxMint(address) public view virtual override returns (uint256) {\\n        return type(uint256).max;\\n    }\\n\\n    /** @dev See {IERC4626-maxWithdraw}. */\\n    function maxWithdraw(address owner) public view virtual override returns (uint256) {\\n        return _convertToAssets(balanceOf(owner), MathUpgradeable.Rounding.Down);\\n    }\\n\\n    /** @dev See {IERC4626-maxRedeem}. */\\n    function maxRedeem(address owner) public view virtual override returns (uint256) {\\n        return balanceOf(owner);\\n    }\\n\\n    /** @dev See {IERC4626-previewDeposit}. */\\n    function previewDeposit(uint256 assets) public view virtual override returns (uint256) {\\n        return _convertToShares(assets, MathUpgradeable.Rounding.Down);\\n    }\\n\\n    /** @dev See {IERC4626-previewMint}. */\\n    function previewMint(uint256 shares) public view virtual override returns (uint256) {\\n        return _convertToAssets(shares, MathUpgradeable.Rounding.Up);\\n    }\\n\\n    /** @dev See {IERC4626-previewWithdraw}. */\\n    function previewWithdraw(uint256 assets) public view virtual override returns (uint256) {\\n        return _convertToShares(assets, MathUpgradeable.Rounding.Up);\\n    }\\n\\n    /** @dev See {IERC4626-previewRedeem}. */\\n    function previewRedeem(uint256 shares) public view virtual override returns (uint256) {\\n        return _convertToAssets(shares, MathUpgradeable.Rounding.Down);\\n    }\\n\\n    /** @dev See {IERC4626-deposit}. */\\n    function deposit(uint256 assets, address receiver) public virtual override returns (uint256) {\\n        require(assets <= maxDeposit(receiver), \\\"ERC4626: deposit more than max\\\");\\n\\n        uint256 shares = previewDeposit(assets);\\n        _deposit(_msgSender(), receiver, assets, shares);\\n\\n        return shares;\\n    }\\n\\n    /** @dev See {IERC4626-mint}.\\n     *\\n     * As opposed to {deposit}, minting is allowed even if the vault is in a state where the price of a share is zero.\\n     * In this case, the shares will be minted without requiring any assets to be deposited.\\n     */\\n    function mint(uint256 shares, address receiver) public virtual override returns (uint256) {\\n        require(shares <= maxMint(receiver), \\\"ERC4626: mint more than max\\\");\\n\\n        uint256 assets = previewMint(shares);\\n        _deposit(_msgSender(), receiver, assets, shares);\\n\\n        return assets;\\n    }\\n\\n    /** @dev See {IERC4626-withdraw}. */\\n    function withdraw(uint256 assets, address receiver, address owner) public virtual override returns (uint256) {\\n        require(assets <= maxWithdraw(owner), \\\"ERC4626: withdraw more than max\\\");\\n\\n        uint256 shares = previewWithdraw(assets);\\n        _withdraw(_msgSender(), receiver, owner, assets, shares);\\n\\n        return shares;\\n    }\\n\\n    /** @dev See {IERC4626-redeem}. */\\n    function redeem(uint256 shares, address receiver, address owner) public virtual override returns (uint256) {\\n        require(shares <= maxRedeem(owner), \\\"ERC4626: redeem more than max\\\");\\n\\n        uint256 assets = previewRedeem(shares);\\n        _withdraw(_msgSender(), receiver, owner, assets, shares);\\n\\n        return assets;\\n    }\\n\\n    /**\\n     * @dev Internal conversion function (from assets to shares) with support for rounding direction.\\n     */\\n    function _convertToShares(uint256 assets, MathUpgradeable.Rounding rounding) internal view virtual returns (uint256) {\\n        return assets.mulDiv(totalSupply() + 10 ** _decimalsOffset(), totalAssets() + 1, rounding);\\n    }\\n\\n    /**\\n     * @dev Internal conversion function (from shares to assets) with support for rounding direction.\\n     */\\n    function _convertToAssets(uint256 shares, MathUpgradeable.Rounding rounding) internal view virtual returns (uint256) {\\n        return shares.mulDiv(totalAssets() + 1, totalSupply() + 10 ** _decimalsOffset(), rounding);\\n    }\\n\\n    /**\\n     * @dev Deposit/mint common workflow.\\n     */\\n    function _deposit(address caller, address receiver, uint256 assets, uint256 shares) internal virtual {\\n        // If _asset is ERC777, `transferFrom` can trigger a reentrancy BEFORE the transfer happens through the\\n        // `tokensToSend` hook. On the other hand, the `tokenReceived` hook, that is triggered after the transfer,\\n        // calls the vault, which is assumed not malicious.\\n        //\\n        // Conclusion: we need to do the transfer before we mint so that any reentrancy would happen before the\\n        // assets are transferred and before the shares are minted, which is a valid state.\\n        // slither-disable-next-line reentrancy-no-eth\\n        SafeERC20Upgradeable.safeTransferFrom(_asset, caller, address(this), assets);\\n        _mint(receiver, shares);\\n\\n        emit Deposit(caller, receiver, assets, shares);\\n    }\\n\\n    /**\\n     * @dev Withdraw/redeem common workflow.\\n     */\\n    function _withdraw(\\n        address caller,\\n        address receiver,\\n        address owner,\\n        uint256 assets,\\n        uint256 shares\\n    ) internal virtual {\\n        if (caller != owner) {\\n            _spendAllowance(owner, caller, shares);\\n        }\\n\\n        // If _asset is ERC777, `transfer` can trigger a reentrancy AFTER the transfer happens through the\\n        // `tokensReceived` hook. On the other hand, the `tokensToSend` hook, that is triggered before the transfer,\\n        // calls the vault, which is assumed not malicious.\\n        //\\n        // Conclusion: we need to do the transfer after the burn so that any reentrancy would happen after the\\n        // shares are burned and after the assets are transferred, which is a valid state.\\n        _burn(owner, shares);\\n        SafeERC20Upgradeable.safeTransfer(_asset, receiver, assets);\\n\\n        emit Withdraw(caller, receiver, owner, assets, shares);\\n    }\\n\\n    function _decimalsOffset() internal view virtual returns (uint8) {\\n        return 0;\\n    }\\n\\n    /**\\n     * @dev This empty reserved space is put in place to allow future versions to add new\\n     * variables without shifting down storage in the inheritance chain.\\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n     */\\n    uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x48a2c0285b0ce8bf768b780142e82ccf08208b343439770464f2cc46c0cef3f5\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n    /**\\n     * @dev Returns the name of the token.\\n     */\\n    function name() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the symbol of the token.\\n     */\\n    function symbol() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the decimals places of the token.\\n     */\\n    function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * ==== Security Considerations\\n *\\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\\n * generally recommended is:\\n *\\n * ```solidity\\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\\n *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\\n *     doThing(..., value);\\n * }\\n *\\n * function doThing(..., uint256 value) public {\\n *     token.safeTransferFrom(msg.sender, address(this), value);\\n *     ...\\n * }\\n * ```\\n *\\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\\n * {SafeERC20-safeTransferFrom}).\\n *\\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\\n * contracts should have entry points that don't rely on permit.\\n */\\ninterface IERC20PermitUpgradeable {\\n    /**\\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n     * given ``owner``'s signed approval.\\n     *\\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n     * ordering also apply here.\\n     *\\n     * Emits an {Approval} event.\\n     *\\n     * Requirements:\\n     *\\n     * - `spender` cannot be the zero address.\\n     * - `deadline` must be a timestamp in the future.\\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n     * over the EIP712-formatted function arguments.\\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\\n     *\\n     * For more information on the signature format, see the\\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n     * section].\\n     *\\n     * CAUTION: See Security Considerations above.\\n     */\\n    function permit(\\n        address owner,\\n        address spender,\\n        uint256 value,\\n        uint256 deadline,\\n        uint8 v,\\n        bytes32 r,\\n        bytes32 s\\n    ) external;\\n\\n    /**\\n     * @dev Returns the current nonce for `owner`. This value must be\\n     * included whenever a signature is generated for {permit}.\\n     *\\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n     * prevents a signature from being used multiple times.\\n     */\\n    function nonces(address owner) external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n     */\\n    // solhint-disable-next-line func-name-mixedcase\\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x07e881de3b9f6d2c07909f193f24b96c7fe4ea60013260f3f25aecd8bab3c2f8\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n    using AddressUpgradeable for address;\\n\\n    /**\\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n     * non-reverting calls are assumed to be successful.\\n     */\\n    function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n    }\\n\\n    /**\\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n     */\\n    function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n    }\\n\\n    /**\\n     * @dev Deprecated. This function has issues similar to the ones found in\\n     * {IERC20-approve}, and its usage is discouraged.\\n     *\\n     * Whenever possible, use {safeIncreaseAllowance} and\\n     * {safeDecreaseAllowance} instead.\\n     */\\n    function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n        // safeApprove should only be called when setting an initial allowance,\\n        // or when resetting it to zero. To increase and decrease it, use\\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n        require(\\n            (value == 0) || (token.allowance(address(this), spender) == 0),\\n            \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n        );\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n    }\\n\\n    /**\\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n     * non-reverting calls are assumed to be successful.\\n     */\\n    function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n        uint256 oldAllowance = token.allowance(address(this), spender);\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n    }\\n\\n    /**\\n     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n     * non-reverting calls are assumed to be successful.\\n     */\\n    function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n        unchecked {\\n            uint256 oldAllowance = token.allowance(address(this), spender);\\n            require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n        }\\n    }\\n\\n    /**\\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n     * to be set to zero before setting it to a non-zero value, such as USDT.\\n     */\\n    function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n        if (!_callOptionalReturnBool(token, approvalCall)) {\\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n            _callOptionalReturn(token, approvalCall);\\n        }\\n    }\\n\\n    /**\\n     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n     * Revert on invalid signature.\\n     */\\n    function safePermit(\\n        IERC20PermitUpgradeable token,\\n        address owner,\\n        address spender,\\n        uint256 value,\\n        uint256 deadline,\\n        uint8 v,\\n        bytes32 r,\\n        bytes32 s\\n    ) internal {\\n        uint256 nonceBefore = token.nonces(owner);\\n        token.permit(owner, spender, value, deadline, v, r, s);\\n        uint256 nonceAfter = token.nonces(owner);\\n        require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n    }\\n\\n    /**\\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\\n     * @param token The token targeted by the call.\\n     * @param data The call data (encoded using abi.encode or one of its variants).\\n     */\\n    function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {\\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n        // the target address contains contract code and also asserts for success in the low-level call.\\n\\n        bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n    }\\n\\n    /**\\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\\n     * @param token The token targeted by the call.\\n     * @param data The call data (encoded using abi.encode or one of its variants).\\n     *\\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n     */\\n    function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n        // and not revert is the subcall reverts.\\n\\n        (bool success, bytes memory returndata) = address(token).call(data);\\n        return\\n            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n    }\\n}\\n\",\"keccak256\":\"0x23b997be73d3dd46885262704f0f8cfc7273fdadfe303d37969a9561373972b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n    /**\\n     * @dev Returns true if `account` is a contract.\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * It is unsafe to assume that an address for which this function returns\\n     * false is an externally-owned account (EOA) and not a contract.\\n     *\\n     * Among others, `isContract` will return false for the following\\n     * types of addresses:\\n     *\\n     *  - an externally-owned account\\n     *  - a contract in construction\\n     *  - an address where a contract will be created\\n     *  - an address where a contract lived, but was destroyed\\n     *\\n     * Furthermore, `isContract` will also return true if the target contract within\\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n     * which only has an effect at the end of a transaction.\\n     * ====\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n     *\\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n     * constructor.\\n     * ====\\n     */\\n    function isContract(address account) internal view returns (bool) {\\n        // This method relies on extcodesize/address.code.length, which returns 0\\n        // for contracts in construction, since the code is only stored at the end\\n        // of the constructor execution.\\n\\n        return account.code.length > 0;\\n    }\\n\\n    /**\\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n     * `recipient`, forwarding all available gas and reverting on errors.\\n     *\\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n     * imposed by `transfer`, making them unable to receive funds via\\n     * `transfer`. {sendValue} removes this limitation.\\n     *\\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n     *\\n     * IMPORTANT: because control is transferred to `recipient`, care must be\\n     * taken to not create reentrancy vulnerabilities. Consider using\\n     * {ReentrancyGuard} or the\\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n     */\\n    function sendValue(address payable recipient, uint256 amount) internal {\\n        require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n        (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n        require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n    }\\n\\n    /**\\n     * @dev Performs a Solidity function call using a low level `call`. A\\n     * plain `call` is an unsafe replacement for a function call: use this\\n     * function instead.\\n     *\\n     * If `target` reverts with a revert reason, it is bubbled up by this\\n     * function (like regular Solidity function calls).\\n     *\\n     * Returns the raw returned data. To convert to the expected return value,\\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n     *\\n     * Requirements:\\n     *\\n     * - `target` must be a contract.\\n     * - calling `target` with `data` must not revert.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n     * `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, 0, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but also transferring `value` wei to `target`.\\n     *\\n     * Requirements:\\n     *\\n     * - the calling contract must have an ETH balance of at least `value`.\\n     * - the called Solidity function must be `payable`.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(\\n        address target,\\n        bytes memory data,\\n        uint256 value,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n        return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal view returns (bytes memory) {\\n        (bool success, bytes memory returndata) = target.staticcall(data);\\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        (bool success, bytes memory returndata) = target.delegatecall(data);\\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n     *\\n     * _Available since v4.8._\\n     */\\n    function verifyCallResultFromTarget(\\n        address target,\\n        bool success,\\n        bytes memory returndata,\\n        string memory errorMessage\\n    ) internal view returns (bytes memory) {\\n        if (success) {\\n            if (returndata.length == 0) {\\n                // only check isContract if the call was successful and the return data is empty\\n                // otherwise we already know that it was a contract\\n                require(isContract(target), \\\"Address: call to non-contract\\\");\\n            }\\n            return returndata;\\n        } else {\\n            _revert(returndata, errorMessage);\\n        }\\n    }\\n\\n    /**\\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n     * revert reason or using the provided one.\\n     *\\n     * _Available since v4.3._\\n     */\\n    function verifyCallResult(\\n        bool success,\\n        bytes memory returndata,\\n        string memory errorMessage\\n    ) internal pure returns (bytes memory) {\\n        if (success) {\\n            return returndata;\\n        } else {\\n            _revert(returndata, errorMessage);\\n        }\\n    }\\n\\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n        // Look for revert reason and bubble it up if present\\n        if (returndata.length > 0) {\\n            // The easiest way to bubble the revert reason is using memory via assembly\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                let returndata_size := mload(returndata)\\n                revert(add(32, returndata), returndata_size)\\n            }\\n        } else {\\n            revert(errorMessage);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n    function __Context_init() internal onlyInitializing {\\n    }\\n\\n    function __Context_init_unchained() internal onlyInitializing {\\n    }\\n    function _msgSender() internal view virtual returns (address) {\\n        return msg.sender;\\n    }\\n\\n    function _msgData() internal view virtual returns (bytes calldata) {\\n        return msg.data;\\n    }\\n\\n    function _contextSuffixLength() internal view virtual returns (uint256) {\\n        return 0;\\n    }\\n\\n    /**\\n     * @dev This empty reserved space is put in place to allow future versions to add new\\n     * variables without shifting down storage in the inheritance chain.\\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n     */\\n    uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x75097e35253e7fb282ee4d7f27a80eaacfa759923185bf17302a89cbc059c5ef\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary MathUpgradeable {\\n    enum Rounding {\\n        Down, // Toward negative infinity\\n        Up, // Toward infinity\\n        Zero // Toward zero\\n    }\\n\\n    /**\\n     * @dev Returns the largest of two numbers.\\n     */\\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a > b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the smallest of two numbers.\\n     */\\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a < b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the average of two numbers. The result is rounded towards\\n     * zero.\\n     */\\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b) / 2 can overflow.\\n        return (a & b) + (a ^ b) / 2;\\n    }\\n\\n    /**\\n     * @dev Returns the ceiling of the division of two numbers.\\n     *\\n     * This differs from standard division with `/` in that it rounds up instead\\n     * of rounding down.\\n     */\\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b - 1) / b can overflow on addition, so we distribute.\\n        return a == 0 ? 0 : (a - 1) / b + 1;\\n    }\\n\\n    /**\\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n     * with further edits by Uniswap Labs also under MIT license.\\n     */\\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n        unchecked {\\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n            // variables such that product = prod1 * 2^256 + prod0.\\n            uint256 prod0; // Least significant 256 bits of the product\\n            uint256 prod1; // Most significant 256 bits of the product\\n            assembly {\\n                let mm := mulmod(x, y, not(0))\\n                prod0 := mul(x, y)\\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n            }\\n\\n            // Handle non-overflow cases, 256 by 256 division.\\n            if (prod1 == 0) {\\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n                // The surrounding unchecked block does not change this fact.\\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n                return prod0 / denominator;\\n            }\\n\\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n            require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n            ///////////////////////////////////////////////\\n            // 512 by 256 division.\\n            ///////////////////////////////////////////////\\n\\n            // Make division exact by subtracting the remainder from [prod1 prod0].\\n            uint256 remainder;\\n            assembly {\\n                // Compute remainder using mulmod.\\n                remainder := mulmod(x, y, denominator)\\n\\n                // Subtract 256 bit number from 512 bit number.\\n                prod1 := sub(prod1, gt(remainder, prod0))\\n                prod0 := sub(prod0, remainder)\\n            }\\n\\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n            // See https://cs.stackexchange.com/q/138556/92363.\\n\\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\\n            uint256 twos = denominator & (~denominator + 1);\\n            assembly {\\n                // Divide denominator by twos.\\n                denominator := div(denominator, twos)\\n\\n                // Divide [prod1 prod0] by twos.\\n                prod0 := div(prod0, twos)\\n\\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n                twos := add(div(sub(0, twos), twos), 1)\\n            }\\n\\n            // Shift in bits from prod1 into prod0.\\n            prod0 |= prod1 * twos;\\n\\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n            // four bits. That is, denominator * inv = 1 mod 2^4.\\n            uint256 inverse = (3 * denominator) ^ 2;\\n\\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n            // in modular arithmetic, doubling the correct bits in each step.\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n            // is no longer required.\\n            result = prod0 * inverse;\\n            return result;\\n        }\\n    }\\n\\n    /**\\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n     */\\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n        uint256 result = mulDiv(x, y, denominator);\\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n            result += 1;\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n     *\\n     * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n     */\\n    function sqrt(uint256 a) internal pure returns (uint256) {\\n        if (a == 0) {\\n            return 0;\\n        }\\n\\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n        //\\n        // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n        //\\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n        // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n        // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n        //\\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n        uint256 result = 1 << (log2(a) >> 1);\\n\\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n        // into the expected uint128 result.\\n        unchecked {\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            return min(result, a / result);\\n        }\\n    }\\n\\n    /**\\n     * @notice Calculates sqrt(a), following the selected rounding direction.\\n     */\\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = sqrt(a);\\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the log in base 2, rounded down, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log2(uint256 value) internal pure returns (uint256) {\\n        uint256 result = 0;\\n        unchecked {\\n            if (value >> 128 > 0) {\\n                value >>= 128;\\n                result += 128;\\n            }\\n            if (value >> 64 > 0) {\\n                value >>= 64;\\n                result += 64;\\n            }\\n            if (value >> 32 > 0) {\\n                value >>= 32;\\n                result += 32;\\n            }\\n            if (value >> 16 > 0) {\\n                value >>= 16;\\n                result += 16;\\n            }\\n            if (value >> 8 > 0) {\\n                value >>= 8;\\n                result += 8;\\n            }\\n            if (value >> 4 > 0) {\\n                value >>= 4;\\n                result += 4;\\n            }\\n            if (value >> 2 > 0) {\\n                value >>= 2;\\n                result += 2;\\n            }\\n            if (value >> 1 > 0) {\\n                result += 1;\\n            }\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = log2(value);\\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the log in base 10, rounded down, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log10(uint256 value) internal pure returns (uint256) {\\n        uint256 result = 0;\\n        unchecked {\\n            if (value >= 10 ** 64) {\\n                value /= 10 ** 64;\\n                result += 64;\\n            }\\n            if (value >= 10 ** 32) {\\n                value /= 10 ** 32;\\n                result += 32;\\n            }\\n            if (value >= 10 ** 16) {\\n                value /= 10 ** 16;\\n                result += 16;\\n            }\\n            if (value >= 10 ** 8) {\\n                value /= 10 ** 8;\\n                result += 8;\\n            }\\n            if (value >= 10 ** 4) {\\n                value /= 10 ** 4;\\n                result += 4;\\n            }\\n            if (value >= 10 ** 2) {\\n                value /= 10 ** 2;\\n                result += 2;\\n            }\\n            if (value >= 10 ** 1) {\\n                result += 1;\\n            }\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = log10(value);\\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the log in base 256, rounded down, of a positive value.\\n     * Returns 0 if given 0.\\n     *\\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n     */\\n    function log256(uint256 value) internal pure returns (uint256) {\\n        uint256 result = 0;\\n        unchecked {\\n            if (value >> 128 > 0) {\\n                value >>= 128;\\n                result += 16;\\n            }\\n            if (value >> 64 > 0) {\\n                value >>= 64;\\n                result += 8;\\n            }\\n            if (value >> 32 > 0) {\\n                value >>= 32;\\n                result += 4;\\n            }\\n            if (value >> 16 > 0) {\\n                value >>= 16;\\n                result += 2;\\n            }\\n            if (value >> 8 > 0) {\\n                result += 1;\\n            }\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = log256(value);\\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x2bc0007987c229ae7624eb29be6a9b84f6a6a5872f76248b15208b131ea41c4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n    /**\\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n     *\\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n     * {RoleAdminChanged} not being emitted signaling this.\\n     *\\n     * _Available since v3.1._\\n     */\\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n    /**\\n     * @dev Emitted when `account` is granted `role`.\\n     *\\n     * `sender` is the account that originated the contract call, an admin role\\n     * bearer except when using {AccessControl-_setupRole}.\\n     */\\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n    /**\\n     * @dev Emitted when `account` is revoked `role`.\\n     *\\n     * `sender` is the account that originated the contract call:\\n     *   - if using `revokeRole`, it is the admin role bearer\\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n     */\\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n    /**\\n     * @dev Returns `true` if `account` has been granted `role`.\\n     */\\n    function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n    /**\\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\\n     * {revokeRole}.\\n     *\\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n     */\\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n    /**\\n     * @dev Grants `role` to `account`.\\n     *\\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\\n     * event.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must have ``role``'s admin role.\\n     */\\n    function grantRole(bytes32 role, address account) external;\\n\\n    /**\\n     * @dev Revokes `role` from `account`.\\n     *\\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must have ``role``'s admin role.\\n     */\\n    function revokeRole(bytes32 role, address account) external;\\n\\n    /**\\n     * @dev Revokes `role` from the calling account.\\n     *\\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n     * purpose is to provide a mechanism for accounts to lose their privileges\\n     * if they are compromised (such as when a trusted device is misplaced).\\n     *\\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\\n     * event.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be `account`.\\n     */\\n    function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n    address private _owner;\\n\\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n    /**\\n     * @dev Initializes the contract setting the deployer as the initial owner.\\n     */\\n    constructor() {\\n        _transferOwnership(_msgSender());\\n    }\\n\\n    /**\\n     * @dev Throws if called by any account other than the owner.\\n     */\\n    modifier onlyOwner() {\\n        _checkOwner();\\n        _;\\n    }\\n\\n    /**\\n     * @dev Returns the address of the current owner.\\n     */\\n    function owner() public view virtual returns (address) {\\n        return _owner;\\n    }\\n\\n    /**\\n     * @dev Throws if the sender is not the owner.\\n     */\\n    function _checkOwner() internal view virtual {\\n        require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n    }\\n\\n    /**\\n     * @dev Leaves the contract without owner. It will not be possible to call\\n     * `onlyOwner` functions. Can only be called by the current owner.\\n     *\\n     * NOTE: Renouncing ownership will leave the contract without an owner,\\n     * thereby disabling any functionality that is only available to the owner.\\n     */\\n    function renounceOwnership() public virtual onlyOwner {\\n        _transferOwnership(address(0));\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Can only be called by the current owner.\\n     */\\n    function transferOwnership(address newOwner) public virtual onlyOwner {\\n        require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n        _transferOwnership(newOwner);\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Internal function without access restriction.\\n     */\\n    function _transferOwnership(address newOwner) internal virtual {\\n        address oldOwner = _owner;\\n        _owner = newOwner;\\n        emit OwnershipTransferred(oldOwner, newOwner);\\n    }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC1967.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\\n *\\n * _Available since v4.8.3._\\n */\\ninterface IERC1967 {\\n    /**\\n     * @dev Emitted when the implementation is upgraded.\\n     */\\n    event Upgraded(address indexed implementation);\\n\\n    /**\\n     * @dev Emitted when the admin account has changed.\\n     */\\n    event AdminChanged(address previousAdmin, address newAdmin);\\n\\n    /**\\n     * @dev Emitted when the beacon is changed.\\n     */\\n    event BeaconUpgraded(address indexed beacon);\\n}\\n\",\"keccak256\":\"0x3cbef5ebc24b415252e2f8c0c9254555d30d9f085603b4b80d9b5ed20ab87e90\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n    /**\\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n     * address.\\n     *\\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n     * function revert if invoked through a proxy.\\n     */\\n    function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/IERC1967.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract ERC1967Upgrade is IERC1967 {\\n    // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n    /**\\n     * @dev Storage slot with the address of the current implementation.\\n     * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n     * validated in the constructor.\\n     */\\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n    /**\\n     * @dev Returns the current implementation address.\\n     */\\n    function _getImplementation() internal view returns (address) {\\n        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n    }\\n\\n    /**\\n     * @dev Stores a new address in the EIP1967 implementation slot.\\n     */\\n    function _setImplementation(address newImplementation) private {\\n        require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n    }\\n\\n    /**\\n     * @dev Perform implementation upgrade\\n     *\\n     * Emits an {Upgraded} event.\\n     */\\n    function _upgradeTo(address newImplementation) internal {\\n        _setImplementation(newImplementation);\\n        emit Upgraded(newImplementation);\\n    }\\n\\n    /**\\n     * @dev Perform implementation upgrade with additional setup call.\\n     *\\n     * Emits an {Upgraded} event.\\n     */\\n    function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\\n        _upgradeTo(newImplementation);\\n        if (data.length > 0 || forceCall) {\\n            Address.functionDelegateCall(newImplementation, data);\\n        }\\n    }\\n\\n    /**\\n     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n     *\\n     * Emits an {Upgraded} event.\\n     */\\n    function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\\n        // Upgrades from old implementations will perform a rollback test. This test requires the new\\n        // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n        // this special case will break upgrade paths from old UUPS implementation to new ones.\\n        if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n            _setImplementation(newImplementation);\\n        } else {\\n            try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n                require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n            } catch {\\n                revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n            }\\n            _upgradeToAndCall(newImplementation, data, forceCall);\\n        }\\n    }\\n\\n    /**\\n     * @dev Storage slot with the admin of the contract.\\n     * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n     * validated in the constructor.\\n     */\\n    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n    /**\\n     * @dev Returns the current admin.\\n     */\\n    function _getAdmin() internal view returns (address) {\\n        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n    }\\n\\n    /**\\n     * @dev Stores a new address in the EIP1967 admin slot.\\n     */\\n    function _setAdmin(address newAdmin) private {\\n        require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n    }\\n\\n    /**\\n     * @dev Changes the admin of the proxy.\\n     *\\n     * Emits an {AdminChanged} event.\\n     */\\n    function _changeAdmin(address newAdmin) internal {\\n        emit AdminChanged(_getAdmin(), newAdmin);\\n        _setAdmin(newAdmin);\\n    }\\n\\n    /**\\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n     */\\n    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n    /**\\n     * @dev Returns the current beacon.\\n     */\\n    function _getBeacon() internal view returns (address) {\\n        return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n    }\\n\\n    /**\\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\\n     */\\n    function _setBeacon(address newBeacon) private {\\n        require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n        require(\\n            Address.isContract(IBeacon(newBeacon).implementation()),\\n            \\\"ERC1967: beacon implementation is not a contract\\\"\\n        );\\n        StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n    }\\n\\n    /**\\n     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n     *\\n     * Emits a {BeaconUpgraded} event.\\n     */\\n    function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\\n        _setBeacon(newBeacon);\\n        emit BeaconUpgraded(newBeacon);\\n        if (data.length > 0 || forceCall) {\\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x3b21ae06bf5957f73fa16754b0669c77b7abd8ba6c072d35c3281d446fdb86c2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n    /**\\n     * @dev Delegates the current call to `implementation`.\\n     *\\n     * This function does not return to its internal call site, it will return directly to the external caller.\\n     */\\n    function _delegate(address implementation) internal virtual {\\n        assembly {\\n            // Copy msg.data. We take full control of memory in this inline assembly\\n            // block because it will not return to Solidity code. We overwrite the\\n            // Solidity scratch pad at memory position 0.\\n            calldatacopy(0, 0, calldatasize())\\n\\n            // Call the implementation.\\n            // out and outsize are 0 because we don't know the size yet.\\n            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n            // Copy the returned data.\\n            returndatacopy(0, 0, returndatasize())\\n\\n            switch result\\n            // delegatecall returns 0 on error.\\n            case 0 {\\n                revert(0, returndatasize())\\n            }\\n            default {\\n                return(0, returndatasize())\\n            }\\n        }\\n    }\\n\\n    /**\\n     * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n     * and {_fallback} should delegate.\\n     */\\n    function _implementation() internal view virtual returns (address);\\n\\n    /**\\n     * @dev Delegates the current call to the address returned by `_implementation()`.\\n     *\\n     * This function does not return to its internal call site, it will return directly to the external caller.\\n     */\\n    function _fallback() internal virtual {\\n        _beforeFallback();\\n        _delegate(_implementation());\\n    }\\n\\n    /**\\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n     * function in the contract matches the call data.\\n     */\\n    fallback() external payable virtual {\\n        _fallback();\\n    }\\n\\n    /**\\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n     * is empty.\\n     */\\n    receive() external payable virtual {\\n        _fallback();\\n    }\\n\\n    /**\\n     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n     * call, or as part of the Solidity `fallback` or `receive` functions.\\n     *\\n     * If overridden should call `super._beforeFallback()`.\\n     */\\n    function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/beacon/BeaconProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IBeacon.sol\\\";\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"../ERC1967/ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that gets the implementation address for each call from an {UpgradeableBeacon}.\\n *\\n * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't\\n * conflict with the storage layout of the implementation behind the proxy.\\n *\\n * _Available since v3.4._\\n */\\ncontract BeaconProxy is Proxy, ERC1967Upgrade {\\n    /**\\n     * @dev Initializes the proxy with `beacon`.\\n     *\\n     * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This\\n     * will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity\\n     * constructor.\\n     *\\n     * Requirements:\\n     *\\n     * - `beacon` must be a contract with the interface {IBeacon}.\\n     */\\n    constructor(address beacon, bytes memory data) payable {\\n        _upgradeBeaconToAndCall(beacon, data, false);\\n    }\\n\\n    /**\\n     * @dev Returns the current beacon address.\\n     */\\n    function _beacon() internal view virtual returns (address) {\\n        return _getBeacon();\\n    }\\n\\n    /**\\n     * @dev Returns the current implementation address of the associated beacon.\\n     */\\n    function _implementation() internal view virtual override returns (address) {\\n        return IBeacon(_getBeacon()).implementation();\\n    }\\n\\n    /**\\n     * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}.\\n     *\\n     * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon.\\n     *\\n     * Requirements:\\n     *\\n     * - `beacon` must be a contract.\\n     * - The implementation returned by `beacon` must be a contract.\\n     */\\n    function _setBeacon(address beacon, bytes memory data) internal virtual {\\n        _upgradeBeaconToAndCall(beacon, data, false);\\n    }\\n}\\n\",\"keccak256\":\"0x85439e74ab467b6a23d45d32bdc9506cbc3760320289afd605f11638c4138e95\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n    /**\\n     * @dev Must return an address that can be used as a delegate call target.\\n     *\\n     * {BeaconProxy} will check that this address is a contract.\\n     */\\n    function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IBeacon.sol\\\";\\nimport \\\"../../access/Ownable.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their\\n * implementation contract, which is where they will delegate all function calls.\\n *\\n * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.\\n */\\ncontract UpgradeableBeacon is IBeacon, Ownable {\\n    address private _implementation;\\n\\n    /**\\n     * @dev Emitted when the implementation returned by the beacon is changed.\\n     */\\n    event Upgraded(address indexed implementation);\\n\\n    /**\\n     * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the\\n     * beacon.\\n     */\\n    constructor(address implementation_) {\\n        _setImplementation(implementation_);\\n    }\\n\\n    /**\\n     * @dev Returns the current implementation address.\\n     */\\n    function implementation() public view virtual override returns (address) {\\n        return _implementation;\\n    }\\n\\n    /**\\n     * @dev Upgrades the beacon to a new implementation.\\n     *\\n     * Emits an {Upgraded} event.\\n     *\\n     * Requirements:\\n     *\\n     * - msg.sender must be the owner of the contract.\\n     * - `newImplementation` must be a contract.\\n     */\\n    function upgradeTo(address newImplementation) public virtual onlyOwner {\\n        _setImplementation(newImplementation);\\n        emit Upgraded(newImplementation);\\n    }\\n\\n    /**\\n     * @dev Sets the implementation contract address for this beacon\\n     *\\n     * Requirements:\\n     *\\n     * - `newImplementation` must be a contract.\\n     */\\n    function _setImplementation(address newImplementation) private {\\n        require(Address.isContract(newImplementation), \\\"UpgradeableBeacon: implementation is not a contract\\\");\\n        _implementation = newImplementation;\\n    }\\n}\\n\",\"keccak256\":\"0x6ec71aef5659f3f74011169948d2fcda8c6599be5bb38f986380a8737f96cc0f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n    /**\\n     * @dev Returns true if `account` is a contract.\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * It is unsafe to assume that an address for which this function returns\\n     * false is an externally-owned account (EOA) and not a contract.\\n     *\\n     * Among others, `isContract` will return false for the following\\n     * types of addresses:\\n     *\\n     *  - an externally-owned account\\n     *  - a contract in construction\\n     *  - an address where a contract will be created\\n     *  - an address where a contract lived, but was destroyed\\n     *\\n     * Furthermore, `isContract` will also return true if the target contract within\\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n     * which only has an effect at the end of a transaction.\\n     * ====\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n     *\\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n     * constructor.\\n     * ====\\n     */\\n    function isContract(address account) internal view returns (bool) {\\n        // This method relies on extcodesize/address.code.length, which returns 0\\n        // for contracts in construction, since the code is only stored at the end\\n        // of the constructor execution.\\n\\n        return account.code.length > 0;\\n    }\\n\\n    /**\\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n     * `recipient`, forwarding all available gas and reverting on errors.\\n     *\\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n     * imposed by `transfer`, making them unable to receive funds via\\n     * `transfer`. {sendValue} removes this limitation.\\n     *\\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n     *\\n     * IMPORTANT: because control is transferred to `recipient`, care must be\\n     * taken to not create reentrancy vulnerabilities. Consider using\\n     * {ReentrancyGuard} or the\\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n     */\\n    function sendValue(address payable recipient, uint256 amount) internal {\\n        require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n        (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n        require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n    }\\n\\n    /**\\n     * @dev Performs a Solidity function call using a low level `call`. A\\n     * plain `call` is an unsafe replacement for a function call: use this\\n     * function instead.\\n     *\\n     * If `target` reverts with a revert reason, it is bubbled up by this\\n     * function (like regular Solidity function calls).\\n     *\\n     * Returns the raw returned data. To convert to the expected return value,\\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n     *\\n     * Requirements:\\n     *\\n     * - `target` must be a contract.\\n     * - calling `target` with `data` must not revert.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n     * `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, 0, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but also transferring `value` wei to `target`.\\n     *\\n     * Requirements:\\n     *\\n     * - the calling contract must have an ETH balance of at least `value`.\\n     * - the called Solidity function must be `payable`.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(\\n        address target,\\n        bytes memory data,\\n        uint256 value,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n        return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal view returns (bytes memory) {\\n        (bool success, bytes memory returndata) = target.staticcall(data);\\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n        return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a delegate call.\\n     *\\n     * _Available since v3.4._\\n     */\\n    function functionDelegateCall(\\n        address target,\\n        bytes memory data,\\n        string memory errorMessage\\n    ) internal returns (bytes memory) {\\n        (bool success, bytes memory returndata) = target.delegatecall(data);\\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n     *\\n     * _Available since v4.8._\\n     */\\n    function verifyCallResultFromTarget(\\n        address target,\\n        bool success,\\n        bytes memory returndata,\\n        string memory errorMessage\\n    ) internal view returns (bytes memory) {\\n        if (success) {\\n            if (returndata.length == 0) {\\n                // only check isContract if the call was successful and the return data is empty\\n                // otherwise we already know that it was a contract\\n                require(isContract(target), \\\"Address: call to non-contract\\\");\\n            }\\n            return returndata;\\n        } else {\\n            _revert(returndata, errorMessage);\\n        }\\n    }\\n\\n    /**\\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n     * revert reason or using the provided one.\\n     *\\n     * _Available since v4.3._\\n     */\\n    function verifyCallResult(\\n        bool success,\\n        bytes memory returndata,\\n        string memory errorMessage\\n    ) internal pure returns (bytes memory) {\\n        if (success) {\\n            return returndata;\\n        } else {\\n            _revert(returndata, errorMessage);\\n        }\\n    }\\n\\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n        // Look for revert reason and bubble it up if present\\n        if (returndata.length > 0) {\\n            // The easiest way to bubble the revert reason is using memory via assembly\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                let returndata_size := mload(returndata)\\n                revert(add(32, returndata), returndata_size)\\n            }\\n        } else {\\n            revert(errorMessage);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n    function _msgSender() internal view virtual returns (address) {\\n        return msg.sender;\\n    }\\n\\n    function _msgData() internal view virtual returns (bytes calldata) {\\n        return msg.data;\\n    }\\n\\n    function _contextSuffixLength() internal view virtual returns (uint256) {\\n        return 0;\\n    }\\n}\\n\",\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n *     function _getImplementation() internal view returns (address) {\\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n *     }\\n *\\n *     function _setImplementation(address newImplementation) internal {\\n *         require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n *     }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlot {\\n    struct AddressSlot {\\n        address value;\\n    }\\n\\n    struct BooleanSlot {\\n        bool value;\\n    }\\n\\n    struct Bytes32Slot {\\n        bytes32 value;\\n    }\\n\\n    struct Uint256Slot {\\n        uint256 value;\\n    }\\n\\n    struct StringSlot {\\n        string value;\\n    }\\n\\n    struct BytesSlot {\\n        bytes value;\\n    }\\n\\n    /**\\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n     */\\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n     */\\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n     */\\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n     */\\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n     */\\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n     */\\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := store.slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n     */\\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n     */\\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := store.slot\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xf09e68aa0dc6722a25bc46490e8d48ed864466d17313b8a0b254c36b54e49899\",\"license\":\"MIT\"},\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\n\\nimport \\\"./IAccessControlManagerV8.sol\\\";\\n\\n/**\\n * @title AccessControlledV8\\n * @author Venus\\n * @notice This contract is helper between access control manager and actual contract. This contract further inherited by other contract (using solidity 0.8.13)\\n * to integrate access controlled mechanism. It provides initialise methods and verifying access methods.\\n */\\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\\n    /// @notice Access control manager contract\\n    IAccessControlManagerV8 internal _accessControlManager;\\n\\n    /**\\n     * @dev This empty reserved space is put in place to allow future versions to add new\\n     * variables without shifting down storage in the inheritance chain.\\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n     */\\n    uint256[49] private __gap;\\n\\n    /// @notice Emitted when access control manager contract address is changed\\n    event NewAccessControlManager(address oldAccessControlManager, address newAccessControlManager);\\n\\n    /// @notice Thrown when the action is prohibited by AccessControlManager\\n    error Unauthorized(address sender, address calledContract, string methodSignature);\\n\\n    function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\\n        __Ownable2Step_init();\\n        __AccessControlled_init_unchained(accessControlManager_);\\n    }\\n\\n    function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\\n        _setAccessControlManager(accessControlManager_);\\n    }\\n\\n    /**\\n     * @notice Sets the address of AccessControlManager\\n     * @dev Admin function to set address of AccessControlManager\\n     * @param accessControlManager_ The new address of the AccessControlManager\\n     * @custom:event Emits NewAccessControlManager event\\n     * @custom:access Only Governance\\n     */\\n    function setAccessControlManager(address accessControlManager_) external onlyOwner {\\n        _setAccessControlManager(accessControlManager_);\\n    }\\n\\n    /**\\n     * @notice Returns the address of the access control manager contract\\n     */\\n    function accessControlManager() external view returns (IAccessControlManagerV8) {\\n        return _accessControlManager;\\n    }\\n\\n    /**\\n     * @dev Internal function to set address of AccessControlManager\\n     * @param accessControlManager_ The new address of the AccessControlManager\\n     */\\n    function _setAccessControlManager(address accessControlManager_) internal {\\n        require(address(accessControlManager_) != address(0), \\\"invalid acess control manager address\\\");\\n        address oldAccessControlManager = address(_accessControlManager);\\n        _accessControlManager = IAccessControlManagerV8(accessControlManager_);\\n        emit NewAccessControlManager(oldAccessControlManager, accessControlManager_);\\n    }\\n\\n    /**\\n     * @notice Reverts if the call is not allowed by AccessControlManager\\n     * @param signature Method signature\\n     */\\n    function _checkAccessAllowed(string memory signature) internal view {\\n        bool isAllowedToCall = _accessControlManager.isAllowedToCall(msg.sender, signature);\\n\\n        if (!isAllowedToCall) {\\n            revert Unauthorized(msg.sender, address(this), signature);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xfe0fd441c84ac907cabc88db69ef04f6d7532d770c7e6a1dfe6e7d6305debb49\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\nimport \\\"@openzeppelin/contracts/access/IAccessControl.sol\\\";\\n\\n/**\\n * @title IAccessControlManagerV8\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV8` contract.\\n */\\ninterface IAccessControlManagerV8 is IAccessControl {\\n    function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n    function revokeCallPermission(\\n        address contractAddress,\\n        string calldata functionSig,\\n        address accountToRevoke\\n    ) external;\\n\\n    function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n    function hasPermission(\\n        address account,\\n        address contractAddress,\\n        string calldata functionSig\\n    ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xaa29b098440d0b3a131c5ecdf25ce548790c1b5ac7bf9b5c0264b6af6f7a1e0b\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\ninterface OracleInterface {\\n    function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n    function updatePrice(address vToken) external;\\n\\n    function updateAssetPrice(address asset) external;\\n\\n    function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface TwapInterface is OracleInterface {\\n    function updateTwap(address asset) external returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n    function validatePriceWithAnchorPrice(\\n        address asset,\\n        uint256 reporterPrice,\\n        uint256 anchorPrice\\n    ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x2432799b0d824fc701beb4c30146e912b9aeecf77b5c1635dde6c5fbe6bfc3a7\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/protocol-reserve/contracts/Interfaces/IProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\ninterface IProtocolShareReserve {\\n    /// @notice it represents the type of vToken income\\n    enum IncomeType {\\n        SPREAD,\\n        LIQUIDATION\\n    }\\n\\n    function updateAssetsState(\\n        address comptroller,\\n        address asset,\\n        IncomeType incomeType\\n    ) external;\\n}\\n\",\"keccak256\":\"0x5fddc5b63fdd850b3b5c83576cda50dcb27a205dbb1a23af17d9da0d9f04fa0a\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/solidity-utilities/contracts/TimeManagerV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { SECONDS_PER_YEAR } from \\\"./constants.sol\\\";\\n\\nabstract contract TimeManagerV8 {\\n    /// @notice Stores blocksPerYear if isTimeBased is true else secondsPerYear is stored\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    uint256 public immutable blocksOrSecondsPerYear;\\n\\n    /// @notice Acknowledges if a contract is time based or not\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    bool public immutable isTimeBased;\\n\\n    /// @notice Stores the current block timestamp or block number depending on isTimeBased\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    function() view returns (uint256) private immutable _getCurrentSlot;\\n\\n    /**\\n     * @dev This empty reserved space is put in place to allow future versions to add new\\n     * variables without shifting down storage in the inheritance chain\\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n     */\\n    uint256[48] private __gap;\\n\\n    /// @notice Thrown when blocks per year is invalid\\n    error InvalidBlocksPerYear();\\n\\n    /// @notice Thrown when time based but blocks per year is provided\\n    error InvalidTimeBasedConfiguration();\\n\\n    /**\\n     * @param timeBased_ A boolean indicating whether the contract is based on time or block\\n     * If timeBased is true than blocksPerYear_ param is ignored as blocksOrSecondsPerYear is set to SECONDS_PER_YEAR\\n     * @param blocksPerYear_ The number of blocks per year\\n     * @custom:error InvalidBlocksPerYear is thrown if blocksPerYear entered is zero and timeBased is false\\n     * @custom:error InvalidTimeBasedConfiguration is thrown if blocksPerYear entered is non zero and timeBased is true\\n     * @custom:oz-upgrades-unsafe-allow constructor\\n     */\\n    constructor(bool timeBased_, uint256 blocksPerYear_) {\\n        if (!timeBased_ && blocksPerYear_ == 0) {\\n            revert InvalidBlocksPerYear();\\n        }\\n\\n        if (timeBased_ && blocksPerYear_ != 0) {\\n            revert InvalidTimeBasedConfiguration();\\n        }\\n\\n        isTimeBased = timeBased_;\\n        blocksOrSecondsPerYear = timeBased_ ? SECONDS_PER_YEAR : blocksPerYear_;\\n        _getCurrentSlot = timeBased_ ? _getBlockTimestamp : _getBlockNumber;\\n    }\\n\\n    /**\\n     * @dev Function to simply retrieve block number or block timestamp\\n     * @return Current block number or block timestamp\\n     */\\n    function getBlockNumberOrTimestamp() public view virtual returns (uint256) {\\n        return _getCurrentSlot();\\n    }\\n\\n    /**\\n     * @dev Returns the current timestamp in seconds\\n     * @return The current timestamp\\n     */\\n    function _getBlockTimestamp() private view returns (uint256) {\\n        return block.timestamp;\\n    }\\n\\n    /**\\n     * @dev Returns the current block number\\n     * @return The current block number\\n     */\\n    function _getBlockNumber() private view returns (uint256) {\\n        return block.number;\\n    }\\n}\\n\",\"keccak256\":\"0x57a2bbb9b8e02b1c0a5c0e305fef1328a22db56c3d4b148c362010a6e767243c\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/solidity-utilities/contracts/constants.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\\nuint256 constant EXP_SCALE = 1e18;\\n\\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\\nuint256 constant MANTISSA_ONE = EXP_SCALE;\\n\\n/// @dev The approximate number of seconds per year\\nuint256 constant SECONDS_PER_YEAR = 31_536_000;\\n\",\"keccak256\":\"0x14de93ead464da249af31bea0e3bcfb62ec693bea3475fb4d90f055ac81dc5eb\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/solidity-utilities/contracts/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Thrown if the supplied value is 0 where it is not allowed\\nerror ZeroValueNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n    if (address_ == address(0)) {\\n        revert ZeroAddressNotAllowed();\\n    }\\n}\\n\\n/// @notice Checks if the provided value is nonzero, reverts otherwise\\n/// @param value_ Value to check\\n/// @custom:error ZeroValueNotAllowed is thrown if the provided value is 0\\nfunction ensureNonzeroValue(uint256 value_) pure {\\n    if (value_ == 0) {\\n        revert ZeroValueNotAllowed();\\n    }\\n}\\n\",\"keccak256\":\"0xdb88e14d50dd21889ca3329d755673d022c47e8da005b6a545c7f69c2c4b7b86\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/venus-protocol/contracts/Tokens/Prime/Interfaces/IPrime.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\nimport { PrimeStorageV1 } from \\\"../PrimeStorage.sol\\\";\\n\\n/**\\n * @title IPrime\\n * @author Venus\\n * @notice Interface for Prime Token\\n */\\ninterface IPrime {\\n    struct APRInfo {\\n        // supply APR of the user in BPS\\n        uint256 supplyAPR;\\n        // borrow APR of the user in BPS\\n        uint256 borrowAPR;\\n        // total score of the market\\n        uint256 totalScore;\\n        // score of the user\\n        uint256 userScore;\\n        // capped XVS balance of the user\\n        uint256 xvsBalanceForScore;\\n        // capital of the user\\n        uint256 capital;\\n        // capped supply of the user\\n        uint256 cappedSupply;\\n        // capped borrow of the user\\n        uint256 cappedBorrow;\\n        // capped supply of user in USD\\n        uint256 supplyCapUSD;\\n        // capped borrow of user in USD\\n        uint256 borrowCapUSD;\\n    }\\n\\n    struct Capital {\\n        // capital of the user\\n        uint256 capital;\\n        // capped supply of the user\\n        uint256 cappedSupply;\\n        // capped borrow of the user\\n        uint256 cappedBorrow;\\n        // capped supply of user in USD\\n        uint256 supplyCapUSD;\\n        // capped borrow of user in USD\\n        uint256 borrowCapUSD;\\n    }\\n\\n    /**\\n     * @notice Returns boosted pending interest accrued for a user for all markets\\n     * @param user the account for which to get the accrued interests\\n     * @return pendingRewards the number of underlying tokens accrued by the user for all markets\\n     */\\n    function getPendingRewards(address user) external returns (PrimeStorageV1.PendingReward[] memory pendingRewards);\\n\\n    /**\\n     * @notice Update total score of multiple users and market\\n     * @param users accounts for which we need to update score\\n     */\\n    function updateScores(address[] memory users) external;\\n\\n    /**\\n     * @notice Update value of alpha\\n     * @param _alphaNumerator numerator of alpha. If alpha is 0.5 then numerator is 1\\n     * @param _alphaDenominator denominator of alpha. If alpha is 0.5 then denominator is 2\\n     */\\n    function updateAlpha(uint128 _alphaNumerator, uint128 _alphaDenominator) external;\\n\\n    /**\\n     * @notice Update multipliers for a market\\n     * @param market address of the market vToken\\n     * @param supplyMultiplier new supply multiplier for the market, scaled by 1e18\\n     * @param borrowMultiplier new borrow multiplier for the market, scaled by 1e18\\n     */\\n    function updateMultipliers(address market, uint256 supplyMultiplier, uint256 borrowMultiplier) external;\\n\\n    /**\\n     * @notice Add a market to prime program\\n     * @param comptroller address of the comptroller\\n     * @param market address of the market vToken\\n     * @param supplyMultiplier the multiplier for supply cap. It should be converted to 1e18\\n     * @param borrowMultiplier the multiplier for borrow cap. It should be converted to 1e18\\n     */\\n    function addMarket(\\n        address comptroller,\\n        address market,\\n        uint256 supplyMultiplier,\\n        uint256 borrowMultiplier\\n    ) external;\\n\\n    /**\\n     * @notice Set limits for total tokens that can be minted\\n     * @param _irrevocableLimit total number of irrevocable tokens that can be minted\\n     * @param _revocableLimit total number of revocable tokens that can be minted\\n     */\\n    function setLimit(uint256 _irrevocableLimit, uint256 _revocableLimit) external;\\n\\n    /**\\n     * @notice Directly issue prime tokens to users\\n     * @param isIrrevocable are the tokens being issued\\n     * @param users list of address to issue tokens to\\n     */\\n    function issue(bool isIrrevocable, address[] calldata users) external;\\n\\n    /**\\n     * @notice Executed by XVSVault whenever user's XVSVault balance changes\\n     * @param user the account address whose balance was updated\\n     */\\n    function xvsUpdated(address user) external;\\n\\n    /**\\n     * @notice accrues interest and updates score for an user for a specific market\\n     * @param user the account address for which to accrue interest and update score\\n     * @param market the market for which to accrue interest and update score\\n     */\\n    function accrueInterestAndUpdateScore(address user, address market) external;\\n\\n    /**\\n     * @notice For claiming prime token when staking period is completed\\n     */\\n    function claim() external;\\n\\n    /**\\n     * @notice For burning any prime token\\n     * @param user the account address for which the prime token will be burned\\n     */\\n    function burn(address user) external;\\n\\n    /**\\n     * @notice To pause or unpause claiming of interest\\n     */\\n    function togglePause() external;\\n\\n    /**\\n     * @notice For user to claim boosted yield\\n     * @param vToken the market for which claim the accrued interest\\n     * @return amount the amount of tokens transferred to the user\\n     */\\n    function claimInterest(address vToken) external returns (uint256);\\n\\n    /**\\n     * @notice For user to claim boosted yield\\n     * @param vToken the market for which claim the accrued interest\\n     * @param user the user for which to claim the accrued interest\\n     * @return amount the amount of tokens transferred to the user\\n     */\\n    function claimInterest(address vToken, address user) external returns (uint256);\\n\\n    /**\\n     * @notice Distributes income from market since last distribution\\n     * @param vToken the market for which to distribute the income\\n     */\\n    function accrueInterest(address vToken) external;\\n\\n    /**\\n     * @notice Returns boosted interest accrued for a user\\n     * @param vToken the market for which to fetch the accrued interest\\n     * @param user the account for which to get the accrued interest\\n     * @return interestAccrued the number of underlying tokens accrued by the user since the last accrual\\n     */\\n    function getInterestAccrued(address vToken, address user) external returns (uint256);\\n\\n    /**\\n     * @notice Retrieves an array of all available markets\\n     * @return an array of addresses representing all available markets\\n     */\\n    function getAllMarkets() external view returns (address[] memory);\\n\\n    /**\\n     * @notice fetch the numbers of seconds remaining for staking period to complete\\n     * @param user the account address for which we are checking the remaining time\\n     * @return timeRemaining the number of seconds the user needs to wait to claim prime token\\n     */\\n    function claimTimeRemaining(address user) external view returns (uint256);\\n\\n    /**\\n     * @notice Returns supply and borrow APR for user for a given market\\n     * @param market the market for which to fetch the APR\\n     * @param user the account for which to get the APR\\n     * @return aprInfo APR information for the user for the given market\\n     */\\n    function calculateAPR(address market, address user) external view returns (APRInfo memory aprInfo);\\n\\n    /**\\n     * @notice Returns supply and borrow APR for estimated supply, borrow and XVS staked\\n     * @param market the market for which to fetch the APR\\n     * @param user the account for which to get the APR\\n     * @param borrow hypothetical borrow amount\\n     * @param supply hypothetical supply amount\\n     * @param xvsStaked hypothetical staked XVS amount\\n     * @return aprInfo APR information for the user for the given market\\n     */\\n    function estimateAPR(\\n        address market,\\n        address user,\\n        uint256 borrow,\\n        uint256 supply,\\n        uint256 xvsStaked\\n    ) external view returns (APRInfo memory aprInfo);\\n\\n    /**\\n     * @notice the total income that's going to be distributed in a year to prime token holders\\n     * @param vToken the market for which to fetch the total income that's going to distributed in a year\\n     * @return amount the total income\\n     */\\n    function incomeDistributionYearly(address vToken) external view returns (uint256 amount);\\n\\n    /**\\n     * @notice Returns if user is a prime holder\\n     * @return isPrimeHolder true if user is a prime holder\\n     */\\n    function isUserPrimeHolder(address user) external view returns (bool);\\n\\n    /**\\n     * @notice Set the limit for the loops can iterate to avoid the DOS\\n     * @param loopsLimit Number of loops limit\\n     */\\n    function setMaxLoopsLimit(uint256 loopsLimit) external;\\n\\n    /**\\n     * @notice Update staked at timestamp for multiple users\\n     * @param users accounts for which we need to update staked at timestamp\\n     * @param timestamps new staked at timestamp for the users\\n     */\\n    function setStakedAt(address[] calldata users, uint256[] calldata timestamps) external;\\n}\\n\",\"keccak256\":\"0xd112f60183416ad796093b4a83a80ddc1b8b655965f02ae55ca82e2a0c68f97d\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/venus-protocol/contracts/Tokens/Prime/PrimeStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\n/**\\n * @title PrimeStorageV1\\n * @author Venus\\n * @notice Storage for Prime Token\\n */\\ncontract PrimeStorageV1 {\\n    struct Token {\\n        bool exists;\\n        bool isIrrevocable;\\n    }\\n\\n    struct Market {\\n        uint256 supplyMultiplier;\\n        uint256 borrowMultiplier;\\n        uint256 rewardIndex;\\n        uint256 sumOfMembersScore;\\n        bool exists;\\n    }\\n\\n    struct Interest {\\n        uint256 accrued;\\n        uint256 score;\\n        uint256 rewardIndex;\\n    }\\n\\n    struct PendingReward {\\n        address vToken;\\n        address rewardToken;\\n        uint256 amount;\\n    }\\n\\n    /// @notice Base unit for computations, usually used in scaling (multiplications, divisions)\\n    uint256 internal constant EXP_SCALE = 1e18;\\n\\n    /// @notice maximum BPS = 100%\\n    uint256 internal constant MAXIMUM_BPS = 1e4;\\n\\n    /// @notice Mapping to get prime token's metadata\\n    mapping(address => Token) public tokens;\\n\\n    /// @notice  Tracks total irrevocable tokens minted\\n    uint256 public totalIrrevocable;\\n\\n    /// @notice  Tracks total revocable tokens minted\\n    uint256 public totalRevocable;\\n\\n    /// @notice  Indicates maximum revocable tokens that can be minted\\n    uint256 public revocableLimit;\\n\\n    /// @notice  Indicates maximum irrevocable tokens that can be minted\\n    uint256 public irrevocableLimit;\\n\\n    /// @notice Tracks when prime token eligible users started staking for claiming prime token\\n    mapping(address => uint256) public stakedAt;\\n\\n    /// @notice vToken to market configuration\\n    mapping(address => Market) public markets;\\n\\n    /// @notice vToken to user to user index\\n    mapping(address => mapping(address => Interest)) public interests;\\n\\n    /// @notice A list of boosted markets\\n    address[] internal _allMarkets;\\n\\n    /// @notice numerator of alpha. Ex: if alpha is 0.5 then this will be 1\\n    uint128 public alphaNumerator;\\n\\n    /// @notice denominator of alpha. Ex: if alpha is 0.5 then this will be 2\\n    uint128 public alphaDenominator;\\n\\n    /// @notice address of XVS vault\\n    address public xvsVault;\\n\\n    /// @notice address of XVS vault reward token\\n    address public xvsVaultRewardToken;\\n\\n    /// @notice address of XVS vault pool id\\n    uint256 public xvsVaultPoolId;\\n\\n    /// @notice mapping to check if a account's score was updated in the round\\n    mapping(uint256 => mapping(address => bool)) public isScoreUpdated;\\n\\n    /// @notice unique id for next round\\n    uint256 public nextScoreUpdateRoundId;\\n\\n    /// @notice total number of accounts whose score needs to be updated\\n    uint256 public totalScoreUpdatesRequired;\\n\\n    /// @notice total number of accounts whose score is yet to be updated\\n    uint256 public pendingScoreUpdates;\\n\\n    /// @notice mapping used to find if an asset is part of prime markets\\n    mapping(address => address) public vTokenForAsset;\\n\\n    /// @notice Address of core pool comptroller contract\\n    address internal corePoolComptroller;\\n\\n    /// @notice unreleased income from PLP that's already distributed to prime holders\\n    /// @dev mapping of asset address => amount\\n    mapping(address => uint256) public unreleasedPLPIncome;\\n\\n    /// @notice The address of PLP contract\\n    address public primeLiquidityProvider;\\n\\n    /// @notice The address of ResilientOracle contract\\n    ResilientOracleInterface public oracle;\\n\\n    /// @notice The address of PoolRegistry contract\\n    address public poolRegistry;\\n\\n    /// @dev This empty reserved space is put in place to allow future versions to add new\\n    /// variables without shifting down storage in the inheritance chain.\\n    uint256[26] private __gap;\\n}\\n\",\"keccak256\":\"0x5285c875114db2ea2be0b81b65722d5761806217022db733323c4e03365a95e7\",\"license\":\"BSD-3-Clause\"},\"contracts/Comptroller.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\nimport { IPrime } from \\\"@venusprotocol/venus-protocol/contracts/Tokens/Prime/Interfaces/IPrime.sol\\\";\\n\\nimport { ComptrollerInterface, Action } from \\\"./ComptrollerInterface.sol\\\";\\nimport { ComptrollerStorage } from \\\"./ComptrollerStorage.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"./MaxLoopsLimitHelper.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title Comptroller\\n * @author Venus\\n * @notice The Comptroller is designed to provide checks for all minting, redeeming, transferring, borrowing, lending, repaying, liquidating,\\n * and seizing done by the `vToken` contract. Each pool has one `Comptroller` checking these interactions across markets. When a user interacts\\n * with a given market by one of these main actions, a call is made to a corresponding hook in the associated `Comptroller`, which either allows\\n * or reverts the transaction. These hooks also update supply and borrow rewards as they are called. The comptroller holds the logic for assessing\\n * liquidity snapshots of an account via the collateral factor and liquidation threshold. This check determines the collateral needed for a borrow,\\n * as well as how much of a borrow may be liquidated. A user may borrow a portion of their collateral with the maximum amount determined by the\\n * markets collateral factor. However, if their borrowed amount exceeds an amount calculated using the market\\u2019s corresponding liquidation threshold,\\n * the borrow is eligible for liquidation.\\n *\\n * The `Comptroller` also includes two functions `liquidateAccount()` and `healAccount()`, which are meant to handle accounts that do not exceed\\n * the `minLiquidatableCollateral` for the `Comptroller`:\\n *\\n * - `healAccount()`: This function is called to seize all of a given user\\u2019s collateral, requiring the `msg.sender` repay a certain percentage\\n * of the debt calculated by `collateral/(borrows*liquidationIncentive)`. The function can only be called if the calculated percentage does not exceed\\n * 100%, because otherwise no `badDebt` would be created and `liquidateAccount()` should be used instead. The difference in the actual amount of debt\\n * and debt paid off is recorded as `badDebt` for each market, which can then be auctioned off for the risk reserves of the associated pool.\\n * - `liquidateAccount()`: This function can only be called if the collateral seized will cover all borrows of an account, as well as the liquidation\\n * incentive. Otherwise, the pool will incur bad debt, in which case the function `healAccount()` should be used instead. This function skips the logic\\n * verifying that the repay amount does not exceed the close factor.\\n */\\ncontract Comptroller is\\n    Ownable2StepUpgradeable,\\n    AccessControlledV8,\\n    ComptrollerStorage,\\n    ComptrollerInterface,\\n    ExponentialNoError,\\n    MaxLoopsLimitHelper\\n{\\n    // PoolRegistry, immutable to save on gas\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    address public immutable poolRegistry;\\n\\n    /// @notice Emitted when an account enters a market\\n    event MarketEntered(VToken indexed vToken, address indexed account);\\n\\n    /// @notice Emitted when an account exits a market\\n    event MarketExited(VToken indexed vToken, address indexed account);\\n\\n    /// @notice Emitted when close factor is changed by admin\\n    event NewCloseFactor(uint256 oldCloseFactorMantissa, uint256 newCloseFactorMantissa);\\n\\n    /// @notice Emitted when a collateral factor is changed by admin\\n    event NewCollateralFactor(VToken vToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa);\\n\\n    /// @notice Emitted when liquidation threshold is changed by admin\\n    event NewLiquidationThreshold(\\n        VToken vToken,\\n        uint256 oldLiquidationThresholdMantissa,\\n        uint256 newLiquidationThresholdMantissa\\n    );\\n\\n    /// @notice Emitted when liquidation incentive is changed by admin\\n    event NewLiquidationIncentive(uint256 oldLiquidationIncentiveMantissa, uint256 newLiquidationIncentiveMantissa);\\n\\n    /// @notice Emitted when price oracle is changed\\n    event NewPriceOracle(ResilientOracleInterface oldPriceOracle, ResilientOracleInterface newPriceOracle);\\n\\n    /// @notice Emitted when an action is paused on a market\\n    event ActionPausedMarket(VToken vToken, Action action, bool pauseState);\\n\\n    /// @notice Emitted when borrow cap for a vToken is changed\\n    event NewBorrowCap(VToken indexed vToken, uint256 newBorrowCap);\\n\\n    /// @notice Emitted when the collateral threshold (in USD) for non-batch liquidations is changed\\n    event NewMinLiquidatableCollateral(uint256 oldMinLiquidatableCollateral, uint256 newMinLiquidatableCollateral);\\n\\n    /// @notice Emitted when supply cap for a vToken is changed\\n    event NewSupplyCap(VToken indexed vToken, uint256 newSupplyCap);\\n\\n    /// @notice Emitted when a rewards distributor is added\\n    event NewRewardsDistributor(address indexed rewardsDistributor, address indexed rewardToken);\\n\\n    /// @notice Emitted when a market is supported\\n    event MarketSupported(VToken vToken);\\n\\n    /// @notice Emitted when prime token contract address is changed\\n    event NewPrimeToken(IPrime oldPrimeToken, IPrime newPrimeToken);\\n\\n    /// @notice Emitted when forced liquidation is enabled or disabled for a market\\n    event IsForcedLiquidationEnabledUpdated(address indexed vToken, bool enable);\\n\\n    /// @notice Emitted when a market is unlisted\\n    event MarketUnlisted(address indexed vToken);\\n    /// @notice Emitted when the borrowing or redeeming delegate rights are updated for an account\\n    event DelegateUpdated(address indexed approver, address indexed delegate, bool approved);\\n\\n    /// @notice Thrown when collateral factor exceeds the upper bound\\n    error InvalidCollateralFactor();\\n\\n    /// @notice Thrown when liquidation threshold exceeds the collateral factor\\n    error InvalidLiquidationThreshold();\\n\\n    /// @notice Thrown when the action is only available to specific sender, but the real sender was different\\n    error UnexpectedSender(address expectedSender, address actualSender);\\n\\n    /// @notice Thrown when the oracle returns an invalid price for some asset\\n    error PriceError(address vToken);\\n\\n    /// @notice Thrown if VToken unexpectedly returned a nonzero error code while trying to get account snapshot\\n    error SnapshotError(address vToken, address user);\\n\\n    /// @notice Thrown when the market is not listed\\n    error MarketNotListed(address market);\\n\\n    /// @notice Thrown when a market has an unexpected comptroller\\n    error ComptrollerMismatch();\\n\\n    /// @notice Thrown when user is not member of market\\n    error MarketNotCollateral(address vToken, address user);\\n\\n    /// @notice Thrown when borrow action is not paused\\n    error BorrowActionNotPaused();\\n\\n    /// @notice Thrown when mint action is not paused\\n    error MintActionNotPaused();\\n\\n    /// @notice Thrown when redeem action is not paused\\n    error RedeemActionNotPaused();\\n\\n    /// @notice Thrown when repay action is not paused\\n    error RepayActionNotPaused();\\n\\n    /// @notice Thrown when seize action is not paused\\n    error SeizeActionNotPaused();\\n\\n    /// @notice Thrown when exit market action is not paused\\n    error ExitMarketActionNotPaused();\\n\\n    /// @notice Thrown when transfer action is not paused\\n    error TransferActionNotPaused();\\n\\n    /// @notice Thrown when enter market action is not paused\\n    error EnterMarketActionNotPaused();\\n\\n    /// @notice Thrown when liquidate action is not paused\\n    error LiquidateActionNotPaused();\\n\\n    /// @notice Thrown when borrow cap is not zero\\n    error BorrowCapIsNotZero();\\n\\n    /// @notice Thrown when supply cap is not zero\\n    error SupplyCapIsNotZero();\\n\\n    /// @notice Thrown when collateral factor is not zero\\n    error CollateralFactorIsNotZero();\\n\\n    /**\\n     * @notice Thrown during the liquidation if user's total collateral amount is lower than\\n     *   a predefined threshold. In this case only batch liquidations (either liquidateAccount\\n     *   or healAccount) are available.\\n     */\\n    error MinimalCollateralViolated(uint256 expectedGreaterThan, uint256 actual);\\n    error CollateralExceedsThreshold(uint256 expectedLessThanOrEqualTo, uint256 actual);\\n    error InsufficientCollateral(uint256 collateralToSeize, uint256 availableCollateral);\\n\\n    /// @notice Thrown when the account doesn't have enough liquidity to redeem or borrow\\n    error InsufficientLiquidity();\\n\\n    /// @notice Thrown when trying to liquidate a healthy account\\n    error InsufficientShortfall();\\n\\n    /// @notice Thrown when trying to repay more than allowed by close factor\\n    error TooMuchRepay();\\n\\n    /// @notice Thrown if the user is trying to exit a market in which they have an outstanding debt\\n    error NonzeroBorrowBalance();\\n\\n    /// @notice Thrown when trying to perform an action that is paused\\n    error ActionPaused(address market, Action action);\\n\\n    /// @notice Thrown when trying to add a market that is already listed\\n    error MarketAlreadyListed(address market);\\n\\n    /// @notice Thrown if the supply cap is exceeded\\n    error SupplyCapExceeded(address market, uint256 cap);\\n\\n    /// @notice Thrown if the borrow cap is exceeded\\n    error BorrowCapExceeded(address market, uint256 cap);\\n\\n    /// @notice Thrown if delegate approval status is already set to the requested value\\n    error DelegationStatusUnchanged();\\n\\n    /// @param poolRegistry_ Pool registry address\\n    /// @custom:oz-upgrades-unsafe-allow constructor\\n    /// @custom:error ZeroAddressNotAllowed is thrown when pool registry address is zero\\n    constructor(address poolRegistry_) {\\n        ensureNonzeroAddress(poolRegistry_);\\n\\n        poolRegistry = poolRegistry_;\\n        _disableInitializers();\\n    }\\n\\n    /**\\n     * @param loopLimit Limit for the loops can iterate to avoid the DOS\\n     * @param accessControlManager Access control manager contract address\\n     */\\n    function initialize(uint256 loopLimit, address accessControlManager) external initializer {\\n        __Ownable2Step_init();\\n        __AccessControlled_init_unchained(accessControlManager);\\n\\n        _setMaxLoopsLimit(loopLimit);\\n    }\\n\\n    /**\\n     * @notice Add assets to be included in account liquidity calculation; enabling them to be used as collateral\\n     * @param vTokens The list of addresses of the vToken markets to be enabled\\n     * @return errors An array of NO_ERROR for compatibility with Venus core tooling\\n     * @custom:event MarketEntered is emitted for each market on success\\n     * @custom:error ActionPaused error is thrown if entering any of the markets is paused\\n     * @custom:error MarketNotListed error is thrown if any of the markets is not listed\\n     * @custom:access Not restricted\\n     */\\n    function enterMarkets(address[] memory vTokens) external override returns (uint256[] memory) {\\n        uint256 len = vTokens.length;\\n\\n        uint256[] memory results = new uint256[](len);\\n        for (uint256 i; i < len; ++i) {\\n            VToken vToken = VToken(vTokens[i]);\\n\\n            _addToMarket(vToken, msg.sender);\\n            results[i] = NO_ERROR;\\n        }\\n\\n        return results;\\n    }\\n\\n    /**\\n     * @notice Unlist a market by setting isListed to false\\n     * @dev Checks if all actions are paused, borrow/supply caps is set to 0 and collateral factor is to 0.\\n     * @param market The address of the market (token) to unlist\\n     * @return uint256 Always NO_ERROR for compatibility with Venus core tooling\\n     * @custom:event MarketUnlisted is emitted on success\\n     * @custom:error MarketNotListed error is thrown when the market is not listed\\n     * @custom:error BorrowActionNotPaused error is thrown if borrow action is not paused\\n     * @custom:error MintActionNotPaused error is thrown if mint action is not paused\\n     * @custom:error RedeemActionNotPaused error is thrown if redeem action is not paused\\n     * @custom:error RepayActionNotPaused error is thrown if repay action is not paused\\n     * @custom:error EnterMarketActionNotPaused error is thrown if enter market action is not paused\\n     * @custom:error LiquidateActionNotPaused error is thrown if liquidate action is not paused\\n     * @custom:error BorrowCapIsNotZero error is thrown if borrow cap is not zero\\n     * @custom:error SupplyCapIsNotZero error is thrown if supply cap is not zero\\n     * @custom:error CollateralFactorIsNotZero error is thrown if collateral factor is not zero\\n     */\\n    function unlistMarket(address market) external returns (uint256) {\\n        _checkAccessAllowed(\\\"unlistMarket(address)\\\");\\n\\n        Market storage _market = markets[market];\\n\\n        if (!_market.isListed) {\\n            revert MarketNotListed(market);\\n        }\\n\\n        if (!actionPaused(market, Action.BORROW)) {\\n            revert BorrowActionNotPaused();\\n        }\\n\\n        if (!actionPaused(market, Action.MINT)) {\\n            revert MintActionNotPaused();\\n        }\\n\\n        if (!actionPaused(market, Action.REDEEM)) {\\n            revert RedeemActionNotPaused();\\n        }\\n\\n        if (!actionPaused(market, Action.REPAY)) {\\n            revert RepayActionNotPaused();\\n        }\\n\\n        if (!actionPaused(market, Action.SEIZE)) {\\n            revert SeizeActionNotPaused();\\n        }\\n\\n        if (!actionPaused(market, Action.ENTER_MARKET)) {\\n            revert EnterMarketActionNotPaused();\\n        }\\n\\n        if (!actionPaused(market, Action.LIQUIDATE)) {\\n            revert LiquidateActionNotPaused();\\n        }\\n\\n        if (!actionPaused(market, Action.TRANSFER)) {\\n            revert TransferActionNotPaused();\\n        }\\n\\n        if (!actionPaused(market, Action.EXIT_MARKET)) {\\n            revert ExitMarketActionNotPaused();\\n        }\\n\\n        if (borrowCaps[market] != 0) {\\n            revert BorrowCapIsNotZero();\\n        }\\n\\n        if (supplyCaps[market] != 0) {\\n            revert SupplyCapIsNotZero();\\n        }\\n\\n        if (_market.collateralFactorMantissa != 0) {\\n            revert CollateralFactorIsNotZero();\\n        }\\n\\n        _market.isListed = false;\\n        emit MarketUnlisted(market);\\n\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice Grants or revokes the borrowing or redeeming delegate rights to / from an account\\n     *  If allowed, the delegate will be able to borrow funds on behalf of the sender\\n     *  Upon a delegated borrow, the delegate will receive the funds, and the borrower\\n     *  will see the debt on their account\\n     *  Upon a delegated redeem, the delegate will receive the redeemed amount and the approver\\n     *  will see a deduction in his vToken balance\\n     * @param delegate The address to update the rights for\\n     * @param approved Whether to grant (true) or revoke (false) the borrowing or redeeming rights\\n     * @custom:event DelegateUpdated emits on success\\n     * @custom:error ZeroAddressNotAllowed is thrown when delegate address is zero\\n     * @custom:error DelegationStatusUnchanged is thrown if approval status is already set to the requested value\\n     * @custom:access Not restricted\\n     */\\n    function updateDelegate(address delegate, bool approved) external {\\n        ensureNonzeroAddress(delegate);\\n        if (approvedDelegates[msg.sender][delegate] == approved) {\\n            revert DelegationStatusUnchanged();\\n        }\\n\\n        approvedDelegates[msg.sender][delegate] = approved;\\n        emit DelegateUpdated(msg.sender, delegate, approved);\\n    }\\n\\n    /**\\n     * @notice Removes asset from sender's account liquidity calculation; disabling them as collateral\\n     * @dev Sender must not have an outstanding borrow balance in the asset,\\n     *  or be providing necessary collateral for an outstanding borrow.\\n     * @param vTokenAddress The address of the asset to be removed\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @custom:event MarketExited is emitted on success\\n     * @custom:error ActionPaused error is thrown if exiting the market is paused\\n     * @custom:error NonzeroBorrowBalance error is thrown if the user has an outstanding borrow in this market\\n     * @custom:error MarketNotListed error is thrown when the market is not listed\\n     * @custom:error InsufficientLiquidity error is thrown if exiting the market would lead to user's insolvency\\n     * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n     * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n     * @custom:access Not restricted\\n     */\\n    function exitMarket(address vTokenAddress) external override returns (uint256) {\\n        _checkActionPauseState(vTokenAddress, Action.EXIT_MARKET);\\n        VToken vToken = VToken(vTokenAddress);\\n        /* Get sender tokensHeld and amountOwed underlying from the vToken */\\n        (uint256 tokensHeld, uint256 amountOwed, ) = _safeGetAccountSnapshot(vToken, msg.sender);\\n\\n        /* Fail if the sender has a borrow balance */\\n        if (amountOwed != 0) {\\n            revert NonzeroBorrowBalance();\\n        }\\n\\n        /* Fail if the sender is not permitted to redeem all of their tokens */\\n        _checkRedeemAllowed(vTokenAddress, msg.sender, tokensHeld);\\n\\n        Market storage marketToExit = markets[address(vToken)];\\n\\n        /* Return true if the sender is not already \\u2018in\\u2019 the market */\\n        if (!marketToExit.accountMembership[msg.sender]) {\\n            return NO_ERROR;\\n        }\\n\\n        /* Set vToken account membership to false */\\n        delete marketToExit.accountMembership[msg.sender];\\n\\n        /* Delete vToken from the account\\u2019s list of assets */\\n        // load into memory for faster iteration\\n        VToken[] memory userAssetList = accountAssets[msg.sender];\\n        uint256 len = userAssetList.length;\\n\\n        uint256 assetIndex = len;\\n        for (uint256 i; i < len; ++i) {\\n            if (userAssetList[i] == vToken) {\\n                assetIndex = i;\\n                break;\\n            }\\n        }\\n\\n        // We *must* have found the asset in the list or our redundant data structure is broken\\n        assert(assetIndex < len);\\n\\n        // copy last item in list to location of item to be removed, reduce length by 1\\n        VToken[] storage storedList = accountAssets[msg.sender];\\n        storedList[assetIndex] = storedList[storedList.length - 1];\\n        storedList.pop();\\n\\n        emit MarketExited(vToken, msg.sender);\\n\\n        return NO_ERROR;\\n    }\\n\\n    /*** Policy Hooks ***/\\n\\n    /**\\n     * @notice Checks if the account should be allowed to mint tokens in the given market\\n     * @param vToken The market to verify the mint against\\n     * @param minter The account which would get the minted tokens\\n     * @param mintAmount The amount of underlying being supplied to the market in exchange for tokens\\n     * @custom:error ActionPaused error is thrown if supplying to this market is paused\\n     * @custom:error MarketNotListed error is thrown when the market is not listed\\n     * @custom:error SupplyCapExceeded error is thrown if the total supply exceeds the cap after minting\\n     * @custom:access Not restricted\\n     */\\n    function preMintHook(address vToken, address minter, uint256 mintAmount) external override {\\n        _checkActionPauseState(vToken, Action.MINT);\\n\\n        if (!markets[vToken].isListed) {\\n            revert MarketNotListed(address(vToken));\\n        }\\n\\n        uint256 supplyCap = supplyCaps[vToken];\\n        // Skipping the cap check for uncapped coins to save some gas\\n        if (supplyCap != type(uint256).max) {\\n            uint256 vTokenSupply = VToken(vToken).totalSupply();\\n            Exp memory exchangeRate = Exp({ mantissa: VToken(vToken).exchangeRateStored() });\\n            uint256 nextTotalSupply = mul_ScalarTruncateAddUInt(exchangeRate, vTokenSupply, mintAmount);\\n            if (nextTotalSupply > supplyCap) {\\n                revert SupplyCapExceeded(vToken, supplyCap);\\n            }\\n        }\\n\\n        // Keep the flywheel moving\\n        uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n        for (uint256 i; i < rewardDistributorsCount; ++i) {\\n            RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n            rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n            rewardsDistributor.distributeSupplierRewardToken(vToken, minter);\\n        }\\n    }\\n\\n    /**\\n     * @notice Validates mint, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n     * @param vToken Asset being minted\\n     * @param minter The address minting the tokens\\n     * @param actualMintAmount The amount of the underlying asset being minted\\n     * @param mintTokens The number of tokens being minted\\n     */\\n    // solhint-disable-next-line no-unused-vars\\n    function mintVerify(address vToken, address minter, uint256 actualMintAmount, uint256 mintTokens) external {\\n        if (address(prime) != address(0)) {\\n            prime.accrueInterestAndUpdateScore(minter, vToken);\\n        }\\n    }\\n\\n    /**\\n     * @notice Checks if the account should be allowed to redeem tokens in the given market\\n     * @param vToken The market to verify the redeem against\\n     * @param redeemer The account which would redeem the tokens\\n     * @param redeemTokens The number of vTokens to exchange for the underlying asset in the market\\n     * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n     * @custom:error MarketNotListed error is thrown when the market is not listed\\n     * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n     * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n     * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n     * @custom:access Not restricted\\n     */\\n    function preRedeemHook(address vToken, address redeemer, uint256 redeemTokens) external override {\\n        _checkActionPauseState(vToken, Action.REDEEM);\\n\\n        _checkRedeemAllowed(vToken, redeemer, redeemTokens);\\n\\n        // Keep the flywheel moving\\n        uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n        for (uint256 i; i < rewardDistributorsCount; ++i) {\\n            RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n            rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n            rewardsDistributor.distributeSupplierRewardToken(vToken, redeemer);\\n        }\\n    }\\n\\n    /**\\n     * @notice Validates redeem, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n     * @param vToken Asset being redeemed\\n     * @param redeemer The address redeeming the tokens\\n     * @param redeemAmount The amount of the underlying asset being redeemed\\n     * @param redeemTokens The number of tokens being redeemed\\n     */\\n    function redeemVerify(address vToken, address redeemer, uint256 redeemAmount, uint256 redeemTokens) external {\\n        if (address(prime) != address(0)) {\\n            prime.accrueInterestAndUpdateScore(redeemer, vToken);\\n        }\\n    }\\n\\n    /**\\n     * @notice Validates repayBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n     * @param vToken Asset being repaid\\n     * @param payer The address repaying the borrow\\n     * @param borrower The address of the borrower\\n     * @param actualRepayAmount The amount of underlying being repaid\\n     */\\n    function repayBorrowVerify(\\n        address vToken,\\n        address payer, // solhint-disable-line no-unused-vars\\n        address borrower,\\n        uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\\n        uint256 borrowerIndex // solhint-disable-line no-unused-vars\\n    ) external {\\n        if (address(prime) != address(0)) {\\n            prime.accrueInterestAndUpdateScore(borrower, vToken);\\n        }\\n    }\\n\\n    /**\\n     * @notice Validates liquidateBorrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n     * @param vTokenBorrowed Asset which was borrowed by the borrower\\n     * @param vTokenCollateral Asset which was used as collateral and will be seized\\n     * @param liquidator The address repaying the borrow and seizing the collateral\\n     * @param borrower The address of the borrower\\n     * @param actualRepayAmount The amount of underlying being repaid\\n     * @param seizeTokens The amount of collateral token that will be seized\\n     */\\n    function liquidateBorrowVerify(\\n        address vTokenBorrowed,\\n        address vTokenCollateral, // solhint-disable-line no-unused-vars\\n        address liquidator,\\n        address borrower,\\n        uint256 actualRepayAmount, // solhint-disable-line no-unused-vars\\n        uint256 seizeTokens // solhint-disable-line no-unused-vars\\n    ) external {\\n        if (address(prime) != address(0)) {\\n            prime.accrueInterestAndUpdateScore(borrower, vTokenBorrowed);\\n            prime.accrueInterestAndUpdateScore(liquidator, vTokenBorrowed);\\n        }\\n    }\\n\\n    /**\\n     * @notice Validates seize, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n     * @param vTokenCollateral Asset which was used as collateral and will be seized\\n     * @param vTokenBorrowed Asset which was borrowed by the borrower\\n     * @param liquidator The address repaying the borrow and seizing the collateral\\n     * @param borrower The address of the borrower\\n     * @param seizeTokens The number of collateral tokens to seize\\n     */\\n    function seizeVerify(\\n        address vTokenCollateral,\\n        address vTokenBorrowed, // solhint-disable-line no-unused-vars\\n        address liquidator,\\n        address borrower,\\n        uint256 seizeTokens // solhint-disable-line no-unused-vars\\n    ) external {\\n        if (address(prime) != address(0)) {\\n            prime.accrueInterestAndUpdateScore(borrower, vTokenCollateral);\\n            prime.accrueInterestAndUpdateScore(liquidator, vTokenCollateral);\\n        }\\n    }\\n\\n    /**\\n     * @notice Validates transfer, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n     * @param vToken Asset being transferred\\n     * @param src The account which sources the tokens\\n     * @param dst The account which receives the tokens\\n     * @param transferTokens The number of vTokens to transfer\\n     */\\n    // solhint-disable-next-line no-unused-vars\\n    function transferVerify(address vToken, address src, address dst, uint256 transferTokens) external {\\n        if (address(prime) != address(0)) {\\n            prime.accrueInterestAndUpdateScore(src, vToken);\\n            prime.accrueInterestAndUpdateScore(dst, vToken);\\n        }\\n    }\\n\\n    /**\\n     * @notice Checks if the account should be allowed to borrow the underlying asset of the given market\\n     * @param vToken The market to verify the borrow against\\n     * @param borrower The account which would borrow the asset\\n     * @param borrowAmount The amount of underlying the account would borrow\\n     * @custom:error ActionPaused error is thrown if borrowing is paused in this market\\n     * @custom:error MarketNotListed error is thrown when the market is not listed\\n     * @custom:error InsufficientLiquidity error is thrown if there is not enough collateral to borrow\\n     * @custom:error BorrowCapExceeded is thrown if the borrow cap will be exceeded should this borrow succeed\\n     * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n     * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n     * @custom:access Not restricted if vToken is enabled as collateral, otherwise only vToken\\n     */\\n    /// disable-eslint\\n    function preBorrowHook(address vToken, address borrower, uint256 borrowAmount) external override {\\n        _checkActionPauseState(vToken, Action.BORROW);\\n\\n        if (!markets[vToken].isListed) {\\n            revert MarketNotListed(address(vToken));\\n        }\\n\\n        if (!markets[vToken].accountMembership[borrower]) {\\n            // only vTokens may call borrowAllowed if borrower not in market\\n            _checkSenderIs(vToken);\\n\\n            // attempt to add borrower to the market or revert\\n            _addToMarket(VToken(msg.sender), borrower);\\n        }\\n\\n        // Update the prices of tokens\\n        updatePrices(borrower);\\n\\n        if (oracle.getUnderlyingPrice(vToken) == 0) {\\n            revert PriceError(address(vToken));\\n        }\\n\\n        uint256 borrowCap = borrowCaps[vToken];\\n        // Skipping the cap check for uncapped coins to save some gas\\n        if (borrowCap != type(uint256).max) {\\n            uint256 totalBorrows = VToken(vToken).totalBorrows();\\n            uint256 badDebt = VToken(vToken).badDebt();\\n            uint256 nextTotalBorrows = totalBorrows + borrowAmount + badDebt;\\n            if (nextTotalBorrows > borrowCap) {\\n                revert BorrowCapExceeded(vToken, borrowCap);\\n            }\\n        }\\n\\n        AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n            borrower,\\n            VToken(vToken),\\n            0,\\n            borrowAmount,\\n            _getCollateralFactor\\n        );\\n\\n        if (snapshot.shortfall > 0) {\\n            revert InsufficientLiquidity();\\n        }\\n\\n        Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n\\n        // Keep the flywheel moving\\n        uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n        for (uint256 i; i < rewardDistributorsCount; ++i) {\\n            RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n            rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n            rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\n        }\\n    }\\n\\n    /**\\n     * @notice Validates borrow, accrues interest and updates score in prime. Reverts on rejection. May emit logs.\\n     * @param vToken Asset whose underlying is being borrowed\\n     * @param borrower The address borrowing the underlying\\n     * @param borrowAmount The amount of the underlying asset requested to borrow\\n     */\\n    // solhint-disable-next-line no-unused-vars\\n    function borrowVerify(address vToken, address borrower, uint256 borrowAmount) external {\\n        if (address(prime) != address(0)) {\\n            prime.accrueInterestAndUpdateScore(borrower, vToken);\\n        }\\n    }\\n\\n    /**\\n     * @notice Checks if the account should be allowed to repay a borrow in the given market\\n     * @param vToken The market to verify the repay against\\n     * @param borrower The account which would borrowed the asset\\n     * @custom:error ActionPaused error is thrown if repayments are paused in this market\\n     * @custom:error MarketNotListed error is thrown when the market is not listed\\n     * @custom:access Not restricted\\n     */\\n    function preRepayHook(address vToken, address borrower) external override {\\n        _checkActionPauseState(vToken, Action.REPAY);\\n\\n        oracle.updatePrice(vToken);\\n\\n        if (!markets[vToken].isListed) {\\n            revert MarketNotListed(address(vToken));\\n        }\\n\\n        // Keep the flywheel moving\\n        uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n        for (uint256 i; i < rewardDistributorsCount; ++i) {\\n            Exp memory borrowIndex = Exp({ mantissa: VToken(vToken).borrowIndex() });\\n            RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n            rewardsDistributor.updateRewardTokenBorrowIndex(vToken, borrowIndex);\\n            rewardsDistributor.distributeBorrowerRewardToken(vToken, borrower, borrowIndex);\\n        }\\n    }\\n\\n    /**\\n     * @notice Checks if the liquidation should be allowed to occur\\n     * @param vTokenBorrowed Asset which was borrowed by the borrower\\n     * @param vTokenCollateral Asset which was used as collateral and will be seized\\n     * @param borrower The address of the borrower\\n     * @param repayAmount The amount of underlying being repaid\\n     * @param skipLiquidityCheck Allows the borrow to be liquidated regardless of the account liquidity\\n     * @custom:error ActionPaused error is thrown if liquidations are paused in this market\\n     * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n     * @custom:error TooMuchRepay error is thrown if the liquidator is trying to repay more than allowed by close factor\\n     * @custom:error MinimalCollateralViolated is thrown if the users' total collateral is lower than the threshold for non-batch liquidations\\n     * @custom:error InsufficientShortfall is thrown when trying to liquidate a healthy account\\n     * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n     * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n     */\\n    function preLiquidateHook(\\n        address vTokenBorrowed,\\n        address vTokenCollateral,\\n        address borrower,\\n        uint256 repayAmount,\\n        bool skipLiquidityCheck\\n    ) external override {\\n        // Pause Action.LIQUIDATE on BORROWED TOKEN to prevent liquidating it.\\n        // If we want to pause liquidating to vTokenCollateral, we should pause\\n        // Action.SEIZE on it\\n        _checkActionPauseState(vTokenBorrowed, Action.LIQUIDATE);\\n\\n        // Update the prices of tokens\\n        updatePrices(borrower);\\n\\n        if (!markets[vTokenBorrowed].isListed) {\\n            revert MarketNotListed(address(vTokenBorrowed));\\n        }\\n        if (!markets[vTokenCollateral].isListed) {\\n            revert MarketNotListed(address(vTokenCollateral));\\n        }\\n\\n        uint256 borrowBalance = VToken(vTokenBorrowed).borrowBalanceStored(borrower);\\n\\n        /* Allow accounts to be liquidated if it is a forced liquidation */\\n        if (skipLiquidityCheck || isForcedLiquidationEnabled[vTokenBorrowed]) {\\n            if (repayAmount > borrowBalance) {\\n                revert TooMuchRepay();\\n            }\\n            return;\\n        }\\n\\n        /* The borrower must have shortfall and collateral > threshold in order to be liquidatable */\\n        AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n        if (snapshot.totalCollateral <= minLiquidatableCollateral) {\\n            /* The liquidator should use either liquidateAccount or healAccount */\\n            revert MinimalCollateralViolated(minLiquidatableCollateral, snapshot.totalCollateral);\\n        }\\n\\n        if (snapshot.shortfall == 0) {\\n            revert InsufficientShortfall();\\n        }\\n\\n        /* The liquidator may not repay more than what is allowed by the closeFactor */\\n        uint256 maxClose = mul_ScalarTruncate(Exp({ mantissa: closeFactorMantissa }), borrowBalance);\\n        if (repayAmount > maxClose) {\\n            revert TooMuchRepay();\\n        }\\n    }\\n\\n    /**\\n     * @notice Checks if the seizing of assets should be allowed to occur\\n     * @param vTokenCollateral Asset which was used as collateral and will be seized\\n     * @param seizerContract Contract that tries to seize the asset (either borrowed vToken or Comptroller)\\n     * @param liquidator The address repaying the borrow and seizing the collateral\\n     * @param borrower The address of the borrower\\n     * @custom:error ActionPaused error is thrown if seizing this type of collateral is paused\\n     * @custom:error MarketNotListed error is thrown if either collateral or borrowed token is not listed\\n     * @custom:error ComptrollerMismatch error is when seizer contract or seized asset belong to different pools\\n     * @custom:access Not restricted\\n     */\\n    function preSeizeHook(\\n        address vTokenCollateral,\\n        address seizerContract,\\n        address liquidator,\\n        address borrower\\n    ) external override {\\n        // Pause Action.SEIZE on COLLATERAL to prevent seizing it.\\n        // If we want to pause liquidating vTokenBorrowed, we should pause\\n        // Action.LIQUIDATE on it\\n        _checkActionPauseState(vTokenCollateral, Action.SEIZE);\\n\\n        Market storage market = markets[vTokenCollateral];\\n\\n        if (!market.isListed) {\\n            revert MarketNotListed(vTokenCollateral);\\n        }\\n\\n        if (seizerContract == address(this)) {\\n            // If Comptroller is the seizer, just check if collateral's comptroller\\n            // is equal to the current address\\n            if (address(VToken(vTokenCollateral).comptroller()) != address(this)) {\\n                revert ComptrollerMismatch();\\n            }\\n        } else {\\n            // If the seizer is not the Comptroller, check that the seizer is a\\n            // listed market, and that the markets' comptrollers match\\n            if (!markets[seizerContract].isListed) {\\n                revert MarketNotListed(seizerContract);\\n            }\\n            if (VToken(vTokenCollateral).comptroller() != VToken(seizerContract).comptroller()) {\\n                revert ComptrollerMismatch();\\n            }\\n        }\\n\\n        if (!market.accountMembership[borrower]) {\\n            revert MarketNotCollateral(vTokenCollateral, borrower);\\n        }\\n\\n        // Keep the flywheel moving\\n        uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n        for (uint256 i; i < rewardDistributorsCount; ++i) {\\n            RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n            rewardsDistributor.updateRewardTokenSupplyIndex(vTokenCollateral);\\n            rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, borrower);\\n            rewardsDistributor.distributeSupplierRewardToken(vTokenCollateral, liquidator);\\n        }\\n    }\\n\\n    /**\\n     * @notice Checks if the account should be allowed to transfer tokens in the given market\\n     * @param vToken The market to verify the transfer against\\n     * @param src The account which sources the tokens\\n     * @param dst The account which receives the tokens\\n     * @param transferTokens The number of vTokens to transfer\\n     * @custom:error ActionPaused error is thrown if withdrawals are paused in this market\\n     * @custom:error MarketNotListed error is thrown when the market is not listed\\n     * @custom:error InsufficientLiquidity error is thrown if the withdrawal would lead to user's insolvency\\n     * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n     * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n     * @custom:access Not restricted\\n     */\\n    function preTransferHook(address vToken, address src, address dst, uint256 transferTokens) external override {\\n        _checkActionPauseState(vToken, Action.TRANSFER);\\n\\n        // Currently the only consideration is whether or not\\n        //  the src is allowed to redeem this many tokens\\n        _checkRedeemAllowed(vToken, src, transferTokens);\\n\\n        // Keep the flywheel moving\\n        uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n        for (uint256 i; i < rewardDistributorsCount; ++i) {\\n            RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n            rewardsDistributor.updateRewardTokenSupplyIndex(vToken);\\n            rewardsDistributor.distributeSupplierRewardToken(vToken, src);\\n            rewardsDistributor.distributeSupplierRewardToken(vToken, dst);\\n        }\\n    }\\n\\n    /*** Pool-level operations ***/\\n\\n    /**\\n     * @notice Seizes all the remaining collateral, makes msg.sender repay the existing\\n     *   borrows, and treats the rest of the debt as bad debt (for each market).\\n     *   The sender has to repay a certain percentage of the debt, computed as\\n     *   collateral / (borrows * liquidationIncentive).\\n     * @param user account to heal\\n     * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for healing\\n     * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n     * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n     * @custom:access Not restricted\\n     */\\n    function healAccount(address user) external {\\n        VToken[] memory userAssets = getAssetsIn(user);\\n        uint256 userAssetsCount = userAssets.length;\\n\\n        address liquidator = msg.sender;\\n        {\\n            ResilientOracleInterface oracle_ = oracle;\\n            // We need all user's markets to be fresh for the computations to be correct\\n            for (uint256 i; i < userAssetsCount; ++i) {\\n                userAssets[i].accrueInterest();\\n                oracle_.updatePrice(address(userAssets[i]));\\n            }\\n        }\\n\\n        AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(user, _getLiquidationThreshold);\\n\\n        if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n            revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n        }\\n\\n        if (snapshot.shortfall == 0) {\\n            revert InsufficientShortfall();\\n        }\\n\\n        // percentage = collateral / (borrows * liquidation incentive)\\n        Exp memory collateral = Exp({ mantissa: snapshot.totalCollateral });\\n        Exp memory scaledBorrows = mul_(\\n            Exp({ mantissa: snapshot.borrows }),\\n            Exp({ mantissa: liquidationIncentiveMantissa })\\n        );\\n\\n        Exp memory percentage = div_(collateral, scaledBorrows);\\n        if (lessThanExp(Exp({ mantissa: MANTISSA_ONE }), percentage)) {\\n            revert CollateralExceedsThreshold(scaledBorrows.mantissa, collateral.mantissa);\\n        }\\n\\n        for (uint256 i; i < userAssetsCount; ++i) {\\n            VToken market = userAssets[i];\\n\\n            (uint256 tokens, uint256 borrowBalance, ) = _safeGetAccountSnapshot(market, user);\\n            uint256 repaymentAmount = mul_ScalarTruncate(percentage, borrowBalance);\\n\\n            // Seize the entire collateral\\n            if (tokens != 0) {\\n                market.seize(liquidator, user, tokens);\\n            }\\n            // Repay a certain percentage of the borrow, forgive the rest\\n            if (borrowBalance != 0) {\\n                market.healBorrow(liquidator, user, repaymentAmount);\\n            }\\n        }\\n    }\\n\\n    /**\\n     * @notice Liquidates all borrows of the borrower. Callable only if the collateral is less than\\n     *   a predefined threshold, and the account collateral can be seized to cover all borrows. If\\n     *   the collateral is higher than the threshold, use regular liquidations. If the collateral is\\n     *   below the threshold, and the account is insolvent, use healAccount.\\n     * @param borrower the borrower address\\n     * @param orders an array of liquidation orders\\n     * @custom:error CollateralExceedsThreshold error is thrown when the collateral is too big for a batch liquidation\\n     * @custom:error InsufficientCollateral error is thrown when there is not enough collateral to cover the debt\\n     * @custom:error SnapshotError is thrown if some vToken fails to return the account's supply and borrows\\n     * @custom:error PriceError is thrown if the oracle returns an incorrect price for some asset\\n     * @custom:access Not restricted\\n     */\\n    function liquidateAccount(address borrower, LiquidationOrder[] calldata orders) external {\\n        // We will accrue interest and update the oracle prices later during the liquidation\\n\\n        AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(borrower, _getLiquidationThreshold);\\n\\n        if (snapshot.totalCollateral > minLiquidatableCollateral) {\\n            // You should use the regular vToken.liquidateBorrow(...) call\\n            revert CollateralExceedsThreshold(minLiquidatableCollateral, snapshot.totalCollateral);\\n        }\\n\\n        uint256 collateralToSeize = mul_ScalarTruncate(\\n            Exp({ mantissa: liquidationIncentiveMantissa }),\\n            snapshot.borrows\\n        );\\n        if (collateralToSeize >= snapshot.totalCollateral) {\\n            // There is not enough collateral to seize. Use healBorrow to repay some part of the borrow\\n            // and record bad debt.\\n            revert InsufficientCollateral(collateralToSeize, snapshot.totalCollateral);\\n        }\\n\\n        if (snapshot.shortfall == 0) {\\n            revert InsufficientShortfall();\\n        }\\n\\n        uint256 ordersCount = orders.length;\\n\\n        _ensureMaxLoops(ordersCount / 2);\\n\\n        for (uint256 i; i < ordersCount; ++i) {\\n            if (!markets[address(orders[i].vTokenBorrowed)].isListed) {\\n                revert MarketNotListed(address(orders[i].vTokenBorrowed));\\n            }\\n            if (!markets[address(orders[i].vTokenCollateral)].isListed) {\\n                revert MarketNotListed(address(orders[i].vTokenCollateral));\\n            }\\n\\n            LiquidationOrder calldata order = orders[i];\\n            order.vTokenBorrowed.forceLiquidateBorrow(\\n                msg.sender,\\n                borrower,\\n                order.repayAmount,\\n                order.vTokenCollateral,\\n                true\\n            );\\n        }\\n\\n        VToken[] memory borrowMarkets = getAssetsIn(borrower);\\n        uint256 marketsCount = borrowMarkets.length;\\n\\n        for (uint256 i; i < marketsCount; ++i) {\\n            (, uint256 borrowBalance, ) = _safeGetAccountSnapshot(borrowMarkets[i], borrower);\\n            require(borrowBalance == 0, \\\"Nonzero borrow balance after liquidation\\\");\\n        }\\n    }\\n\\n    /**\\n     * @notice Sets the closeFactor to use when liquidating borrows\\n     * @param newCloseFactorMantissa New close factor, scaled by 1e18\\n     * @custom:event Emits NewCloseFactor on success\\n     * @custom:access Controlled by AccessControlManager\\n     */\\n    function setCloseFactor(uint256 newCloseFactorMantissa) external {\\n        _checkAccessAllowed(\\\"setCloseFactor(uint256)\\\");\\n        require(MAX_CLOSE_FACTOR_MANTISSA >= newCloseFactorMantissa, \\\"Close factor greater than maximum close factor\\\");\\n        require(MIN_CLOSE_FACTOR_MANTISSA <= newCloseFactorMantissa, \\\"Close factor smaller than minimum close factor\\\");\\n\\n        uint256 oldCloseFactorMantissa = closeFactorMantissa;\\n        closeFactorMantissa = newCloseFactorMantissa;\\n        emit NewCloseFactor(oldCloseFactorMantissa, newCloseFactorMantissa);\\n    }\\n\\n    /**\\n     * @notice Sets the collateralFactor for a market\\n     * @dev This function is restricted by the AccessControlManager\\n     * @param vToken The market to set the factor on\\n     * @param newCollateralFactorMantissa The new collateral factor, scaled by 1e18\\n     * @param newLiquidationThresholdMantissa The new liquidation threshold, scaled by 1e18\\n     * @custom:event Emits NewCollateralFactor when collateral factor is updated\\n     *    and NewLiquidationThreshold when liquidation threshold is updated\\n     * @custom:error MarketNotListed error is thrown when the market is not listed\\n     * @custom:error InvalidCollateralFactor error is thrown when collateral factor is too high\\n     * @custom:error InvalidLiquidationThreshold error is thrown when liquidation threshold is lower than collateral factor\\n     * @custom:error PriceError is thrown when the oracle returns an invalid price for the asset\\n     * @custom:access Controlled by AccessControlManager\\n     */\\n    function setCollateralFactor(\\n        VToken vToken,\\n        uint256 newCollateralFactorMantissa,\\n        uint256 newLiquidationThresholdMantissa\\n    ) external {\\n        _checkAccessAllowed(\\\"setCollateralFactor(address,uint256,uint256)\\\");\\n\\n        // Verify market is listed\\n        Market storage market = markets[address(vToken)];\\n        if (!market.isListed) {\\n            revert MarketNotListed(address(vToken));\\n        }\\n\\n        // Check collateral factor <= 0.9\\n        if (newCollateralFactorMantissa > MAX_COLLATERAL_FACTOR_MANTISSA) {\\n            revert InvalidCollateralFactor();\\n        }\\n\\n        // Ensure that liquidation threshold <= 1\\n        if (newLiquidationThresholdMantissa > MANTISSA_ONE) {\\n            revert InvalidLiquidationThreshold();\\n        }\\n\\n        // Ensure that liquidation threshold >= CF\\n        if (newLiquidationThresholdMantissa < newCollateralFactorMantissa) {\\n            revert InvalidLiquidationThreshold();\\n        }\\n\\n        // If collateral factor != 0, fail if price == 0\\n        if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(address(vToken)) == 0) {\\n            revert PriceError(address(vToken));\\n        }\\n\\n        uint256 oldCollateralFactorMantissa = market.collateralFactorMantissa;\\n        if (newCollateralFactorMantissa != oldCollateralFactorMantissa) {\\n            market.collateralFactorMantissa = newCollateralFactorMantissa;\\n            emit NewCollateralFactor(vToken, oldCollateralFactorMantissa, newCollateralFactorMantissa);\\n        }\\n\\n        uint256 oldLiquidationThresholdMantissa = market.liquidationThresholdMantissa;\\n        if (newLiquidationThresholdMantissa != oldLiquidationThresholdMantissa) {\\n            market.liquidationThresholdMantissa = newLiquidationThresholdMantissa;\\n            emit NewLiquidationThreshold(vToken, oldLiquidationThresholdMantissa, newLiquidationThresholdMantissa);\\n        }\\n    }\\n\\n    /**\\n     * @notice Sets liquidationIncentive\\n     * @dev This function is restricted by the AccessControlManager\\n     * @param newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18\\n     * @custom:event Emits NewLiquidationIncentive on success\\n     * @custom:access Controlled by AccessControlManager\\n     */\\n    function setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external {\\n        require(newLiquidationIncentiveMantissa >= MANTISSA_ONE, \\\"liquidation incentive should be greater than 1e18\\\");\\n\\n        _checkAccessAllowed(\\\"setLiquidationIncentive(uint256)\\\");\\n\\n        // Save current value for use in log\\n        uint256 oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa;\\n\\n        // Set liquidation incentive to new incentive\\n        liquidationIncentiveMantissa = newLiquidationIncentiveMantissa;\\n\\n        // Emit event with old incentive, new incentive\\n        emit NewLiquidationIncentive(oldLiquidationIncentiveMantissa, newLiquidationIncentiveMantissa);\\n    }\\n\\n    /**\\n     * @notice Add the market to the markets mapping and set it as listed\\n     * @dev Only callable by the PoolRegistry\\n     * @param vToken The address of the market (token) to list\\n     * @custom:error MarketAlreadyListed is thrown if the market is already listed in this pool\\n     * @custom:access Only PoolRegistry\\n     */\\n    function supportMarket(VToken vToken) external {\\n        _checkSenderIs(poolRegistry);\\n\\n        if (markets[address(vToken)].isListed) {\\n            revert MarketAlreadyListed(address(vToken));\\n        }\\n\\n        require(vToken.isVToken(), \\\"Comptroller: Invalid vToken\\\"); // Sanity check to make sure its really a VToken\\n\\n        Market storage newMarket = markets[address(vToken)];\\n        newMarket.isListed = true;\\n        newMarket.collateralFactorMantissa = 0;\\n        newMarket.liquidationThresholdMantissa = 0;\\n\\n        _addMarket(address(vToken));\\n\\n        uint256 rewardDistributorsCount = rewardsDistributors.length;\\n\\n        for (uint256 i; i < rewardDistributorsCount; ++i) {\\n            rewardsDistributors[i].initializeMarket(address(vToken));\\n        }\\n\\n        emit MarketSupported(vToken);\\n    }\\n\\n    /**\\n     * @notice Set the given borrow caps for the given vToken markets. Borrowing that brings total borrows to or above borrow cap will revert.\\n     * @dev This function is restricted by the AccessControlManager\\n     * @dev A borrow cap of type(uint256).max corresponds to unlimited borrowing.\\n     * @dev Borrow caps smaller than the current total borrows are accepted. This way, new borrows will not be allowed\\n            until the total borrows amount goes below the new borrow cap\\n     * @param vTokens The addresses of the markets (tokens) to change the borrow caps for\\n     * @param newBorrowCaps The new borrow cap values in underlying to be set. A value of type(uint256).max corresponds to unlimited borrowing.\\n     * @custom:access Controlled by AccessControlManager\\n     */\\n    function setMarketBorrowCaps(VToken[] calldata vTokens, uint256[] calldata newBorrowCaps) external {\\n        _checkAccessAllowed(\\\"setMarketBorrowCaps(address[],uint256[])\\\");\\n\\n        uint256 numMarkets = vTokens.length;\\n        uint256 numBorrowCaps = newBorrowCaps.length;\\n\\n        require(numMarkets != 0 && numMarkets == numBorrowCaps, \\\"invalid input\\\");\\n\\n        _ensureMaxLoops(numMarkets);\\n\\n        for (uint256 i; i < numMarkets; ++i) {\\n            borrowCaps[address(vTokens[i])] = newBorrowCaps[i];\\n            emit NewBorrowCap(vTokens[i], newBorrowCaps[i]);\\n        }\\n    }\\n\\n    /**\\n     * @notice Set the given supply caps for the given vToken markets. Supply that brings total Supply to or above supply cap will revert.\\n     * @dev This function is restricted by the AccessControlManager\\n     * @dev A supply cap of type(uint256).max corresponds to unlimited supply.\\n     * @dev Supply caps smaller than the current total supplies are accepted. This way, new supplies will not be allowed\\n            until the total supplies amount goes below the new supply cap\\n     * @param vTokens The addresses of the markets (tokens) to change the supply caps for\\n     * @param newSupplyCaps The new supply cap values in underlying to be set. A value of type(uint256).max corresponds to unlimited supply.\\n     * @custom:access Controlled by AccessControlManager\\n     */\\n    function setMarketSupplyCaps(VToken[] calldata vTokens, uint256[] calldata newSupplyCaps) external {\\n        _checkAccessAllowed(\\\"setMarketSupplyCaps(address[],uint256[])\\\");\\n        uint256 vTokensCount = vTokens.length;\\n\\n        require(vTokensCount != 0, \\\"invalid number of markets\\\");\\n        require(vTokensCount == newSupplyCaps.length, \\\"invalid number of markets\\\");\\n\\n        _ensureMaxLoops(vTokensCount);\\n\\n        for (uint256 i; i < vTokensCount; ++i) {\\n            supplyCaps[address(vTokens[i])] = newSupplyCaps[i];\\n            emit NewSupplyCap(vTokens[i], newSupplyCaps[i]);\\n        }\\n    }\\n\\n    /**\\n     * @notice Pause/unpause specified actions\\n     * @dev This function is restricted by the AccessControlManager\\n     * @param marketsList Markets to pause/unpause the actions on\\n     * @param actionsList List of action ids to pause/unpause\\n     * @param paused The new paused state (true=paused, false=unpaused)\\n     * @custom:access Controlled by AccessControlManager\\n     */\\n    function setActionsPaused(VToken[] calldata marketsList, Action[] calldata actionsList, bool paused) external {\\n        _checkAccessAllowed(\\\"setActionsPaused(address[],uint256[],bool)\\\");\\n\\n        uint256 marketsCount = marketsList.length;\\n        uint256 actionsCount = actionsList.length;\\n\\n        _ensureMaxLoops(marketsCount * actionsCount);\\n\\n        for (uint256 marketIdx; marketIdx < marketsCount; ++marketIdx) {\\n            for (uint256 actionIdx; actionIdx < actionsCount; ++actionIdx) {\\n                _setActionPaused(address(marketsList[marketIdx]), actionsList[actionIdx], paused);\\n            }\\n        }\\n    }\\n\\n    /**\\n     * @notice Set the given collateral threshold for non-batch liquidations. Regular liquidations\\n     *   will fail if the collateral amount is less than this threshold. Liquidators should use batch\\n     *   operations like liquidateAccount or healAccount.\\n     * @dev This function is restricted by the AccessControlManager\\n     * @param newMinLiquidatableCollateral The new min liquidatable collateral (in USD).\\n     * @custom:access Controlled by AccessControlManager\\n     */\\n    function setMinLiquidatableCollateral(uint256 newMinLiquidatableCollateral) external {\\n        _checkAccessAllowed(\\\"setMinLiquidatableCollateral(uint256)\\\");\\n\\n        uint256 oldMinLiquidatableCollateral = minLiquidatableCollateral;\\n        minLiquidatableCollateral = newMinLiquidatableCollateral;\\n        emit NewMinLiquidatableCollateral(oldMinLiquidatableCollateral, newMinLiquidatableCollateral);\\n    }\\n\\n    /**\\n     * @notice Add a new RewardsDistributor and initialize it with all markets. We can add several RewardsDistributor\\n     * contracts with the same rewardToken, and there could be overlaping among them considering the last reward slot (block or second)\\n     * @dev Only callable by the admin\\n     * @param _rewardsDistributor Address of the RewardDistributor contract to add\\n     * @custom:access Only Governance\\n     * @custom:event Emits NewRewardsDistributor with distributor address\\n     */\\n    function addRewardsDistributor(RewardsDistributor _rewardsDistributor) external onlyOwner {\\n        require(!rewardsDistributorExists[address(_rewardsDistributor)], \\\"already exists\\\");\\n\\n        uint256 rewardsDistributorsLen = rewardsDistributors.length;\\n        _ensureMaxLoops(rewardsDistributorsLen + 1);\\n\\n        rewardsDistributors.push(_rewardsDistributor);\\n        rewardsDistributorExists[address(_rewardsDistributor)] = true;\\n\\n        uint256 marketsCount = allMarkets.length;\\n\\n        for (uint256 i; i < marketsCount; ++i) {\\n            _rewardsDistributor.initializeMarket(address(allMarkets[i]));\\n        }\\n\\n        emit NewRewardsDistributor(address(_rewardsDistributor), address(_rewardsDistributor.rewardToken()));\\n    }\\n\\n    /**\\n     * @notice Sets a new price oracle for the Comptroller\\n     * @dev Only callable by the admin\\n     * @param newOracle Address of the new price oracle to set\\n     * @custom:event Emits NewPriceOracle on success\\n     * @custom:error ZeroAddressNotAllowed is thrown when the new oracle address is zero\\n     */\\n    function setPriceOracle(ResilientOracleInterface newOracle) external onlyOwner {\\n        ensureNonzeroAddress(address(newOracle));\\n\\n        ResilientOracleInterface oldOracle = oracle;\\n        oracle = newOracle;\\n        emit NewPriceOracle(oldOracle, newOracle);\\n    }\\n\\n    /**\\n     * @notice Set the for loop iteration limit to avoid DOS\\n     * @param limit Limit for the max loops can execute at a time\\n     */\\n    function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n        _setMaxLoopsLimit(limit);\\n    }\\n\\n    /**\\n     * @notice Sets the prime token contract for the comptroller\\n     * @param _prime Address of the Prime contract\\n     */\\n    function setPrimeToken(IPrime _prime) external onlyOwner {\\n        ensureNonzeroAddress(address(_prime));\\n\\n        emit NewPrimeToken(prime, _prime);\\n        prime = _prime;\\n    }\\n\\n    /**\\n     * @notice Enables forced liquidations for a market. If forced liquidation is enabled,\\n     * borrows in the market may be liquidated regardless of the account liquidity\\n     * @param vTokenBorrowed Borrowed vToken\\n     * @param enable Whether to enable forced liquidations\\n     */\\n    function setForcedLiquidation(address vTokenBorrowed, bool enable) external {\\n        _checkAccessAllowed(\\\"setForcedLiquidation(address,bool)\\\");\\n        ensureNonzeroAddress(vTokenBorrowed);\\n\\n        if (!markets[vTokenBorrowed].isListed) {\\n            revert MarketNotListed(vTokenBorrowed);\\n        }\\n\\n        isForcedLiquidationEnabled[vTokenBorrowed] = enable;\\n        emit IsForcedLiquidationEnabledUpdated(vTokenBorrowed, enable);\\n    }\\n\\n    /**\\n     * @notice Determine the current account liquidity with respect to liquidation threshold requirements\\n     * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n     * @param account The account get liquidity for\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @return liquidity Account liquidity in excess of liquidation threshold requirements,\\n     * @return shortfall Account shortfall below liquidation threshold requirements\\n     */\\n    function getAccountLiquidity(\\n        address account\\n    ) external view returns (uint256 error, uint256 liquidity, uint256 shortfall) {\\n        AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getLiquidationThreshold);\\n        return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n    }\\n\\n    /**\\n     * @notice Determine the current account liquidity with respect to collateral requirements\\n     * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n     * @param account The account get liquidity for\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @return liquidity Account liquidity in excess of collateral requirements,\\n     * @return shortfall Account shortfall below collateral requirements\\n     */\\n    function getBorrowingPower(\\n        address account\\n    ) external view returns (uint256 error, uint256 liquidity, uint256 shortfall) {\\n        AccountLiquiditySnapshot memory snapshot = _getCurrentLiquiditySnapshot(account, _getCollateralFactor);\\n        return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n    }\\n\\n    /**\\n     * @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed\\n     * @dev The interface of this function is intentionally kept compatible with Compound and Venus Core\\n     * @param vTokenModify The market to hypothetically redeem/borrow in\\n     * @param account The account to determine liquidity for\\n     * @param redeemTokens The number of tokens to hypothetically redeem\\n     * @param borrowAmount The amount of underlying to hypothetically borrow\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @return liquidity Hypothetical account liquidity in excess of collateral requirements,\\n     * @return shortfall Hypothetical account shortfall below collateral requirements\\n     */\\n    function getHypotheticalAccountLiquidity(\\n        address account,\\n        address vTokenModify,\\n        uint256 redeemTokens,\\n        uint256 borrowAmount\\n    ) external view returns (uint256 error, uint256 liquidity, uint256 shortfall) {\\n        AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n            account,\\n            VToken(vTokenModify),\\n            redeemTokens,\\n            borrowAmount,\\n            _getCollateralFactor\\n        );\\n        return (NO_ERROR, snapshot.liquidity, snapshot.shortfall);\\n    }\\n\\n    /**\\n     * @notice Return all of the markets\\n     * @dev The automatic getter may be used to access an individual market.\\n     * @return markets The list of market addresses\\n     */\\n    function getAllMarkets() external view override returns (VToken[] memory) {\\n        return allMarkets;\\n    }\\n\\n    /**\\n     * @notice Check if a market is marked as listed (active)\\n     * @param vToken vToken Address for the market to check\\n     * @return listed True if listed otherwise false\\n     */\\n    function isMarketListed(VToken vToken) external view returns (bool) {\\n        return markets[address(vToken)].isListed;\\n    }\\n\\n    /*** Assets You Are In ***/\\n\\n    /**\\n     * @notice Returns whether the given account is entered in a given market\\n     * @param account The address of the account to check\\n     * @param vToken The vToken to check\\n     * @return True if the account is in the market specified, otherwise false.\\n     */\\n    function checkMembership(address account, VToken vToken) external view returns (bool) {\\n        return markets[address(vToken)].accountMembership[account];\\n    }\\n\\n    /**\\n     * @notice Calculate number of tokens of collateral asset to seize given an underlying amount\\n     * @dev Used in liquidation (called in vToken.liquidateBorrowFresh)\\n     * @param vTokenBorrowed The address of the borrowed vToken\\n     * @param vTokenCollateral The address of the collateral vToken\\n     * @param actualRepayAmount The amount of vTokenBorrowed underlying to convert into vTokenCollateral tokens\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @return tokensToSeize Number of vTokenCollateral tokens to be seized in a liquidation\\n     * @custom:error PriceError if the oracle returns an invalid price\\n     */\\n    function liquidateCalculateSeizeTokens(\\n        address vTokenBorrowed,\\n        address vTokenCollateral,\\n        uint256 actualRepayAmount\\n    ) external view override returns (uint256 error, uint256 tokensToSeize) {\\n        /* Read oracle prices for borrowed and collateral markets */\\n        uint256 priceBorrowedMantissa = _safeGetUnderlyingPrice(VToken(vTokenBorrowed));\\n        uint256 priceCollateralMantissa = _safeGetUnderlyingPrice(VToken(vTokenCollateral));\\n\\n        /*\\n         * Get the exchange rate and calculate the number of collateral tokens to seize:\\n         *  seizeAmount = actualRepayAmount * liquidationIncentive * priceBorrowed / priceCollateral\\n         *  seizeTokens = seizeAmount / exchangeRate\\n         *   = actualRepayAmount * (liquidationIncentive * priceBorrowed) / (priceCollateral * exchangeRate)\\n         */\\n        uint256 exchangeRateMantissa = VToken(vTokenCollateral).exchangeRateStored(); // Note: reverts on error\\n        uint256 seizeTokens;\\n        Exp memory numerator;\\n        Exp memory denominator;\\n        Exp memory ratio;\\n\\n        numerator = mul_(Exp({ mantissa: liquidationIncentiveMantissa }), Exp({ mantissa: priceBorrowedMantissa }));\\n        denominator = mul_(Exp({ mantissa: priceCollateralMantissa }), Exp({ mantissa: exchangeRateMantissa }));\\n        ratio = div_(numerator, denominator);\\n\\n        seizeTokens = mul_ScalarTruncate(ratio, actualRepayAmount);\\n\\n        return (NO_ERROR, seizeTokens);\\n    }\\n\\n    /**\\n     * @notice Returns reward speed given a vToken\\n     * @param vToken The vToken to get the reward speeds for\\n     * @return rewardSpeeds Array of total supply and borrow speeds and reward token for all reward distributors\\n     */\\n    function getRewardsByMarket(address vToken) external view returns (RewardSpeeds[] memory rewardSpeeds) {\\n        uint256 rewardsDistributorsLength = rewardsDistributors.length;\\n        rewardSpeeds = new RewardSpeeds[](rewardsDistributorsLength);\\n        for (uint256 i; i < rewardsDistributorsLength; ++i) {\\n            RewardsDistributor rewardsDistributor = rewardsDistributors[i];\\n            address rewardToken = address(rewardsDistributor.rewardToken());\\n            rewardSpeeds[i] = RewardSpeeds({\\n                rewardToken: rewardToken,\\n                supplySpeed: rewardsDistributor.rewardTokenSupplySpeeds(vToken),\\n                borrowSpeed: rewardsDistributor.rewardTokenBorrowSpeeds(vToken)\\n            });\\n        }\\n        return rewardSpeeds;\\n    }\\n\\n    /**\\n     * @notice Return all reward distributors for this pool\\n     * @return Array of RewardDistributor addresses\\n     */\\n    function getRewardDistributors() external view returns (RewardsDistributor[] memory) {\\n        return rewardsDistributors;\\n    }\\n\\n    /**\\n     * @notice A marker method that returns true for a valid Comptroller contract\\n     * @return Always true\\n     */\\n    function isComptroller() external pure override returns (bool) {\\n        return true;\\n    }\\n\\n    /**\\n     * @notice Update the prices of all the tokens associated with the provided account\\n     * @param account Address of the account to get associated tokens with\\n     */\\n    function updatePrices(address account) public {\\n        VToken[] memory vTokens = getAssetsIn(account);\\n        uint256 vTokensCount = vTokens.length;\\n\\n        ResilientOracleInterface oracle_ = oracle;\\n\\n        for (uint256 i; i < vTokensCount; ++i) {\\n            oracle_.updatePrice(address(vTokens[i]));\\n        }\\n    }\\n\\n    /**\\n     * @notice Checks if a certain action is paused on a market\\n     * @param market vToken address\\n     * @param action Action to check\\n     * @return paused True if the action is paused otherwise false\\n     */\\n    function actionPaused(address market, Action action) public view returns (bool) {\\n        return _actionPaused[market][action];\\n    }\\n\\n    /**\\n     * @notice Returns the assets an account has entered\\n     * @param account The address of the account to pull assets for\\n     * @return A list with the assets the account has entered\\n     */\\n    function getAssetsIn(address account) public view returns (VToken[] memory) {\\n        uint256 len;\\n        VToken[] memory _accountAssets = accountAssets[account];\\n        uint256 _accountAssetsLength = _accountAssets.length;\\n\\n        VToken[] memory assetsIn = new VToken[](_accountAssetsLength);\\n\\n        for (uint256 i; i < _accountAssetsLength; ++i) {\\n            Market storage market = markets[address(_accountAssets[i])];\\n            if (market.isListed) {\\n                assetsIn[len] = _accountAssets[i];\\n                ++len;\\n            }\\n        }\\n\\n        assembly {\\n            mstore(assetsIn, len)\\n        }\\n\\n        return assetsIn;\\n    }\\n\\n    /**\\n     * @notice Add the market to the borrower's \\\"assets in\\\" for liquidity calculations\\n     * @param vToken The market to enter\\n     * @param borrower The address of the account to modify\\n     */\\n    function _addToMarket(VToken vToken, address borrower) internal {\\n        _checkActionPauseState(address(vToken), Action.ENTER_MARKET);\\n        Market storage marketToJoin = markets[address(vToken)];\\n\\n        if (!marketToJoin.isListed) {\\n            revert MarketNotListed(address(vToken));\\n        }\\n\\n        if (marketToJoin.accountMembership[borrower]) {\\n            // already joined\\n            return;\\n        }\\n\\n        // survived the gauntlet, add to list\\n        // NOTE: we store these somewhat redundantly as a significant optimization\\n        //  this avoids having to iterate through the list for the most common use cases\\n        //  that is, only when we need to perform liquidity checks\\n        //  and not whenever we want to check if an account is in a particular market\\n        marketToJoin.accountMembership[borrower] = true;\\n        accountAssets[borrower].push(vToken);\\n\\n        emit MarketEntered(vToken, borrower);\\n    }\\n\\n    /**\\n     * @notice Internal function to validate that a market hasn't already been added\\n     * and if it hasn't adds it\\n     * @param vToken The market to support\\n     */\\n    function _addMarket(address vToken) internal {\\n        uint256 marketsCount = allMarkets.length;\\n\\n        for (uint256 i; i < marketsCount; ++i) {\\n            if (allMarkets[i] == VToken(vToken)) {\\n                revert MarketAlreadyListed(vToken);\\n            }\\n        }\\n        allMarkets.push(VToken(vToken));\\n        marketsCount = allMarkets.length;\\n        _ensureMaxLoops(marketsCount);\\n    }\\n\\n    /**\\n     * @dev Pause/unpause an action on a market\\n     * @param market Market to pause/unpause the action on\\n     * @param action Action id to pause/unpause\\n     * @param paused The new paused state (true=paused, false=unpaused)\\n     */\\n    function _setActionPaused(address market, Action action, bool paused) internal {\\n        require(markets[market].isListed, \\\"cannot pause a market that is not listed\\\");\\n        _actionPaused[market][action] = paused;\\n        emit ActionPausedMarket(VToken(market), action, paused);\\n    }\\n\\n    /**\\n     * @dev Internal function to check that vTokens can be safely redeemed for the underlying asset.\\n     * @param vToken Address of the vTokens to redeem\\n     * @param redeemer Account redeeming the tokens\\n     * @param redeemTokens The number of tokens to redeem\\n     */\\n    function _checkRedeemAllowed(address vToken, address redeemer, uint256 redeemTokens) internal {\\n        Market storage market = markets[vToken];\\n\\n        if (!market.isListed) {\\n            revert MarketNotListed(address(vToken));\\n        }\\n\\n        /* If the redeemer is not 'in' the market, then we can bypass the liquidity check */\\n        if (!market.accountMembership[redeemer]) {\\n            return;\\n        }\\n\\n        // Update the prices of tokens\\n        updatePrices(redeemer);\\n\\n        /* Otherwise, perform a hypothetical liquidity check to guard against shortfall */\\n        AccountLiquiditySnapshot memory snapshot = _getHypotheticalLiquiditySnapshot(\\n            redeemer,\\n            VToken(vToken),\\n            redeemTokens,\\n            0,\\n            _getCollateralFactor\\n        );\\n        if (snapshot.shortfall > 0) {\\n            revert InsufficientLiquidity();\\n        }\\n    }\\n\\n    /**\\n     * @notice Get the total collateral, weighted collateral, borrow balance, liquidity, shortfall\\n     * @param account The account to get the snapshot for\\n     * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n     *  liquidation threshold. Accepts the address of the vToken and returns the weight as Exp.\\n     * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n     *  without calculating accumulated interest.\\n     * @return snapshot Account liquidity snapshot\\n     */\\n    function _getCurrentLiquiditySnapshot(\\n        address account,\\n        function(VToken) internal view returns (Exp memory) weight\\n    ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\\n        return _getHypotheticalLiquiditySnapshot(account, VToken(address(0)), 0, 0, weight);\\n    }\\n\\n    /**\\n     * @notice Determine what the supply/borrow balances would be if the given amounts were redeemed/borrowed\\n     * @param vTokenModify The market to hypothetically redeem/borrow in\\n     * @param account The account to determine liquidity for\\n     * @param redeemTokens The number of tokens to hypothetically redeem\\n     * @param borrowAmount The amount of underlying to hypothetically borrow\\n     * @param weight The function to compute the weight of the collateral \\u2013\\u00a0either collateral factor or\\n         liquidation threshold. Accepts the address of the VToken and returns the weight\\n     * @dev Note that we calculate the exchangeRateStored for each collateral vToken using stored data,\\n     *  without calculating accumulated interest.\\n     * @return snapshot Account liquidity snapshot\\n     */\\n    function _getHypotheticalLiquiditySnapshot(\\n        address account,\\n        VToken vTokenModify,\\n        uint256 redeemTokens,\\n        uint256 borrowAmount,\\n        function(VToken) internal view returns (Exp memory) weight\\n    ) internal view returns (AccountLiquiditySnapshot memory snapshot) {\\n        // For each asset the account is in\\n        VToken[] memory assets = getAssetsIn(account);\\n        uint256 assetsCount = assets.length;\\n\\n        for (uint256 i; i < assetsCount; ++i) {\\n            VToken asset = assets[i];\\n\\n            // Read the balances and exchange rate from the vToken\\n            (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) = _safeGetAccountSnapshot(\\n                asset,\\n                account\\n            );\\n\\n            // Get the normalized price of the asset\\n            Exp memory oraclePrice = Exp({ mantissa: _safeGetUnderlyingPrice(asset) });\\n\\n            // Pre-compute conversion factors from vTokens -> usd\\n            Exp memory vTokenPrice = mul_(Exp({ mantissa: exchangeRateMantissa }), oraclePrice);\\n            Exp memory weightedVTokenPrice = mul_(weight(asset), vTokenPrice);\\n\\n            // weightedCollateral += weightedVTokenPrice * vTokenBalance\\n            snapshot.weightedCollateral = mul_ScalarTruncateAddUInt(\\n                weightedVTokenPrice,\\n                vTokenBalance,\\n                snapshot.weightedCollateral\\n            );\\n\\n            // totalCollateral += vTokenPrice * vTokenBalance\\n            snapshot.totalCollateral = mul_ScalarTruncateAddUInt(vTokenPrice, vTokenBalance, snapshot.totalCollateral);\\n\\n            // borrows += oraclePrice * borrowBalance\\n            snapshot.borrows = mul_ScalarTruncateAddUInt(oraclePrice, borrowBalance, snapshot.borrows);\\n\\n            // Calculate effects of interacting with vTokenModify\\n            if (asset == vTokenModify) {\\n                // redeem effect\\n                // effects += tokensToDenom * redeemTokens\\n                snapshot.effects = mul_ScalarTruncateAddUInt(weightedVTokenPrice, redeemTokens, snapshot.effects);\\n\\n                // borrow effect\\n                // effects += oraclePrice * borrowAmount\\n                snapshot.effects = mul_ScalarTruncateAddUInt(oraclePrice, borrowAmount, snapshot.effects);\\n            }\\n        }\\n\\n        uint256 borrowPlusEffects = snapshot.borrows + snapshot.effects;\\n        // These are safe, as the underflow condition is checked first\\n        unchecked {\\n            if (snapshot.weightedCollateral > borrowPlusEffects) {\\n                snapshot.liquidity = snapshot.weightedCollateral - borrowPlusEffects;\\n                snapshot.shortfall = 0;\\n            } else {\\n                snapshot.liquidity = 0;\\n                snapshot.shortfall = borrowPlusEffects - snapshot.weightedCollateral;\\n            }\\n        }\\n\\n        return snapshot;\\n    }\\n\\n    /**\\n     * @dev Retrieves price from oracle for an asset and checks it is nonzero\\n     * @param asset Address for asset to query price\\n     * @return Underlying price\\n     */\\n    function _safeGetUnderlyingPrice(VToken asset) internal view returns (uint256) {\\n        uint256 oraclePriceMantissa = oracle.getUnderlyingPrice(address(asset));\\n        if (oraclePriceMantissa == 0) {\\n            revert PriceError(address(asset));\\n        }\\n        return oraclePriceMantissa;\\n    }\\n\\n    /**\\n     * @dev Return collateral factor for a market\\n     * @param asset Address for asset\\n     * @return Collateral factor as exponential\\n     */\\n    function _getCollateralFactor(VToken asset) internal view returns (Exp memory) {\\n        return Exp({ mantissa: markets[address(asset)].collateralFactorMantissa });\\n    }\\n\\n    /**\\n     * @dev Retrieves liquidation threshold for a market as an exponential\\n     * @param asset Address for asset to liquidation threshold\\n     * @return Liquidation threshold as exponential\\n     */\\n    function _getLiquidationThreshold(VToken asset) internal view returns (Exp memory) {\\n        return Exp({ mantissa: markets[address(asset)].liquidationThresholdMantissa });\\n    }\\n\\n    /**\\n     * @dev Returns supply and borrow balances of user in vToken, reverts on failure\\n     * @param vToken Market to query\\n     * @param user Account address\\n     * @return vTokenBalance Balance of vTokens, the same as vToken.balanceOf(user)\\n     * @return borrowBalance Borrowed amount, including the interest\\n     * @return exchangeRateMantissa Stored exchange rate\\n     */\\n    function _safeGetAccountSnapshot(\\n        VToken vToken,\\n        address user\\n    ) internal view returns (uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRateMantissa) {\\n        uint256 err;\\n        (err, vTokenBalance, borrowBalance, exchangeRateMantissa) = vToken.getAccountSnapshot(user);\\n        if (err != 0) {\\n            revert SnapshotError(address(vToken), user);\\n        }\\n        return (vTokenBalance, borrowBalance, exchangeRateMantissa);\\n    }\\n\\n    /// @notice Reverts if the call is not from expectedSender\\n    /// @param expectedSender Expected transaction sender\\n    function _checkSenderIs(address expectedSender) internal view {\\n        if (msg.sender != expectedSender) {\\n            revert UnexpectedSender(expectedSender, msg.sender);\\n        }\\n    }\\n\\n    /// @notice Reverts if a certain action is paused on a market\\n    /// @param market Market to check\\n    /// @param action Action to check\\n    function _checkActionPauseState(address market, Action action) private view {\\n        if (actionPaused(market, action)) {\\n            revert ActionPaused(market, action);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x7c6e1c6264e4681f82a9ac1bcd9155197a930033291ee5561ad97a56006f5e9c\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\n\\nenum Action {\\n    MINT,\\n    REDEEM,\\n    BORROW,\\n    REPAY,\\n    SEIZE,\\n    LIQUIDATE,\\n    TRANSFER,\\n    ENTER_MARKET,\\n    EXIT_MARKET\\n}\\n\\n/**\\n * @title ComptrollerInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract.\\n */\\ninterface ComptrollerInterface {\\n    /*** Assets You Are In ***/\\n\\n    function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n    function exitMarket(address vToken) external returns (uint256);\\n\\n    /*** Policy Hooks ***/\\n\\n    function preMintHook(address vToken, address minter, uint256 mintAmount) external;\\n\\n    function preRedeemHook(address vToken, address redeemer, uint256 redeemTokens) external;\\n\\n    function preBorrowHook(address vToken, address borrower, uint256 borrowAmount) external;\\n\\n    function preRepayHook(address vToken, address borrower) external;\\n\\n    function preLiquidateHook(\\n        address vTokenBorrowed,\\n        address vTokenCollateral,\\n        address borrower,\\n        uint256 repayAmount,\\n        bool skipLiquidityCheck\\n    ) external;\\n\\n    function preSeizeHook(\\n        address vTokenCollateral,\\n        address vTokenBorrowed,\\n        address liquidator,\\n        address borrower\\n    ) external;\\n\\n    function borrowVerify(address vToken, address borrower, uint borrowAmount) external;\\n\\n    function mintVerify(address vToken, address minter, uint mintAmount, uint mintTokens) external;\\n\\n    function redeemVerify(address vToken, address redeemer, uint redeemAmount, uint redeemTokens) external;\\n\\n    function repayBorrowVerify(\\n        address vToken,\\n        address payer,\\n        address borrower,\\n        uint repayAmount,\\n        uint borrowerIndex\\n    ) external;\\n\\n    function liquidateBorrowVerify(\\n        address vTokenBorrowed,\\n        address vTokenCollateral,\\n        address liquidator,\\n        address borrower,\\n        uint repayAmount,\\n        uint seizeTokens\\n    ) external;\\n\\n    function seizeVerify(\\n        address vTokenCollateral,\\n        address vTokenBorrowed,\\n        address liquidator,\\n        address borrower,\\n        uint seizeTokens\\n    ) external;\\n\\n    function transferVerify(address vToken, address src, address dst, uint transferTokens) external;\\n\\n    function preTransferHook(address vToken, address src, address dst, uint256 transferTokens) external;\\n\\n    function isComptroller() external view returns (bool);\\n\\n    /*** Liquidity/Liquidation Calculations ***/\\n\\n    function liquidateCalculateSeizeTokens(\\n        address vTokenBorrowed,\\n        address vTokenCollateral,\\n        uint256 repayAmount\\n    ) external view returns (uint256, uint256);\\n\\n    function getAllMarkets() external view returns (VToken[] memory);\\n\\n    function actionPaused(address market, Action action) external view returns (bool);\\n}\\n\\n/**\\n * @title ComptrollerViewInterface\\n * @author Venus\\n * @notice Interface implemented by the `Comptroller` contract, including only some util view functions.\\n */\\ninterface ComptrollerViewInterface {\\n    function markets(address) external view returns (bool, uint256);\\n\\n    function oracle() external view returns (ResilientOracleInterface);\\n\\n    function getAssetsIn(address) external view returns (VToken[] memory);\\n\\n    function closeFactorMantissa() external view returns (uint256);\\n\\n    function liquidationIncentiveMantissa() external view returns (uint256);\\n\\n    function minLiquidatableCollateral() external view returns (uint256);\\n\\n    function getRewardDistributors() external view returns (RewardsDistributor[] memory);\\n\\n    function getAllMarkets() external view returns (VToken[] memory);\\n\\n    function borrowCaps(address) external view returns (uint256);\\n\\n    function supplyCaps(address) external view returns (uint256);\\n\\n    function approvedDelegates(address user, address delegate) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xcbf7f9977472650c61345b7cbde23e81f626e1f8863bab4c6ce3dacfc7604919\",\"license\":\"BSD-3-Clause\"},\"contracts/ComptrollerStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { VToken } from \\\"./VToken.sol\\\";\\nimport { RewardsDistributor } from \\\"./Rewards/RewardsDistributor.sol\\\";\\nimport { IPrime } from \\\"@venusprotocol/venus-protocol/contracts/Tokens/Prime/Interfaces/IPrime.sol\\\";\\nimport { Action } from \\\"./ComptrollerInterface.sol\\\";\\n\\n/**\\n * @title ComptrollerStorage\\n * @author Venus\\n * @notice Storage layout for the `Comptroller` contract.\\n */\\ncontract ComptrollerStorage {\\n    struct LiquidationOrder {\\n        VToken vTokenCollateral;\\n        VToken vTokenBorrowed;\\n        uint256 repayAmount;\\n    }\\n\\n    struct AccountLiquiditySnapshot {\\n        uint256 totalCollateral;\\n        uint256 weightedCollateral;\\n        uint256 borrows;\\n        uint256 effects;\\n        uint256 liquidity;\\n        uint256 shortfall;\\n    }\\n\\n    struct RewardSpeeds {\\n        address rewardToken;\\n        uint256 supplySpeed;\\n        uint256 borrowSpeed;\\n    }\\n\\n    struct Market {\\n        // Whether or not this market is listed\\n        bool isListed;\\n        //  Multiplier representing the most one can borrow against their collateral in this market.\\n        //  For instance, 0.9 to allow borrowing 90% of collateral value.\\n        //  Must be between 0 and 1, and stored as a mantissa.\\n        uint256 collateralFactorMantissa;\\n        //  Multiplier representing the collateralization after which the borrow is eligible\\n        //  for liquidation. For instance, 0.8 liquidate when the borrow is 80% of collateral\\n        //  value. Must be between 0 and collateral factor, stored as a mantissa.\\n        uint256 liquidationThresholdMantissa;\\n        // Per-market mapping of \\\"accounts in this asset\\\"\\n        mapping(address => bool) accountMembership;\\n    }\\n\\n    /**\\n     * @notice Oracle which gives the price of any given asset\\n     */\\n    ResilientOracleInterface public oracle;\\n\\n    /**\\n     * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow\\n     */\\n    uint256 public closeFactorMantissa;\\n\\n    /**\\n     * @notice Multiplier representing the discount on collateral that a liquidator receives\\n     */\\n    uint256 public liquidationIncentiveMantissa;\\n\\n    /**\\n     * @notice Per-account mapping of \\\"assets you are in\\\"\\n     */\\n    mapping(address => VToken[]) public accountAssets;\\n\\n    /**\\n     * @notice Official mapping of vTokens -> Market metadata\\n     * @dev Used e.g. to determine if a market is supported\\n     */\\n    mapping(address => Market) public markets;\\n\\n    /// @notice A list of all markets\\n    VToken[] public allMarkets;\\n\\n    /// @notice Borrow caps enforced by borrowAllowed for each vToken address. Defaults to zero which restricts borrowing.\\n    mapping(address => uint256) public borrowCaps;\\n\\n    /// @notice Minimal collateral required for regular (non-batch) liquidations\\n    uint256 public minLiquidatableCollateral;\\n\\n    /// @notice Supply caps enforced by mintAllowed for each vToken address. Defaults to zero which corresponds to minting not allowed\\n    mapping(address => uint256) public supplyCaps;\\n\\n    /// @notice True if a certain action is paused on a certain market\\n    mapping(address => mapping(Action => bool)) internal _actionPaused;\\n\\n    // List of Reward Distributors added\\n    RewardsDistributor[] internal rewardsDistributors;\\n\\n    // Used to check if rewards distributor is added\\n    mapping(address => bool) internal rewardsDistributorExists;\\n\\n    /// @notice Flag indicating whether forced liquidation enabled for a market\\n    mapping(address => bool) public isForcedLiquidationEnabled;\\n\\n    uint256 internal constant NO_ERROR = 0;\\n\\n    // closeFactorMantissa must be strictly greater than this value\\n    uint256 internal constant MIN_CLOSE_FACTOR_MANTISSA = 0.05e18; // 0.05\\n\\n    // closeFactorMantissa must not exceed this value\\n    uint256 internal constant MAX_CLOSE_FACTOR_MANTISSA = 0.9e18; // 0.9\\n\\n    // No collateralFactorMantissa may exceed this value\\n    uint256 internal constant MAX_COLLATERAL_FACTOR_MANTISSA = 0.95e18; // 0.95\\n\\n    /// Prime token address\\n    IPrime public prime;\\n\\n    /// @notice Whether the delegate is allowed to borrow or redeem on behalf of the user\\n    //mapping(address user => mapping (address delegate => bool approved)) public approvedDelegates;\\n    mapping(address => mapping(address => bool)) public approvedDelegates;\\n\\n    /**\\n     * @dev This empty reserved space is put in place to allow future versions to add new\\n     * variables without shifting down storage in the inheritance chain.\\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n     */\\n    uint256[47] private __gap;\\n}\\n\",\"keccak256\":\"0x4df44cb65ac152bac2be4b4545430e703005a74a55b72e144100b16421bd8bfd\",\"license\":\"BSD-3-Clause\"},\"contracts/ERC4626/Interfaces/IComptroller.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { Action } from \\\"../../ComptrollerInterface.sol\\\";\\nimport { RewardsDistributor } from \\\"../../Rewards/RewardsDistributor.sol\\\";\\n\\n/**\\n * @title IComptroller\\n * @author Venus\\n * @notice Combined interface for the `Comptroller` contract, including both core and view functions.\\n */\\ninterface IComptroller {\\n    function actionPaused(address market, Action action) external view returns (bool);\\n\\n    function getRewardDistributors() external view returns (RewardsDistributor[] memory);\\n\\n    function supplyCaps(address) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0xf1c8d4e69f39652edd0699319ce5dce3c6b00241d6b090fc1da3b13072073b1f\",\"license\":\"BSD-3-Clause\"},\"contracts/ERC4626/Interfaces/IProtocolShareReserve.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\ninterface IProtocolShareReserve {\\n    /// @notice it represents the type of vToken income\\n    enum IncomeType {\\n        SPREAD,\\n        LIQUIDATION,\\n        ERC4626_WRAPPER_REWARDS,\\n        FLASHLOAN\\n    }\\n\\n    function updateAssetsState(address comptroller, address asset, IncomeType incomeType) external;\\n}\\n\",\"keccak256\":\"0x9ca700a59330cb3bb1b1fe1cbd93b02c06d6ba8f9457ab12e03e87bec0c41235\",\"license\":\"BSD-3-Clause\"},\"contracts/ERC4626/VenusERC4626.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { ERC4626Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC4626Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { ERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\\\";\\nimport { ReentrancyGuardUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\n\\nimport { IProtocolShareReserve } from \\\"./Interfaces/IProtocolShareReserve.sol\\\";\\nimport { RewardsDistributor } from \\\".././Rewards/RewardsDistributor.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\nimport { IComptroller } from \\\"./Interfaces/IComptroller.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"@venusprotocol/solidity-utilities/contracts/validators.sol\\\";\\n\\nimport { Action } from \\\"../ComptrollerInterface.sol\\\";\\nimport { EXP_SCALE } from \\\".././lib/constants.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\n\\n/// @title VenusERC4626\\n/// @notice ERC4626 wrapper for Venus vTokens, enabling standard ERC4626 vault interactions with Venus Protocol.\\ncontract VenusERC4626 is ERC4626Upgradeable, AccessControlledV8, MaxLoopsLimitHelper, ReentrancyGuardUpgradeable {\\n    using SafeERC20Upgradeable for ERC20Upgradeable;\\n\\n    enum Rounding {\\n        Down,\\n        Up\\n    }\\n\\n    /// @notice Error code representing no errors in Venus operations.\\n    uint256 internal constant NO_ERROR = 0;\\n\\n    /// @notice The Venus vToken associated with this ERC4626 vault.\\n    VToken public vToken;\\n\\n    /// @notice The Venus Comptroller contract, responsible for market operations.\\n    IComptroller public comptroller;\\n\\n    /// @notice The recipient of rewards distributed by the Venus Protocol.\\n    address public rewardRecipient;\\n\\n    /// @notice Emitted when rewards are claimed.\\n    /// @param amount The amount of reward tokens claimed.\\n    /// @param rewardToken The address of the reward token claimed.\\n    event ClaimRewards(uint256 amount, address indexed rewardToken);\\n\\n    /// @notice Emitted when the reward recipient address is updated.\\n    /// @param oldRecipient The previous reward recipient address.\\n    /// @param newRecipient The new reward recipient address.\\n    event RewardRecipientUpdated(address indexed oldRecipient, address indexed newRecipient);\\n\\n    /// @notice Event emitted when tokens are swept\\n    event SweepToken(address indexed token, address indexed receiver, uint256 amount);\\n\\n    /// @notice Thrown when a Venus protocol call returns an error.\\n    /// @dev This error is triggered if a Venus operation (such as minting or redeeming vTokens) fails.\\n    /// @param errorCode The error code returned by the Venus protocol.\\n    error VenusERC4626__VenusError(uint256 errorCode);\\n\\n    /// @notice Thrown when a deposit exceeds the maximum allowed limit.\\n    /// @dev This error is triggered if the deposit amount is greater than `maxDeposit(receiver)`.\\n    error ERC4626__DepositMoreThanMax();\\n\\n    /// @notice Thrown when a mint operation exceeds the maximum allowed limit.\\n    /// @dev This error is triggered if the mint amount is greater than `maxMint(receiver)`.\\n    error ERC4626__MintMoreThanMax();\\n\\n    /// @notice Thrown when a withdrawal exceeds the maximum available assets.\\n    /// @dev This error is triggered if the withdrawal amount is greater than `maxWithdraw(owner)`.\\n    error ERC4626__WithdrawMoreThanMax();\\n\\n    /// @notice Thrown when a redemption exceeds the maximum redeemable shares.\\n    /// @dev This error is triggered if the redemption amount is greater than `maxRedeem(owner)`.\\n    error ERC4626__RedeemMoreThanMax();\\n\\n    /// @notice Thrown when attempting an operation with a zero amount.\\n    /// @dev This error prevents unnecessary transactions with zero amounts in deposit, withdraw, mint, or redeem operations.\\n    /// @param operation The name of the operation that failed (e.g., \\\"deposit\\\", \\\"withdraw\\\", \\\"mint\\\", \\\"redeem\\\").\\n    error ERC4626__ZeroAmount(string operation);\\n\\n    /// @custom:oz-upgrades-unsafe-allow constructor\\n    constructor() {\\n        // Note that the contract is upgradeable. Use initialize() or reinitializers\\n        // to set the state variables.\\n        _disableInitializers();\\n    }\\n\\n    /// @notice Initializes the VenusERC4626 vault, only with the VToken address associated to the vault\\n    /// @dev `initialize2` should be invoked to complete the configuration of the vault\\n    /// @param vToken_ The VToken associated with the vault, representing the yield-bearing asset.\\n    function initialize(address vToken_) public initializer {\\n        ensureNonzeroAddress(vToken_);\\n\\n        vToken = VToken(vToken_);\\n        comptroller = IComptroller(address(vToken.comptroller()));\\n        ERC20Upgradeable asset = ERC20Upgradeable(vToken.underlying());\\n\\n        __ERC20_init(_generateVaultName(asset), _generateVaultSymbol(asset));\\n        __ERC4626_init(asset);\\n        __ReentrancyGuard_init();\\n    }\\n\\n    /**\\n     * @notice Set the limit for the loops can iterate to avoid the DOS\\n     * @param loopsLimit Number of loops limit\\n     * @custom:event Emits MaxLoopsLimitUpdated event on success\\n     * @custom:access Controlled by ACM\\n     */\\n    function setMaxLoopsLimit(uint256 loopsLimit) external {\\n        _checkAccessAllowed(\\\"setMaxLoopsLimit(uint256)\\\");\\n        _setMaxLoopsLimit(loopsLimit);\\n    }\\n\\n    /// @notice Sets a new reward recipient address\\n    /// @param newRecipient The address of the new reward recipient\\n    /// @custom:access Controlled by ACM\\n    function setRewardRecipient(address newRecipient) external {\\n        _checkAccessAllowed(\\\"setRewardRecipient(address)\\\");\\n        _setRewardRecipient(newRecipient);\\n    }\\n\\n    /// @notice Sweeps the input token address tokens from the contract and sends them to the owner\\n    /// @param token Address of the token\\n    /// @custom:event SweepToken emits on success\\n    /// @custom:access Only owner\\n    function sweepToken(IERC20Upgradeable token) external onlyOwner {\\n        uint256 balance = token.balanceOf(address(this));\\n\\n        if (balance > 0) {\\n            address owner_ = owner();\\n            SafeERC20Upgradeable.safeTransfer(token, owner_, balance);\\n            emit SweepToken(address(token), owner_, balance);\\n        }\\n    }\\n\\n    /// @notice Claims rewards from all reward distributors associated with the VToken and transfers them to the reward recipient.\\n    /// @dev Iterates through all reward distributors fetched from the comptroller, claims rewards, and transfers them if available.\\n    function claimRewards() external {\\n        IComptroller _comptroller = comptroller;\\n        VToken _vToken = vToken;\\n        address _rewardRecipient = rewardRecipient;\\n\\n        RewardsDistributor[] memory rewardDistributors = comptroller.getRewardDistributors();\\n\\n        _ensureMaxLoops(rewardDistributors.length);\\n\\n        for (uint256 i = 0; i < rewardDistributors.length; i++) {\\n            RewardsDistributor rewardDistributor = rewardDistributors[i];\\n            IERC20Upgradeable rewardToken = IERC20Upgradeable(address(rewardDistributor.rewardToken()));\\n\\n            VToken[] memory vTokens = new VToken[](1);\\n            vTokens[0] = _vToken;\\n            RewardsDistributor(rewardDistributor).claimRewardToken(address(this), vTokens);\\n            uint256 rewardBalance = rewardToken.balanceOf(address(this));\\n\\n            if (rewardBalance > 0) {\\n                SafeERC20Upgradeable.safeTransfer(rewardToken, _rewardRecipient, rewardBalance);\\n\\n                // Try to update the asset state on the recipient if reward recipient is a protocol share reserve\\n                // reward recipient cannot be an EOA\\n                try\\n                    IProtocolShareReserve(_rewardRecipient).updateAssetsState(\\n                        address(_comptroller),\\n                        address(rewardToken),\\n                        IProtocolShareReserve.IncomeType.ERC4626_WRAPPER_REWARDS\\n                    )\\n                {} catch {}\\n            }\\n            emit ClaimRewards(rewardBalance, address(rewardToken));\\n        }\\n    }\\n\\n    /// @notice Second function to invoked to complete the configuration of the vault, setting the rest of the attributes\\n    /// @param accessControlManager_ Address of the ACM contract\\n    /// @param rewardRecipient_ The address that will receive rewards generated by the vault.\\n    /// @param loopsLimit_ The maximum number of loops allowed for reward distribution.\\n    /// @param vaultOwner_ The owner that will be set for the created vault\\n    function initialize2(\\n        address accessControlManager_,\\n        address rewardRecipient_,\\n        uint256 loopsLimit_,\\n        address vaultOwner_\\n    ) public reinitializer(2) {\\n        ensureNonzeroAddress(vaultOwner_);\\n\\n        __AccessControlled_init(accessControlManager_);\\n        _setMaxLoopsLimit(loopsLimit_);\\n        _setRewardRecipient(rewardRecipient_);\\n        _transferOwnership(vaultOwner_);\\n    }\\n\\n    /// @inheritdoc ERC4626Upgradeable\\n    function deposit(uint256 assets, address receiver) public override nonReentrant returns (uint256) {\\n        ensureNonzeroAddress(receiver);\\n\\n        vToken.accrueInterest();\\n        if (assets == 0) {\\n            revert ERC4626__ZeroAmount(\\\"deposit\\\");\\n        }\\n        if (assets > maxDeposit(receiver)) {\\n            revert ERC4626__DepositMoreThanMax();\\n        }\\n\\n        uint256 shares = previewDeposit(assets);\\n        if (shares == 0) {\\n            revert ERC4626__ZeroAmount(\\\"deposit\\\");\\n        }\\n        _deposit(_msgSender(), receiver, assets, shares);\\n        afterDeposit(assets);\\n        return shares;\\n    }\\n\\n    /// @inheritdoc ERC4626Upgradeable\\n    function mint(uint256 shares, address receiver) public override nonReentrant returns (uint256) {\\n        ensureNonzeroAddress(receiver);\\n\\n        vToken.accrueInterest();\\n        if (shares == 0) {\\n            revert ERC4626__ZeroAmount(\\\"mint\\\");\\n        }\\n        if (shares > maxMint(receiver)) {\\n            revert ERC4626__MintMoreThanMax();\\n        }\\n        uint256 assets = previewMint(shares);\\n        if (assets == 0) {\\n            revert ERC4626__ZeroAmount(\\\"mint\\\");\\n        }\\n        _deposit(_msgSender(), receiver, assets, shares);\\n        afterDeposit(assets);\\n        return assets;\\n    }\\n\\n    /// @inheritdoc ERC4626Upgradeable\\n    function withdraw(uint256 assets, address receiver, address owner) public override nonReentrant returns (uint256) {\\n        ensureNonzeroAddress(receiver);\\n        ensureNonzeroAddress(owner);\\n\\n        vToken.accrueInterest();\\n        if (assets == 0) {\\n            revert ERC4626__ZeroAmount(\\\"withdraw\\\");\\n        }\\n        if (assets > maxWithdraw(owner)) {\\n            revert ERC4626__WithdrawMoreThanMax();\\n        }\\n\\n        uint256 shares = previewWithdraw(assets);\\n        if (shares == 0) {\\n            revert ERC4626__ZeroAmount(\\\"withdraw\\\");\\n        }\\n        uint256 actualAssets = beforeWithdraw(assets);\\n        _withdraw(_msgSender(), receiver, owner, actualAssets, shares);\\n        return shares;\\n    }\\n\\n    /// @inheritdoc ERC4626Upgradeable\\n    function redeem(uint256 shares, address receiver, address owner) public override nonReentrant returns (uint256) {\\n        ensureNonzeroAddress(receiver);\\n        ensureNonzeroAddress(owner);\\n\\n        vToken.accrueInterest();\\n        if (shares == 0) {\\n            revert ERC4626__ZeroAmount(\\\"redeem\\\");\\n        }\\n        if (shares > maxRedeem(owner)) {\\n            revert ERC4626__RedeemMoreThanMax();\\n        }\\n\\n        uint256 assets = previewRedeem(shares);\\n        if (assets == 0) {\\n            revert ERC4626__ZeroAmount(\\\"redeem\\\");\\n        }\\n\\n        // actualAssets should be equal to assets, because of the round performed in previewRedeem\\n        // but let's use the returned value anyway\\n        uint256 actualAssets = beforeWithdraw(assets);\\n        _withdraw(_msgSender(), receiver, owner, actualAssets, shares);\\n        return actualAssets;\\n    }\\n\\n    /// @inheritdoc ERC4626Upgradeable\\n    function previewDeposit(uint256 assets) public view virtual override returns (uint256) {\\n        // round down the asset amount, to deposit an amont equivalent to a natural number of vTokens, without decimals\\n        uint256 adjustedAssets = _roundAssets(assets, Rounding.Down);\\n\\n        return super.previewDeposit(adjustedAssets);\\n    }\\n\\n    /// @inheritdoc ERC4626Upgradeable\\n    function previewMint(uint256 shares) public view virtual override returns (uint256) {\\n        uint256 assets = super.previewMint(shares);\\n\\n        // round up the asset amount, to deposit an amont equivalent to a natural number of vTokens, without decimals\\n        return _roundAssets(assets, Rounding.Up);\\n    }\\n\\n    /// @inheritdoc ERC4626Upgradeable\\n    function previewWithdraw(uint256 assets) public view virtual override returns (uint256) {\\n        // round up the asset amount to redeem a natural number of vTokens, without decimals\\n        uint256 adjustedAssets = _roundAssets(assets, Rounding.Up);\\n\\n        return super.previewWithdraw(adjustedAssets);\\n    }\\n\\n    /// @inheritdoc ERC4626Upgradeable\\n    function previewRedeem(uint256 shares) public view virtual override returns (uint256) {\\n        uint256 assets = super.previewRedeem(shares);\\n\\n        // round down the asset amount to redeem a natural number of vTokens, without decimals\\n        return _roundAssets(assets, Rounding.Down);\\n    }\\n\\n    /// @notice Returns the total amount of assets deposited\\n    /// @return Amount of assets deposited\\n    function totalAssets() public view virtual override returns (uint256) {\\n        return (vToken.balanceOf(address(this)) * vToken.exchangeRateStored()) / EXP_SCALE;\\n    }\\n\\n    /// @notice Returns the maximum deposit allowed based on Venus supply caps.\\n    /// @dev If minting is paused or the supply cap is reached, returns 0.\\n    /// @param /*account*/ The address of the account.\\n    /// @return The maximum amount of assets that can be deposited.\\n    function maxDeposit(address /*account*/) public view virtual override returns (uint256) {\\n        if (comptroller.actionPaused(address(vToken), Action.MINT)) {\\n            return 0;\\n        }\\n\\n        uint256 supplyCap = comptroller.supplyCaps(address(vToken));\\n        uint256 totalSupply_ = (vToken.totalSupply() * vToken.exchangeRateStored()) / EXP_SCALE;\\n        return supplyCap > totalSupply_ ? supplyCap - totalSupply_ : 0;\\n    }\\n\\n    /// @notice Returns the maximum amount of shares that can be minted.\\n    /// @dev This is derived from the maximum deposit amount converted to shares.\\n    /// @param /*account*/ The address of the account.\\n    /// @return The maximum number of shares that can be minted.\\n    function maxMint(address /*account*/) public view virtual override returns (uint256) {\\n        return convertToShares(maxDeposit(address(0)));\\n    }\\n\\n    /// @notice Returns the maximum amount that can be withdrawn.\\n    /// @dev The withdrawable amount is limited by the available cash in the vault.\\n    /// @param receiver The address of the account withdrawing.\\n    /// @return The maximum amount of assets that can be withdrawn.\\n    function maxWithdraw(address receiver) public view virtual override returns (uint256) {\\n        if (comptroller.actionPaused(address(vToken), Action.REDEEM)) {\\n            return 0;\\n        }\\n\\n        uint256 cash = vToken.getCash();\\n        uint256 totalReserves = vToken.totalReserves();\\n        uint256 assetsBalance = convertToAssets(balanceOf(receiver));\\n\\n        if (cash < totalReserves) {\\n            return 0;\\n        } else {\\n            uint256 availableCash = cash - totalReserves;\\n            return availableCash < assetsBalance ? availableCash : assetsBalance;\\n        }\\n    }\\n\\n    /// @notice Returns the maximum amount of shares that can be redeemed.\\n    /// @dev Redemption is limited by the available cash in the vault.\\n    /// @param receiver The address of the account redeeming.\\n    /// @return The maximum number of shares that can be redeemed.\\n    function maxRedeem(address receiver) public view virtual override returns (uint256) {\\n        if (comptroller.actionPaused(address(vToken), Action.REDEEM)) {\\n            return 0;\\n        }\\n\\n        uint256 cash = vToken.getCash();\\n        uint256 totalReserves = vToken.totalReserves();\\n        if (cash < totalReserves) {\\n            return 0;\\n        } else {\\n            uint256 availableCash = cash - totalReserves;\\n            uint256 availableCashInShares = convertToShares(availableCash);\\n            uint256 shareBalance = balanceOf(receiver);\\n            return availableCashInShares < shareBalance ? availableCashInShares : shareBalance;\\n        }\\n    }\\n\\n    /// @notice Redeems underlying assets before withdrawing from the vault.\\n    /// @dev Calls `redeemUnderlying` on the vToken contract. Reverts on error.\\n    /// @param assets The amount of underlying assets to redeem.\\n    /// @return The amount of assets transferred in\\n    function beforeWithdraw(uint256 assets) internal returns (uint256) {\\n        IERC20Upgradeable token = IERC20Upgradeable(asset());\\n        uint256 balanceBefore = token.balanceOf(address(this));\\n\\n        uint256 errorCode = vToken.redeemUnderlying(assets);\\n        if (errorCode != NO_ERROR) {\\n            revert VenusERC4626__VenusError(errorCode);\\n        }\\n\\n        uint256 balanceAfter = token.balanceOf(address(this));\\n        // Return the amount that was *actually* transferred\\n        return balanceAfter - balanceBefore;\\n    }\\n\\n    /// @notice Mints vTokens after depositing assets.\\n    /// @dev Calls `mint` on the vToken contract. Reverts on error.\\n    /// @param assets The amount of underlying assets to deposit.\\n    function afterDeposit(uint256 assets) internal {\\n        ERC20Upgradeable(asset()).safeApprove(address(vToken), assets);\\n        uint256 errorCode = vToken.mint(assets);\\n        if (errorCode != NO_ERROR) {\\n            revert VenusERC4626__VenusError(errorCode);\\n        }\\n    }\\n\\n    /// @notice Sets a new reward recipient address\\n    /// @param newRecipient The address of the new reward recipient\\n    /// @custom:error ZeroAddressNotAllowed is thrown when the new recipient address is zero\\n    /// @custom:event RewardRecipientUpdated is emitted when the reward recipient address is updated\\n    function _setRewardRecipient(address newRecipient) internal {\\n        ensureNonzeroAddress(newRecipient);\\n\\n        emit RewardRecipientUpdated(rewardRecipient, newRecipient);\\n        rewardRecipient = newRecipient;\\n    }\\n\\n    /// @notice Override `_decimalsOffset` to normalize decimals to 18 for all VenusERC4626 vaults.\\n    /// @return Gap between 18 and the decimals of the asset token\\n    function _decimalsOffset() internal view virtual override returns (uint8) {\\n        return 18 - ERC20Upgradeable(asset()).decimals();\\n    }\\n\\n    /// @notice Generates an returns the derived name of the vault considering the asset name\\n    /// @param asset_ Asset to be accepted in the vault whose name this function will return\\n    /// @return Name of the vault considering the asset name\\n    function _generateVaultName(ERC20Upgradeable asset_) internal view returns (string memory) {\\n        return string(abi.encodePacked(\\\"ERC4626-Wrapped Venus \\\", asset_.name()));\\n    }\\n\\n    /// @notice Generates and returns the derived symbol of the vault considering the asset symbol\\n    /// @param asset_ Asset to be accepted in the vault whose symbol this function will return\\n    /// @return Symbol of the vault considering the asset name\\n    function _generateVaultSymbol(ERC20Upgradeable asset_) internal view returns (string memory) {\\n        return string(abi.encodePacked(\\\"v4626\\\", asset_.symbol()));\\n    }\\n\\n    /// @notice Round the amount of assets, up or down, to a multiple of the exchange rate. That way the\\n    /// associated number of VTokens won't have any decimals\\n    /// @param assets The amount of assets to round\\n    /// @param rounding If the round should be up (Rounding.Up), or down (Rounding.Down)\\n    /// @return The rounded amount of assets\\n    function _roundAssets(uint256 assets, Rounding rounding) internal view returns (uint256) {\\n        uint256 exchangeRate = vToken.exchangeRateStored();\\n        uint256 redeemTokens = (assets * EXP_SCALE) / exchangeRate;\\n\\n        uint256 _redeemAmount = (redeemTokens * exchangeRate) / EXP_SCALE;\\n\\n        if (_redeemAmount != 0 && _redeemAmount != assets && rounding == Rounding.Up) redeemTokens++; // round up\\n\\n        // redeemAmount = exchangeRate * redeemTokens\\n        return (exchangeRate * redeemTokens) / EXP_SCALE;\\n    }\\n}\\n\",\"keccak256\":\"0x0b2b435c7b78752c80f5f8413f3bb58188f9966e34483760b6f90fa79ce81cc6\",\"license\":\"BSD-3-Clause\"},\"contracts/ERC4626/VenusERC4626Factory.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { ERC4626Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC4626Upgradeable.sol\\\";\\nimport { UpgradeableBeacon } from \\\"@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol\\\";\\nimport { BeaconProxy } from \\\"@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol\\\";\\n\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\nimport { PoolRegistryInterface } from \\\"../Pool/PoolRegistryInterface.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\nimport { VTokenInterface } from \\\"../VTokenInterfaces.sol\\\";\\nimport { VenusERC4626 } from \\\"./VenusERC4626.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"@venusprotocol/solidity-utilities/contracts/validators.sol\\\";\\n\\n/// @title VenusERC4626Factory\\n/// @notice Factory for creating VenusERC4626 contracts\\ncontract VenusERC4626Factory is AccessControlledV8, MaxLoopsLimitHelper {\\n    /// @notice A constant salt value used for deterministic contract deployment\\n    bytes32 public constant SALT = keccak256(\\\"Venus-ERC4626 Vault\\\");\\n\\n    /// @notice The beacon contract for VenusERC4626 proxies\\n    UpgradeableBeacon public beacon;\\n\\n    /// @notice The Pool Registry contract\\n    PoolRegistryInterface public poolRegistry;\\n\\n    /// @notice The address that will receive the liquidity mining rewards\\n    address public rewardRecipient;\\n\\n    // @notice Map of vaults created by this factory\\n    mapping(address vToken => ERC4626Upgradeable vault) public createdVaults;\\n\\n    /// @notice Emitted when a new ERC4626 vault has been created\\n    /// @param vToken The vToken used by the vault\\n    /// @param vault The vault that was created\\n    event CreateERC4626(VTokenInterface indexed vToken, ERC4626Upgradeable indexed vault);\\n\\n    /// @notice Emitted when the reward recipient address is updated.\\n    /// @param oldRecipient The previous reward recipient address.\\n    /// @param newRecipient The new reward recipient address.\\n    event RewardRecipientUpdated(address indexed oldRecipient, address indexed newRecipient);\\n\\n    /// @notice Thrown when the provided vToken is not registered in PoolRegistry\\n    error VenusERC4626Factory__InvalidVToken();\\n\\n    /// @notice Thrown when a VenusERC4626 already exists for the provided vToken\\n    error VenusERC4626Factory__ERC4626AlreadyExists();\\n\\n    /// @custom:oz-upgrades-unsafe-allow constructor\\n    constructor() {\\n        // Note that the contract is upgradeable. Use initialize() or reinitializers\\n        // to set the state variables.\\n        _disableInitializers();\\n    }\\n\\n    /// @notice Initializes the contract\\n    /// @param accessControlManager Address of the ACM contract\\n    /// @param poolRegistryAddress Address of the Pool Registry contract\\n    /// @param rewardRecipientAddress Reward recipient address\\n    /// @param venusERC4626Implementation Address of the VenusERC4626 implementation contract\\n    /// @param loopsLimitNumber The loops limit for the MaxLoopsLimit helper\\n    function initialize(\\n        address accessControlManager,\\n        address poolRegistryAddress,\\n        address rewardRecipientAddress,\\n        address venusERC4626Implementation,\\n        uint256 loopsLimitNumber\\n    ) external initializer {\\n        ensureNonzeroAddress(accessControlManager);\\n        ensureNonzeroAddress(poolRegistryAddress);\\n        ensureNonzeroAddress(rewardRecipientAddress);\\n        ensureNonzeroAddress(venusERC4626Implementation);\\n\\n        __AccessControlled_init(accessControlManager);\\n\\n        poolRegistry = PoolRegistryInterface(poolRegistryAddress);\\n        rewardRecipient = rewardRecipientAddress;\\n        _setMaxLoopsLimit(loopsLimitNumber);\\n\\n        // Deploy the upgradeable beacon with the initial implementation\\n        beacon = new UpgradeableBeacon(venusERC4626Implementation);\\n\\n        // The owner of the beacon will initially be the owner of the factory\\n        beacon.transferOwnership(owner());\\n    }\\n\\n    /// @notice Sets a new reward recipient address\\n    /// @param newRecipient The address of the new reward recipient\\n    /// @custom:access Controlled by ACM\\n    /// @custom:error ZeroAddressNotAllowed is thrown when the new recipient address is zero\\n    /// @custom:event RewardRecipientUpdated is emitted when the reward recipient address is updated\\n    function setRewardRecipient(address newRecipient) external {\\n        _checkAccessAllowed(\\\"setRewardRecipient(address)\\\");\\n        ensureNonzeroAddress(newRecipient);\\n\\n        emit RewardRecipientUpdated(rewardRecipient, newRecipient);\\n        rewardRecipient = newRecipient;\\n    }\\n\\n    /**\\n     * @notice Set the limit for the loops can iterate to avoid the DOS\\n     * @param loopsLimit Number of loops limit\\n     * @custom:event Emits MaxLoopsLimitUpdated event on success\\n     * @custom:access Controlled by ACM\\n     */\\n    function setMaxLoopsLimit(uint256 loopsLimit) external {\\n        _checkAccessAllowed(\\\"setMaxLoopsLimit(uint256)\\\");\\n        _setMaxLoopsLimit(loopsLimit);\\n    }\\n\\n    /// @notice Creates a VenusERC4626 vault for a given asset and comptroller\\n    /// @param vToken The vToken address to create the vault\\n    /// @return vault The deployed VenusERC4626 vault\\n    /// @custom:error ZeroAddressNotAllowed is thrown when the vToken address is zero\\n    /// @custom:error VenusERC4626Factory__InvalidVToken is thrown when the provided vToken is not supported by the poolRegistry\\n    /// @custom:error VenusERC4626Factory__ERC4626AlreadyExists is thrown when this factory already created a VenusERC4626 for the provided vToken\\n    /// @custom:event CreateERC4626 is emitted when the ERC4626 wrapper is created\\n    function createERC4626(address vToken) external returns (ERC4626Upgradeable vault) {\\n        ensureNonzeroAddress(vToken);\\n\\n        if (address(createdVaults[vToken]) != address(0)) {\\n            revert VenusERC4626Factory__ERC4626AlreadyExists();\\n        }\\n\\n        VTokenInterface vToken_ = VTokenInterface(vToken);\\n\\n        address comptroller = address(vToken_.comptroller());\\n\\n        if (vToken != poolRegistry.getVTokenForAsset(comptroller, vToken_.underlying())) {\\n            revert VenusERC4626Factory__InvalidVToken();\\n        }\\n\\n        VenusERC4626 venusERC4626 = VenusERC4626(\\n            address(\\n                new BeaconProxy{ salt: SALT }(\\n                    address(beacon),\\n                    abi.encodeWithSelector(VenusERC4626.initialize.selector, vToken)\\n                )\\n            )\\n        );\\n\\n        venusERC4626.initialize2(address(_accessControlManager), rewardRecipient, maxLoopsLimit, owner());\\n\\n        vault = ERC4626Upgradeable(address(venusERC4626));\\n\\n        createdVaults[vToken] = vault;\\n\\n        emit CreateERC4626(vToken_, vault);\\n    }\\n\\n    /// @notice Predicts the vault address for a given vToken\\n    /// @param vToken The vToken address\\n    /// @return The precomputed vault address\\n    function computeVaultAddress(address vToken) public view returns (address) {\\n        return\\n            address(\\n                uint160(\\n                    uint256(\\n                        keccak256(\\n                            abi.encodePacked(\\n                                bytes1(0xff),\\n                                address(this),\\n                                SALT,\\n                                keccak256(\\n                                    abi.encodePacked(\\n                                        type(BeaconProxy).creationCode,\\n                                        abi.encode(\\n                                            address(beacon),\\n                                            abi.encodeWithSelector(VenusERC4626.initialize.selector, vToken)\\n                                        )\\n                                    )\\n                                )\\n                            )\\n                        )\\n                    )\\n                )\\n            );\\n    }\\n}\\n\",\"keccak256\":\"0x8e7de031a38fd725941c857c4a9b56e30c996acddc95f66c8411bec1cc1c4563\",\"license\":\"BSD-3-Clause\"},\"contracts/ErrorReporter.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\n/**\\n * @title TokenErrorReporter\\n * @author Venus\\n * @notice Errors that can be thrown by the `VToken` contract.\\n */\\ncontract TokenErrorReporter {\\n    uint256 public constant NO_ERROR = 0; // support legacy return codes\\n\\n    error TransferNotAllowed();\\n\\n    error MintFreshnessCheck();\\n\\n    error RedeemFreshnessCheck();\\n    error RedeemTransferOutNotPossible();\\n\\n    error BorrowFreshnessCheck();\\n    error BorrowCashNotAvailable();\\n    error DelegateNotApproved();\\n\\n    error RepayBorrowFreshnessCheck();\\n\\n    error HealBorrowUnauthorized();\\n    error ForceLiquidateBorrowUnauthorized();\\n\\n    error LiquidateFreshnessCheck();\\n    error LiquidateCollateralFreshnessCheck();\\n    error LiquidateAccrueCollateralInterestFailed(uint256 errorCode);\\n    error LiquidateLiquidatorIsBorrower();\\n    error LiquidateCloseAmountIsZero();\\n    error LiquidateCloseAmountIsUintMax();\\n\\n    error LiquidateSeizeLiquidatorIsBorrower();\\n\\n    error ProtocolSeizeShareTooBig();\\n\\n    error SetReserveFactorFreshCheck();\\n    error SetReserveFactorBoundsCheck();\\n\\n    error AddReservesFactorFreshCheck(uint256 actualAddAmount);\\n\\n    error ReduceReservesFreshCheck();\\n    error ReduceReservesCashNotAvailable();\\n    error ReduceReservesCashValidation();\\n\\n    error SetInterestRateModelFreshCheck();\\n}\\n\",\"keccak256\":\"0x7a7ced1caaac2d9242659ebd50b99f308c725ce958ac9e11f7ada404b1d97a7b\",\"license\":\"BSD-3-Clause\"},\"contracts/ExponentialNoError.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \\\"./lib/constants.sol\\\";\\n\\n/**\\n * @title Exponential module for storing fixed-precision decimals\\n * @author Compound\\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\\n *         Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\\n *         `Exp({mantissa: 5100000000000000000})`.\\n */\\ncontract ExponentialNoError {\\n    struct Exp {\\n        uint256 mantissa;\\n    }\\n\\n    struct Double {\\n        uint256 mantissa;\\n    }\\n\\n    uint256 internal constant EXP_SCALE = EXP_SCALE_;\\n    uint256 internal constant DOUBLE_SCALE = 1e36;\\n    uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\\n    uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\\n\\n    /**\\n     * @dev Truncates the given exp to a whole number value.\\n     *      For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\\n     */\\n    function truncate(Exp memory exp) internal pure returns (uint256) {\\n        // Note: We are not using careful math here as we're performing a division that cannot fail\\n        return exp.mantissa / EXP_SCALE;\\n    }\\n\\n    /**\\n     * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\\n     */\\n    // solhint-disable-next-line func-name-mixedcase\\n    function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\\n        Exp memory product = mul_(a, scalar);\\n        return truncate(product);\\n    }\\n\\n    /**\\n     * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\\n     */\\n    // solhint-disable-next-line func-name-mixedcase\\n    function mul_ScalarTruncateAddUInt(Exp memory a, uint256 scalar, uint256 addend) internal pure returns (uint256) {\\n        Exp memory product = mul_(a, scalar);\\n        return add_(truncate(product), addend);\\n    }\\n\\n    /**\\n     * @dev Checks if first Exp is less than second Exp.\\n     */\\n    function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\\n        return left.mantissa < right.mantissa;\\n    }\\n\\n    function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\\n        require(n <= type(uint224).max, errorMessage);\\n        return uint224(n);\\n    }\\n\\n    function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\\n        require(n <= type(uint32).max, errorMessage);\\n        return uint32(n);\\n    }\\n\\n    function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n        return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\\n    }\\n\\n    function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n        return Double({ mantissa: add_(a.mantissa, b.mantissa) });\\n    }\\n\\n    function add_(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a + b;\\n    }\\n\\n    function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n        return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\\n    }\\n\\n    function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n        return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\\n    }\\n\\n    function sub_(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a - b;\\n    }\\n\\n    function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n        return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / EXP_SCALE });\\n    }\\n\\n    function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n        return Exp({ mantissa: mul_(a.mantissa, b) });\\n    }\\n\\n    function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n        return mul_(a, b.mantissa) / EXP_SCALE;\\n    }\\n\\n    function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n        return Double({ mantissa: mul_(a.mantissa, b.mantissa) / DOUBLE_SCALE });\\n    }\\n\\n    function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n        return Double({ mantissa: mul_(a.mantissa, b) });\\n    }\\n\\n    function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\\n        return mul_(a, b.mantissa) / DOUBLE_SCALE;\\n    }\\n\\n    function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a * b;\\n    }\\n\\n    function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\\n        return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\\n    }\\n\\n    function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\\n        return Exp({ mantissa: div_(a.mantissa, b) });\\n    }\\n\\n    function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\\n        return div_(mul_(a, EXP_SCALE), b.mantissa);\\n    }\\n\\n    function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\\n        return Double({ mantissa: div_(mul_(a.mantissa, DOUBLE_SCALE), b.mantissa) });\\n    }\\n\\n    function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\\n        return Double({ mantissa: div_(a.mantissa, b) });\\n    }\\n\\n    function div_(uint256 a, Double memory b) internal pure returns (uint256) {\\n        return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\\n    }\\n\\n    function div_(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a / b;\\n    }\\n\\n    function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\\n        return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\\n    }\\n}\\n\",\"keccak256\":\"0x8afbe8a24fe3539c124e718681ed3dcebd24c40dd53095786c0155998213b9b0\",\"license\":\"BSD-3-Clause\"},\"contracts/InterestRateModel.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\n/**\\n * @title Compound's InterestRateModel Interface\\n * @author Compound\\n */\\nabstract contract InterestRateModel {\\n    /**\\n     * @notice Calculates the current borrow interest rate per slot (block or second)\\n     * @param cash The total amount of cash the market has\\n     * @param borrows The total amount of borrows the market has outstanding\\n     * @param reserves The total amount of reserves the market has\\n     * @param badDebt The amount of badDebt in the market\\n     * @return The borrow rate percentage per slot (block or second) as a mantissa (scaled by EXP_SCALE)\\n     */\\n    function getBorrowRate(\\n        uint256 cash,\\n        uint256 borrows,\\n        uint256 reserves,\\n        uint256 badDebt\\n    ) external view virtual returns (uint256);\\n\\n    /**\\n     * @notice Calculates the current supply interest rate per slot (block or second)\\n     * @param cash The total amount of cash the market has\\n     * @param borrows The total amount of borrows the market has outstanding\\n     * @param reserves The total amount of reserves the market has\\n     * @param reserveFactorMantissa The current reserve factor the market has\\n     * @param badDebt The amount of badDebt in the market\\n     * @return The supply rate percentage per slot (block or second) as a mantissa (scaled by EXP_SCALE)\\n     */\\n    function getSupplyRate(\\n        uint256 cash,\\n        uint256 borrows,\\n        uint256 reserves,\\n        uint256 reserveFactorMantissa,\\n        uint256 badDebt\\n    ) external view virtual returns (uint256);\\n\\n    /**\\n     * @notice Indicator that this is an InterestRateModel contract (for inspection)\\n     * @return Always true\\n     */\\n    function isInterestRateModel() external pure virtual returns (bool) {\\n        return true;\\n    }\\n}\\n\",\"keccak256\":\"0xc4fda1ab75ebe4b187b707c4f10c58780f343cf343c537f641dc75d3cd28ab51\",\"license\":\"BSD-3-Clause\"},\"contracts/MaxLoopsLimitHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\n/**\\n * @title MaxLoopsLimitHelper\\n * @author Venus\\n * @notice Abstract contract used to avoid collection with too many items that would generate gas errors and DoS.\\n */\\nabstract contract MaxLoopsLimitHelper {\\n    // Limit for the loops to avoid the DOS\\n    uint256 public maxLoopsLimit;\\n\\n    /**\\n     * @dev This empty reserved space is put in place to allow future versions to add new\\n     * variables without shifting down storage in the inheritance chain.\\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n     */\\n    uint256[49] private __gap;\\n\\n    /// @notice Emitted when max loops limit is set\\n    event MaxLoopsLimitUpdated(uint256 oldMaxLoopsLimit, uint256 newmaxLoopsLimit);\\n\\n    /// @notice Thrown an error on maxLoopsLimit exceeds for any loop\\n    error MaxLoopsLimitExceeded(uint256 loopsLimit, uint256 requiredLoops);\\n\\n    /**\\n     * @notice Set the limit for the loops can iterate to avoid the DOS\\n     * @param limit Limit for the max loops can execute at a time\\n     */\\n    function _setMaxLoopsLimit(uint256 limit) internal {\\n        require(limit > maxLoopsLimit, \\\"Comptroller: Invalid maxLoopsLimit\\\");\\n\\n        uint256 oldMaxLoopsLimit = maxLoopsLimit;\\n        maxLoopsLimit = limit;\\n\\n        emit MaxLoopsLimitUpdated(oldMaxLoopsLimit, limit);\\n    }\\n\\n    /**\\n     * @notice Compare the maxLoopsLimit with number of the times loop iterate\\n     * @param len Length of the loops iterate\\n     * @custom:error MaxLoopsLimitExceeded error is thrown when loops length exceeds maxLoopsLimit\\n     */\\n    function _ensureMaxLoops(uint256 len) internal view {\\n        if (len > maxLoopsLimit) {\\n            revert MaxLoopsLimitExceeded(maxLoopsLimit, len);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x4c25e30635485d162177effa384eee51768b0141a567a0da16ff6ad673274166\",\"license\":\"BSD-3-Clause\"},\"contracts/Pool/PoolRegistryInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\n/**\\n * @title PoolRegistryInterface\\n * @author Venus\\n * @notice Interface implemented by `PoolRegistry`.\\n */\\ninterface PoolRegistryInterface {\\n    /**\\n     * @notice Struct for a Venus interest rate pool.\\n     */\\n    struct VenusPool {\\n        string name;\\n        address creator;\\n        address comptroller;\\n        uint256 blockPosted;\\n        uint256 timestampPosted;\\n    }\\n\\n    /**\\n     * @notice Struct for a Venus interest rate pool metadata.\\n     */\\n    struct VenusPoolMetaData {\\n        string category;\\n        string logoURL;\\n        string description;\\n    }\\n\\n    /// @notice Get all pools in PoolRegistry\\n    function getAllPools() external view returns (VenusPool[] memory);\\n\\n    /// @notice Get a pool by comptroller address\\n    function getPoolByComptroller(address comptroller) external view returns (VenusPool memory);\\n\\n    /// @notice Get the address of the VToken contract in the Pool where the underlying token is the provided asset\\n    function getVTokenForAsset(address comptroller, address asset) external view returns (address);\\n\\n    /// @notice Get the addresss of the Pools supported that include a market for the provided asset\\n    function getPoolsSupportedByAsset(address asset) external view returns (address[] memory);\\n\\n    /// @notice Get the metadata of a Pool by comptroller address\\n    function getVenusPoolMetadata(address comptroller) external view returns (VenusPoolMetaData memory);\\n}\\n\",\"keccak256\":\"0x7b39cda3b372a686501ce3c2aad288c6af410148110318249d75d4516729c92c\",\"license\":\"BSD-3-Clause\"},\"contracts/Rewards/RewardsDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\nimport { TimeManagerV8 } from \\\"@venusprotocol/solidity-utilities/contracts/TimeManagerV8.sol\\\";\\n\\nimport { ExponentialNoError } from \\\"../ExponentialNoError.sol\\\";\\nimport { VToken } from \\\"../VToken.sol\\\";\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\nimport { MaxLoopsLimitHelper } from \\\"../MaxLoopsLimitHelper.sol\\\";\\nimport { RewardsDistributorStorage } from \\\"./RewardsDistributorStorage.sol\\\";\\n\\n/**\\n * @title `RewardsDistributor`\\n * @author Venus\\n * @notice Contract used to configure, track and distribute rewards to users based on their actions (borrows and supplies) in the protocol.\\n * Users can receive additional rewards through a `RewardsDistributor`. Each `RewardsDistributor` proxy is initialized with a specific reward\\n * token and `Comptroller`, which can then distribute the reward token to users that supply or borrow in the associated pool.\\n * Authorized users can set the reward token borrow and supply speeds for each market in the pool. This sets a fixed amount of reward\\n * token to be released each slot (block or second) for borrowers and suppliers, which is distributed based on a user\\u2019s percentage of the borrows or supplies\\n * respectively. The owner can also set up reward distributions to contributor addresses (distinct from suppliers and borrowers) by setting\\n * their contributor reward token speed, which similarly allocates a fixed amount of reward token per slot (block or second).\\n *\\n * The owner has the ability to transfer any amount of reward tokens held by the contract to any other address. Rewards are not distributed\\n * automatically and must be claimed by a user calling `claimRewardToken()`. Users should be aware that it is up to the owner and other centralized\\n * entities to ensure that the `RewardsDistributor` holds enough tokens to distribute the accumulated rewards of users and contributors.\\n */\\ncontract RewardsDistributor is\\n    ExponentialNoError,\\n    Ownable2StepUpgradeable,\\n    AccessControlledV8,\\n    MaxLoopsLimitHelper,\\n    RewardsDistributorStorage,\\n    TimeManagerV8\\n{\\n    using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n    /// @notice The initial REWARD TOKEN index for a market\\n    uint224 public constant INITIAL_INDEX = 1e36;\\n\\n    /// @notice Emitted when REWARD TOKEN is distributed to a supplier\\n    event DistributedSupplierRewardToken(\\n        VToken indexed vToken,\\n        address indexed supplier,\\n        uint256 rewardTokenDelta,\\n        uint256 rewardTokenTotal,\\n        uint256 rewardTokenSupplyIndex\\n    );\\n\\n    /// @notice Emitted when REWARD TOKEN is distributed to a borrower\\n    event DistributedBorrowerRewardToken(\\n        VToken indexed vToken,\\n        address indexed borrower,\\n        uint256 rewardTokenDelta,\\n        uint256 rewardTokenTotal,\\n        uint256 rewardTokenBorrowIndex\\n    );\\n\\n    /// @notice Emitted when a new supply-side REWARD TOKEN speed is calculated for a market\\n    event RewardTokenSupplySpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n    /// @notice Emitted when a new borrow-side REWARD TOKEN speed is calculated for a market\\n    event RewardTokenBorrowSpeedUpdated(VToken indexed vToken, uint256 newSpeed);\\n\\n    /// @notice Emitted when REWARD TOKEN is granted by admin\\n    event RewardTokenGranted(address indexed recipient, uint256 amount);\\n\\n    /// @notice Emitted when a new REWARD TOKEN speed is set for a contributor\\n    event ContributorRewardTokenSpeedUpdated(address indexed contributor, uint256 newSpeed);\\n\\n    /// @notice Emitted when a market is initialized\\n    event MarketInitialized(address indexed vToken);\\n\\n    /// @notice Emitted when a reward token supply index is updated\\n    event RewardTokenSupplyIndexUpdated(address indexed vToken);\\n\\n    /// @notice Emitted when a reward token borrow index is updated\\n    event RewardTokenBorrowIndexUpdated(address indexed vToken, Exp marketBorrowIndex);\\n\\n    /// @notice Emitted when a reward for contributor is updated\\n    event ContributorRewardsUpdated(address indexed contributor, uint256 rewardAccrued);\\n\\n    /// @notice Emitted when a reward token last rewarding block for supply is updated\\n    event SupplyLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n    /// @notice Emitted when a reward token last rewarding block for borrow is updated\\n    event BorrowLastRewardingBlockUpdated(address indexed vToken, uint32 newBlock);\\n\\n    /// @notice Emitted when a reward token last rewarding timestamp for supply is updated\\n    event SupplyLastRewardingBlockTimestampUpdated(address indexed vToken, uint256 newTimestamp);\\n\\n    /// @notice Emitted when a reward token last rewarding timestamp for borrow is updated\\n    event BorrowLastRewardingBlockTimestampUpdated(address indexed vToken, uint256 newTimestamp);\\n\\n    modifier onlyComptroller() {\\n        require(address(comptroller) == msg.sender, \\\"Only comptroller can call this function\\\");\\n        _;\\n    }\\n\\n    /**\\n     * @param timeBased_ A boolean indicating whether the contract is based on time or block.\\n     * @param blocksPerYear_ The number of blocks per year\\n     * @custom:oz-upgrades-unsafe-allow constructor\\n     */\\n    constructor(bool timeBased_, uint256 blocksPerYear_) TimeManagerV8(timeBased_, blocksPerYear_) {\\n        // Note that the contract is upgradeable. Use initialize() or reinitializers\\n        // to set the state variables.\\n        _disableInitializers();\\n    }\\n\\n    /**\\n     * @notice RewardsDistributor initializer\\n     * @dev Initializes the deployer to owner\\n     * @param comptroller_ Comptroller to attach the reward distributor to\\n     * @param rewardToken_ Reward token to distribute\\n     * @param loopsLimit_ Maximum number of iterations for the loops in this contract\\n     * @param accessControlManager_ AccessControlManager contract address\\n     */\\n    function initialize(\\n        Comptroller comptroller_,\\n        IERC20Upgradeable rewardToken_,\\n        uint256 loopsLimit_,\\n        address accessControlManager_\\n    ) external initializer {\\n        comptroller = comptroller_;\\n        rewardToken = rewardToken_;\\n        __Ownable2Step_init();\\n        __AccessControlled_init_unchained(accessControlManager_);\\n\\n        _setMaxLoopsLimit(loopsLimit_);\\n    }\\n\\n    /**\\n     * @notice Initializes the market state for a specific vToken\\n     * @param vToken The address of the vToken to be initialized\\n     * @custom:event MarketInitialized emits on success\\n     * @custom:access Only Comptroller\\n     */\\n    function initializeMarket(address vToken) external onlyComptroller {\\n        uint256 blockNumberOrTimestamp = getBlockNumberOrTimestamp();\\n\\n        isTimeBased\\n            ? _initializeMarketTimestampBased(vToken, blockNumberOrTimestamp)\\n            : _initializeMarketBlockBased(vToken, safe32(blockNumberOrTimestamp, \\\"block number exceeds 32 bits\\\"));\\n\\n        emit MarketInitialized(vToken);\\n    }\\n\\n    /*** Reward Token Distribution ***/\\n\\n    /**\\n     * @notice Calculate reward token accrued by a borrower and possibly transfer it to them\\n     *         Borrowers will begin to accrue after the first interaction with the protocol.\\n     * @dev This function should only be called when the user has a borrow position in the market\\n     *      (e.g. Comptroller.preBorrowHook, and Comptroller.preRepayHook)\\n     *      We avoid an external call to check if they are in the market to save gas because this function is called in many places\\n     * @param vToken The market in which the borrower is interacting\\n     * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n     * @param marketBorrowIndex The current global borrow index of vToken\\n     */\\n    function distributeBorrowerRewardToken(\\n        address vToken,\\n        address borrower,\\n        Exp memory marketBorrowIndex\\n    ) external onlyComptroller {\\n        _distributeBorrowerRewardToken(vToken, borrower, marketBorrowIndex);\\n    }\\n\\n    function updateRewardTokenSupplyIndex(address vToken) external onlyComptroller {\\n        _updateRewardTokenSupplyIndex(vToken);\\n    }\\n\\n    /**\\n     * @notice Transfer REWARD TOKEN to the recipient\\n     * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all\\n     * @param recipient The address of the recipient to transfer REWARD TOKEN to\\n     * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n     */\\n    function grantRewardToken(address recipient, uint256 amount) external onlyOwner {\\n        uint256 amountLeft = _grantRewardToken(recipient, amount);\\n        require(amountLeft == 0, \\\"insufficient rewardToken for grant\\\");\\n        emit RewardTokenGranted(recipient, amount);\\n    }\\n\\n    function updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) external onlyComptroller {\\n        _updateRewardTokenBorrowIndex(vToken, marketBorrowIndex);\\n    }\\n\\n    /**\\n     * @notice Set REWARD TOKEN borrow and supply speeds for the specified markets\\n     * @param vTokens The markets whose REWARD TOKEN speed to update\\n     * @param supplySpeeds New supply-side REWARD TOKEN speed for the corresponding market\\n     * @param borrowSpeeds New borrow-side REWARD TOKEN speed for the corresponding market\\n     */\\n    function setRewardTokenSpeeds(\\n        VToken[] memory vTokens,\\n        uint256[] memory supplySpeeds,\\n        uint256[] memory borrowSpeeds\\n    ) external {\\n        _checkAccessAllowed(\\\"setRewardTokenSpeeds(address[],uint256[],uint256[])\\\");\\n        uint256 numTokens = vTokens.length;\\n        require(numTokens == supplySpeeds.length && numTokens == borrowSpeeds.length, \\\"invalid setRewardTokenSpeeds\\\");\\n\\n        for (uint256 i; i < numTokens; ++i) {\\n            _setRewardTokenSpeed(vTokens[i], supplySpeeds[i], borrowSpeeds[i]);\\n        }\\n    }\\n\\n    /**\\n     * @notice Set REWARD TOKEN last rewarding block for the specified markets, used when contract is block based\\n     * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\\n     * @param supplyLastRewardingBlocks New supply-side REWARD TOKEN last rewarding block for the corresponding market\\n     * @param borrowLastRewardingBlocks New borrow-side REWARD TOKEN last rewarding block for the corresponding market\\n     */\\n    function setLastRewardingBlocks(\\n        VToken[] calldata vTokens,\\n        uint32[] calldata supplyLastRewardingBlocks,\\n        uint32[] calldata borrowLastRewardingBlocks\\n    ) external {\\n        _checkAccessAllowed(\\\"setLastRewardingBlocks(address[],uint32[],uint32[])\\\");\\n        require(!isTimeBased, \\\"Block-based operation only\\\");\\n\\n        uint256 numTokens = vTokens.length;\\n        require(\\n            numTokens == supplyLastRewardingBlocks.length && numTokens == borrowLastRewardingBlocks.length,\\n            \\\"RewardsDistributor::setLastRewardingBlocks invalid input\\\"\\n        );\\n\\n        for (uint256 i; i < numTokens; ) {\\n            _setLastRewardingBlock(vTokens[i], supplyLastRewardingBlocks[i], borrowLastRewardingBlocks[i]);\\n            unchecked {\\n                ++i;\\n            }\\n        }\\n    }\\n\\n    /**\\n     * @notice Set REWARD TOKEN last rewarding block timestamp for the specified markets, used when contract is time based\\n     * @param vTokens The markets whose REWARD TOKEN last rewarding block to update\\n     * @param supplyLastRewardingBlockTimestamps New supply-side REWARD TOKEN last rewarding block timestamp for the corresponding market\\n     * @param borrowLastRewardingBlockTimestamps New borrow-side REWARD TOKEN last rewarding block timestamp for the corresponding market\\n     */\\n    function setLastRewardingBlockTimestamps(\\n        VToken[] calldata vTokens,\\n        uint256[] calldata supplyLastRewardingBlockTimestamps,\\n        uint256[] calldata borrowLastRewardingBlockTimestamps\\n    ) external {\\n        _checkAccessAllowed(\\\"setLastRewardingBlockTimestamps(address[],uint256[],uint256[])\\\");\\n        require(isTimeBased, \\\"Time-based operation only\\\");\\n\\n        uint256 numTokens = vTokens.length;\\n        require(\\n            numTokens == supplyLastRewardingBlockTimestamps.length &&\\n                numTokens == borrowLastRewardingBlockTimestamps.length,\\n            \\\"RewardsDistributor::setLastRewardingBlockTimestamps invalid input\\\"\\n        );\\n\\n        for (uint256 i; i < numTokens; ) {\\n            _setLastRewardingBlockTimestamp(\\n                vTokens[i],\\n                supplyLastRewardingBlockTimestamps[i],\\n                borrowLastRewardingBlockTimestamps[i]\\n            );\\n            unchecked {\\n                ++i;\\n            }\\n        }\\n    }\\n\\n    /**\\n     * @notice Set REWARD TOKEN speed for a single contributor\\n     * @param contributor The contributor whose REWARD TOKEN speed to update\\n     * @param rewardTokenSpeed New REWARD TOKEN speed for contributor\\n     */\\n    function setContributorRewardTokenSpeed(address contributor, uint256 rewardTokenSpeed) external onlyOwner {\\n        // note that REWARD TOKEN speed could be set to 0 to halt liquidity rewards for a contributor\\n        updateContributorRewards(contributor);\\n        if (rewardTokenSpeed == 0) {\\n            // release storage\\n            delete lastContributorBlock[contributor];\\n        } else {\\n            lastContributorBlock[contributor] = getBlockNumberOrTimestamp();\\n        }\\n        rewardTokenContributorSpeeds[contributor] = rewardTokenSpeed;\\n\\n        emit ContributorRewardTokenSpeedUpdated(contributor, rewardTokenSpeed);\\n    }\\n\\n    function distributeSupplierRewardToken(address vToken, address supplier) external onlyComptroller {\\n        _distributeSupplierRewardToken(vToken, supplier);\\n    }\\n\\n    /**\\n     * @notice Claim all the rewardToken accrued by holder in all markets\\n     * @param holder The address to claim REWARD TOKEN for\\n     */\\n    function claimRewardToken(address holder) external {\\n        return claimRewardToken(holder, comptroller.getAllMarkets());\\n    }\\n\\n    /**\\n     * @notice Set the limit for the loops can iterate to avoid the DOS\\n     * @param limit Limit for the max loops can execute at a time\\n     */\\n    function setMaxLoopsLimit(uint256 limit) external onlyOwner {\\n        _setMaxLoopsLimit(limit);\\n    }\\n\\n    /**\\n     * @notice Calculate additional accrued REWARD TOKEN for a contributor since last accrual\\n     * @param contributor The address to calculate contributor rewards for\\n     */\\n    function updateContributorRewards(address contributor) public {\\n        uint256 rewardTokenSpeed = rewardTokenContributorSpeeds[contributor];\\n        uint256 blockNumberOrTimestamp = getBlockNumberOrTimestamp();\\n        uint256 deltaBlocksOrTimestamp = sub_(blockNumberOrTimestamp, lastContributorBlock[contributor]);\\n        if (deltaBlocksOrTimestamp > 0 && rewardTokenSpeed > 0) {\\n            uint256 newAccrued = mul_(deltaBlocksOrTimestamp, rewardTokenSpeed);\\n            uint256 contributorAccrued = add_(rewardTokenAccrued[contributor], newAccrued);\\n\\n            rewardTokenAccrued[contributor] = contributorAccrued;\\n            lastContributorBlock[contributor] = blockNumberOrTimestamp;\\n\\n            emit ContributorRewardsUpdated(contributor, rewardTokenAccrued[contributor]);\\n        }\\n    }\\n\\n    /**\\n     * @notice Claim all the rewardToken accrued by holder in the specified markets\\n     * @param holder The address to claim REWARD TOKEN for\\n     * @param vTokens The list of markets to claim REWARD TOKEN in\\n     */\\n    function claimRewardToken(address holder, VToken[] memory vTokens) public {\\n        uint256 vTokensCount = vTokens.length;\\n\\n        _ensureMaxLoops(vTokensCount);\\n\\n        for (uint256 i; i < vTokensCount; ++i) {\\n            VToken vToken = vTokens[i];\\n            require(comptroller.isMarketListed(vToken), \\\"market must be listed\\\");\\n            Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n            _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n            _distributeBorrowerRewardToken(address(vToken), holder, borrowIndex);\\n            _updateRewardTokenSupplyIndex(address(vToken));\\n            _distributeSupplierRewardToken(address(vToken), holder);\\n        }\\n        rewardTokenAccrued[holder] = _grantRewardToken(holder, rewardTokenAccrued[holder]);\\n    }\\n\\n    /**\\n     * @notice Set REWARD TOKEN last rewarding block for a single market.\\n     * @param vToken market's whose reward token last rewarding block to be updated\\n     * @param supplyLastRewardingBlock New supply-side REWARD TOKEN last rewarding block for market\\n     * @param borrowLastRewardingBlock New borrow-side REWARD TOKEN last rewarding block for market\\n     */\\n    function _setLastRewardingBlock(\\n        VToken vToken,\\n        uint32 supplyLastRewardingBlock,\\n        uint32 borrowLastRewardingBlock\\n    ) internal {\\n        require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n        uint256 blockNumber = getBlockNumberOrTimestamp();\\n\\n        require(supplyLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n        require(borrowLastRewardingBlock > blockNumber, \\\"setting last rewarding block in the past is not allowed\\\");\\n\\n        uint32 currentSupplyLastRewardingBlock = rewardTokenSupplyState[address(vToken)].lastRewardingBlock;\\n        uint32 currentBorrowLastRewardingBlock = rewardTokenBorrowState[address(vToken)].lastRewardingBlock;\\n\\n        require(\\n            currentSupplyLastRewardingBlock == 0 || currentSupplyLastRewardingBlock > blockNumber,\\n            \\\"this RewardsDistributor is already locked\\\"\\n        );\\n        require(\\n            currentBorrowLastRewardingBlock == 0 || currentBorrowLastRewardingBlock > blockNumber,\\n            \\\"this RewardsDistributor is already locked\\\"\\n        );\\n\\n        if (currentSupplyLastRewardingBlock != supplyLastRewardingBlock) {\\n            rewardTokenSupplyState[address(vToken)].lastRewardingBlock = supplyLastRewardingBlock;\\n            emit SupplyLastRewardingBlockUpdated(address(vToken), supplyLastRewardingBlock);\\n        }\\n\\n        if (currentBorrowLastRewardingBlock != borrowLastRewardingBlock) {\\n            rewardTokenBorrowState[address(vToken)].lastRewardingBlock = borrowLastRewardingBlock;\\n            emit BorrowLastRewardingBlockUpdated(address(vToken), borrowLastRewardingBlock);\\n        }\\n    }\\n\\n    /**\\n     * @notice Set REWARD TOKEN last rewarding timestamp for a single market.\\n     * @param vToken market's whose reward token last rewarding timestamp to be updated\\n     * @param supplyLastRewardingBlockTimestamp New supply-side REWARD TOKEN last rewarding timestamp for market\\n     * @param borrowLastRewardingBlockTimestamp New borrow-side REWARD TOKEN last rewarding timestamp for market\\n     */\\n    function _setLastRewardingBlockTimestamp(\\n        VToken vToken,\\n        uint256 supplyLastRewardingBlockTimestamp,\\n        uint256 borrowLastRewardingBlockTimestamp\\n    ) internal {\\n        require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n        uint256 blockTimestamp = getBlockNumberOrTimestamp();\\n\\n        require(\\n            supplyLastRewardingBlockTimestamp > blockTimestamp,\\n            \\\"setting last rewarding timestamp in the past is not allowed\\\"\\n        );\\n        require(\\n            borrowLastRewardingBlockTimestamp > blockTimestamp,\\n            \\\"setting last rewarding timestamp in the past is not allowed\\\"\\n        );\\n\\n        uint256 currentSupplyLastRewardingBlockTimestamp = rewardTokenSupplyStateTimeBased[address(vToken)]\\n            .lastRewardingTimestamp;\\n        uint256 currentBorrowLastRewardingBlockTimestamp = rewardTokenBorrowStateTimeBased[address(vToken)]\\n            .lastRewardingTimestamp;\\n\\n        require(\\n            currentSupplyLastRewardingBlockTimestamp == 0 || currentSupplyLastRewardingBlockTimestamp > blockTimestamp,\\n            \\\"this RewardsDistributor is already locked\\\"\\n        );\\n        require(\\n            currentBorrowLastRewardingBlockTimestamp == 0 || currentBorrowLastRewardingBlockTimestamp > blockTimestamp,\\n            \\\"this RewardsDistributor is already locked\\\"\\n        );\\n\\n        if (currentSupplyLastRewardingBlockTimestamp != supplyLastRewardingBlockTimestamp) {\\n            rewardTokenSupplyStateTimeBased[address(vToken)].lastRewardingTimestamp = supplyLastRewardingBlockTimestamp;\\n            emit SupplyLastRewardingBlockTimestampUpdated(address(vToken), supplyLastRewardingBlockTimestamp);\\n        }\\n\\n        if (currentBorrowLastRewardingBlockTimestamp != borrowLastRewardingBlockTimestamp) {\\n            rewardTokenBorrowStateTimeBased[address(vToken)].lastRewardingTimestamp = borrowLastRewardingBlockTimestamp;\\n            emit BorrowLastRewardingBlockTimestampUpdated(address(vToken), borrowLastRewardingBlockTimestamp);\\n        }\\n    }\\n\\n    /**\\n     * @notice Set REWARD TOKEN speed for a single market.\\n     * @param vToken market's whose reward token rate to be updated\\n     * @param supplySpeed New supply-side REWARD TOKEN speed for market\\n     * @param borrowSpeed New borrow-side REWARD TOKEN speed for market\\n     */\\n    function _setRewardTokenSpeed(VToken vToken, uint256 supplySpeed, uint256 borrowSpeed) internal {\\n        require(comptroller.isMarketListed(vToken), \\\"rewardToken market is not listed\\\");\\n\\n        if (rewardTokenSupplySpeeds[address(vToken)] != supplySpeed) {\\n            // Supply speed updated so let's update supply state to ensure that\\n            //  1. REWARD TOKEN accrued properly for the old speed, and\\n            //  2. REWARD TOKEN accrued at the new speed starts after this block.\\n            _updateRewardTokenSupplyIndex(address(vToken));\\n\\n            // Update speed and emit event\\n            rewardTokenSupplySpeeds[address(vToken)] = supplySpeed;\\n            emit RewardTokenSupplySpeedUpdated(vToken, supplySpeed);\\n        }\\n\\n        if (rewardTokenBorrowSpeeds[address(vToken)] != borrowSpeed) {\\n            // Borrow speed updated so let's update borrow state to ensure that\\n            //  1. REWARD TOKEN accrued properly for the old speed, and\\n            //  2. REWARD TOKEN accrued at the new speed starts after this block.\\n            Exp memory borrowIndex = Exp({ mantissa: vToken.borrowIndex() });\\n            _updateRewardTokenBorrowIndex(address(vToken), borrowIndex);\\n\\n            // Update speed and emit event\\n            rewardTokenBorrowSpeeds[address(vToken)] = borrowSpeed;\\n            emit RewardTokenBorrowSpeedUpdated(vToken, borrowSpeed);\\n        }\\n    }\\n\\n    /**\\n     * @notice Calculate REWARD TOKEN accrued by a supplier and possibly transfer it to them.\\n     * @param vToken The market in which the supplier is interacting\\n     * @param supplier The address of the supplier to distribute REWARD TOKEN to\\n     */\\n    function _distributeSupplierRewardToken(address vToken, address supplier) internal {\\n        RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n        TimeBasedRewardToken storage supplyStateTimeBased = rewardTokenSupplyStateTimeBased[vToken];\\n\\n        uint256 supplyIndex = isTimeBased ? supplyStateTimeBased.index : supplyState.index;\\n        uint256 supplierIndex = rewardTokenSupplierIndex[vToken][supplier];\\n\\n        // Update supplier's index to the current index since we are distributing accrued REWARD TOKEN\\n        rewardTokenSupplierIndex[vToken][supplier] = supplyIndex;\\n\\n        if (supplierIndex == 0 && supplyIndex >= INITIAL_INDEX) {\\n            // Covers the case where users supplied tokens before the market's supply state index was set.\\n            // Rewards the user with REWARD TOKEN accrued from the start of when supplier rewards were first\\n            // set for the market.\\n            supplierIndex = INITIAL_INDEX;\\n        }\\n\\n        // Calculate change in the cumulative sum of the REWARD TOKEN per vToken accrued\\n        Double memory deltaIndex = Double({ mantissa: sub_(supplyIndex, supplierIndex) });\\n\\n        uint256 supplierTokens = VToken(vToken).balanceOf(supplier);\\n\\n        // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerVToken\\n        uint256 supplierDelta = mul_(supplierTokens, deltaIndex);\\n\\n        uint256 supplierAccrued = add_(rewardTokenAccrued[supplier], supplierDelta);\\n        rewardTokenAccrued[supplier] = supplierAccrued;\\n\\n        emit DistributedSupplierRewardToken(VToken(vToken), supplier, supplierDelta, supplierAccrued, supplyIndex);\\n    }\\n\\n    /**\\n     * @notice Calculate reward token accrued by a borrower and possibly transfer it to them.\\n     * @param vToken The market in which the borrower is interacting\\n     * @param borrower The address of the borrower to distribute REWARD TOKEN to\\n     * @param marketBorrowIndex The current global borrow index of vToken\\n     */\\n    function _distributeBorrowerRewardToken(address vToken, address borrower, Exp memory marketBorrowIndex) internal {\\n        RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n        TimeBasedRewardToken storage borrowStateTimeBased = rewardTokenBorrowStateTimeBased[vToken];\\n\\n        uint256 borrowIndex = isTimeBased ? borrowStateTimeBased.index : borrowState.index;\\n        uint256 borrowerIndex = rewardTokenBorrowerIndex[vToken][borrower];\\n\\n        // Update borrowers's index to the current index since we are distributing accrued REWARD TOKEN\\n        rewardTokenBorrowerIndex[vToken][borrower] = borrowIndex;\\n\\n        if (borrowerIndex == 0 && borrowIndex >= INITIAL_INDEX) {\\n            // Covers the case where users borrowed tokens before the market's borrow state index was set.\\n            // Rewards the user with REWARD TOKEN accrued from the start of when borrower rewards were first\\n            // set for the market.\\n            borrowerIndex = INITIAL_INDEX;\\n        }\\n\\n        // Calculate change in the cumulative sum of the REWARD TOKEN per borrowed unit accrued\\n        Double memory deltaIndex = Double({ mantissa: sub_(borrowIndex, borrowerIndex) });\\n\\n        uint256 borrowerAmount = div_(VToken(vToken).borrowBalanceStored(borrower), marketBorrowIndex);\\n\\n        // Calculate REWARD TOKEN accrued: vTokenAmount * accruedPerBorrowedUnit\\n        if (borrowerAmount != 0) {\\n            uint256 borrowerDelta = mul_(borrowerAmount, deltaIndex);\\n\\n            uint256 borrowerAccrued = add_(rewardTokenAccrued[borrower], borrowerDelta);\\n            rewardTokenAccrued[borrower] = borrowerAccrued;\\n\\n            emit DistributedBorrowerRewardToken(VToken(vToken), borrower, borrowerDelta, borrowerAccrued, borrowIndex);\\n        }\\n    }\\n\\n    /**\\n     * @notice Transfer REWARD TOKEN to the user.\\n     * @dev Note: If there is not enough REWARD TOKEN, we do not perform the transfer all.\\n     * @param user The address of the user to transfer REWARD TOKEN to\\n     * @param amount The amount of REWARD TOKEN to (possibly) transfer\\n     * @return The amount of REWARD TOKEN which was NOT transferred to the user\\n     */\\n    function _grantRewardToken(address user, uint256 amount) internal returns (uint256) {\\n        uint256 rewardTokenRemaining = rewardToken.balanceOf(address(this));\\n        if (amount > 0 && amount <= rewardTokenRemaining) {\\n            rewardToken.safeTransfer(user, amount);\\n            return 0;\\n        }\\n        return amount;\\n    }\\n\\n    /**\\n     * @notice Accrue REWARD TOKEN to the market by updating the supply index\\n     * @param vToken The market whose supply index to update\\n     * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n     */\\n    function _updateRewardTokenSupplyIndex(address vToken) internal {\\n        RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n        TimeBasedRewardToken storage supplyStateTimeBased = rewardTokenSupplyStateTimeBased[vToken];\\n\\n        uint256 supplySpeed = rewardTokenSupplySpeeds[vToken];\\n        uint256 blockNumberOrTimestamp = getBlockNumberOrTimestamp();\\n\\n        if (!isTimeBased) {\\n            safe32(blockNumberOrTimestamp, \\\"block number exceeds 32 bits\\\");\\n        }\\n\\n        uint256 lastRewardingBlockOrTimestamp = isTimeBased\\n            ? supplyStateTimeBased.lastRewardingTimestamp\\n            : uint256(supplyState.lastRewardingBlock);\\n\\n        if (lastRewardingBlockOrTimestamp > 0 && blockNumberOrTimestamp > lastRewardingBlockOrTimestamp) {\\n            blockNumberOrTimestamp = lastRewardingBlockOrTimestamp;\\n        }\\n\\n        uint256 deltaBlocksOrTimestamp = sub_(\\n            blockNumberOrTimestamp,\\n            (isTimeBased ? supplyStateTimeBased.timestamp : uint256(supplyState.block))\\n        );\\n        if (deltaBlocksOrTimestamp > 0 && supplySpeed > 0) {\\n            uint256 supplyTokens = VToken(vToken).totalSupply();\\n            uint256 accruedSinceUpdate = mul_(deltaBlocksOrTimestamp, supplySpeed);\\n            Double memory ratio = supplyTokens > 0\\n                ? fraction(accruedSinceUpdate, supplyTokens)\\n                : Double({ mantissa: 0 });\\n            uint224 supplyIndex = isTimeBased ? supplyStateTimeBased.index : supplyState.index;\\n            uint224 index = safe224(\\n                add_(Double({ mantissa: supplyIndex }), ratio).mantissa,\\n                \\\"new index exceeds 224 bits\\\"\\n            );\\n\\n            if (isTimeBased) {\\n                supplyStateTimeBased.index = index;\\n                supplyStateTimeBased.timestamp = blockNumberOrTimestamp;\\n            } else {\\n                supplyState.index = index;\\n                supplyState.block = uint32(blockNumberOrTimestamp);\\n            }\\n        } else if (deltaBlocksOrTimestamp > 0) {\\n            isTimeBased ? supplyStateTimeBased.timestamp = blockNumberOrTimestamp : supplyState.block = uint32(\\n                blockNumberOrTimestamp\\n            );\\n        }\\n\\n        emit RewardTokenSupplyIndexUpdated(vToken);\\n    }\\n\\n    /**\\n     * @notice Accrue REWARD TOKEN to the market by updating the borrow index\\n     * @param vToken The market whose borrow index to update\\n     * @param marketBorrowIndex The current global borrow index of vToken\\n     * @dev Index is a cumulative sum of the REWARD TOKEN per vToken accrued\\n     */\\n    function _updateRewardTokenBorrowIndex(address vToken, Exp memory marketBorrowIndex) internal {\\n        RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n        TimeBasedRewardToken storage borrowStateTimeBased = rewardTokenBorrowStateTimeBased[vToken];\\n\\n        uint256 borrowSpeed = rewardTokenBorrowSpeeds[vToken];\\n        uint256 blockNumberOrTimestamp = getBlockNumberOrTimestamp();\\n\\n        if (!isTimeBased) {\\n            safe32(blockNumberOrTimestamp, \\\"block number exceeds 32 bits\\\");\\n        }\\n\\n        uint256 lastRewardingBlockOrTimestamp = isTimeBased\\n            ? borrowStateTimeBased.lastRewardingTimestamp\\n            : uint256(borrowState.lastRewardingBlock);\\n\\n        if (lastRewardingBlockOrTimestamp > 0 && blockNumberOrTimestamp > lastRewardingBlockOrTimestamp) {\\n            blockNumberOrTimestamp = lastRewardingBlockOrTimestamp;\\n        }\\n\\n        uint256 deltaBlocksOrTimestamp = sub_(\\n            blockNumberOrTimestamp,\\n            (isTimeBased ? borrowStateTimeBased.timestamp : uint256(borrowState.block))\\n        );\\n        if (deltaBlocksOrTimestamp > 0 && borrowSpeed > 0) {\\n            uint256 borrowAmount = div_(VToken(vToken).totalBorrows(), marketBorrowIndex);\\n            uint256 accruedSinceUpdate = mul_(deltaBlocksOrTimestamp, borrowSpeed);\\n            Double memory ratio = borrowAmount > 0\\n                ? fraction(accruedSinceUpdate, borrowAmount)\\n                : Double({ mantissa: 0 });\\n            uint224 borrowIndex = isTimeBased ? borrowStateTimeBased.index : borrowState.index;\\n            uint224 index = safe224(\\n                add_(Double({ mantissa: borrowIndex }), ratio).mantissa,\\n                \\\"new index exceeds 224 bits\\\"\\n            );\\n\\n            if (isTimeBased) {\\n                borrowStateTimeBased.index = index;\\n                borrowStateTimeBased.timestamp = blockNumberOrTimestamp;\\n            } else {\\n                borrowState.index = index;\\n                borrowState.block = uint32(blockNumberOrTimestamp);\\n            }\\n        } else if (deltaBlocksOrTimestamp > 0) {\\n            if (isTimeBased) {\\n                borrowStateTimeBased.timestamp = blockNumberOrTimestamp;\\n            } else {\\n                borrowState.block = uint32(blockNumberOrTimestamp);\\n            }\\n        }\\n\\n        emit RewardTokenBorrowIndexUpdated(vToken, marketBorrowIndex);\\n    }\\n\\n    /**\\n     * @notice Initializes the market state for a specific vToken called when contract is block-based\\n     * @param vToken The address of the vToken to be initialized\\n     * @param blockNumber current block number\\n     */\\n    function _initializeMarketBlockBased(address vToken, uint32 blockNumber) internal {\\n        RewardToken storage supplyState = rewardTokenSupplyState[vToken];\\n        RewardToken storage borrowState = rewardTokenBorrowState[vToken];\\n\\n        /*\\n         * Update market state indices\\n         */\\n        if (supplyState.index == 0) {\\n            // Initialize supply state index with default value\\n            supplyState.index = INITIAL_INDEX;\\n        }\\n\\n        if (borrowState.index == 0) {\\n            // Initialize borrow state index with default value\\n            borrowState.index = INITIAL_INDEX;\\n        }\\n\\n        /*\\n         * Update market state block numbers\\n         */\\n        supplyState.block = borrowState.block = blockNumber;\\n    }\\n\\n    /**\\n     * @notice Initializes the market state for a specific vToken called when contract is time-based\\n     * @param vToken The address of the vToken to be initialized\\n     * @param blockTimestamp current block timestamp\\n     */\\n    function _initializeMarketTimestampBased(address vToken, uint256 blockTimestamp) internal {\\n        TimeBasedRewardToken storage supplyState = rewardTokenSupplyStateTimeBased[vToken];\\n        TimeBasedRewardToken storage borrowState = rewardTokenBorrowStateTimeBased[vToken];\\n\\n        /*\\n         * Update market state indices\\n         */\\n        if (supplyState.index == 0) {\\n            // Initialize supply state index with default value\\n            supplyState.index = INITIAL_INDEX;\\n        }\\n\\n        if (borrowState.index == 0) {\\n            // Initialize borrow state index with default value\\n            borrowState.index = INITIAL_INDEX;\\n        }\\n\\n        /*\\n         * Update market state block timestamp\\n         */\\n        supplyState.timestamp = borrowState.timestamp = blockTimestamp;\\n    }\\n}\\n\",\"keccak256\":\"0x3cc824e59c923cfe25c4f1a875959b7e9410cde8e73cd405de13f301298c697f\",\"license\":\"BSD-3-Clause\"},\"contracts/Rewards/RewardsDistributorStorage.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\nimport { Comptroller } from \\\"../Comptroller.sol\\\";\\n\\n/**\\n * @title RewardsDistributorStorage\\n * @author Venus\\n * @dev Storage for RewardsDistributor\\n */\\ncontract RewardsDistributorStorage {\\n    struct RewardToken {\\n        // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\\n        uint224 index;\\n        // The block number the index was last updated at\\n        uint32 block;\\n        // The block number at which to stop rewards\\n        uint32 lastRewardingBlock;\\n    }\\n\\n    struct TimeBasedRewardToken {\\n        // The market's last updated rewardTokenBorrowIndex or rewardTokenSupplyIndex\\n        uint224 index;\\n        // The block timestamp the index was last updated at\\n        uint256 timestamp;\\n        // The block timestamp at which to stop rewards\\n        uint256 lastRewardingTimestamp;\\n    }\\n\\n    /// @notice The REWARD TOKEN market supply state for each market\\n    mapping(address => RewardToken) public rewardTokenSupplyState;\\n\\n    /// @notice The REWARD TOKEN borrow index for each market for each supplier as of the last time they accrued REWARD TOKEN\\n    mapping(address => mapping(address => uint256)) public rewardTokenSupplierIndex;\\n\\n    /// @notice The REWARD TOKEN accrued but not yet transferred to each user\\n    mapping(address => uint256) public rewardTokenAccrued;\\n\\n    /// @notice The rate at which rewardToken is distributed to the corresponding borrow market per slot (block or second)\\n    mapping(address => uint256) public rewardTokenBorrowSpeeds;\\n\\n    /// @notice The rate at which rewardToken is distributed to the corresponding supply market per slot (block or second)\\n    mapping(address => uint256) public rewardTokenSupplySpeeds;\\n\\n    /// @notice The REWARD TOKEN market borrow state for each market\\n    mapping(address => RewardToken) public rewardTokenBorrowState;\\n\\n    /// @notice The portion of REWARD TOKEN that each contributor receives per slot (block or second)\\n    mapping(address => uint256) public rewardTokenContributorSpeeds;\\n\\n    /// @notice Last slot (block or second) at which a contributor's REWARD TOKEN rewards have been allocated\\n    mapping(address => uint256) public lastContributorBlock;\\n\\n    /// @notice The REWARD TOKEN borrow index for each market for each borrower as of the last time they accrued REWARD TOKEN\\n    mapping(address => mapping(address => uint256)) public rewardTokenBorrowerIndex;\\n\\n    Comptroller internal comptroller;\\n\\n    IERC20Upgradeable public rewardToken;\\n\\n    /// @notice The REWARD TOKEN market supply state for each market\\n    mapping(address => TimeBasedRewardToken) public rewardTokenSupplyStateTimeBased;\\n\\n    /// @notice The REWARD TOKEN market borrow state for each market\\n    mapping(address => TimeBasedRewardToken) public rewardTokenBorrowStateTimeBased;\\n\\n    /**\\n     * @dev This empty reserved space is put in place to allow future versions to add new\\n     * variables without shifting down storage in the inheritance chain\\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n     */\\n    uint256[37] private __gap;\\n}\\n\",\"keccak256\":\"0x70e5015a78a2acf95277949c8b4796e10b9ac194130be006d5e5217e158070c0\",\"license\":\"BSD-3-Clause\"},\"contracts/VToken.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { Ownable2StepUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\\\";\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { SafeERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AccessControlledV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\\\";\\nimport { IProtocolShareReserve } from \\\"@venusprotocol/protocol-reserve/contracts/Interfaces/IProtocolShareReserve.sol\\\";\\n\\nimport { VTokenInterface } from \\\"./VTokenInterfaces.sol\\\";\\nimport { ComptrollerInterface, ComptrollerViewInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { TokenErrorReporter } from \\\"./ErrorReporter.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\nimport { ExponentialNoError } from \\\"./ExponentialNoError.sol\\\";\\nimport { TimeManagerV8 } from \\\"@venusprotocol/solidity-utilities/contracts/TimeManagerV8.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"./lib/validators.sol\\\";\\n\\n/**\\n * @title VToken\\n * @author Venus\\n * @notice Each asset that is supported by a pool is integrated through an instance of the `VToken` contract. As outlined in the protocol overview,\\n * each isolated pool creates its own `vToken` corresponding to an asset. Within a given pool, each included `vToken` is referred to as a market of\\n * the pool. The main actions a user regularly interacts with in a market are:\\n\\n- mint/redeem of vTokens;\\n- transfer of vTokens;\\n- borrow/repay a loan on an underlying asset;\\n- liquidate a borrow or liquidate/heal an account.\\n\\n * A user supplies the underlying asset to a pool by minting `vTokens`, where the corresponding `vToken` amount is determined by the `exchangeRate`.\\n * The `exchangeRate` will change over time, dependent on a number of factors, some of which accrue interest. Additionally, once users have minted\\n * `vToken` in a pool, they can borrow any asset in the isolated pool by using their `vToken` as collateral. In order to borrow an asset or use a `vToken`\\n * as collateral, the user must be entered into each corresponding market (else, the `vToken` will not be considered collateral for a borrow). Note that\\n * a user may borrow up to a portion of their collateral determined by the market\\u2019s collateral factor. However, if their borrowed amount exceeds an amount\\n * calculated using the market\\u2019s corresponding liquidation threshold, the borrow is eligible for liquidation. When a user repays a borrow, they must also\\n * pay off interest accrued on the borrow.\\n * \\n * The Venus protocol includes unique mechanisms for healing an account and liquidating an account. These actions are performed in the `Comptroller`\\n * and consider all borrows and collateral for which a given account is entered within a market. These functions may only be called on an account with a\\n * total collateral amount that is no larger than a universal `minLiquidatableCollateral` value, which is used for all markets within a `Comptroller`.\\n * Both functions settle all of an account\\u2019s borrows, but `healAccount()` may add `badDebt` to a vToken. For more detail, see the description of\\n * `healAccount()` and `liquidateAccount()` in the `Comptroller` summary section below.\\n */\\ncontract VToken is\\n    Ownable2StepUpgradeable,\\n    AccessControlledV8,\\n    VTokenInterface,\\n    ExponentialNoError,\\n    TokenErrorReporter,\\n    TimeManagerV8\\n{\\n    using SafeERC20Upgradeable for IERC20Upgradeable;\\n\\n    uint256 internal constant DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA = 5e16; // 5%\\n\\n    // Maximum fraction of interest that can be set aside for reserves\\n    uint256 internal constant MAX_RESERVE_FACTOR_MANTISSA = 1e18;\\n\\n    // Maximum borrow rate that can ever be applied per slot(block or second)\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    uint256 internal immutable MAX_BORROW_RATE_MANTISSA;\\n\\n    /**\\n     * Reentrancy Guard **\\n     */\\n\\n    /**\\n     * @dev Prevents a contract from calling itself, directly or indirectly.\\n     */\\n    modifier nonReentrant() {\\n        require(_notEntered, \\\"re-entered\\\");\\n        _notEntered = false;\\n        _;\\n        _notEntered = true; // get a gas-refund post-Istanbul\\n    }\\n\\n    /**\\n     * @param timeBased_ A boolean indicating whether the contract is based on time or block.\\n     * @param blocksPerYear_ The number of blocks per year\\n     * @param maxBorrowRateMantissa_ The maximum value of borrowing rate mantissa\\n     * @custom:oz-upgrades-unsafe-allow constructor\\n     */\\n    constructor(\\n        bool timeBased_,\\n        uint256 blocksPerYear_,\\n        uint256 maxBorrowRateMantissa_\\n    ) TimeManagerV8(timeBased_, blocksPerYear_) {\\n        // Note that the contract is upgradeable. Use initialize() or reinitializers\\n        // to set the state variables.\\n        require(maxBorrowRateMantissa_ <= 1e18, \\\"Max borrow rate must be <= 1e18\\\");\\n\\n        MAX_BORROW_RATE_MANTISSA = maxBorrowRateMantissa_;\\n        _disableInitializers();\\n    }\\n\\n    /**\\n     * @notice Construct a new money market\\n     * @param underlying_ The address of the underlying asset\\n     * @param comptroller_ The address of the Comptroller\\n     * @param interestRateModel_ The address of the interest rate model\\n     * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n     * @param name_ ERC-20 name of this token\\n     * @param symbol_ ERC-20 symbol of this token\\n     * @param decimals_ ERC-20 decimal precision of this token\\n     * @param admin_ Address of the administrator of this token\\n     * @param accessControlManager_ AccessControlManager contract address\\n     * @param riskManagement Addresses of risk & income related contracts\\n     * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n     * @custom:error ZeroAddressNotAllowed is thrown when admin address is zero\\n     * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n     * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n     */\\n    function initialize(\\n        address underlying_,\\n        ComptrollerInterface comptroller_,\\n        InterestRateModel interestRateModel_,\\n        uint256 initialExchangeRateMantissa_,\\n        string memory name_,\\n        string memory symbol_,\\n        uint8 decimals_,\\n        address admin_,\\n        address accessControlManager_,\\n        RiskManagementInit memory riskManagement,\\n        uint256 reserveFactorMantissa_\\n    ) external initializer {\\n        ensureNonzeroAddress(admin_);\\n\\n        // Initialize the market\\n        _initialize(\\n            underlying_,\\n            comptroller_,\\n            interestRateModel_,\\n            initialExchangeRateMantissa_,\\n            name_,\\n            symbol_,\\n            decimals_,\\n            admin_,\\n            accessControlManager_,\\n            riskManagement,\\n            reserveFactorMantissa_\\n        );\\n    }\\n\\n    /**\\n     * @notice Transfer `amount` tokens from `msg.sender` to `dst`\\n     * @param dst The address of the destination account\\n     * @param amount The number of tokens to transfer\\n     * @return success True if the transfer succeeded, reverts otherwise\\n     * @custom:event Emits Transfer event on success\\n     * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n     * @custom:access Not restricted\\n     */\\n    function transfer(address dst, uint256 amount) external override nonReentrant returns (bool) {\\n        _transferTokens(msg.sender, msg.sender, dst, amount);\\n        return true;\\n    }\\n\\n    /**\\n     * @notice Transfer `amount` tokens from `src` to `dst`\\n     * @param src The address of the source account\\n     * @param dst The address of the destination account\\n     * @param amount The number of tokens to transfer\\n     * @return success True if the transfer succeeded, reverts otherwise\\n     * @custom:event Emits Transfer event on success\\n     * @custom:error TransferNotAllowed is thrown if trying to transfer to self\\n     * @custom:access Not restricted\\n     */\\n    function transferFrom(address src, address dst, uint256 amount) external override nonReentrant returns (bool) {\\n        _transferTokens(msg.sender, src, dst, amount);\\n        return true;\\n    }\\n\\n    /**\\n     * @notice Approve `spender` to transfer up to `amount` from `src`\\n     * @dev This will overwrite the approval amount for `spender`\\n     *  and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\\n     * @param spender The address of the account which may transfer tokens\\n     * @param amount The number of tokens that are approved (uint256.max means infinite)\\n     * @return success Whether or not the approval succeeded\\n     * @custom:event Emits Approval event\\n     * @custom:access Not restricted\\n     * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n     */\\n    function approve(address spender, uint256 amount) external override returns (bool) {\\n        ensureNonzeroAddress(spender);\\n\\n        address src = msg.sender;\\n        transferAllowances[src][spender] = amount;\\n        emit Approval(src, spender, amount);\\n        return true;\\n    }\\n\\n    /**\\n     * @notice Increase approval for `spender`\\n     * @param spender The address of the account which may transfer tokens\\n     * @param addedValue The number of additional tokens spender can transfer\\n     * @return success Whether or not the approval succeeded\\n     * @custom:event Emits Approval event\\n     * @custom:access Not restricted\\n     * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n     */\\n    function increaseAllowance(address spender, uint256 addedValue) external override returns (bool) {\\n        ensureNonzeroAddress(spender);\\n\\n        address src = msg.sender;\\n        uint256 newAllowance = transferAllowances[src][spender];\\n        newAllowance += addedValue;\\n        transferAllowances[src][spender] = newAllowance;\\n\\n        emit Approval(src, spender, newAllowance);\\n        return true;\\n    }\\n\\n    /**\\n     * @notice Decreases approval for `spender`\\n     * @param spender The address of the account which may transfer tokens\\n     * @param subtractedValue The number of tokens to remove from total approval\\n     * @return success Whether or not the approval succeeded\\n     * @custom:event Emits Approval event\\n     * @custom:access Not restricted\\n     * @custom:error ZeroAddressNotAllowed is thrown when spender address is zero\\n     */\\n    function decreaseAllowance(address spender, uint256 subtractedValue) external override returns (bool) {\\n        ensureNonzeroAddress(spender);\\n\\n        address src = msg.sender;\\n        uint256 currentAllowance = transferAllowances[src][spender];\\n        require(currentAllowance >= subtractedValue, \\\"decreased allowance below zero\\\");\\n        unchecked {\\n            currentAllowance -= subtractedValue;\\n        }\\n\\n        transferAllowances[src][spender] = currentAllowance;\\n\\n        emit Approval(src, spender, currentAllowance);\\n        return true;\\n    }\\n\\n    /**\\n     * @notice Get the underlying balance of the `owner`\\n     * @dev This also accrues interest in a transaction\\n     * @param owner The address of the account to query\\n     * @return amount The amount of underlying owned by `owner`\\n     */\\n    function balanceOfUnderlying(address owner) external override returns (uint256) {\\n        Exp memory exchangeRate = Exp({ mantissa: exchangeRateCurrent() });\\n        return mul_ScalarTruncate(exchangeRate, accountTokens[owner]);\\n    }\\n\\n    /**\\n     * @notice Returns the current total borrows plus accrued interest\\n     * @return totalBorrows The total borrows with interest\\n     */\\n    function totalBorrowsCurrent() external override nonReentrant returns (uint256) {\\n        accrueInterest();\\n        return totalBorrows;\\n    }\\n\\n    /**\\n     * @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex\\n     * @param account The address whose balance should be calculated after updating borrowIndex\\n     * @return borrowBalance The calculated balance\\n     */\\n    function borrowBalanceCurrent(address account) external override nonReentrant returns (uint256) {\\n        accrueInterest();\\n        return _borrowBalanceStored(account);\\n    }\\n\\n    /**\\n     * @notice Sender supplies assets into the market and receives vTokens in exchange\\n     * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n     * @param mintAmount The amount of the underlying asset to supply\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n     * @custom:access Not restricted\\n     */\\n    function mint(uint256 mintAmount) external override nonReentrant returns (uint256) {\\n        accrueInterest();\\n\\n        _mintFresh(msg.sender, msg.sender, mintAmount);\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice Sender calls on-behalf of minter. minter supplies assets into the market and receives vTokens in exchange\\n     * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n     * @param minter User whom the supply will be attributed to\\n     * @param mintAmount The amount of the underlying asset to supply\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @custom:event Emits Mint and Transfer events; may emit AccrueInterest\\n     * @custom:access Not restricted\\n     * @custom:error ZeroAddressNotAllowed is thrown when minter address is zero\\n     */\\n    function mintBehalf(address minter, uint256 mintAmount) external override nonReentrant returns (uint256) {\\n        ensureNonzeroAddress(minter);\\n\\n        accrueInterest();\\n\\n        _mintFresh(msg.sender, minter, mintAmount);\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice Sender redeems vTokens in exchange for the underlying asset\\n     * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n     * @param redeemTokens The number of vTokens to redeem into underlying\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\\n     * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\\n     * @custom:access Not restricted\\n     */\\n    function redeem(uint256 redeemTokens) external override nonReentrant returns (uint256) {\\n        accrueInterest();\\n\\n        _redeemFresh(msg.sender, msg.sender, redeemTokens, 0);\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice Sender redeems assets on behalf of some other address. This function is only available\\n     *   for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n     * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n     * @param redeemer The user on behalf of whom to redeem\\n     * @param redeemTokens The number of vTokens to redeem into underlying\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @custom:error InsufficientRedeemApproval is thrown when sender is not approved by the redeemer for the given amount\\n     * @custom:error RedeemTransferOutNotPossible is thrown when the protocol has insufficient cash\\n     * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\\n     * @custom:access Not restricted\\n     */\\n    function redeemBehalf(address redeemer, uint256 redeemTokens) external override nonReentrant returns (uint256) {\\n        _ensureSenderIsDelegateOf(redeemer);\\n\\n        accrueInterest();\\n\\n        _redeemFresh(redeemer, msg.sender, redeemTokens, 0);\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice Sender redeems vTokens in exchange for a specified amount of underlying asset\\n     * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n     * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     */\\n    function redeemUnderlying(uint256 redeemAmount) external override nonReentrant returns (uint256) {\\n        accrueInterest();\\n\\n        _redeemFresh(msg.sender, msg.sender, 0, redeemAmount);\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice Sender redeems underlying assets on behalf of some other address. This function is only available\\n     *   for senders, explicitly marked as delegates of the supplier using `comptroller.updateDelegate`\\n     * @dev Accrues interest whether or not the operation succeeds, unless reverted\\n     * @param redeemer, on behalf of whom to redeem\\n     * @param redeemAmount The amount of underlying to receive from redeeming vTokens\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @custom:error InsufficientRedeemApproval is thrown when sender is not approved by the redeemer for the given amount\\n     * @custom:event Emits Redeem and Transfer events; may emit AccrueInterest\\n     * @custom:access Not restricted\\n     */\\n    function redeemUnderlyingBehalf(\\n        address redeemer,\\n        uint256 redeemAmount\\n    ) external override nonReentrant returns (uint256) {\\n        _ensureSenderIsDelegateOf(redeemer);\\n\\n        accrueInterest();\\n\\n        _redeemFresh(redeemer, msg.sender, 0, redeemAmount);\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice Sender borrows assets from the protocol to their own address\\n     * @param borrowAmount The amount of the underlying asset to borrow\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @custom:event Emits Borrow event; may emit AccrueInterest\\n     * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\\n     * @custom:access Not restricted\\n     */\\n    function borrow(uint256 borrowAmount) external override nonReentrant returns (uint256) {\\n        accrueInterest();\\n\\n        _borrowFresh(msg.sender, msg.sender, borrowAmount);\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice Sender borrows assets on behalf of some other address. This function is only available\\n     *   for senders, explicitly marked as delegates of the borrower using `comptroller.updateDelegate`\\n     * @param borrower The borrower, on behalf of whom to borrow\\n     * @param borrowAmount The amount of the underlying asset to borrow\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @custom:error DelegateNotApproved is thrown if caller is not approved delegate\\n     * @custom:error BorrowCashNotAvailable is thrown when the protocol has insufficient cash\\n     * @custom:event Emits Borrow event; may emit AccrueInterest\\n     * @custom:access Not restricted\\n     */\\n    function borrowBehalf(address borrower, uint256 borrowAmount) external override returns (uint256) {\\n        _ensureSenderIsDelegateOf(borrower);\\n        accrueInterest();\\n\\n        _borrowFresh(borrower, msg.sender, borrowAmount);\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice Sender repays their own borrow\\n     * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n     * @custom:access Not restricted\\n     */\\n    function repayBorrow(uint256 repayAmount) external override nonReentrant returns (uint256) {\\n        accrueInterest();\\n\\n        _repayBorrowFresh(msg.sender, msg.sender, repayAmount);\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice Sender repays a borrow belonging to borrower\\n     * @param borrower the account with the debt being payed off\\n     * @param repayAmount The amount to repay, or type(uint256).max for the full outstanding amount\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @custom:event Emits RepayBorrow event; may emit AccrueInterest\\n     * @custom:access Not restricted\\n     */\\n    function repayBorrowBehalf(address borrower, uint256 repayAmount) external override nonReentrant returns (uint256) {\\n        accrueInterest();\\n\\n        _repayBorrowFresh(msg.sender, borrower, repayAmount);\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice The sender liquidates the borrowers collateral.\\n     *  The collateral seized is transferred to the liquidator.\\n     * @param borrower The borrower of this vToken to be liquidated\\n     * @param repayAmount The amount of the underlying borrowed asset to repay\\n     * @param vTokenCollateral The market in which to seize collateral from the borrower\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n     * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n     * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n     * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n     * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n     * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n     * @custom:access Not restricted\\n     */\\n    function liquidateBorrow(\\n        address borrower,\\n        uint256 repayAmount,\\n        VTokenInterface vTokenCollateral\\n    ) external override returns (uint256) {\\n        _liquidateBorrow(msg.sender, borrower, repayAmount, vTokenCollateral, false);\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice sets protocol share accumulated from liquidations\\n     * @dev must be equal or less than liquidation incentive - 1\\n     * @param newProtocolSeizeShareMantissa_ new protocol share mantissa\\n     * @custom:event Emits NewProtocolSeizeShare event on success\\n     * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n     * @custom:error ProtocolSeizeShareTooBig is thrown when the new seize share is too high\\n     * @custom:access Controlled by AccessControlManager\\n     */\\n    function setProtocolSeizeShare(uint256 newProtocolSeizeShareMantissa_) external {\\n        _checkAccessAllowed(\\\"setProtocolSeizeShare(uint256)\\\");\\n        uint256 liquidationIncentive = ComptrollerViewInterface(address(comptroller)).liquidationIncentiveMantissa();\\n        if (newProtocolSeizeShareMantissa_ + MANTISSA_ONE > liquidationIncentive) {\\n            revert ProtocolSeizeShareTooBig();\\n        }\\n\\n        uint256 oldProtocolSeizeShareMantissa = protocolSeizeShareMantissa;\\n        protocolSeizeShareMantissa = newProtocolSeizeShareMantissa_;\\n        emit NewProtocolSeizeShare(oldProtocolSeizeShareMantissa, newProtocolSeizeShareMantissa_);\\n    }\\n\\n    /**\\n     * @notice accrues interest and sets a new reserve factor for the protocol using _setReserveFactorFresh\\n     * @dev Admin function to accrue interest and set a new reserve factor\\n     * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n     * @custom:event Emits NewReserveFactor event; may emit AccrueInterest\\n     * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n     * @custom:error SetReserveFactorBoundsCheck is thrown when the new reserve factor is too high\\n     * @custom:access Controlled by AccessControlManager\\n     */\\n    function setReserveFactor(uint256 newReserveFactorMantissa) external override nonReentrant {\\n        _checkAccessAllowed(\\\"setReserveFactor(uint256)\\\");\\n\\n        accrueInterest();\\n        _setReserveFactorFresh(newReserveFactorMantissa);\\n    }\\n\\n    /**\\n     * @notice Accrues interest and reduces reserves by transferring to the protocol reserve contract\\n     * @dev Gracefully return if reserves already reduced in accrueInterest\\n     * @param reduceAmount Amount of reduction to reserves\\n     * @custom:event Emits ReservesReduced event; may emit AccrueInterest\\n     * @custom:error ReduceReservesCashNotAvailable is thrown when the vToken does not have sufficient cash\\n     * @custom:error ReduceReservesCashValidation is thrown when trying to withdraw more cash than the reserves have\\n     * @custom:access Not restricted\\n     */\\n    function reduceReserves(uint256 reduceAmount) external override nonReentrant {\\n        accrueInterest();\\n        if (reduceReservesBlockNumber == getBlockNumberOrTimestamp()) return;\\n        _reduceReservesFresh(reduceAmount);\\n    }\\n\\n    /**\\n     * @notice The sender adds to reserves.\\n     * @param addAmount The amount of underlying token to add as reserves\\n     * @custom:event Emits ReservesAdded event; may emit AccrueInterest\\n     * @custom:access Not restricted\\n     */\\n    function addReserves(uint256 addAmount) external override nonReentrant {\\n        accrueInterest();\\n        _addReservesFresh(addAmount);\\n    }\\n\\n    /**\\n     * @notice accrues interest and updates the interest rate model using _setInterestRateModelFresh\\n     * @dev Admin function to accrue interest and update the interest rate model\\n     * @param newInterestRateModel the new interest rate model to use\\n     * @custom:event Emits NewMarketInterestRateModel event; may emit AccrueInterest\\n     * @custom:error Unauthorized error is thrown when the call is not authorized by AccessControlManager\\n     * @custom:access Controlled by AccessControlManager\\n     */\\n    function setInterestRateModel(InterestRateModel newInterestRateModel) external override {\\n        _checkAccessAllowed(\\\"setInterestRateModel(address)\\\");\\n\\n        accrueInterest();\\n        _setInterestRateModelFresh(newInterestRateModel);\\n    }\\n\\n    /**\\n     * @notice Repays a certain amount of debt, treats the rest of the borrow as bad debt, essentially\\n     *   \\\"forgiving\\\" the borrower. Healing is a situation that should rarely happen. However, some pools\\n     *   may list risky assets or be configured improperly \\u2013 we want to still handle such cases gracefully.\\n     *   We assume that Comptroller does the seizing, so this function is only available to Comptroller.\\n     * @dev This function does not call any Comptroller hooks (like \\\"healAllowed\\\"), because we assume\\n     *   the Comptroller does all the necessary checks before calling this function.\\n     * @param payer account who repays the debt\\n     * @param borrower account to heal\\n     * @param repayAmount amount to repay\\n     * @custom:event Emits RepayBorrow, BadDebtIncreased events; may emit AccrueInterest\\n     * @custom:error HealBorrowUnauthorized is thrown when the request does not come from Comptroller\\n     * @custom:access Only Comptroller\\n     */\\n    function healBorrow(address payer, address borrower, uint256 repayAmount) external override nonReentrant {\\n        if (repayAmount != 0) {\\n            comptroller.preRepayHook(address(this), borrower);\\n        }\\n\\n        if (msg.sender != address(comptroller)) {\\n            revert HealBorrowUnauthorized();\\n        }\\n\\n        uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n        uint256 totalBorrowsNew = totalBorrows;\\n\\n        uint256 actualRepayAmount;\\n        if (repayAmount != 0) {\\n            // _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n            // We violate checks-effects-interactions here to account for tokens that take transfer fees\\n            actualRepayAmount = _doTransferIn(payer, repayAmount);\\n            totalBorrowsNew = totalBorrowsNew - actualRepayAmount;\\n            emit RepayBorrow(\\n                payer,\\n                borrower,\\n                actualRepayAmount,\\n                accountBorrowsPrev - actualRepayAmount,\\n                totalBorrowsNew\\n            );\\n        }\\n\\n        // The transaction will fail if trying to repay too much\\n        uint256 badDebtDelta = accountBorrowsPrev - actualRepayAmount;\\n        if (badDebtDelta != 0) {\\n            uint256 badDebtOld = badDebt;\\n            uint256 badDebtNew = badDebtOld + badDebtDelta;\\n            totalBorrowsNew = totalBorrowsNew - badDebtDelta;\\n            badDebt = badDebtNew;\\n\\n            // We treat healing as \\\"repayment\\\", where vToken is the payer\\n            emit RepayBorrow(address(this), borrower, badDebtDelta, 0, totalBorrowsNew);\\n            emit BadDebtIncreased(borrower, badDebtDelta, badDebtOld, badDebtNew);\\n        }\\n\\n        accountBorrows[borrower].principal = 0;\\n        accountBorrows[borrower].interestIndex = borrowIndex;\\n        totalBorrows = totalBorrowsNew;\\n\\n        emit HealBorrow(payer, borrower, repayAmount);\\n    }\\n\\n    /**\\n     * @notice The extended version of liquidations, callable only by Comptroller. May skip\\n     *  the close factor check. The collateral seized is transferred to the liquidator.\\n     * @param liquidator The address repaying the borrow and seizing collateral\\n     * @param borrower The borrower of this vToken to be liquidated\\n     * @param repayAmount The amount of the underlying borrowed asset to repay\\n     * @param vTokenCollateral The market in which to seize collateral from the borrower\\n     * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n     *   regardless of the account liquidity\\n     * @custom:event Emits LiquidateBorrow event; may emit AccrueInterest\\n     * @custom:error ForceLiquidateBorrowUnauthorized is thrown when the request does not come from Comptroller\\n     * @custom:error LiquidateAccrueCollateralInterestFailed is thrown when it is not possible to accrue interest on the collateral vToken\\n     * @custom:error LiquidateCollateralFreshnessCheck is thrown when interest has not been accrued on the collateral vToken\\n     * @custom:error LiquidateLiquidatorIsBorrower is thrown when trying to liquidate self\\n     * @custom:error LiquidateCloseAmountIsZero is thrown when repayment amount is zero\\n     * @custom:error LiquidateCloseAmountIsUintMax is thrown when repayment amount is UINT_MAX\\n     * @custom:access Only Comptroller\\n     */\\n    function forceLiquidateBorrow(\\n        address liquidator,\\n        address borrower,\\n        uint256 repayAmount,\\n        VTokenInterface vTokenCollateral,\\n        bool skipLiquidityCheck\\n    ) external override {\\n        if (msg.sender != address(comptroller)) {\\n            revert ForceLiquidateBorrowUnauthorized();\\n        }\\n        _liquidateBorrow(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\n    }\\n\\n    /**\\n     * @notice Transfers collateral tokens (this market) to the liquidator.\\n     * @dev Will fail unless called by another vToken during the process of liquidation.\\n     *  It's absolutely critical to use msg.sender as the borrowed vToken and not a parameter.\\n     * @param liquidator The account receiving seized collateral\\n     * @param borrower The account having collateral seized\\n     * @param seizeTokens The number of vTokens to seize\\n     * @custom:event Emits Transfer, ReservesAdded events\\n     * @custom:error LiquidateSeizeLiquidatorIsBorrower is thrown when trying to liquidate self\\n     * @custom:access Not restricted\\n     */\\n    function seize(address liquidator, address borrower, uint256 seizeTokens) external override nonReentrant {\\n        _seize(msg.sender, liquidator, borrower, seizeTokens);\\n    }\\n\\n    /**\\n     * @notice Updates bad debt\\n     * @dev Called only when bad debt is recovered from auction\\n     * @param recoveredAmount_ The amount of bad debt recovered\\n     * @custom:event Emits BadDebtRecovered event\\n     * @custom:access Only Shortfall contract\\n     */\\n    function badDebtRecovered(uint256 recoveredAmount_) external {\\n        require(msg.sender == shortfall, \\\"only shortfall contract can update bad debt\\\");\\n        require(recoveredAmount_ <= badDebt, \\\"more than bad debt recovered from auction\\\");\\n\\n        uint256 badDebtOld = badDebt;\\n        uint256 badDebtNew = badDebtOld - recoveredAmount_;\\n        badDebt = badDebtNew;\\n\\n        emit BadDebtRecovered(badDebtOld, badDebtNew);\\n    }\\n\\n    /**\\n     * @notice Sets protocol share reserve contract address\\n     * @param protocolShareReserve_ The address of the protocol share reserve contract\\n     * @custom:error ZeroAddressNotAllowed is thrown when protocol share reserve address is zero\\n     * @custom:access Only Governance\\n     */\\n    function setProtocolShareReserve(address payable protocolShareReserve_) external onlyOwner {\\n        _setProtocolShareReserve(protocolShareReserve_);\\n    }\\n\\n    /**\\n     * @notice Sets shortfall contract address\\n     * @param shortfall_ The address of the shortfall contract\\n     * @custom:error ZeroAddressNotAllowed is thrown when shortfall contract address is zero\\n     * @custom:access Only Governance\\n     */\\n    function setShortfallContract(address shortfall_) external onlyOwner {\\n        _setShortfallContract(shortfall_);\\n    }\\n\\n    /**\\n     * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to admin (timelock)\\n     * @param token The address of the ERC-20 token to sweep\\n     * @custom:access Only Governance\\n     */\\n    function sweepToken(IERC20Upgradeable token) external override {\\n        require(msg.sender == owner(), \\\"VToken::sweepToken: only admin can sweep tokens\\\");\\n        require(address(token) != underlying, \\\"VToken::sweepToken: can not sweep underlying token\\\");\\n        uint256 balance = token.balanceOf(address(this));\\n        token.safeTransfer(owner(), balance);\\n\\n        emit SweepToken(address(token));\\n    }\\n\\n    /**\\n     * @notice A public function to set new threshold of slot(block or second) difference after which funds will be sent to the protocol share reserve\\n     * @param _newReduceReservesBlockOrTimestampDelta slot(block or second) difference value\\n     * @custom:access Only Governance\\n     */\\n    function setReduceReservesBlockDelta(uint256 _newReduceReservesBlockOrTimestampDelta) external {\\n        _checkAccessAllowed(\\\"setReduceReservesBlockDelta(uint256)\\\");\\n        require(_newReduceReservesBlockOrTimestampDelta > 0, \\\"Invalid Input\\\");\\n        emit NewReduceReservesBlockDelta(reduceReservesBlockDelta, _newReduceReservesBlockOrTimestampDelta);\\n        reduceReservesBlockDelta = _newReduceReservesBlockOrTimestampDelta;\\n    }\\n\\n    /**\\n     * @notice Get the current allowance from `owner` for `spender`\\n     * @param owner The address of the account which owns the tokens to be spent\\n     * @param spender The address of the account which may transfer tokens\\n     * @return amount The number of tokens allowed to be spent (type(uint256).max means infinite)\\n     */\\n    function allowance(address owner, address spender) external view override returns (uint256) {\\n        return transferAllowances[owner][spender];\\n    }\\n\\n    /**\\n     * @notice Get the token balance of the `owner`\\n     * @param owner The address of the account to query\\n     * @return amount The number of tokens owned by `owner`\\n     */\\n    function balanceOf(address owner) external view override returns (uint256) {\\n        return accountTokens[owner];\\n    }\\n\\n    /**\\n     * @notice Get a snapshot of the account's balances, and the cached exchange rate\\n     * @dev This is used by comptroller to more efficiently perform liquidity checks.\\n     * @param account Address of the account to snapshot\\n     * @return error Always NO_ERROR for compatibility with Venus core tooling\\n     * @return vTokenBalance User's balance of vTokens\\n     * @return borrowBalance Amount owed in terms of underlying\\n     * @return exchangeRate Stored exchange rate\\n     */\\n    function getAccountSnapshot(\\n        address account\\n    )\\n        external\\n        view\\n        override\\n        returns (uint256 error, uint256 vTokenBalance, uint256 borrowBalance, uint256 exchangeRate)\\n    {\\n        return (NO_ERROR, accountTokens[account], _borrowBalanceStored(account), _exchangeRateStored());\\n    }\\n\\n    /**\\n     * @notice Get cash balance of this vToken in the underlying asset\\n     * @return cash The quantity of underlying asset owned by this contract\\n     */\\n    function getCash() external view override returns (uint256) {\\n        return _getCashPrior();\\n    }\\n\\n    /**\\n     * @notice Returns the current per slot(block or second) borrow interest rate for this vToken\\n     * @return rate The borrow interest rate per slot(block or second), scaled by 1e18\\n     */\\n    function borrowRatePerBlock() external view override returns (uint256) {\\n        return interestRateModel.getBorrowRate(_getCashPrior(), totalBorrows, totalReserves, badDebt);\\n    }\\n\\n    /**\\n     * @notice Returns the current per-slot(block or second) supply interest rate for this v\\n     * @return rate The supply interest rate per slot(block or second), scaled by 1e18\\n     */\\n    function supplyRatePerBlock() external view override returns (uint256) {\\n        return\\n            interestRateModel.getSupplyRate(\\n                _getCashPrior(),\\n                totalBorrows,\\n                totalReserves,\\n                reserveFactorMantissa,\\n                badDebt\\n            );\\n    }\\n\\n    /**\\n     * @notice Return the borrow balance of account based on stored data\\n     * @param account The address whose balance should be calculated\\n     * @return borrowBalance The calculated balance\\n     */\\n    function borrowBalanceStored(address account) external view override returns (uint256) {\\n        return _borrowBalanceStored(account);\\n    }\\n\\n    /**\\n     * @notice Calculates the exchange rate from the underlying to the VToken\\n     * @dev This function does not accrue interest before calculating the exchange rate\\n     * @return exchangeRate Calculated exchange rate scaled by 1e18\\n     */\\n    function exchangeRateStored() external view override returns (uint256) {\\n        return _exchangeRateStored();\\n    }\\n\\n    /**\\n     * @notice Accrue interest then return the up-to-date exchange rate\\n     * @return exchangeRate Calculated exchange rate scaled by 1e18\\n     */\\n    function exchangeRateCurrent() public override nonReentrant returns (uint256) {\\n        accrueInterest();\\n        return _exchangeRateStored();\\n    }\\n\\n    /**\\n     * @notice Applies accrued interest to total borrows and reserves\\n     * @dev This calculates interest accrued from the last checkpointed slot(block or second)\\n     *  up to the current slot(block or second) and writes new checkpoint to storage and\\n     *  reduce spread reserves to protocol share reserve\\n     *  if currentSlot - reduceReservesBlockNumber >= slotDelta\\n     * @return Always NO_ERROR\\n     * @custom:event Emits AccrueInterest event on success\\n     * @custom:access Not restricted\\n     */\\n    function accrueInterest() public virtual override returns (uint256) {\\n        /* Remember the initial block number or timestamp */\\n        uint256 currentSlotNumber = getBlockNumberOrTimestamp();\\n        uint256 accrualSlotNumberPrior = accrualBlockNumber;\\n\\n        /* Short-circuit accumulating 0 interest */\\n        if (accrualSlotNumberPrior == currentSlotNumber) {\\n            return NO_ERROR;\\n        }\\n\\n        /* Read the previous values out of storage */\\n        uint256 cashPrior = _getCashPrior();\\n        uint256 borrowsPrior = totalBorrows;\\n        uint256 reservesPrior = totalReserves;\\n        uint256 borrowIndexPrior = borrowIndex;\\n\\n        /* Calculate the current borrow interest rate */\\n        uint256 borrowRateMantissa = interestRateModel.getBorrowRate(cashPrior, borrowsPrior, reservesPrior, badDebt);\\n        require(borrowRateMantissa <= MAX_BORROW_RATE_MANTISSA, \\\"borrow rate is absurdly high\\\");\\n\\n        /* Calculate the number of slots elapsed since the last accrual */\\n        uint256 slotDelta = currentSlotNumber - accrualSlotNumberPrior;\\n\\n        /*\\n         * Calculate the interest accumulated into borrows and reserves and the new index:\\n         *  simpleInterestFactor = borrowRate * slotDelta\\n         *  interestAccumulated = simpleInterestFactor * totalBorrows\\n         *  totalBorrowsNew = interestAccumulated + totalBorrows\\n         *  totalReservesNew = interestAccumulated * reserveFactor + totalReserves\\n         *  borrowIndexNew = simpleInterestFactor * borrowIndex + borrowIndex\\n         */\\n\\n        Exp memory simpleInterestFactor = mul_(Exp({ mantissa: borrowRateMantissa }), slotDelta);\\n        uint256 interestAccumulated = mul_ScalarTruncate(simpleInterestFactor, borrowsPrior);\\n        uint256 totalBorrowsNew = interestAccumulated + borrowsPrior;\\n        uint256 totalReservesNew = mul_ScalarTruncateAddUInt(\\n            Exp({ mantissa: reserveFactorMantissa }),\\n            interestAccumulated,\\n            reservesPrior\\n        );\\n        uint256 borrowIndexNew = mul_ScalarTruncateAddUInt(simpleInterestFactor, borrowIndexPrior, borrowIndexPrior);\\n\\n        /////////////////////////\\n        // EFFECTS & INTERACTIONS\\n        // (No safe failures beyond this point)\\n\\n        /* We write the previously calculated values into storage */\\n        accrualBlockNumber = currentSlotNumber;\\n        borrowIndex = borrowIndexNew;\\n        totalBorrows = totalBorrowsNew;\\n        totalReserves = totalReservesNew;\\n\\n        if (currentSlotNumber - reduceReservesBlockNumber >= reduceReservesBlockDelta) {\\n            reduceReservesBlockNumber = currentSlotNumber;\\n            if (cashPrior < totalReservesNew) {\\n                _reduceReservesFresh(cashPrior);\\n            } else {\\n                _reduceReservesFresh(totalReservesNew);\\n            }\\n        }\\n\\n        /* We emit an AccrueInterest event */\\n        emit AccrueInterest(cashPrior, interestAccumulated, borrowIndexNew, totalBorrowsNew);\\n\\n        return NO_ERROR;\\n    }\\n\\n    /**\\n     * @notice User supplies assets into the market and receives vTokens in exchange\\n     * @dev Assumes interest has already been accrued up to the current block or timestamp\\n     * @param payer The address of the account which is sending the assets for supply\\n     * @param minter The address of the account which is supplying the assets\\n     * @param mintAmount The amount of the underlying asset to supply\\n     */\\n    function _mintFresh(address payer, address minter, uint256 mintAmount) internal {\\n        /* Fail if mint not allowed */\\n        comptroller.preMintHook(address(this), minter, mintAmount);\\n\\n        /* Verify market's slot(block or second) number equals current slot(block or second) number */\\n        if (accrualBlockNumber != getBlockNumberOrTimestamp()) {\\n            revert MintFreshnessCheck();\\n        }\\n\\n        Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n\\n        /////////////////////////\\n        // EFFECTS & INTERACTIONS\\n        // (No safe failures beyond this point)\\n\\n        /*\\n         *  We call `_doTransferIn` for the minter and the mintAmount.\\n         *  `_doTransferIn` reverts if anything goes wrong, since we can't be sure if\\n         *  side-effects occurred. The function returns the amount actually transferred,\\n         *  in case of a fee. On success, the vToken holds an additional `actualMintAmount`\\n         *  of cash.\\n         */\\n        uint256 actualMintAmount = _doTransferIn(payer, mintAmount);\\n\\n        /*\\n         * We get the current exchange rate and calculate the number of vTokens to be minted:\\n         *  mintTokens = actualMintAmount / exchangeRate\\n         */\\n\\n        uint256 mintTokens = div_(actualMintAmount, exchangeRate);\\n\\n        /*\\n         * We calculate the new total supply of vTokens and minter token balance, checking for overflow:\\n         *  totalSupplyNew = totalSupply + mintTokens\\n         *  accountTokensNew = accountTokens[minter] + mintTokens\\n         * And write them into storage\\n         */\\n        totalSupply = totalSupply + mintTokens;\\n        uint256 balanceAfter = accountTokens[minter] + mintTokens;\\n        accountTokens[minter] = balanceAfter;\\n\\n        /* We emit a Mint event, and a Transfer event */\\n        emit Mint(minter, actualMintAmount, mintTokens, balanceAfter);\\n        emit Transfer(address(0), minter, mintTokens);\\n\\n        /* We call the defense and prime accrue interest hook */\\n        comptroller.mintVerify(address(this), minter, actualMintAmount, mintTokens);\\n    }\\n\\n    /**\\n     * @notice Redeemer redeems vTokens in exchange for the underlying assets, transferred to the receiver. Redeemer and receiver can be the same\\n     *   address, or different addresses if the receiver was previously approved by the redeemer as a valid delegate (see Comptroller.updateDelegate)\\n     * @dev Assumes interest has already been accrued up to the current slot(block or second)\\n     * @param redeemer The address of the account which is redeeming the tokens\\n     * @param receiver The receiver of the underlying tokens\\n     * @param redeemTokensIn The number of vTokens to redeem into underlying (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n     * @param redeemAmountIn The number of underlying tokens to receive from redeeming vTokens (only one of redeemTokensIn or redeemAmountIn may be non-zero)\\n     */\\n    function _redeemFresh(address redeemer, address receiver, uint256 redeemTokensIn, uint256 redeemAmountIn) internal {\\n        require(redeemTokensIn == 0 || redeemAmountIn == 0, \\\"one of redeemTokensIn or redeemAmountIn must be zero\\\");\\n\\n        /* Verify market's slot(block or second) number equals current slot(block or second) number */\\n        if (accrualBlockNumber != getBlockNumberOrTimestamp()) {\\n            revert RedeemFreshnessCheck();\\n        }\\n\\n        /* exchangeRate = invoke Exchange Rate Stored() */\\n        Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n\\n        uint256 redeemTokens;\\n        uint256 redeemAmount;\\n\\n        /* If redeemTokensIn > 0: */\\n        if (redeemTokensIn > 0) {\\n            /*\\n             * We calculate the exchange rate and the amount of underlying to be redeemed:\\n             *  redeemTokens = redeemTokensIn\\n             */\\n            redeemTokens = redeemTokensIn;\\n        } else {\\n            /*\\n             * We get the current exchange rate and calculate the amount to be redeemed:\\n             *  redeemTokens = redeemAmountIn / exchangeRate\\n             */\\n            redeemTokens = div_(redeemAmountIn, exchangeRate);\\n\\n            uint256 _redeemAmount = mul_(redeemTokens, exchangeRate);\\n            if (_redeemAmount != 0 && _redeemAmount != redeemAmountIn) redeemTokens++; // round up\\n        }\\n\\n        // redeemAmount = exchangeRate * redeemTokens\\n        redeemAmount = mul_ScalarTruncate(exchangeRate, redeemTokens);\\n\\n        // Revert if amount is zero\\n        if (redeemAmount == 0) {\\n            revert(\\\"redeemAmount is zero\\\");\\n        }\\n\\n        /* Fail if redeem not allowed */\\n        comptroller.preRedeemHook(address(this), redeemer, redeemTokens);\\n\\n        /* Fail gracefully if protocol has insufficient cash */\\n        if (_getCashPrior() - totalReserves < redeemAmount) {\\n            revert RedeemTransferOutNotPossible();\\n        }\\n\\n        /////////////////////////\\n        // EFFECTS & INTERACTIONS\\n        // (No safe failures beyond this point)\\n\\n        /*\\n         * We write the previously calculated values into storage.\\n         *  Note: Avoid token reentrancy attacks by writing reduced supply before external transfer.\\n         */\\n        totalSupply = totalSupply - redeemTokens;\\n        uint256 balanceAfter = accountTokens[redeemer] - redeemTokens;\\n        accountTokens[redeemer] = balanceAfter;\\n\\n        /*\\n         * We invoke _doTransferOut for the receiver and the redeemAmount.\\n         *  On success, the vToken has redeemAmount less of cash.\\n         *  _doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n         */\\n        _doTransferOut(receiver, redeemAmount);\\n\\n        /* We emit a Transfer event, and a Redeem event */\\n        emit Transfer(redeemer, address(this), redeemTokens);\\n        emit Redeem(redeemer, redeemAmount, redeemTokens, balanceAfter);\\n\\n        /* We call the defense and prime accrue interest hook */\\n        comptroller.redeemVerify(address(this), redeemer, redeemAmount, redeemTokens);\\n    }\\n\\n    /**\\n     * @notice Users or their delegates borrow assets from the protocol\\n     * @param borrower User who borrows the assets\\n     * @param receiver The receiver of the tokens, if called by a delegate\\n     * @param borrowAmount The amount of the underlying asset to borrow\\n     */\\n    function _borrowFresh(address borrower, address receiver, uint256 borrowAmount) internal {\\n        /* Fail if borrow not allowed */\\n        comptroller.preBorrowHook(address(this), borrower, borrowAmount);\\n\\n        /* Verify market's slot(block or second) number equals current slot(block or second) number */\\n        if (accrualBlockNumber != getBlockNumberOrTimestamp()) {\\n            revert BorrowFreshnessCheck();\\n        }\\n\\n        /* Fail gracefully if protocol has insufficient underlying cash */\\n        if (_getCashPrior() - totalReserves < borrowAmount) {\\n            revert BorrowCashNotAvailable();\\n        }\\n\\n        /*\\n         * We calculate the new borrower and total borrow balances, failing on overflow:\\n         *  accountBorrowNew = accountBorrow + borrowAmount\\n         *  totalBorrowsNew = totalBorrows + borrowAmount\\n         */\\n        uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n        uint256 accountBorrowsNew = accountBorrowsPrev + borrowAmount;\\n        uint256 totalBorrowsNew = totalBorrows + borrowAmount;\\n\\n        /////////////////////////\\n        // EFFECTS & INTERACTIONS\\n        // (No safe failures beyond this point)\\n\\n        /*\\n         * We write the previously calculated values into storage.\\n         *  Note: Avoid token reentrancy attacks by writing increased borrow before external transfer.\\n        `*/\\n        accountBorrows[borrower].principal = accountBorrowsNew;\\n        accountBorrows[borrower].interestIndex = borrowIndex;\\n        totalBorrows = totalBorrowsNew;\\n\\n        /*\\n         * We invoke _doTransferOut for the receiver and the borrowAmount.\\n         *  On success, the vToken borrowAmount less of cash.\\n         *  _doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n         */\\n        _doTransferOut(receiver, borrowAmount);\\n\\n        /* We emit a Borrow event */\\n        emit Borrow(borrower, borrowAmount, accountBorrowsNew, totalBorrowsNew);\\n\\n        /* We call the defense and prime accrue interest hook */\\n        comptroller.borrowVerify(address(this), borrower, borrowAmount);\\n    }\\n\\n    /**\\n     * @notice Borrows are repaid by another user (possibly the borrower).\\n     * @param payer the account paying off the borrow\\n     * @param borrower the account with the debt being payed off\\n     * @param repayAmount the amount of underlying tokens being returned, or type(uint256).max for the full outstanding amount\\n     * @return (uint) the actual repayment amount.\\n     */\\n    function _repayBorrowFresh(address payer, address borrower, uint256 repayAmount) internal returns (uint256) {\\n        /* Fail if repayBorrow not allowed */\\n        comptroller.preRepayHook(address(this), borrower);\\n\\n        /* Verify market's slot(block or second) number equals current slot(block or second) number */\\n        if (accrualBlockNumber != getBlockNumberOrTimestamp()) {\\n            revert RepayBorrowFreshnessCheck();\\n        }\\n\\n        /* We fetch the amount the borrower owes, with accumulated interest */\\n        uint256 accountBorrowsPrev = _borrowBalanceStored(borrower);\\n\\n        uint256 repayAmountFinal = repayAmount >= accountBorrowsPrev ? accountBorrowsPrev : repayAmount;\\n\\n        /////////////////////////\\n        // EFFECTS & INTERACTIONS\\n        // (No safe failures beyond this point)\\n\\n        /*\\n         * We call _doTransferIn for the payer and the repayAmount\\n         *  On success, the vToken holds an additional repayAmount of cash.\\n         *  _doTransferIn reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n         *   it returns the amount actually transferred, in case of a fee.\\n         */\\n        uint256 actualRepayAmount = _doTransferIn(payer, repayAmountFinal);\\n\\n        /*\\n         * We calculate the new borrower and total borrow balances, failing on underflow:\\n         *  accountBorrowsNew = accountBorrows - actualRepayAmount\\n         *  totalBorrowsNew = totalBorrows - actualRepayAmount\\n         */\\n        uint256 accountBorrowsNew = accountBorrowsPrev - actualRepayAmount;\\n        uint256 totalBorrowsNew = totalBorrows - actualRepayAmount;\\n\\n        /* We write the previously calculated values into storage */\\n        accountBorrows[borrower].principal = accountBorrowsNew;\\n        accountBorrows[borrower].interestIndex = borrowIndex;\\n        totalBorrows = totalBorrowsNew;\\n\\n        /* We emit a RepayBorrow event */\\n        emit RepayBorrow(payer, borrower, actualRepayAmount, accountBorrowsNew, totalBorrowsNew);\\n\\n        /* We call the defense and prime accrue interest hook */\\n        comptroller.repayBorrowVerify(address(this), payer, borrower, actualRepayAmount, borrowIndex);\\n\\n        return actualRepayAmount;\\n    }\\n\\n    /**\\n     * @notice The sender liquidates the borrowers collateral.\\n     *  The collateral seized is transferred to the liquidator.\\n     * @param liquidator The address repaying the borrow and seizing collateral\\n     * @param borrower The borrower of this vToken to be liquidated\\n     * @param vTokenCollateral The market in which to seize collateral from the borrower\\n     * @param repayAmount The amount of the underlying borrowed asset to repay\\n     * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n     *   regardless of the account liquidity\\n     */\\n    function _liquidateBorrow(\\n        address liquidator,\\n        address borrower,\\n        uint256 repayAmount,\\n        VTokenInterface vTokenCollateral,\\n        bool skipLiquidityCheck\\n    ) internal nonReentrant {\\n        accrueInterest();\\n\\n        uint256 error = vTokenCollateral.accrueInterest();\\n        if (error != NO_ERROR) {\\n            // accrueInterest emits logs on errors, but we still want to log the fact that an attempted liquidation failed\\n            revert LiquidateAccrueCollateralInterestFailed(error);\\n        }\\n\\n        _liquidateBorrowFresh(liquidator, borrower, repayAmount, vTokenCollateral, skipLiquidityCheck);\\n    }\\n\\n    /**\\n     * @notice The liquidator liquidates the borrowers collateral.\\n     *  The collateral seized is transferred to the liquidator.\\n     * @param liquidator The address repaying the borrow and seizing collateral\\n     * @param borrower The borrower of this vToken to be liquidated\\n     * @param vTokenCollateral The market in which to seize collateral from the borrower\\n     * @param repayAmount The amount of the underlying borrowed asset to repay\\n     * @param skipLiquidityCheck If set to true, allows to liquidate up to 100% of the borrow\\n     *   regardless of the account liquidity\\n     */\\n    function _liquidateBorrowFresh(\\n        address liquidator,\\n        address borrower,\\n        uint256 repayAmount,\\n        VTokenInterface vTokenCollateral,\\n        bool skipLiquidityCheck\\n    ) internal {\\n        /* Fail if liquidate not allowed */\\n        comptroller.preLiquidateHook(\\n            address(this),\\n            address(vTokenCollateral),\\n            borrower,\\n            repayAmount,\\n            skipLiquidityCheck\\n        );\\n\\n        /* Verify market's slot(block or second) number equals current slot(block or second) number */\\n        if (accrualBlockNumber != getBlockNumberOrTimestamp()) {\\n            revert LiquidateFreshnessCheck();\\n        }\\n\\n        /* Verify vTokenCollateral market's slot(block or second) number equals current slot(block or second) number */\\n        if (vTokenCollateral.accrualBlockNumber() != getBlockNumberOrTimestamp()) {\\n            revert LiquidateCollateralFreshnessCheck();\\n        }\\n\\n        /* Fail if borrower = liquidator */\\n        if (borrower == liquidator) {\\n            revert LiquidateLiquidatorIsBorrower();\\n        }\\n\\n        /* Fail if repayAmount = 0 */\\n        if (repayAmount == 0) {\\n            revert LiquidateCloseAmountIsZero();\\n        }\\n\\n        /* Fail if repayAmount = type(uint256).max */\\n        if (repayAmount == type(uint256).max) {\\n            revert LiquidateCloseAmountIsUintMax();\\n        }\\n\\n        /* Fail if repayBorrow fails */\\n        uint256 actualRepayAmount = _repayBorrowFresh(liquidator, borrower, repayAmount);\\n\\n        /////////////////////////\\n        // EFFECTS & INTERACTIONS\\n        // (No safe failures beyond this point)\\n\\n        /* We calculate the number of collateral tokens that will be seized */\\n        (uint256 amountSeizeError, uint256 seizeTokens) = comptroller.liquidateCalculateSeizeTokens(\\n            address(this),\\n            address(vTokenCollateral),\\n            actualRepayAmount\\n        );\\n        require(amountSeizeError == NO_ERROR, \\\"LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED\\\");\\n\\n        /* Revert if borrower collateral token balance < seizeTokens */\\n        require(vTokenCollateral.balanceOf(borrower) >= seizeTokens, \\\"LIQUIDATE_SEIZE_TOO_MUCH\\\");\\n\\n        // If this is also the collateral, call _seize internally to avoid re-entrancy, otherwise make an external call\\n        if (address(vTokenCollateral) == address(this)) {\\n            _seize(address(this), liquidator, borrower, seizeTokens);\\n        } else {\\n            vTokenCollateral.seize(liquidator, borrower, seizeTokens);\\n        }\\n\\n        /* We emit a LiquidateBorrow event */\\n        emit LiquidateBorrow(liquidator, borrower, actualRepayAmount, address(vTokenCollateral), seizeTokens);\\n\\n        /* We call the defense and prime accrue interest hook */\\n        comptroller.liquidateBorrowVerify(\\n            address(this),\\n            address(vTokenCollateral),\\n            liquidator,\\n            borrower,\\n            actualRepayAmount,\\n            seizeTokens\\n        );\\n    }\\n\\n    /**\\n     * @notice Transfers collateral tokens (this market) to the liquidator.\\n     * @dev Called only during an in-kind liquidation, or by liquidateBorrow during the liquidation of another VToken.\\n     *  It's absolutely critical to use msg.sender as the seizer vToken and not a parameter.\\n     * @param seizerContract The contract seizing the collateral (either borrowed vToken or Comptroller)\\n     * @param liquidator The account receiving seized collateral\\n     * @param borrower The account having collateral seized\\n     * @param seizeTokens The number of vTokens to seize\\n     */\\n    function _seize(address seizerContract, address liquidator, address borrower, uint256 seizeTokens) internal {\\n        /* Fail if seize not allowed */\\n        comptroller.preSeizeHook(address(this), seizerContract, liquidator, borrower);\\n\\n        /* Fail if borrower = liquidator */\\n        if (borrower == liquidator) {\\n            revert LiquidateSeizeLiquidatorIsBorrower();\\n        }\\n\\n        /*\\n         * We calculate the new borrower and liquidator token balances, failing on underflow/overflow:\\n         *  borrowerTokensNew = accountTokens[borrower] - seizeTokens\\n         *  liquidatorTokensNew = accountTokens[liquidator] + seizeTokens\\n         */\\n        uint256 liquidationIncentiveMantissa = ComptrollerViewInterface(address(comptroller))\\n            .liquidationIncentiveMantissa();\\n        uint256 numerator = mul_(seizeTokens, Exp({ mantissa: protocolSeizeShareMantissa }));\\n        uint256 protocolSeizeTokens = div_(numerator, Exp({ mantissa: liquidationIncentiveMantissa }));\\n        uint256 liquidatorSeizeTokens = seizeTokens - protocolSeizeTokens;\\n        Exp memory exchangeRate = Exp({ mantissa: _exchangeRateStored() });\\n        uint256 protocolSeizeAmount = mul_ScalarTruncate(exchangeRate, protocolSeizeTokens);\\n\\n        /////////////////////////\\n        // EFFECTS & INTERACTIONS\\n        // (No safe failures beyond this point)\\n\\n        /* We write the calculated values into storage */\\n        totalSupply = totalSupply - protocolSeizeTokens;\\n        accountTokens[borrower] = accountTokens[borrower] - seizeTokens;\\n        accountTokens[liquidator] = accountTokens[liquidator] + liquidatorSeizeTokens;\\n\\n        // _doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n        // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\\n        _doTransferOut(protocolShareReserve, protocolSeizeAmount);\\n\\n        // Update the pool asset's state in the protocol share reserve for the above transfer.\\n        IProtocolShareReserve(protocolShareReserve).updateAssetsState(\\n            address(comptroller),\\n            underlying,\\n            IProtocolShareReserve.IncomeType.LIQUIDATION\\n        );\\n\\n        /* Emit a Transfer event */\\n        emit Transfer(borrower, liquidator, liquidatorSeizeTokens);\\n        emit ProtocolSeize(borrower, protocolShareReserve, protocolSeizeAmount);\\n\\n        /* We call the defense and prime accrue interest hook */\\n        comptroller.seizeVerify(address(this), seizerContract, liquidator, borrower, seizeTokens);\\n    }\\n\\n    function _setComptroller(ComptrollerInterface newComptroller) internal {\\n        ComptrollerInterface oldComptroller = comptroller;\\n        // Ensure invoke comptroller.isComptroller() returns true\\n        require(newComptroller.isComptroller(), \\\"marker method returned false\\\");\\n\\n        // Set market's comptroller to newComptroller\\n        comptroller = newComptroller;\\n\\n        // Emit NewComptroller(oldComptroller, newComptroller)\\n        emit NewComptroller(oldComptroller, newComptroller);\\n    }\\n\\n    /**\\n     * @notice Sets a new reserve factor for the protocol (*requires fresh interest accrual)\\n     * @dev Admin function to set a new reserve factor\\n     * @param newReserveFactorMantissa New reserve factor (from 0 to 1e18)\\n     */\\n    function _setReserveFactorFresh(uint256 newReserveFactorMantissa) internal {\\n        // Verify market's slot(block or second) number equals current slot(block or second) number\\n        if (accrualBlockNumber != getBlockNumberOrTimestamp()) {\\n            revert SetReserveFactorFreshCheck();\\n        }\\n\\n        // Check newReserveFactor \\u2264 maxReserveFactor\\n        if (newReserveFactorMantissa > MAX_RESERVE_FACTOR_MANTISSA) {\\n            revert SetReserveFactorBoundsCheck();\\n        }\\n\\n        uint256 oldReserveFactorMantissa = reserveFactorMantissa;\\n        reserveFactorMantissa = newReserveFactorMantissa;\\n\\n        emit NewReserveFactor(oldReserveFactorMantissa, newReserveFactorMantissa);\\n    }\\n\\n    /**\\n     * @notice Add reserves by transferring from caller\\n     * @dev Requires fresh interest accrual\\n     * @param addAmount Amount of addition to reserves\\n     * @return actualAddAmount The actual amount added, excluding the potential token fees\\n     */\\n    function _addReservesFresh(uint256 addAmount) internal returns (uint256) {\\n        // totalReserves + actualAddAmount\\n        uint256 totalReservesNew;\\n        uint256 actualAddAmount;\\n\\n        // We fail gracefully unless market's slot(block or second) number equals current slot(block or second) number\\n        if (accrualBlockNumber != getBlockNumberOrTimestamp()) {\\n            revert AddReservesFactorFreshCheck(actualAddAmount);\\n        }\\n\\n        actualAddAmount = _doTransferIn(msg.sender, addAmount);\\n        totalReservesNew = totalReserves + actualAddAmount;\\n        totalReserves = totalReservesNew;\\n        emit ReservesAdded(msg.sender, actualAddAmount, totalReservesNew);\\n\\n        return actualAddAmount;\\n    }\\n\\n    /**\\n     * @notice Reduces reserves by transferring to the protocol reserve contract\\n     * @dev Requires fresh interest accrual\\n     * @param reduceAmount Amount of reduction to reserves\\n     */\\n    function _reduceReservesFresh(uint256 reduceAmount) internal {\\n        if (reduceAmount == 0) {\\n            return;\\n        }\\n        // totalReserves - reduceAmount\\n        uint256 totalReservesNew;\\n\\n        // We fail gracefully unless market's slot(block or second) number equals current slot(block or second) number\\n        if (accrualBlockNumber != getBlockNumberOrTimestamp()) {\\n            revert ReduceReservesFreshCheck();\\n        }\\n\\n        // Fail gracefully if protocol has insufficient underlying cash\\n        if (_getCashPrior() < reduceAmount) {\\n            revert ReduceReservesCashNotAvailable();\\n        }\\n\\n        // Check reduceAmount \\u2264 reserves[n] (totalReserves)\\n        if (reduceAmount > totalReserves) {\\n            revert ReduceReservesCashValidation();\\n        }\\n\\n        /////////////////////////\\n        // EFFECTS & INTERACTIONS\\n        // (No safe failures beyond this point)\\n\\n        totalReservesNew = totalReserves - reduceAmount;\\n\\n        // Store reserves[n+1] = reserves[n] - reduceAmount\\n        totalReserves = totalReservesNew;\\n\\n        // _doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.\\n        // Transferring an underlying asset to the protocolShareReserve contract to channel the funds for different use.\\n        _doTransferOut(protocolShareReserve, reduceAmount);\\n\\n        // Update the pool asset's state in the protocol share reserve for the above transfer.\\n        IProtocolShareReserve(protocolShareReserve).updateAssetsState(\\n            address(comptroller),\\n            underlying,\\n            IProtocolShareReserve.IncomeType.SPREAD\\n        );\\n\\n        emit SpreadReservesReduced(protocolShareReserve, reduceAmount, totalReservesNew);\\n    }\\n\\n    /**\\n     * @notice updates the interest rate model (*requires fresh interest accrual)\\n     * @dev Admin function to update the interest rate model\\n     * @param newInterestRateModel the new interest rate model to use\\n     */\\n    function _setInterestRateModelFresh(InterestRateModel newInterestRateModel) internal {\\n        // Used to store old model for use in the event that is emitted on success\\n        InterestRateModel oldInterestRateModel;\\n\\n        // We fail gracefully unless market's slot(block or second) number equals current slot(block or second) number\\n        if (accrualBlockNumber != getBlockNumberOrTimestamp()) {\\n            revert SetInterestRateModelFreshCheck();\\n        }\\n\\n        // Track the market's current interest rate model\\n        oldInterestRateModel = interestRateModel;\\n\\n        // Ensure invoke newInterestRateModel.isInterestRateModel() returns true\\n        require(newInterestRateModel.isInterestRateModel(), \\\"marker method returned false\\\");\\n\\n        // Set the interest rate model to newInterestRateModel\\n        interestRateModel = newInterestRateModel;\\n\\n        // Emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel)\\n        emit NewMarketInterestRateModel(oldInterestRateModel, newInterestRateModel);\\n    }\\n\\n    /**\\n     * Safe Token **\\n     */\\n\\n    /**\\n     * @dev Similar to ERC-20 transfer, but handles tokens that have transfer fees.\\n     *      This function returns the actual amount received,\\n     *      which may be less than `amount` if there is a fee attached to the transfer.\\n     * @param from Sender of the underlying tokens\\n     * @param amount Amount of underlying to transfer\\n     * @return Actual amount received\\n     */\\n    function _doTransferIn(address from, uint256 amount) internal virtual returns (uint256) {\\n        IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n        uint256 balanceBefore = token.balanceOf(address(this));\\n        token.safeTransferFrom(from, address(this), amount);\\n        uint256 balanceAfter = token.balanceOf(address(this));\\n        // Return the amount that was *actually* transferred\\n        return balanceAfter - balanceBefore;\\n    }\\n\\n    /**\\n     * @dev Just a regular ERC-20 transfer, reverts on failure\\n     * @param to Receiver of the underlying tokens\\n     * @param amount Amount of underlying to transfer\\n     */\\n    function _doTransferOut(address to, uint256 amount) internal virtual {\\n        IERC20Upgradeable token = IERC20Upgradeable(underlying);\\n        token.safeTransfer(to, amount);\\n    }\\n\\n    /**\\n     * @notice Transfer `tokens` tokens from `src` to `dst` by `spender`\\n     * @dev Called by both `transfer` and `transferFrom` internally\\n     * @param spender The address of the account performing the transfer\\n     * @param src The address of the source account\\n     * @param dst The address of the destination account\\n     * @param tokens The number of tokens to transfer\\n     */\\n    function _transferTokens(address spender, address src, address dst, uint256 tokens) internal {\\n        /* Fail if transfer not allowed */\\n        comptroller.preTransferHook(address(this), src, dst, tokens);\\n\\n        /* Do not allow self-transfers */\\n        if (src == dst) {\\n            revert TransferNotAllowed();\\n        }\\n\\n        /* Get the allowance, infinite for the account owner */\\n        uint256 startingAllowance;\\n        if (spender == src) {\\n            startingAllowance = type(uint256).max;\\n        } else {\\n            startingAllowance = transferAllowances[src][spender];\\n        }\\n\\n        /* Do the calculations, checking for {under,over}flow */\\n        uint256 allowanceNew = startingAllowance - tokens;\\n        uint256 srcTokensNew = accountTokens[src] - tokens;\\n        uint256 dstTokensNew = accountTokens[dst] + tokens;\\n\\n        /////////////////////////\\n        // EFFECTS & INTERACTIONS\\n\\n        accountTokens[src] = srcTokensNew;\\n        accountTokens[dst] = dstTokensNew;\\n\\n        /* Eat some of the allowance (if necessary) */\\n        if (startingAllowance != type(uint256).max) {\\n            transferAllowances[src][spender] = allowanceNew;\\n        }\\n\\n        /* We emit a Transfer event */\\n        emit Transfer(src, dst, tokens);\\n\\n        comptroller.transferVerify(address(this), src, dst, tokens);\\n    }\\n\\n    /**\\n     * @notice Initialize the money market\\n     * @param underlying_ The address of the underlying asset\\n     * @param comptroller_ The address of the Comptroller\\n     * @param interestRateModel_ The address of the interest rate model\\n     * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18\\n     * @param name_ ERC-20 name of this token\\n     * @param symbol_ ERC-20 symbol of this token\\n     * @param decimals_ ERC-20 decimal precision of this token\\n     * @param admin_ Address of the administrator of this token\\n     * @param accessControlManager_ AccessControlManager contract address\\n     * @param riskManagement Addresses of risk & income related contracts\\n     * @param reserveFactorMantissa_ Percentage of borrow interest that goes to reserves (from 0 to 1e18)\\n     */\\n    function _initialize(\\n        address underlying_,\\n        ComptrollerInterface comptroller_,\\n        InterestRateModel interestRateModel_,\\n        uint256 initialExchangeRateMantissa_,\\n        string memory name_,\\n        string memory symbol_,\\n        uint8 decimals_,\\n        address admin_,\\n        address accessControlManager_,\\n        RiskManagementInit memory riskManagement,\\n        uint256 reserveFactorMantissa_\\n    ) internal onlyInitializing {\\n        __Ownable2Step_init();\\n        __AccessControlled_init_unchained(accessControlManager_);\\n        require(accrualBlockNumber == 0 && borrowIndex == 0, \\\"market may only be initialized once\\\");\\n\\n        // Set initial exchange rate\\n        initialExchangeRateMantissa = initialExchangeRateMantissa_;\\n        require(initialExchangeRateMantissa > 0, \\\"initial exchange rate must be greater than zero.\\\");\\n\\n        _setComptroller(comptroller_);\\n\\n        // Initialize slot(block or second) number and borrow index (slot(block or second) number mocks depend on comptroller being set)\\n        accrualBlockNumber = getBlockNumberOrTimestamp();\\n        borrowIndex = MANTISSA_ONE;\\n\\n        // Set the interest rate model (depends on slot(block or second) number / borrow index)\\n        _setInterestRateModelFresh(interestRateModel_);\\n\\n        _setReserveFactorFresh(reserveFactorMantissa_);\\n\\n        name = name_;\\n        symbol = symbol_;\\n        decimals = decimals_;\\n        _setShortfallContract(riskManagement.shortfall);\\n        _setProtocolShareReserve(riskManagement.protocolShareReserve);\\n        protocolSeizeShareMantissa = DEFAULT_PROTOCOL_SEIZE_SHARE_MANTISSA;\\n\\n        // Set underlying and sanity check it\\n        underlying = underlying_;\\n        IERC20Upgradeable(underlying).totalSupply();\\n\\n        // The counter starts true to prevent changing it from zero to non-zero (i.e. smaller cost/refund)\\n        _notEntered = true;\\n        _transferOwnership(admin_);\\n    }\\n\\n    function _setShortfallContract(address shortfall_) internal {\\n        ensureNonzeroAddress(shortfall_);\\n        address oldShortfall = shortfall;\\n        shortfall = shortfall_;\\n        emit NewShortfallContract(oldShortfall, shortfall_);\\n    }\\n\\n    function _setProtocolShareReserve(address payable protocolShareReserve_) internal {\\n        ensureNonzeroAddress(protocolShareReserve_);\\n        address oldProtocolShareReserve = address(protocolShareReserve);\\n        protocolShareReserve = protocolShareReserve_;\\n        emit NewProtocolShareReserve(oldProtocolShareReserve, address(protocolShareReserve_));\\n    }\\n\\n    function _ensureSenderIsDelegateOf(address user) internal view {\\n        if (!ComptrollerViewInterface(address(comptroller)).approvedDelegates(user, msg.sender)) {\\n            revert DelegateNotApproved();\\n        }\\n    }\\n\\n    /**\\n     * @notice Gets balance of this contract in terms of the underlying\\n     * @dev This excludes the value of the current message, if any\\n     * @return The quantity of underlying tokens owned by this contract\\n     */\\n    function _getCashPrior() internal view virtual returns (uint256) {\\n        return IERC20Upgradeable(underlying).balanceOf(address(this));\\n    }\\n\\n    /**\\n     * @notice Return the borrow balance of account based on stored data\\n     * @param account The address whose balance should be calculated\\n     * @return borrowBalance the calculated balance\\n     */\\n    function _borrowBalanceStored(address account) internal view returns (uint256) {\\n        /* Get borrowBalance and borrowIndex */\\n        BorrowSnapshot memory borrowSnapshot = accountBorrows[account];\\n\\n        /* If borrowBalance = 0 then borrowIndex is likely also 0.\\n         * Rather than failing the calculation with a division by 0, we immediately return 0 in this case.\\n         */\\n        if (borrowSnapshot.principal == 0) {\\n            return 0;\\n        }\\n\\n        /* Calculate new borrow balance using the interest index:\\n         *  recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex\\n         */\\n        uint256 principalTimesIndex = borrowSnapshot.principal * borrowIndex;\\n\\n        return principalTimesIndex / borrowSnapshot.interestIndex;\\n    }\\n\\n    /**\\n     * @notice Calculates the exchange rate from the underlying to the VToken\\n     * @dev This function does not accrue interest before calculating the exchange rate\\n     * @return exchangeRate Calculated exchange rate scaled by 1e18\\n     */\\n    function _exchangeRateStored() internal view virtual returns (uint256) {\\n        uint256 _totalSupply = totalSupply;\\n        if (_totalSupply == 0) {\\n            /*\\n             * If there are no tokens minted:\\n             *  exchangeRate = initialExchangeRate\\n             */\\n            return initialExchangeRateMantissa;\\n        }\\n        /*\\n         * Otherwise:\\n         *  exchangeRate = (totalCash + totalBorrows + badDebt - totalReserves) / totalSupply\\n         */\\n        uint256 totalCash = _getCashPrior();\\n        uint256 cashPlusBorrowsMinusReserves = totalCash + totalBorrows + badDebt - totalReserves;\\n        uint256 exchangeRate = (cashPlusBorrowsMinusReserves * EXP_SCALE) / _totalSupply;\\n\\n        return exchangeRate;\\n    }\\n}\\n\",\"keccak256\":\"0xa220ca317fe69b920b86e43f054c43b5f891f12160fd312c9a21668f969ee056\",\"license\":\"BSD-3-Clause\"},\"contracts/VTokenInterfaces.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\nimport { ComptrollerInterface } from \\\"./ComptrollerInterface.sol\\\";\\nimport { InterestRateModel } from \\\"./InterestRateModel.sol\\\";\\n\\n/**\\n * @title VTokenStorage\\n * @author Venus\\n * @notice Storage layout used by the `VToken` contract\\n */\\n// solhint-disable-next-line max-states-count\\ncontract VTokenStorage {\\n    /**\\n     * @notice Container for borrow balance information\\n     * @member principal Total balance (with accrued interest), after applying the most recent balance-changing action\\n     * @member interestIndex Global borrowIndex as of the most recent balance-changing action\\n     */\\n    struct BorrowSnapshot {\\n        uint256 principal;\\n        uint256 interestIndex;\\n    }\\n\\n    /**\\n     * @dev Guard variable for re-entrancy checks\\n     */\\n    bool internal _notEntered;\\n\\n    /**\\n     * @notice Underlying asset for this VToken\\n     */\\n    address public underlying;\\n\\n    /**\\n     * @notice EIP-20 token name for this token\\n     */\\n    string public name;\\n\\n    /**\\n     * @notice EIP-20 token symbol for this token\\n     */\\n    string public symbol;\\n\\n    /**\\n     * @notice EIP-20 token decimals for this token\\n     */\\n    uint8 public decimals;\\n\\n    /**\\n     * @notice Protocol share Reserve contract address\\n     */\\n    address payable public protocolShareReserve;\\n\\n    /**\\n     * @notice Contract which oversees inter-vToken operations\\n     */\\n    ComptrollerInterface public comptroller;\\n\\n    /**\\n     * @notice Model which tells what the current interest rate should be\\n     */\\n    InterestRateModel public interestRateModel;\\n\\n    // Initial exchange rate used when minting the first VTokens (used when totalSupply = 0)\\n    uint256 internal initialExchangeRateMantissa;\\n\\n    /**\\n     * @notice Fraction of interest currently set aside for reserves\\n     */\\n    uint256 public reserveFactorMantissa;\\n\\n    /**\\n     * @notice Slot(block or second) number that interest was last accrued at\\n     */\\n    uint256 public accrualBlockNumber;\\n\\n    /**\\n     * @notice Accumulator of the total earned interest rate since the opening of the market\\n     */\\n    uint256 public borrowIndex;\\n\\n    /**\\n     * @notice Total amount of outstanding borrows of the underlying in this market\\n     */\\n    uint256 public totalBorrows;\\n\\n    /**\\n     * @notice Total amount of reserves of the underlying held in this market\\n     */\\n    uint256 public totalReserves;\\n\\n    /**\\n     * @notice Total number of tokens in circulation\\n     */\\n    uint256 public totalSupply;\\n\\n    /**\\n     * @notice Total bad debt of the market\\n     */\\n    uint256 public badDebt;\\n\\n    // Official record of token balances for each account\\n    mapping(address => uint256) internal accountTokens;\\n\\n    // Approved token transfer amounts on behalf of others\\n    mapping(address => mapping(address => uint256)) internal transferAllowances;\\n\\n    // Mapping of account addresses to outstanding borrow balances\\n    mapping(address => BorrowSnapshot) internal accountBorrows;\\n\\n    /**\\n     * @notice Share of seized collateral that is added to reserves\\n     */\\n    uint256 public protocolSeizeShareMantissa;\\n\\n    /**\\n     * @notice Storage of Shortfall contract address\\n     */\\n    address public shortfall;\\n\\n    /**\\n     * @notice delta slot (block or second) after which reserves will be reduced\\n     */\\n    uint256 public reduceReservesBlockDelta;\\n\\n    /**\\n     * @notice last slot (block or second) number at which reserves were reduced\\n     */\\n    uint256 public reduceReservesBlockNumber;\\n\\n    /**\\n     * @dev This empty reserved space is put in place to allow future versions to add new\\n     * variables without shifting down storage in the inheritance chain.\\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n     */\\n    uint256[48] private __gap;\\n}\\n\\n/**\\n * @title VTokenInterface\\n * @author Venus\\n * @notice Interface implemented by the `VToken` contract\\n */\\nabstract contract VTokenInterface is VTokenStorage {\\n    struct RiskManagementInit {\\n        address shortfall;\\n        address payable protocolShareReserve;\\n    }\\n\\n    /*** Market Events ***/\\n\\n    /**\\n     * @notice Event emitted when interest is accrued\\n     */\\n    event AccrueInterest(uint256 cashPrior, uint256 interestAccumulated, uint256 borrowIndex, uint256 totalBorrows);\\n\\n    /**\\n     * @notice Event emitted when tokens are minted\\n     */\\n    event Mint(address indexed minter, uint256 mintAmount, uint256 mintTokens, uint256 accountBalance);\\n\\n    /**\\n     * @notice Event emitted when tokens are redeemed\\n     */\\n    event Redeem(address indexed redeemer, uint256 redeemAmount, uint256 redeemTokens, uint256 accountBalance);\\n\\n    /**\\n     * @notice Event emitted when underlying is borrowed\\n     */\\n    event Borrow(address indexed borrower, uint256 borrowAmount, uint256 accountBorrows, uint256 totalBorrows);\\n\\n    /**\\n     * @notice Event emitted when a borrow is repaid\\n     */\\n    event RepayBorrow(\\n        address indexed payer,\\n        address indexed borrower,\\n        uint256 repayAmount,\\n        uint256 accountBorrows,\\n        uint256 totalBorrows\\n    );\\n\\n    /**\\n     * @notice Event emitted when bad debt is accumulated on a market\\n     * @param borrower borrower to \\\"forgive\\\"\\n     * @param badDebtDelta amount of new bad debt recorded\\n     * @param badDebtOld previous bad debt value\\n     * @param badDebtNew new bad debt value\\n     */\\n    event BadDebtIncreased(address indexed borrower, uint256 badDebtDelta, uint256 badDebtOld, uint256 badDebtNew);\\n\\n    /**\\n     * @notice Event emitted when bad debt is recovered via an auction\\n     * @param badDebtOld previous bad debt value\\n     * @param badDebtNew new bad debt value\\n     */\\n    event BadDebtRecovered(uint256 badDebtOld, uint256 badDebtNew);\\n\\n    /**\\n     * @notice Event emitted when a borrow is liquidated\\n     */\\n    event LiquidateBorrow(\\n        address indexed liquidator,\\n        address indexed borrower,\\n        uint256 repayAmount,\\n        address indexed vTokenCollateral,\\n        uint256 seizeTokens\\n    );\\n\\n    /*** Admin Events ***/\\n\\n    /**\\n     * @notice Event emitted when comptroller is changed\\n     */\\n    event NewComptroller(ComptrollerInterface indexed oldComptroller, ComptrollerInterface indexed newComptroller);\\n\\n    /**\\n     * @notice Event emitted when shortfall contract address is changed\\n     */\\n    event NewShortfallContract(address indexed oldShortfall, address indexed newShortfall);\\n\\n    /**\\n     * @notice Event emitted when protocol share reserve contract address is changed\\n     */\\n    event NewProtocolShareReserve(address indexed oldProtocolShareReserve, address indexed newProtocolShareReserve);\\n\\n    /**\\n     * @notice Event emitted when interestRateModel is changed\\n     */\\n    event NewMarketInterestRateModel(\\n        InterestRateModel indexed oldInterestRateModel,\\n        InterestRateModel indexed newInterestRateModel\\n    );\\n\\n    /**\\n     * @notice Event emitted when protocol seize share is changed\\n     */\\n    event NewProtocolSeizeShare(uint256 oldProtocolSeizeShareMantissa, uint256 newProtocolSeizeShareMantissa);\\n\\n    /**\\n     * @notice Event emitted when the reserve factor is changed\\n     */\\n    event NewReserveFactor(uint256 oldReserveFactorMantissa, uint256 newReserveFactorMantissa);\\n\\n    /**\\n     * @notice Event emitted when the reserves are added\\n     */\\n    event ReservesAdded(address indexed benefactor, uint256 addAmount, uint256 newTotalReserves);\\n\\n    /**\\n     * @notice Event emitted when the spread reserves are reduced\\n     */\\n    event SpreadReservesReduced(address indexed protocolShareReserve, uint256 reduceAmount, uint256 newTotalReserves);\\n\\n    /**\\n     * @notice EIP20 Transfer event\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n    /**\\n     * @notice EIP20 Approval event\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n    /**\\n     * @notice Event emitted when healing the borrow\\n     */\\n    event HealBorrow(address indexed payer, address indexed borrower, uint256 repayAmount);\\n\\n    /**\\n     * @notice Event emitted when tokens are swept\\n     */\\n    event SweepToken(address indexed token);\\n\\n    /**\\n     * @notice Event emitted when reduce reserves slot (block or second) delta is changed\\n     */\\n    event NewReduceReservesBlockDelta(\\n        uint256 oldReduceReservesBlockOrTimestampDelta,\\n        uint256 newReduceReservesBlockOrTimestampDelta\\n    );\\n\\n    /**\\n     * @notice Event emitted when liquidation reserves are reduced\\n     */\\n    event ProtocolSeize(address indexed from, address indexed to, uint256 amount);\\n\\n    /*** User Interface ***/\\n\\n    function mint(uint256 mintAmount) external virtual returns (uint256);\\n\\n    function mintBehalf(address minter, uint256 mintAllowed) external virtual returns (uint256);\\n\\n    function redeem(uint256 redeemTokens) external virtual returns (uint256);\\n\\n    function redeemBehalf(address redeemer, uint256 redeemTokens) external virtual returns (uint256);\\n\\n    function redeemUnderlying(uint256 redeemAmount) external virtual returns (uint256);\\n\\n    function redeemUnderlyingBehalf(address redeemer, uint256 redeemAmount) external virtual returns (uint256);\\n\\n    function borrow(uint256 borrowAmount) external virtual returns (uint256);\\n\\n    function borrowBehalf(address borrwwer, uint256 borrowAmount) external virtual returns (uint256);\\n\\n    function repayBorrow(uint256 repayAmount) external virtual returns (uint256);\\n\\n    function repayBorrowBehalf(address borrower, uint256 repayAmount) external virtual returns (uint256);\\n\\n    function liquidateBorrow(\\n        address borrower,\\n        uint256 repayAmount,\\n        VTokenInterface vTokenCollateral\\n    ) external virtual returns (uint256);\\n\\n    function healBorrow(address payer, address borrower, uint256 repayAmount) external virtual;\\n\\n    function forceLiquidateBorrow(\\n        address liquidator,\\n        address borrower,\\n        uint256 repayAmount,\\n        VTokenInterface vTokenCollateral,\\n        bool skipCloseFactorCheck\\n    ) external virtual;\\n\\n    function seize(address liquidator, address borrower, uint256 seizeTokens) external virtual;\\n\\n    function transfer(address dst, uint256 amount) external virtual returns (bool);\\n\\n    function transferFrom(address src, address dst, uint256 amount) external virtual returns (bool);\\n\\n    function accrueInterest() external virtual returns (uint256);\\n\\n    function sweepToken(IERC20Upgradeable token) external virtual;\\n\\n    /*** Admin Functions ***/\\n\\n    function setReserveFactor(uint256 newReserveFactorMantissa) external virtual;\\n\\n    function reduceReserves(uint256 reduceAmount) external virtual;\\n\\n    function exchangeRateCurrent() external virtual returns (uint256);\\n\\n    function borrowBalanceCurrent(address account) external virtual returns (uint256);\\n\\n    function setInterestRateModel(InterestRateModel newInterestRateModel) external virtual;\\n\\n    function addReserves(uint256 addAmount) external virtual;\\n\\n    function totalBorrowsCurrent() external virtual returns (uint256);\\n\\n    function balanceOfUnderlying(address owner) external virtual returns (uint256);\\n\\n    function approve(address spender, uint256 amount) external virtual returns (bool);\\n\\n    function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool);\\n\\n    function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool);\\n\\n    function allowance(address owner, address spender) external view virtual returns (uint256);\\n\\n    function balanceOf(address owner) external view virtual returns (uint256);\\n\\n    function getAccountSnapshot(address account) external view virtual returns (uint256, uint256, uint256, uint256);\\n\\n    function borrowRatePerBlock() external view virtual returns (uint256);\\n\\n    function supplyRatePerBlock() external view virtual returns (uint256);\\n\\n    function borrowBalanceStored(address account) external view virtual returns (uint256);\\n\\n    function exchangeRateStored() external view virtual returns (uint256);\\n\\n    function getCash() external view virtual returns (uint256);\\n\\n    /**\\n     * @notice Indicator that this is a VToken contract (for inspection)\\n     * @return Always true\\n     */\\n    function isVToken() external pure virtual returns (bool) {\\n        return true;\\n    }\\n}\\n\",\"keccak256\":\"0x7c4cbb879e3a931cfee4fa7a9eb1978eddff18087a1c4f56decedb84c2479f1e\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/constants.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\n/// @dev The approximate number of seconds per year\\nuint256 constant SECONDS_PER_YEAR = 31_536_000;\\n\\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\\nuint256 constant EXP_SCALE = 1e18;\\n\\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\\nuint256 constant MANTISSA_ONE = EXP_SCALE;\\n\",\"keccak256\":\"0x54ab3a6f3bc87569ed12370f3470a1ec84cea9796d4d0ccf3d07dd4280c044aa\",\"license\":\"BSD-3-Clause\"},\"contracts/lib/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n    if (address_ == address(0)) {\\n        revert ZeroAddressNotAllowed();\\n    }\\n}\\n\",\"keccak256\":\"0x93bdd5cfb100f0f9a1d446857e23c3633df6ab12c266333c978428edd96b1367\",\"license\":\"BSD-3-Clause\"}},\"version\":1}",
  "bytecode": "0x6080604052348015600f57600080fd5b506016601a565b60d7565b600054610100900460ff161560855760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161460d5576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b611d31806100e66000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c8063afcff50f116100a2578063be26317e11610071578063be26317e1461024f578063e30c397814610258578063e521136f14610269578063f2fde38b1461027c578063f7013ef61461028f57600080fd5b8063afcff50f146101cd578063b4a0bdf3146101e0578063b599410a146101f1578063ba9a91a51461021a57600080fd5b806379ba5097116100e957806379ba50971461017b57806380d45a2d146101835780638da5cb5b14610196578063a9e50471146101a7578063abeccaa4146101ba57600080fd5b80630e32cb861461011b57806317f333401461013057806359659e9014610160578063715018a614610173575b600080fd5b61012e610129366004610f66565b6102a2565b005b60fd54610143906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b60fb54610143906001600160a01b031681565b61012e6102b6565b61012e6102ca565b61012e610191366004610f8a565b610346565b6033546001600160a01b0316610143565b6101436101b5366004610f66565b61038d565b6101436101c8366004610f66565b6104d4565b60fc54610143906001600160a01b031681565b6097546001600160a01b0316610143565b6101436101ff366004610f66565b60fe602052600090815260409020546001600160a01b031681565b6102417f1991af52b18eb46fa8c9d75910fd649338d33ba3882cfe1e1afbc13a3b4df5b981565b604051908152602001610157565b61024160c95481565b6065546001600160a01b0316610143565b61012e610277366004610f66565b61083d565b61012e61028a366004610f66565b6108e0565b61012e61029d366004610fa3565b610951565b6102aa610b8f565b6102b381610be9565b50565b6102be610b8f565b6102c86000610caf565b565b60655433906001600160a01b0316811461033d5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b6102b381610caf565b6103846040518060400160405280601981526020017f7365744d61784c6f6f70734c696d69742875696e743235362900000000000000815250610cc8565b6102b381610d66565b600060ff60f81b307f1991af52b18eb46fa8c9d75910fd649338d33ba3882cfe1e1afbc13a3b4df5b9604051806020016103c690610f37565b601f1982820381018352601f90910116604081905260fb546001600160a01b038881166024840152169063189acdbd60e31b9060440160408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b0319909516949094179093525161043b939201611057565b60408051601f19818403018152908290526104599291602001611083565b604051602081830303815290604052805190602001206040516020016104b694939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051601f19818403018152919052805160209091012092915050565b60006104df82610e00565b6001600160a01b03828116600090815260fe6020526040902054161561051857604051634fa32ea760e01b815260040160405180910390fd5b60008290506000816001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561055d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058191906110b2565b905060fc60009054906101000a90046001600160a01b03166001600160a01b031663266e0a7f82846001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060a91906110b2565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015610655573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067991906110b2565b6001600160a01b0316846001600160a01b0316146106aa57604051630a74323b60e21b815260040160405180910390fd5b60fb54604080516001600160a01b0387811660248084019190915283518084039091018152604490920183526020820180516001600160e01b031663189acdbd60e31b17905291516000937f1991af52b18eb46fa8c9d75910fd649338d33ba3882cfe1e1afbc13a3b4df5b99316919061072390610f37565b61072e929190611057565b8190604051809103906000f590508015801561074e573d6000803e3d6000fd5b5060975460fd5460c954603354604080516320f08d2d60e11b81526001600160a01b039586166004820152938516602485015260448401929092528316606483015251929350908316916341e11a5a9160848082019260009290919082900301818387803b1580156107bf57600080fd5b505af11580156107d3573d6000803e3d6000fd5b505050506001600160a01b03858116600090815260fe602052604080822080546001600160a01b0319168585169081179091559051939650869390928616917fcbd4e5d1362721c7fd10daaabb1a046344447d4798be55684b8a6b4fc1765d7291a3505050919050565b61087b6040518060400160405280601b81526020017f736574526577617264526563697069656e742861646472657373290000000000815250610cc8565b61088481610e00565b60fd546040516001600160a01b038084169216907fc8c11bb97ac2ffa10ce2e2a98f4c1fd8df84cfa2e1a15e013ed2383ab1f527ad90600090a360fd80546001600160a01b0319166001600160a01b0392909216919091179055565b6108e8610b8f565b606580546001600160a01b0383166001600160a01b031990911681179091556109196033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600054610100900460ff16158080156109715750600054600160ff909116105b8061098b5750303b15801561098b575060005460ff166001145b6109ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610334565b6000805460ff191660011790558015610a11576000805461ff0019166101001790555b610a1a86610e00565b610a2385610e00565b610a2c84610e00565b610a3583610e00565b610a3e86610e27565b60fc80546001600160a01b038088166001600160a01b03199283161790925560fd805492871692909116919091179055610a7782610d66565b82604051610a8490610f44565b6001600160a01b039091168152602001604051809103906000f080158015610ab0573d6000803e3d6000fd5b5060fb80546001600160a01b03929092166001600160a01b03199092168217905563f2fde38b610ae86033546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b158015610b2957600080fd5b505af1158015610b3d573d6000803e3d6000fd5b505050508015610b87576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6033546001600160a01b031633146102c85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610334565b6001600160a01b038116610c4d5760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b6064820152608401610334565b609780546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa091015b60405180910390a15050565b606580546001600160a01b03191690556102b381610e5f565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab90610cfb9033908690600401611057565b602060405180830381865afa158015610d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3c91906110cf565b905080610d6257333083604051634a3fa29360e01b8152600401610334939291906110f1565b5050565b60c9548111610dc25760405162461bcd60e51b815260206004820152602260248201527f436f6d7074726f6c6c65723a20496e76616c6964206d61784c6f6f70734c696d6044820152611a5d60f21b6064820152608401610334565b60c980549082905560408051828152602081018490527fc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa9101610ca3565b6001600160a01b0381166102b3576040516342bcdf7f60e11b815260040160405180910390fd5b600054610100900460ff16610e4e5760405162461bcd60e51b815260040161033490611126565b610e56610eb1565b6102b381610ee0565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610ed85760405162461bcd60e51b815260040161033490611126565b6102c8610f07565b600054610100900460ff166102aa5760405162461bcd60e51b815260040161033490611126565b600054610100900460ff16610f2e5760405162461bcd60e51b815260040161033490611126565b6102c833610caf565b6106cc8061117283390190565b6104be8061183e83390190565b6001600160a01b03811681146102b357600080fd5b600060208284031215610f7857600080fd5b8135610f8381610f51565b9392505050565b600060208284031215610f9c57600080fd5b5035919050565b600080600080600060a08688031215610fbb57600080fd5b8535610fc681610f51565b94506020860135610fd681610f51565b93506040860135610fe681610f51565b92506060860135610ff681610f51565b949793965091946080013592915050565b60005b8381101561102257818101518382015260200161100a565b50506000910152565b60008151808452611043816020860160208601611007565b601f01601f19169290920160200192915050565b6001600160a01b038316815260406020820181905260009061107b9083018461102b565b949350505050565b60008351611095818460208801611007565b8351908301906110a9818360208801611007565b01949350505050565b6000602082840312156110c457600080fd5b8151610f8381610f51565b6000602082840312156110e157600080fd5b81518015158114610f8357600080fd5b6001600160a01b0384811682528316602082015260606040820181905260009061111d9083018461102b565b95945050505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fe60806040526040516106cc3803806106cc83398101604081905261002291610420565b61002e82826000610035565b505061054a565b61003e836100f6565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100f1576100ef836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e991906104e0565b8361027a565b505b505050565b6001600160a01b0381163b6101605760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101d4816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c591906104e0565b6001600160a01b03163b151590565b6102395760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610157565b7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b0392909216919091179055565b606061029f83836040518060600160405280602781526020016106a5602791396102a6565b9392505050565b6060600080856001600160a01b0316856040516102c391906104fb565b600060405180830381855af49150503d80600081146102fe576040519150601f19603f3d011682016040523d82523d6000602084013e610303565b606091505b5090925090506103158683838761031f565b9695505050505050565b6060831561038e578251600003610387576001600160a01b0385163b6103875760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610157565b5081610398565b61039883836103a0565b949350505050565b8151156103b05781518083602001fd5b8060405162461bcd60e51b81526004016101579190610517565b80516001600160a01b03811681146103e157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156104175781810151838201526020016103ff565b50506000910152565b6000806040838503121561043357600080fd5b61043c836103ca565b60208401519092506001600160401b038082111561045957600080fd5b818501915085601f83011261046d57600080fd5b81518181111561047f5761047f6103e6565b604051601f8201601f19908116603f011681019083821181831017156104a7576104a76103e6565b816040528281528860208487010111156104c057600080fd5b6104d18360208301602088016103fc565b80955050505050509250929050565b6000602082840312156104f257600080fd5b61029f826103ca565b6000825161050d8184602087016103fc565b9190910192915050565b60208152600082518060208401526105368160408501602087016103fc565b601f01601f19169190910160400192915050565b61014c806105596000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610029565b6100c2565b565b600061005c7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bd91906100e6565b905090565b3660008037600080366000845af43d6000803e8080156100e1573d6000f35b3d6000fd5b6000602082840312156100f857600080fd5b81516001600160a01b038116811461010f57600080fd5b939250505056fea264697066735822122046b4f5e91a9c4ce5899089d64fe12e498987ddec7b0ba224fa5caa490cf7c92464736f6c63430008190033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564608060405234801561001057600080fd5b506040516104be3803806104be83398101604081905261002f9161013a565b61003833610047565b61004181610097565b5061016a565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381163b6101185760405162461bcd60e51b815260206004820152603360248201527f5570677261646561626c65426561636f6e3a20696d706c656d656e746174696f60448201527f6e206973206e6f74206120636f6e747261637400000000000000000000000000606482015260840160405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60006020828403121561014c57600080fd5b81516001600160a01b038116811461016357600080fd5b9392505050565b610345806101796000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80633659cfe61461005c5780635c60da1b14610071578063715018a61461009a5780638da5cb5b146100a2578063f2fde38b146100b3575b600080fd5b61006f61006a3660046102df565b6100c6565b005b6001546001600160a01b03165b6040516001600160a01b03909116815260200160405180910390f35b61006f61010e565b6000546001600160a01b031661007e565b61006f6100c13660046102df565b610122565b6100ce6101a0565b6100d7816101fa565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6101166101a0565b610120600061028f565b565b61012a6101a0565b6001600160a01b0381166101945760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61019d8161028f565b50565b6000546001600160a01b031633146101205760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161018b565b6001600160a01b0381163b61026d5760405162461bcd60e51b815260206004820152603360248201527f5570677261646561626c65426561636f6e3a20696d706c656d656e746174696f6044820152721b881a5cc81b9bdd08184818dbdb9d1c9858dd606a1b606482015260840161018b565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156102f157600080fd5b81356001600160a01b038116811461030857600080fd5b939250505056fea2646970667358221220d545fd9e5dad1533895a65b3a05d1e6f1c1c47d5577fa2c59eec7f8e53dae96b64736f6c63430008190033a2646970667358221220c7d36e1e7efe73208a00c52d44ea45baa78bb15774848082ddb263481e408f8364736f6c63430008190033",
  "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c8063afcff50f116100a2578063be26317e11610071578063be26317e1461024f578063e30c397814610258578063e521136f14610269578063f2fde38b1461027c578063f7013ef61461028f57600080fd5b8063afcff50f146101cd578063b4a0bdf3146101e0578063b599410a146101f1578063ba9a91a51461021a57600080fd5b806379ba5097116100e957806379ba50971461017b57806380d45a2d146101835780638da5cb5b14610196578063a9e50471146101a7578063abeccaa4146101ba57600080fd5b80630e32cb861461011b57806317f333401461013057806359659e9014610160578063715018a614610173575b600080fd5b61012e610129366004610f66565b6102a2565b005b60fd54610143906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b60fb54610143906001600160a01b031681565b61012e6102b6565b61012e6102ca565b61012e610191366004610f8a565b610346565b6033546001600160a01b0316610143565b6101436101b5366004610f66565b61038d565b6101436101c8366004610f66565b6104d4565b60fc54610143906001600160a01b031681565b6097546001600160a01b0316610143565b6101436101ff366004610f66565b60fe602052600090815260409020546001600160a01b031681565b6102417f1991af52b18eb46fa8c9d75910fd649338d33ba3882cfe1e1afbc13a3b4df5b981565b604051908152602001610157565b61024160c95481565b6065546001600160a01b0316610143565b61012e610277366004610f66565b61083d565b61012e61028a366004610f66565b6108e0565b61012e61029d366004610fa3565b610951565b6102aa610b8f565b6102b381610be9565b50565b6102be610b8f565b6102c86000610caf565b565b60655433906001600160a01b0316811461033d5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b6102b381610caf565b6103846040518060400160405280601981526020017f7365744d61784c6f6f70734c696d69742875696e743235362900000000000000815250610cc8565b6102b381610d66565b600060ff60f81b307f1991af52b18eb46fa8c9d75910fd649338d33ba3882cfe1e1afbc13a3b4df5b9604051806020016103c690610f37565b601f1982820381018352601f90910116604081905260fb546001600160a01b038881166024840152169063189acdbd60e31b9060440160408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b0319909516949094179093525161043b939201611057565b60408051601f19818403018152908290526104599291602001611083565b604051602081830303815290604052805190602001206040516020016104b694939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051601f19818403018152919052805160209091012092915050565b60006104df82610e00565b6001600160a01b03828116600090815260fe6020526040902054161561051857604051634fa32ea760e01b815260040160405180910390fd5b60008290506000816001600160a01b0316635fe3b5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561055d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058191906110b2565b905060fc60009054906101000a90046001600160a01b03166001600160a01b031663266e0a7f82846001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060a91906110b2565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015610655573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067991906110b2565b6001600160a01b0316846001600160a01b0316146106aa57604051630a74323b60e21b815260040160405180910390fd5b60fb54604080516001600160a01b0387811660248084019190915283518084039091018152604490920183526020820180516001600160e01b031663189acdbd60e31b17905291516000937f1991af52b18eb46fa8c9d75910fd649338d33ba3882cfe1e1afbc13a3b4df5b99316919061072390610f37565b61072e929190611057565b8190604051809103906000f590508015801561074e573d6000803e3d6000fd5b5060975460fd5460c954603354604080516320f08d2d60e11b81526001600160a01b039586166004820152938516602485015260448401929092528316606483015251929350908316916341e11a5a9160848082019260009290919082900301818387803b1580156107bf57600080fd5b505af11580156107d3573d6000803e3d6000fd5b505050506001600160a01b03858116600090815260fe602052604080822080546001600160a01b0319168585169081179091559051939650869390928616917fcbd4e5d1362721c7fd10daaabb1a046344447d4798be55684b8a6b4fc1765d7291a3505050919050565b61087b6040518060400160405280601b81526020017f736574526577617264526563697069656e742861646472657373290000000000815250610cc8565b61088481610e00565b60fd546040516001600160a01b038084169216907fc8c11bb97ac2ffa10ce2e2a98f4c1fd8df84cfa2e1a15e013ed2383ab1f527ad90600090a360fd80546001600160a01b0319166001600160a01b0392909216919091179055565b6108e8610b8f565b606580546001600160a01b0383166001600160a01b031990911681179091556109196033546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600054610100900460ff16158080156109715750600054600160ff909116105b8061098b5750303b15801561098b575060005460ff166001145b6109ee5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610334565b6000805460ff191660011790558015610a11576000805461ff0019166101001790555b610a1a86610e00565b610a2385610e00565b610a2c84610e00565b610a3583610e00565b610a3e86610e27565b60fc80546001600160a01b038088166001600160a01b03199283161790925560fd805492871692909116919091179055610a7782610d66565b82604051610a8490610f44565b6001600160a01b039091168152602001604051809103906000f080158015610ab0573d6000803e3d6000fd5b5060fb80546001600160a01b03929092166001600160a01b03199092168217905563f2fde38b610ae86033546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b158015610b2957600080fd5b505af1158015610b3d573d6000803e3d6000fd5b505050508015610b87576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6033546001600160a01b031633146102c85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610334565b6001600160a01b038116610c4d5760405162461bcd60e51b815260206004820152602560248201527f696e76616c696420616365737320636f6e74726f6c206d616e61676572206164604482015264647265737360d81b6064820152608401610334565b609780546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa091015b60405180910390a15050565b606580546001600160a01b03191690556102b381610e5f565b6097546040516318c5e8ab60e01b81526000916001600160a01b0316906318c5e8ab90610cfb9033908690600401611057565b602060405180830381865afa158015610d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3c91906110cf565b905080610d6257333083604051634a3fa29360e01b8152600401610334939291906110f1565b5050565b60c9548111610dc25760405162461bcd60e51b815260206004820152602260248201527f436f6d7074726f6c6c65723a20496e76616c6964206d61784c6f6f70734c696d6044820152611a5d60f21b6064820152608401610334565b60c980549082905560408051828152602081018490527fc2d09fef144f7c8a86f71ea459f8fc17f675768eb1ae369cbd77fb31d467aafa9101610ca3565b6001600160a01b0381166102b3576040516342bcdf7f60e11b815260040160405180910390fd5b600054610100900460ff16610e4e5760405162461bcd60e51b815260040161033490611126565b610e56610eb1565b6102b381610ee0565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16610ed85760405162461bcd60e51b815260040161033490611126565b6102c8610f07565b600054610100900460ff166102aa5760405162461bcd60e51b815260040161033490611126565b600054610100900460ff16610f2e5760405162461bcd60e51b815260040161033490611126565b6102c833610caf565b6106cc8061117283390190565b6104be8061183e83390190565b6001600160a01b03811681146102b357600080fd5b600060208284031215610f7857600080fd5b8135610f8381610f51565b9392505050565b600060208284031215610f9c57600080fd5b5035919050565b600080600080600060a08688031215610fbb57600080fd5b8535610fc681610f51565b94506020860135610fd681610f51565b93506040860135610fe681610f51565b92506060860135610ff681610f51565b949793965091946080013592915050565b60005b8381101561102257818101518382015260200161100a565b50506000910152565b60008151808452611043816020860160208601611007565b601f01601f19169290920160200192915050565b6001600160a01b038316815260406020820181905260009061107b9083018461102b565b949350505050565b60008351611095818460208801611007565b8351908301906110a9818360208801611007565b01949350505050565b6000602082840312156110c457600080fd5b8151610f8381610f51565b6000602082840312156110e157600080fd5b81518015158114610f8357600080fd5b6001600160a01b0384811682528316602082015260606040820181905260009061111d9083018461102b565b95945050505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fe60806040526040516106cc3803806106cc83398101604081905261002291610420565b61002e82826000610035565b505061054a565b61003e836100f6565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100f1576100ef836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e991906104e0565b8361027a565b505b505050565b6001600160a01b0381163b6101605760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101d4816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c591906104e0565b6001600160a01b03163b151590565b6102395760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610157565b7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b0392909216919091179055565b606061029f83836040518060600160405280602781526020016106a5602791396102a6565b9392505050565b6060600080856001600160a01b0316856040516102c391906104fb565b600060405180830381855af49150503d80600081146102fe576040519150601f19603f3d011682016040523d82523d6000602084013e610303565b606091505b5090925090506103158683838761031f565b9695505050505050565b6060831561038e578251600003610387576001600160a01b0385163b6103875760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610157565b5081610398565b61039883836103a0565b949350505050565b8151156103b05781518083602001fd5b8060405162461bcd60e51b81526004016101579190610517565b80516001600160a01b03811681146103e157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156104175781810151838201526020016103ff565b50506000910152565b6000806040838503121561043357600080fd5b61043c836103ca565b60208401519092506001600160401b038082111561045957600080fd5b818501915085601f83011261046d57600080fd5b81518181111561047f5761047f6103e6565b604051601f8201601f19908116603f011681019083821181831017156104a7576104a76103e6565b816040528281528860208487010111156104c057600080fd5b6104d18360208301602088016103fc565b80955050505050509250929050565b6000602082840312156104f257600080fd5b61029f826103ca565b6000825161050d8184602087016103fc565b9190910192915050565b60208152600082518060208401526105368160408501602087016103fc565b601f01601f19169190910160400192915050565b61014c806105596000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610029565b6100c2565b565b600061005c7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bd91906100e6565b905090565b3660008037600080366000845af43d6000803e8080156100e1573d6000f35b3d6000fd5b6000602082840312156100f857600080fd5b81516001600160a01b038116811461010f57600080fd5b939250505056fea264697066735822122046b4f5e91a9c4ce5899089d64fe12e498987ddec7b0ba224fa5caa490cf7c92464736f6c63430008190033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564608060405234801561001057600080fd5b506040516104be3803806104be83398101604081905261002f9161013a565b61003833610047565b61004181610097565b5061016a565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381163b6101185760405162461bcd60e51b815260206004820152603360248201527f5570677261646561626c65426561636f6e3a20696d706c656d656e746174696f60448201527f6e206973206e6f74206120636f6e747261637400000000000000000000000000606482015260840160405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60006020828403121561014c57600080fd5b81516001600160a01b038116811461016357600080fd5b9392505050565b610345806101796000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80633659cfe61461005c5780635c60da1b14610071578063715018a61461009a5780638da5cb5b146100a2578063f2fde38b146100b3575b600080fd5b61006f61006a3660046102df565b6100c6565b005b6001546001600160a01b03165b6040516001600160a01b03909116815260200160405180910390f35b61006f61010e565b6000546001600160a01b031661007e565b61006f6100c13660046102df565b610122565b6100ce6101a0565b6100d7816101fa565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6101166101a0565b610120600061028f565b565b61012a6101a0565b6001600160a01b0381166101945760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61019d8161028f565b50565b6000546001600160a01b031633146101205760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161018b565b6001600160a01b0381163b61026d5760405162461bcd60e51b815260206004820152603360248201527f5570677261646561626c65426561636f6e3a20696d706c656d656e746174696f6044820152721b881a5cc81b9bdd08184818dbdb9d1c9858dd606a1b606482015260840161018b565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156102f157600080fd5b81356001600160a01b038116811461030857600080fd5b939250505056fea2646970667358221220d545fd9e5dad1533895a65b3a05d1e6f1c1c47d5577fa2c59eec7f8e53dae96b64736f6c63430008190033a2646970667358221220c7d36e1e7efe73208a00c52d44ea45baa78bb15774848082ddb263481e408f8364736f6c63430008190033",
  "devdoc": {
    "events": {
      "CreateERC4626(address,address)": {
        "params": {
          "vToken": "The vToken used by the vault",
          "vault": "The vault that was created"
        }
      },
      "Initialized(uint8)": {
        "details": "Triggered when the contract has been initialized or reinitialized."
      },
      "RewardRecipientUpdated(address,address)": {
        "params": {
          "newRecipient": "The new reward recipient address.",
          "oldRecipient": "The previous reward recipient address."
        }
      }
    },
    "kind": "dev",
    "methods": {
      "acceptOwnership()": {
        "details": "The new owner accepts the ownership transfer."
      },
      "computeVaultAddress(address)": {
        "params": {
          "vToken": "The vToken address"
        },
        "returns": {
          "_0": "The precomputed vault address"
        }
      },
      "constructor": {
        "custom:oz-upgrades-unsafe-allow": "constructor"
      },
      "createERC4626(address)": {
        "custom:error": "ZeroAddressNotAllowed is thrown when the vToken address is zeroVenusERC4626Factory__InvalidVToken is thrown when the provided vToken is not supported by the poolRegistryVenusERC4626Factory__ERC4626AlreadyExists is thrown when this factory already created a VenusERC4626 for the provided vToken",
        "custom:event": "CreateERC4626 is emitted when the ERC4626 wrapper is created",
        "params": {
          "vToken": "The vToken address to create the vault"
        },
        "returns": {
          "vault": "The deployed VenusERC4626 vault"
        }
      },
      "initialize(address,address,address,address,uint256)": {
        "params": {
          "accessControlManager": "Address of the ACM contract",
          "loopsLimitNumber": "The loops limit for the MaxLoopsLimit helper",
          "poolRegistryAddress": "Address of the Pool Registry contract",
          "rewardRecipientAddress": "Reward recipient address",
          "venusERC4626Implementation": "Address of the VenusERC4626 implementation contract"
        }
      },
      "owner()": {
        "details": "Returns the address of the current owner."
      },
      "pendingOwner()": {
        "details": "Returns the address of the pending owner."
      },
      "renounceOwnership()": {
        "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner."
      },
      "setAccessControlManager(address)": {
        "custom:access": "Only Governance",
        "custom:event": "Emits NewAccessControlManager event",
        "details": "Admin function to set address of AccessControlManager",
        "params": {
          "accessControlManager_": "The new address of the AccessControlManager"
        }
      },
      "setMaxLoopsLimit(uint256)": {
        "custom:access": "Controlled by ACM",
        "custom:event": "Emits MaxLoopsLimitUpdated event on success",
        "params": {
          "loopsLimit": "Number of loops limit"
        }
      },
      "setRewardRecipient(address)": {
        "custom:access": "Controlled by ACM",
        "custom:error": "ZeroAddressNotAllowed is thrown when the new recipient address is zero",
        "custom:event": "RewardRecipientUpdated is emitted when the reward recipient address is updated",
        "params": {
          "newRecipient": "The address of the new reward recipient"
        }
      },
      "transferOwnership(address)": {
        "details": "Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner."
      }
    },
    "title": "VenusERC4626Factory",
    "version": 1
  },
  "userdoc": {
    "errors": {
      "MaxLoopsLimitExceeded(uint256,uint256)": [
        {
          "notice": "Thrown an error on maxLoopsLimit exceeds for any loop"
        }
      ],
      "Unauthorized(address,address,string)": [
        {
          "notice": "Thrown when the action is prohibited by AccessControlManager"
        }
      ],
      "VenusERC4626Factory__ERC4626AlreadyExists()": [
        {
          "notice": "Thrown when a VenusERC4626 already exists for the provided vToken"
        }
      ],
      "VenusERC4626Factory__InvalidVToken()": [
        {
          "notice": "Thrown when the provided vToken is not registered in PoolRegistry"
        }
      ],
      "ZeroAddressNotAllowed()": [
        {
          "notice": "Thrown if the supplied address is a zero address where it is not allowed"
        }
      ]
    },
    "events": {
      "CreateERC4626(address,address)": {
        "notice": "Emitted when a new ERC4626 vault has been created"
      },
      "MaxLoopsLimitUpdated(uint256,uint256)": {
        "notice": "Emitted when max loops limit is set"
      },
      "NewAccessControlManager(address,address)": {
        "notice": "Emitted when access control manager contract address is changed"
      },
      "RewardRecipientUpdated(address,address)": {
        "notice": "Emitted when the reward recipient address is updated."
      }
    },
    "kind": "user",
    "methods": {
      "SALT()": {
        "notice": "A constant salt value used for deterministic contract deployment"
      },
      "accessControlManager()": {
        "notice": "Returns the address of the access control manager contract"
      },
      "beacon()": {
        "notice": "The beacon contract for VenusERC4626 proxies"
      },
      "computeVaultAddress(address)": {
        "notice": "Predicts the vault address for a given vToken"
      },
      "createERC4626(address)": {
        "notice": "Creates a VenusERC4626 vault for a given asset and comptroller"
      },
      "initialize(address,address,address,address,uint256)": {
        "notice": "Initializes the contract"
      },
      "poolRegistry()": {
        "notice": "The Pool Registry contract"
      },
      "rewardRecipient()": {
        "notice": "The address that will receive the liquidity mining rewards"
      },
      "setAccessControlManager(address)": {
        "notice": "Sets the address of AccessControlManager"
      },
      "setMaxLoopsLimit(uint256)": {
        "notice": "Set the limit for the loops can iterate to avoid the DOS"
      },
      "setRewardRecipient(address)": {
        "notice": "Sets a new reward recipient address"
      }
    },
    "notice": "Factory for creating VenusERC4626 contracts",
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 460,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "_initialized",
        "offset": 0,
        "slot": "0",
        "type": "t_uint8"
      },
      {
        "astId": 463,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "_initializing",
        "offset": 1,
        "slot": "0",
        "type": "t_bool"
      },
      {
        "astId": 2994,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "__gap",
        "offset": 0,
        "slot": "1",
        "type": "t_array(t_uint256)50_storage"
      },
      {
        "astId": 164,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "_owner",
        "offset": 0,
        "slot": "51",
        "type": "t_address"
      },
      {
        "astId": 284,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "__gap",
        "offset": 0,
        "slot": "52",
        "type": "t_array(t_uint256)49_storage"
      },
      {
        "astId": 57,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "_pendingOwner",
        "offset": 0,
        "slot": "101",
        "type": "t_address"
      },
      {
        "astId": 151,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "__gap",
        "offset": 0,
        "slot": "102",
        "type": "t_array(t_uint256)49_storage"
      },
      {
        "astId": 9591,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "_accessControlManager",
        "offset": 0,
        "slot": "151",
        "type": "t_contract(IAccessControlManagerV8)9776"
      },
      {
        "astId": 9596,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "__gap",
        "offset": 0,
        "slot": "152",
        "type": "t_array(t_uint256)49_storage"
      },
      {
        "astId": 31511,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "maxLoopsLimit",
        "offset": 0,
        "slot": "201",
        "type": "t_uint256"
      },
      {
        "astId": 31516,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "__gap",
        "offset": 0,
        "slot": "202",
        "type": "t_array(t_uint256)49_storage"
      },
      {
        "astId": 24049,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "beacon",
        "offset": 0,
        "slot": "251",
        "type": "t_contract(UpgradeableBeacon)6525"
      },
      {
        "astId": 24053,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "poolRegistry",
        "offset": 0,
        "slot": "252",
        "type": "t_contract(PoolRegistryInterface)32421"
      },
      {
        "astId": 24056,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "rewardRecipient",
        "offset": 0,
        "slot": "253",
        "type": "t_address"
      },
      {
        "astId": 24061,
        "contract": "contracts/ERC4626/VenusERC4626Factory.sol:VenusERC4626Factory",
        "label": "createdVaults",
        "offset": 0,
        "slot": "254",
        "type": "t_mapping(t_address,t_contract(ERC4626Upgradeable)2177)"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_array(t_uint256)49_storage": {
        "base": "t_uint256",
        "encoding": "inplace",
        "label": "uint256[49]",
        "numberOfBytes": "1568"
      },
      "t_array(t_uint256)50_storage": {
        "base": "t_uint256",
        "encoding": "inplace",
        "label": "uint256[50]",
        "numberOfBytes": "1600"
      },
      "t_bool": {
        "encoding": "inplace",
        "label": "bool",
        "numberOfBytes": "1"
      },
      "t_contract(ERC4626Upgradeable)2177": {
        "encoding": "inplace",
        "label": "contract ERC4626Upgradeable",
        "numberOfBytes": "20"
      },
      "t_contract(IAccessControlManagerV8)9776": {
        "encoding": "inplace",
        "label": "contract IAccessControlManagerV8",
        "numberOfBytes": "20"
      },
      "t_contract(PoolRegistryInterface)32421": {
        "encoding": "inplace",
        "label": "contract PoolRegistryInterface",
        "numberOfBytes": "20"
      },
      "t_contract(UpgradeableBeacon)6525": {
        "encoding": "inplace",
        "label": "contract UpgradeableBeacon",
        "numberOfBytes": "20"
      },
      "t_mapping(t_address,t_contract(ERC4626Upgradeable)2177)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => contract ERC4626Upgradeable)",
        "numberOfBytes": "32",
        "value": "t_contract(ERC4626Upgradeable)2177"
      },
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      },
      "t_uint8": {
        "encoding": "inplace",
        "label": "uint8",
        "numberOfBytes": "1"
      }
    }
  }
}
