{
  "address": "0x660c6d8C5FDDC4F47C749E0f7e03634513f23e0e",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "accountant",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "weethLRT",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "weth",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "resilientOracle",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "annualGrowthRate",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_snapshotInterval",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "initialSnapshotMaxExchangeRate",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "initialSnapshotTimestamp",
          "type": "uint256"
        },
        {
          "internalType": "address",
          "name": "accessControlManager",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_snapshotGap",
          "type": "uint256"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [],
      "name": "InvalidGrowthRate",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidInitialSnapshot",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidSnapshotMaxExchangeRate",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidTokenAddress",
      "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": "ZeroAddressNotAllowed",
      "type": "error"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "oldGrowthRatePerSecond",
          "type": "uint256"
        },
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "newGrowthRatePerSecond",
          "type": "uint256"
        },
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "oldSnapshotInterval",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "newSnapshotInterval",
          "type": "uint256"
        }
      ],
      "name": "GrowthRateUpdated",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "oldSnapshotGap",
          "type": "uint256"
        },
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "newSnapshotGap",
          "type": "uint256"
        }
      ],
      "name": "SnapshotGapUpdated",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "maxExchangeRate",
          "type": "uint256"
        },
        {
          "indexed": true,
          "internalType": "uint256",
          "name": "timestamp",
          "type": "uint256"
        }
      ],
      "name": "SnapshotUpdated",
      "type": "event"
    },
    {
      "inputs": [],
      "name": "ACCESS_CONTROL_MANAGER",
      "outputs": [
        {
          "internalType": "contract IAccessControlManagerV8",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "ACCOUNTANT",
      "outputs": [
        {
          "internalType": "contract IAccountant",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "CORRELATED_TOKEN",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "RESILIENT_ORACLE",
      "outputs": [
        {
          "internalType": "contract ResilientOracleInterface",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "UNDERLYING_TOKEN",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "getMaxAllowedExchangeRate",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "asset",
          "type": "address"
        }
      ],
      "name": "getPrice",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "getUnderlyingAmount",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "growthRatePerSecond",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "isCapped",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "_annualGrowthRate",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_snapshotInterval",
          "type": "uint256"
        }
      ],
      "name": "setGrowthRate",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "_snapshotMaxExchangeRate",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_snapshotTimestamp",
          "type": "uint256"
        }
      ],
      "name": "setSnapshot",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "_snapshotGap",
          "type": "uint256"
        }
      ],
      "name": "setSnapshotGap",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "snapshotGap",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "snapshotInterval",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "snapshotMaxExchangeRate",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "snapshotTimestamp",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "updateSnapshot",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ],
  "transactionHash": "0xa84758cfc3531ecaae31a76fede3326f3751de4d70acb7eecdd6b1c9a1cbcc96",
  "receipt": {
    "to": null,
    "from": "0x63c72cf38D2C35278e2F18A4FE79225A66dFA942",
    "contractAddress": "0x660c6d8C5FDDC4F47C749E0f7e03634513f23e0e",
    "transactionIndex": 215,
    "gasUsed": "837822",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0x43f88b329f70c5e04eb0b5150223d5d409fd7be5308d64679ac5b8c1ec2219cd",
    "transactionHash": "0xa84758cfc3531ecaae31a76fede3326f3751de4d70acb7eecdd6b1c9a1cbcc96",
    "logs": [],
    "blockNumber": 8311172,
    "cumulativeGasUsed": "23681662",
    "status": 1,
    "byzantium": true
  },
  "args": [
    "0x04d7B1244Ff052319D154E627004EaE5b7a05FCf",
    "0xE233527306c2fa1E159e251a2E5893334505A5E0",
    "0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
    "0x8000eca36201dddf5805Aa4BeFD73d1EB4D23264",
    "150000000000000000",
    "115792089237316195423570985008687907853269984665640564039457584007913129639935",
    "1004263421125944312",
    1747054992,
    "0xbf705C00578d43B6147ab4eaE04DBBEd1ccCdc96",
    0
  ],
  "numDeployments": 1,
  "solcInputHash": "8100be9851a60cd39397bcc019f102c9",
  "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accountant\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"weethLRT\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"weth\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resilientOracle\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"annualGrowthRate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_snapshotInterval\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"initialSnapshotMaxExchangeRate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"initialSnapshotTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accessControlManager\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_snapshotGap\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidGrowthRate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitialSnapshot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSnapshotMaxExchangeRate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenAddress\",\"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\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldGrowthRatePerSecond\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newGrowthRatePerSecond\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldSnapshotInterval\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSnapshotInterval\",\"type\":\"uint256\"}],\"name\":\"GrowthRateUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"oldSnapshotGap\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"newSnapshotGap\",\"type\":\"uint256\"}],\"name\":\"SnapshotGapUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxExchangeRate\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"SnapshotUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ACCESS_CONTROL_MANAGER\",\"outputs\":[{\"internalType\":\"contract IAccessControlManagerV8\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ACCOUNTANT\",\"outputs\":[{\"internalType\":\"contract IAccountant\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"CORRELATED_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RESILIENT_ORACLE\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UNDERLYING_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getMaxAllowedExchangeRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getUnderlyingAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"growthRatePerSecond\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isCapped\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_annualGrowthRate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_snapshotInterval\",\"type\":\"uint256\"}],\"name\":\"setGrowthRate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_snapshotMaxExchangeRate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_snapshotTimestamp\",\"type\":\"uint256\"}],\"name\":\"setSnapshot\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_snapshotGap\",\"type\":\"uint256\"}],\"name\":\"setSnapshotGap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"snapshotGap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"snapshotInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"snapshotMaxExchangeRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"snapshotTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateSnapshot\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"kind\":\"dev\",\"methods\":{\"getMaxAllowedExchangeRate()\":{\"returns\":{\"_0\":\"maxExchangeRate Maximum allowed exchange rate\"}},\"getPrice(address)\":{\"custom:error\":\"InvalidTokenAddress error is thrown if the token address is invalid\",\"params\":{\"asset\":\"Address of the token\"},\"returns\":{\"_0\":\"price The price of the token in scaled decimal places. It can be capped to a maximum value taking into account the growth rate\"}},\"getUnderlyingAmount()\":{\"returns\":{\"_0\":\"amount Amount of WETH\"}},\"isCapped()\":{\"returns\":{\"_0\":\"isCapped Boolean indicating if the price is capped\"}},\"setGrowthRate(uint256,uint256)\":{\"custom:error\":\"InvalidGrowthRate error is thrown if the growth rate is invalid\",\"custom:event\":\"Emits GrowthRateUpdated event on successful update of the growth rate\",\"params\":{\"_annualGrowthRate\":\"The annual growth rate to set\",\"_snapshotInterval\":\"The snapshot interval to set\"}},\"setSnapshot(uint256,uint256)\":{\"custom:event\":\"Emits SnapshotUpdated event on successful update of the snapshot\",\"params\":{\"_snapshotMaxExchangeRate\":\"The exchange rate to set\",\"_snapshotTimestamp\":\"The timestamp to set\"}},\"setSnapshotGap(uint256)\":{\"custom:event\":\"Emits SnapshotGapUpdated event on successful update of the snapshot gap\",\"params\":{\"_snapshotGap\":\"The snapshot gap to set\"}},\"updateSnapshot()\":{\"custom:error\":\"InvalidSnapshotMaxExchangeRate error is thrown if the max snapshot exchange rate is zero\",\"custom:event\":\"Emits SnapshotUpdated event on successful update of the snapshot\"}},\"title\":\"WeETHAccountantOracle\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidGrowthRate()\":[{\"notice\":\"Thrown if the growth rate is invalid\"}],\"InvalidInitialSnapshot()\":[{\"notice\":\"Thrown if the initial snapshot is invalid\"}],\"InvalidSnapshotMaxExchangeRate()\":[{\"notice\":\"Thrown if the max snapshot exchange rate is invalid\"}],\"InvalidTokenAddress()\":[{\"notice\":\"Thrown if the token address is invalid\"}],\"Unauthorized(address,address,string)\":[{\"notice\":\"@notice Thrown when the action is prohibited by AccessControlManager\"}],\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}]},\"events\":{\"GrowthRateUpdated(uint256,uint256,uint256,uint256)\":{\"notice\":\"Emitted when the growth rate is updated\"},\"SnapshotGapUpdated(uint256,uint256)\":{\"notice\":\"Emitted when the snapshot gap is updated\"},\"SnapshotUpdated(uint256,uint256)\":{\"notice\":\"Emitted when the snapshot is updated\"}},\"kind\":\"user\",\"methods\":{\"ACCESS_CONTROL_MANAGER()\":{\"notice\":\"Address of the AccessControlManager contract\"},\"ACCOUNTANT()\":{\"notice\":\"Address of Accountant\"},\"CORRELATED_TOKEN()\":{\"notice\":\"Address of the correlated token\"},\"RESILIENT_ORACLE()\":{\"notice\":\"Address of Resilient Oracle\"},\"UNDERLYING_TOKEN()\":{\"notice\":\"Address of the underlying token\"},\"constructor\":{\"notice\":\"Constructor for the implementation contract.\"},\"getMaxAllowedExchangeRate()\":{\"notice\":\"Gets the maximum allowed exchange rate for token\"},\"getPrice(address)\":{\"notice\":\"Fetches the price of the token\"},\"getUnderlyingAmount()\":{\"notice\":\"Gets the WETH for 1 weETH LRT\"},\"isCapped()\":{\"notice\":\"Returns if the price is capped\"},\"setGrowthRate(uint256,uint256)\":{\"notice\":\"Sets the growth rate and snapshot interval\"},\"setSnapshot(uint256,uint256)\":{\"notice\":\"Directly sets the snapshot exchange rate and timestamp\"},\"setSnapshotGap(uint256)\":{\"notice\":\"Sets the snapshot gap\"},\"snapshotGap()\":{\"notice\":\"Gap to add when updating the snapshot\"},\"snapshotInterval()\":{\"notice\":\"Snapshot update interval\"},\"snapshotMaxExchangeRate()\":{\"notice\":\"Last stored snapshot maximum exchange rate\"},\"snapshotTimestamp()\":{\"notice\":\"Last stored snapshot timestamp\"},\"updateSnapshot()\":{\"notice\":\"Updates the snapshot price and timestamp\"}},\"notice\":\"This oracle fetches the price of Ether.fi tokens based on an `Accountant` contract (i.e. weETHs and weETHk)\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracles/WeETHAccountantOracle.sol\":\"WeETHAccountantOracle\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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/token/ERC20/IERC20.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 IERC20 {\\n    /**\\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n     * another (`to`).\\n     *\\n     * Note that `value` may be zero.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    /**\\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n     * a call to {approve}. `value` is the new allowance.\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n    /**\\n     * @dev Returns the amount of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves `amount` tokens from the caller's account to `to`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address to, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Moves `amount` tokens from `from` to `to` using the\\n     * allowance mechanism. `amount` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n    /**\\n     * @dev Returns the name of the token.\\n     */\\n    function name() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the symbol of the token.\\n     */\\n    function symbol() external view returns (string memory);\\n\\n    /**\\n     * @dev Returns the decimals places of the token.\\n     */\\n    function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@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/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\"},\"contracts/interfaces/IAccountant.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\ninterface IAccountant {\\n    function getRateSafe() external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x04672ffcad2a2f951d7afc7288a5875dc6e67d12445666c959ac64966102b06b\",\"license\":\"BSD-3-Clause\"},\"contracts/interfaces/ICappedOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\ninterface ICappedOracle {\\n    function updateSnapshot() external;\\n}\\n\",\"keccak256\":\"0xad239e65b5e92b3486418c5ccca120247702251f9724cd96657c3cfdc7fedc31\",\"license\":\"BSD-3-Clause\"},\"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 BoundValidatorInterface {\\n    function validatePriceWithAnchorPrice(\\n        address asset,\\n        uint256 reporterPrice,\\n        uint256 anchorPrice\\n    ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xd3bbb7c9eef19e8f467342df6034ef95399a00964646fb8c82b438968ae3a8c0\",\"license\":\"BSD-3-Clause\"},\"contracts/oracles/WeETHAccountantOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { CorrelatedTokenOracle } from \\\"./common/CorrelatedTokenOracle.sol\\\";\\nimport { IAccountant } from \\\"../interfaces/IAccountant.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"@venusprotocol/solidity-utilities/contracts/validators.sol\\\";\\n\\n/**\\n * @title WeETHAccountantOracle\\n * @author Venus\\n * @notice This oracle fetches the price of Ether.fi tokens based on an `Accountant` contract (i.e. weETHs and weETHk)\\n */\\ncontract WeETHAccountantOracle is CorrelatedTokenOracle {\\n    /// @notice Address of Accountant\\n    IAccountant public immutable ACCOUNTANT;\\n\\n    /// @notice Constructor for the implementation contract.\\n    constructor(\\n        address accountant,\\n        address weethLRT,\\n        address weth,\\n        address resilientOracle,\\n        uint256 annualGrowthRate,\\n        uint256 _snapshotInterval,\\n        uint256 initialSnapshotMaxExchangeRate,\\n        uint256 initialSnapshotTimestamp,\\n        address accessControlManager,\\n        uint256 _snapshotGap\\n    )\\n        CorrelatedTokenOracle(\\n            weethLRT,\\n            weth,\\n            resilientOracle,\\n            annualGrowthRate,\\n            _snapshotInterval,\\n            initialSnapshotMaxExchangeRate,\\n            initialSnapshotTimestamp,\\n            accessControlManager,\\n            _snapshotGap\\n        )\\n    {\\n        ensureNonzeroAddress(accountant);\\n        ACCOUNTANT = IAccountant(accountant);\\n    }\\n\\n    /**\\n     * @notice Gets the WETH for 1 weETH LRT\\n     * @return amount Amount of WETH\\n     */\\n    function getUnderlyingAmount() public view override returns (uint256) {\\n        return ACCOUNTANT.getRateSafe();\\n    }\\n}\\n\",\"keccak256\":\"0x2294bc2982a57a72bcbb464aa73bb7ef063dc8dc729fddbeb13efc07fbd3d9c0\",\"license\":\"BSD-3-Clause\"},\"contracts/oracles/common/CorrelatedTokenOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { OracleInterface, ResilientOracleInterface } from \\\"../../interfaces/OracleInterface.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"@venusprotocol/solidity-utilities/contracts/validators.sol\\\";\\nimport { SECONDS_PER_YEAR } from \\\"@venusprotocol/solidity-utilities/contracts/constants.sol\\\";\\nimport { IERC20Metadata } from \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport { ICappedOracle } from \\\"../../interfaces/ICappedOracle.sol\\\";\\nimport { IAccessControlManagerV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\\\";\\n\\n/**\\n * @title CorrelatedTokenOracle\\n * @notice This oracle fetches the price of a token that is correlated to another token.\\n */\\nabstract contract CorrelatedTokenOracle is OracleInterface, ICappedOracle {\\n    /// @notice Address of the correlated token\\n    address public immutable CORRELATED_TOKEN;\\n\\n    /// @notice Address of the underlying token\\n    address public immutable UNDERLYING_TOKEN;\\n\\n    /// @notice Address of Resilient Oracle\\n    ResilientOracleInterface public immutable RESILIENT_ORACLE;\\n\\n    /// @notice Address of the AccessControlManager contract\\n    IAccessControlManagerV8 public immutable ACCESS_CONTROL_MANAGER;\\n\\n    //// @notice Growth rate percentage in seconds. Ex: 1e18 is 100%\\n    uint256 public growthRatePerSecond;\\n\\n    /// @notice Snapshot update interval\\n    uint256 public snapshotInterval;\\n\\n    /// @notice Last stored snapshot maximum exchange rate\\n    uint256 public snapshotMaxExchangeRate;\\n\\n    /// @notice Last stored snapshot timestamp\\n    uint256 public snapshotTimestamp;\\n\\n    /// @notice Gap to add when updating the snapshot\\n    uint256 public snapshotGap;\\n\\n    /// @notice Emitted when the snapshot is updated\\n    event SnapshotUpdated(uint256 indexed maxExchangeRate, uint256 indexed timestamp);\\n\\n    /// @notice Emitted when the growth rate is updated\\n    event GrowthRateUpdated(\\n        uint256 indexed oldGrowthRatePerSecond,\\n        uint256 indexed newGrowthRatePerSecond,\\n        uint256 indexed oldSnapshotInterval,\\n        uint256 newSnapshotInterval\\n    );\\n\\n    /// @notice Emitted when the snapshot gap is updated\\n    event SnapshotGapUpdated(uint256 indexed oldSnapshotGap, uint256 indexed newSnapshotGap);\\n\\n    /// @notice Thrown if the token address is invalid\\n    error InvalidTokenAddress();\\n\\n    /// @notice Thrown if the growth rate is invalid\\n    error InvalidGrowthRate();\\n\\n    /// @notice Thrown if the initial snapshot is invalid\\n    error InvalidInitialSnapshot();\\n\\n    /// @notice Thrown if the max snapshot exchange rate is invalid\\n    error InvalidSnapshotMaxExchangeRate();\\n\\n    /// @notice @notice Thrown when the action is prohibited by AccessControlManager\\n    error Unauthorized(address sender, address calledContract, string methodSignature);\\n\\n    /**\\n     * @notice Constructor for the implementation contract.\\n     * @custom:error InvalidGrowthRate error is thrown if the growth rate is invalid\\n     * @custom:error InvalidInitialSnapshot error is thrown if the initial snapshot values are invalid\\n     */\\n    constructor(\\n        address _correlatedToken,\\n        address _underlyingToken,\\n        address _resilientOracle,\\n        uint256 _annualGrowthRate,\\n        uint256 _snapshotInterval,\\n        uint256 _initialSnapshotMaxExchangeRate,\\n        uint256 _initialSnapshotTimestamp,\\n        address _accessControlManager,\\n        uint256 _snapshotGap\\n    ) {\\n        growthRatePerSecond = _annualGrowthRate / SECONDS_PER_YEAR;\\n\\n        if ((growthRatePerSecond == 0 && _snapshotInterval > 0) || (growthRatePerSecond > 0 && _snapshotInterval == 0))\\n            revert InvalidGrowthRate();\\n\\n        if ((_initialSnapshotMaxExchangeRate == 0 || _initialSnapshotTimestamp == 0) && _snapshotInterval > 0) {\\n            revert InvalidInitialSnapshot();\\n        }\\n\\n        ensureNonzeroAddress(_correlatedToken);\\n        ensureNonzeroAddress(_underlyingToken);\\n        ensureNonzeroAddress(_resilientOracle);\\n        ensureNonzeroAddress(_accessControlManager);\\n\\n        CORRELATED_TOKEN = _correlatedToken;\\n        UNDERLYING_TOKEN = _underlyingToken;\\n        RESILIENT_ORACLE = ResilientOracleInterface(_resilientOracle);\\n        snapshotInterval = _snapshotInterval;\\n\\n        snapshotMaxExchangeRate = _initialSnapshotMaxExchangeRate;\\n        snapshotTimestamp = _initialSnapshotTimestamp;\\n        snapshotGap = _snapshotGap;\\n\\n        ACCESS_CONTROL_MANAGER = IAccessControlManagerV8(_accessControlManager);\\n    }\\n\\n    /**\\n     * @notice Directly sets the snapshot exchange rate and timestamp\\n     * @param _snapshotMaxExchangeRate The exchange rate to set\\n     * @param _snapshotTimestamp The timestamp to set\\n     * @custom:event Emits SnapshotUpdated event on successful update of the snapshot\\n     */\\n    function setSnapshot(uint256 _snapshotMaxExchangeRate, uint256 _snapshotTimestamp) external {\\n        _checkAccessAllowed(\\\"setSnapshot(uint256,uint256)\\\");\\n\\n        snapshotMaxExchangeRate = _snapshotMaxExchangeRate;\\n        snapshotTimestamp = _snapshotTimestamp;\\n\\n        emit SnapshotUpdated(snapshotMaxExchangeRate, snapshotTimestamp);\\n    }\\n\\n    /**\\n     * @notice Sets the growth rate and snapshot interval\\n     * @param _annualGrowthRate The annual growth rate to set\\n     * @param _snapshotInterval The snapshot interval to set\\n     * @custom:error InvalidGrowthRate error is thrown if the growth rate is invalid\\n     * @custom:event Emits GrowthRateUpdated event on successful update of the growth rate\\n     */\\n    function setGrowthRate(uint256 _annualGrowthRate, uint256 _snapshotInterval) external {\\n        _checkAccessAllowed(\\\"setGrowthRate(uint256,uint256)\\\");\\n        uint256 oldGrowthRatePerSecond = growthRatePerSecond;\\n\\n        growthRatePerSecond = _annualGrowthRate / SECONDS_PER_YEAR;\\n\\n        if ((growthRatePerSecond == 0 && _snapshotInterval > 0) || (growthRatePerSecond > 0 && _snapshotInterval == 0))\\n            revert InvalidGrowthRate();\\n\\n        emit GrowthRateUpdated(oldGrowthRatePerSecond, growthRatePerSecond, snapshotInterval, _snapshotInterval);\\n\\n        snapshotInterval = _snapshotInterval;\\n    }\\n\\n    /**\\n     * @notice Sets the snapshot gap\\n     * @param _snapshotGap The snapshot gap to set\\n     * @custom:event Emits SnapshotGapUpdated event on successful update of the snapshot gap\\n     */\\n    function setSnapshotGap(uint256 _snapshotGap) external {\\n        _checkAccessAllowed(\\\"setSnapshotGap(uint256)\\\");\\n\\n        emit SnapshotGapUpdated(snapshotGap, _snapshotGap);\\n\\n        snapshotGap = _snapshotGap;\\n    }\\n\\n    /**\\n     * @notice Returns if the price is capped\\n     * @return isCapped Boolean indicating if the price is capped\\n     */\\n    function isCapped() external view virtual returns (bool) {\\n        if (snapshotInterval == 0) {\\n            return false;\\n        }\\n\\n        uint256 maxAllowedExchangeRate = getMaxAllowedExchangeRate();\\n        if (maxAllowedExchangeRate == 0) {\\n            return false;\\n        }\\n\\n        uint256 exchangeRate = getUnderlyingAmount();\\n\\n        return exchangeRate > maxAllowedExchangeRate;\\n    }\\n\\n    /**\\n     * @notice Updates the snapshot price and timestamp\\n     * @custom:event Emits SnapshotUpdated event on successful update of the snapshot\\n     * @custom:error InvalidSnapshotMaxExchangeRate error is thrown if the max snapshot exchange rate is zero\\n     */\\n    function updateSnapshot() public override {\\n        if (block.timestamp - snapshotTimestamp < snapshotInterval || snapshotInterval == 0) return;\\n\\n        uint256 exchangeRate = getUnderlyingAmount();\\n        uint256 maxAllowedExchangeRate = getMaxAllowedExchangeRate();\\n\\n        snapshotMaxExchangeRate =\\n            (exchangeRate > maxAllowedExchangeRate ? maxAllowedExchangeRate : exchangeRate) +\\n            snapshotGap;\\n        snapshotTimestamp = block.timestamp;\\n\\n        if (snapshotMaxExchangeRate == 0) revert InvalidSnapshotMaxExchangeRate();\\n\\n        RESILIENT_ORACLE.updateAssetPrice(UNDERLYING_TOKEN);\\n        emit SnapshotUpdated(snapshotMaxExchangeRate, snapshotTimestamp);\\n    }\\n\\n    /**\\n     * @notice Fetches the price of the token\\n     * @param asset Address of the token\\n     * @return price The price of the token in scaled decimal places. It can be capped\\n     * to a maximum value taking into account the growth rate\\n     * @custom:error InvalidTokenAddress error is thrown if the token address is invalid\\n     */\\n    function getPrice(address asset) public view override returns (uint256) {\\n        if (asset != CORRELATED_TOKEN) revert InvalidTokenAddress();\\n\\n        uint256 exchangeRate = getUnderlyingAmount();\\n\\n        if (snapshotInterval == 0) {\\n            return _calculatePrice(exchangeRate);\\n        }\\n\\n        uint256 maxAllowedExchangeRate = getMaxAllowedExchangeRate();\\n\\n        uint256 finalExchangeRate = (exchangeRate > maxAllowedExchangeRate && maxAllowedExchangeRate != 0)\\n            ? maxAllowedExchangeRate\\n            : exchangeRate;\\n\\n        return _calculatePrice(finalExchangeRate);\\n    }\\n\\n    /**\\n     * @notice Gets the maximum allowed exchange rate for token\\n     * @return maxExchangeRate Maximum allowed exchange rate\\n     */\\n    function getMaxAllowedExchangeRate() public view returns (uint256) {\\n        uint256 timeElapsed = block.timestamp - snapshotTimestamp;\\n        uint256 maxExchangeRate = snapshotMaxExchangeRate +\\n            (snapshotMaxExchangeRate * growthRatePerSecond * timeElapsed) /\\n            1e18;\\n        return maxExchangeRate;\\n    }\\n\\n    /**\\n     * @notice Gets the underlying amount for correlated token\\n     * @return underlyingAmount Amount of underlying token\\n     */\\n    function getUnderlyingAmount() public view virtual returns (uint256);\\n\\n    /**\\n     * @notice Fetches price of the token based on an underlying exchange rate\\n     * @param exchangeRate The underlying exchange rate to use\\n     * @return price The price of the token in scaled decimal places\\n     */\\n    function _calculatePrice(uint256 exchangeRate) internal view returns (uint256) {\\n        uint256 underlyingUSDPrice = RESILIENT_ORACLE.getPrice(UNDERLYING_TOKEN);\\n\\n        IERC20Metadata token = IERC20Metadata(CORRELATED_TOKEN);\\n        uint256 decimals = token.decimals();\\n\\n        return (exchangeRate * underlyingUSDPrice) / (10 ** decimals);\\n    }\\n\\n    /**\\n     * @notice Reverts if the call is not allowed by AccessControlManager\\n     * @param signature Method signature\\n     * @custom:error Unauthorized error is thrown if the call is not allowed\\n     */\\n    function _checkAccessAllowed(string memory signature) internal view {\\n        bool isAllowedToCall = ACCESS_CONTROL_MANAGER.isAllowedToCall(msg.sender, signature);\\n\\n        if (!isAllowedToCall) {\\n            revert Unauthorized(msg.sender, address(this), signature);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0x808b444fa4d1d440dc43de290f1eb59a64646ce9085028b286fa30346305872e\",\"license\":\"BSD-3-Clause\"}},\"version\":1}",
  "bytecode": "0x610120604052348015610010575f80fd5b50604051610efd380380610efd83398101604081905261002f9161017d565b8888888888888888886100466301e133808761020e565b5f81905515801561005657505f85115b8061006a57505f805411801561006a575084155b15610088576040516353b7e64560e11b815260040160405180910390fd5b831580610093575082155b801561009e57505f85115b156100bc5760405163b8a5589b60e01b815260040160405180910390fd5b6100c589610138565b6100ce88610138565b6100d787610138565b6100e082610138565b6001600160a01b0398891660805296881660a05294871660c052600192909255600255600355506004919091551660e05261011a8a610138565b5050506001600160a01b03909616610100525061022d945050505050565b6001600160a01b03811661015f576040516342bcdf7f60e11b815260040160405180910390fd5b50565b80516001600160a01b0381168114610178575f80fd5b919050565b5f805f805f805f805f806101408b8d031215610197575f80fd5b6101a08b610162565b99506101ae60208c01610162565b98506101bc60408c01610162565b97506101ca60608c01610162565b965060808b0151955060a08b0151945060c08b0151935060e08b015192506101f56101008c01610162565b91506101208b015190509295989b9194979a5092959850565b5f8261022857634e487b7160e01b5f52601260045260245ffd5b500490565b60805160a05160c05160e05161010051610c5b6102a25f395f818161024301526106a401525f818161019101526108e401525f81816102730152818161059c01526107b701525f818161013601528181610574015261078b01525f8181610209015281816102b001526108250152610c5b5ff3fe608060405234801561000f575f80fd5b5060043610610111575f3560e01c8063692404261161009e5780639c43eb541161006e5780639c43eb5414610265578063a4edcd4c1461026e578063abb8561314610295578063ac5a693e1461029d578063bdf13af2146102a5575f80fd5b806369240426146101fc57806369818a35146102045780637fc4e4a01461022b5780638b9d29401461023e575f80fd5b806345be2dc7116100e457806345be2dc71461018c5780635213f9c8146101b3578063596efe6f146101c8578063643d813d146101d1578063671528d4146101e4575f80fd5b806307d0413c1461011557806329db1be6146101315780634169d2451461017057806341976e0914610179575b5f80fd5b61011e60015481565b6040519081526020015b60405180910390f35b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610128565b61011e60045481565b61011e61018736600461098d565b6102ad565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101c66101c13660046109b3565b61035e565b005b61011e60025481565b6101c66101df3660046109ca565b6103cf565b6101ec6104a5565b6040519015158152602001610128565b6101c66104e0565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101c66102393660046109ca565b610629565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b61011e60035481565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b61011e6106a1565b61011e5f5481565b61011e610727565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461030057604051630f58058360e11b815260040160405180910390fd5b5f6103096106a1565b90506001545f036103245761031d81610774565b9392505050565b5f61032d610727565b90505f818311801561033e57508115155b610348578261034a565b815b905061035581610774565b95945050505050565b61039c6040518060400160405280601781526020017f736574536e617073686f744761702875696e74323536290000000000000000008152506108cb565b6004546040518291907feb3716d3f8388c182853c1dc98b18931f3a600bbab31f2ff48631f6412e4997f905f90a3600455565b61040d6040518060400160405280601e81526020017f73657447726f777468526174652875696e743235362c75696e743235362900008152506108cb565b5f5461041d6301e13380846109fe565b5f81905515801561042d57505f82115b8061044157505f8054118015610441575081155b1561045f576040516353b7e64560e11b815260040160405180910390fd5b6001545f54827fa65cbeb0e28a8803a912daac67c472c160aa01e2c988755fa424f290321de6088560405161049691815260200190565b60405180910390a45060015550565b5f6001545f036104b457505f90565b5f6104bd610727565b9050805f036104cd575f91505090565b5f6104d66106a1565b9190911192915050565b6001546003546104f09042610a1d565b10806104fc5750600154155b1561050357565b5f61050c6106a1565b90505f610517610727565b9050600454818311610529578261052b565b815b6105359190610a36565b6002819055426003555f0361055d57604051635f18388760e01b815260040160405180910390fd5b60405163b62cad6960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b62cad69906024015f604051808303815f87803b1580156105dd575f80fd5b505af11580156105ef573d5f803e3d5ffd5b505050506003546002547f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d60405160405180910390a35050565b6106676040518060400160405280601c81526020017f736574536e617073686f742875696e743235362c75696e7432353629000000008152506108cb565b60028290556003819055604051819083907f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d905f90a35050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663282a87006040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106fe573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107229190610a49565b905090565b5f80600354426107379190610a1d565b90505f670de0b6b3a7640000825f546002546107539190610a60565b61075d9190610a60565b61076791906109fe565b60025461031d9190610a36565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa1580156107fc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108209190610a49565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610883573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108a79190610a77565b60ff1690506108b781600a610b77565b6108c18487610a60565b61035591906109fe565b6040516318c5e8ab60e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906318c5e8ab9061091b9033908690600401610bb0565b602060405180830381865afa158015610936573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061095a9190610bdb565b90508061098957333083604051634a3fa29360e01b815260040161098093929190610bfa565b60405180910390fd5b5050565b5f6020828403121561099d575f80fd5b81356001600160a01b038116811461031d575f80fd5b5f602082840312156109c3575f80fd5b5035919050565b5f80604083850312156109db575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f82610a1857634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610a3057610a306109ea565b92915050565b80820180821115610a3057610a306109ea565b5f60208284031215610a59575f80fd5b5051919050565b8082028115828204841417610a3057610a306109ea565b5f60208284031215610a87575f80fd5b815160ff8116811461031d575f80fd5b600181815b80851115610ad157815f1904821115610ab757610ab76109ea565b80851615610ac457918102915b93841c9390800290610a9c565b509250929050565b5f82610ae757506001610a30565b81610af357505f610a30565b8160018114610b095760028114610b1357610b2f565b6001915050610a30565b60ff841115610b2457610b246109ea565b50506001821b610a30565b5060208310610133831016604e8410600b8410161715610b52575081810a610a30565b610b5c8383610a97565b805f1904821115610b6f57610b6f6109ea565b029392505050565b5f61031d8383610ad9565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03831681526040602082018190525f90610bd390830184610b82565b949350505050565b5f60208284031215610beb575f80fd5b8151801515811461031d575f80fd5b6001600160a01b038481168252831660208201526060604082018190525f9061035590830184610b8256fea2646970667358221220400196db5b1780dd6dcceaf950d95adbd16740ceff28d9d2f35c2067ee07255564736f6c63430008190033",
  "deployedBytecode": "0x608060405234801561000f575f80fd5b5060043610610111575f3560e01c8063692404261161009e5780639c43eb541161006e5780639c43eb5414610265578063a4edcd4c1461026e578063abb8561314610295578063ac5a693e1461029d578063bdf13af2146102a5575f80fd5b806369240426146101fc57806369818a35146102045780637fc4e4a01461022b5780638b9d29401461023e575f80fd5b806345be2dc7116100e457806345be2dc71461018c5780635213f9c8146101b3578063596efe6f146101c8578063643d813d146101d1578063671528d4146101e4575f80fd5b806307d0413c1461011557806329db1be6146101315780634169d2451461017057806341976e0914610179575b5f80fd5b61011e60015481565b6040519081526020015b60405180910390f35b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610128565b61011e60045481565b61011e61018736600461098d565b6102ad565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101c66101c13660046109b3565b61035e565b005b61011e60025481565b6101c66101df3660046109ca565b6103cf565b6101ec6104a5565b6040519015158152602001610128565b6101c66104e0565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101c66102393660046109ca565b610629565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b61011e60035481565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b61011e6106a1565b61011e5f5481565b61011e610727565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461030057604051630f58058360e11b815260040160405180910390fd5b5f6103096106a1565b90506001545f036103245761031d81610774565b9392505050565b5f61032d610727565b90505f818311801561033e57508115155b610348578261034a565b815b905061035581610774565b95945050505050565b61039c6040518060400160405280601781526020017f736574536e617073686f744761702875696e74323536290000000000000000008152506108cb565b6004546040518291907feb3716d3f8388c182853c1dc98b18931f3a600bbab31f2ff48631f6412e4997f905f90a3600455565b61040d6040518060400160405280601e81526020017f73657447726f777468526174652875696e743235362c75696e743235362900008152506108cb565b5f5461041d6301e13380846109fe565b5f81905515801561042d57505f82115b8061044157505f8054118015610441575081155b1561045f576040516353b7e64560e11b815260040160405180910390fd5b6001545f54827fa65cbeb0e28a8803a912daac67c472c160aa01e2c988755fa424f290321de6088560405161049691815260200190565b60405180910390a45060015550565b5f6001545f036104b457505f90565b5f6104bd610727565b9050805f036104cd575f91505090565b5f6104d66106a1565b9190911192915050565b6001546003546104f09042610a1d565b10806104fc5750600154155b1561050357565b5f61050c6106a1565b90505f610517610727565b9050600454818311610529578261052b565b815b6105359190610a36565b6002819055426003555f0361055d57604051635f18388760e01b815260040160405180910390fd5b60405163b62cad6960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b62cad69906024015f604051808303815f87803b1580156105dd575f80fd5b505af11580156105ef573d5f803e3d5ffd5b505050506003546002547f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d60405160405180910390a35050565b6106676040518060400160405280601c81526020017f736574536e617073686f742875696e743235362c75696e7432353629000000008152506108cb565b60028290556003819055604051819083907f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d905f90a35050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663282a87006040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106fe573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107229190610a49565b905090565b5f80600354426107379190610a1d565b90505f670de0b6b3a7640000825f546002546107539190610a60565b61075d9190610a60565b61076791906109fe565b60025461031d9190610a36565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa1580156107fc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108209190610a49565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610883573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108a79190610a77565b60ff1690506108b781600a610b77565b6108c18487610a60565b61035591906109fe565b6040516318c5e8ab60e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906318c5e8ab9061091b9033908690600401610bb0565b602060405180830381865afa158015610936573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061095a9190610bdb565b90508061098957333083604051634a3fa29360e01b815260040161098093929190610bfa565b60405180910390fd5b5050565b5f6020828403121561099d575f80fd5b81356001600160a01b038116811461031d575f80fd5b5f602082840312156109c3575f80fd5b5035919050565b5f80604083850312156109db575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f82610a1857634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610a3057610a306109ea565b92915050565b80820180821115610a3057610a306109ea565b5f60208284031215610a59575f80fd5b5051919050565b8082028115828204841417610a3057610a306109ea565b5f60208284031215610a87575f80fd5b815160ff8116811461031d575f80fd5b600181815b80851115610ad157815f1904821115610ab757610ab76109ea565b80851615610ac457918102915b93841c9390800290610a9c565b509250929050565b5f82610ae757506001610a30565b81610af357505f610a30565b8160018114610b095760028114610b1357610b2f565b6001915050610a30565b60ff841115610b2457610b246109ea565b50506001821b610a30565b5060208310610133831016604e8410600b8410161715610b52575081810a610a30565b610b5c8383610a97565b805f1904821115610b6f57610b6f6109ea565b029392505050565b5f61031d8383610ad9565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03831681526040602082018190525f90610bd390830184610b82565b949350505050565b5f60208284031215610beb575f80fd5b8151801515811461031d575f80fd5b6001600160a01b038481168252831660208201526060604082018190525f9061035590830184610b8256fea2646970667358221220400196db5b1780dd6dcceaf950d95adbd16740ceff28d9d2f35c2067ee07255564736f6c63430008190033",
  "devdoc": {
    "author": "Venus",
    "kind": "dev",
    "methods": {
      "getMaxAllowedExchangeRate()": {
        "returns": {
          "_0": "maxExchangeRate Maximum allowed exchange rate"
        }
      },
      "getPrice(address)": {
        "custom:error": "InvalidTokenAddress error is thrown if the token address is invalid",
        "params": {
          "asset": "Address of the token"
        },
        "returns": {
          "_0": "price The price of the token in scaled decimal places. It can be capped to a maximum value taking into account the growth rate"
        }
      },
      "getUnderlyingAmount()": {
        "returns": {
          "_0": "amount Amount of WETH"
        }
      },
      "isCapped()": {
        "returns": {
          "_0": "isCapped Boolean indicating if the price is capped"
        }
      },
      "setGrowthRate(uint256,uint256)": {
        "custom:error": "InvalidGrowthRate error is thrown if the growth rate is invalid",
        "custom:event": "Emits GrowthRateUpdated event on successful update of the growth rate",
        "params": {
          "_annualGrowthRate": "The annual growth rate to set",
          "_snapshotInterval": "The snapshot interval to set"
        }
      },
      "setSnapshot(uint256,uint256)": {
        "custom:event": "Emits SnapshotUpdated event on successful update of the snapshot",
        "params": {
          "_snapshotMaxExchangeRate": "The exchange rate to set",
          "_snapshotTimestamp": "The timestamp to set"
        }
      },
      "setSnapshotGap(uint256)": {
        "custom:event": "Emits SnapshotGapUpdated event on successful update of the snapshot gap",
        "params": {
          "_snapshotGap": "The snapshot gap to set"
        }
      },
      "updateSnapshot()": {
        "custom:error": "InvalidSnapshotMaxExchangeRate error is thrown if the max snapshot exchange rate is zero",
        "custom:event": "Emits SnapshotUpdated event on successful update of the snapshot"
      }
    },
    "title": "WeETHAccountantOracle",
    "version": 1
  },
  "userdoc": {
    "errors": {
      "InvalidGrowthRate()": [
        {
          "notice": "Thrown if the growth rate is invalid"
        }
      ],
      "InvalidInitialSnapshot()": [
        {
          "notice": "Thrown if the initial snapshot is invalid"
        }
      ],
      "InvalidSnapshotMaxExchangeRate()": [
        {
          "notice": "Thrown if the max snapshot exchange rate is invalid"
        }
      ],
      "InvalidTokenAddress()": [
        {
          "notice": "Thrown if the token address is invalid"
        }
      ],
      "Unauthorized(address,address,string)": [
        {
          "notice": "@notice Thrown when the action is prohibited by AccessControlManager"
        }
      ],
      "ZeroAddressNotAllowed()": [
        {
          "notice": "Thrown if the supplied address is a zero address where it is not allowed"
        }
      ]
    },
    "events": {
      "GrowthRateUpdated(uint256,uint256,uint256,uint256)": {
        "notice": "Emitted when the growth rate is updated"
      },
      "SnapshotGapUpdated(uint256,uint256)": {
        "notice": "Emitted when the snapshot gap is updated"
      },
      "SnapshotUpdated(uint256,uint256)": {
        "notice": "Emitted when the snapshot is updated"
      }
    },
    "kind": "user",
    "methods": {
      "ACCESS_CONTROL_MANAGER()": {
        "notice": "Address of the AccessControlManager contract"
      },
      "ACCOUNTANT()": {
        "notice": "Address of Accountant"
      },
      "CORRELATED_TOKEN()": {
        "notice": "Address of the correlated token"
      },
      "RESILIENT_ORACLE()": {
        "notice": "Address of Resilient Oracle"
      },
      "UNDERLYING_TOKEN()": {
        "notice": "Address of the underlying token"
      },
      "constructor": {
        "notice": "Constructor for the implementation contract."
      },
      "getMaxAllowedExchangeRate()": {
        "notice": "Gets the maximum allowed exchange rate for token"
      },
      "getPrice(address)": {
        "notice": "Fetches the price of the token"
      },
      "getUnderlyingAmount()": {
        "notice": "Gets the WETH for 1 weETH LRT"
      },
      "isCapped()": {
        "notice": "Returns if the price is capped"
      },
      "setGrowthRate(uint256,uint256)": {
        "notice": "Sets the growth rate and snapshot interval"
      },
      "setSnapshot(uint256,uint256)": {
        "notice": "Directly sets the snapshot exchange rate and timestamp"
      },
      "setSnapshotGap(uint256)": {
        "notice": "Sets the snapshot gap"
      },
      "snapshotGap()": {
        "notice": "Gap to add when updating the snapshot"
      },
      "snapshotInterval()": {
        "notice": "Snapshot update interval"
      },
      "snapshotMaxExchangeRate()": {
        "notice": "Last stored snapshot maximum exchange rate"
      },
      "snapshotTimestamp()": {
        "notice": "Last stored snapshot timestamp"
      },
      "updateSnapshot()": {
        "notice": "Updates the snapshot price and timestamp"
      }
    },
    "notice": "This oracle fetches the price of Ether.fi tokens based on an `Accountant` contract (i.e. weETHs and weETHk)",
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 6407,
        "contract": "contracts/oracles/WeETHAccountantOracle.sol:WeETHAccountantOracle",
        "label": "growthRatePerSecond",
        "offset": 0,
        "slot": "0",
        "type": "t_uint256"
      },
      {
        "astId": 6410,
        "contract": "contracts/oracles/WeETHAccountantOracle.sol:WeETHAccountantOracle",
        "label": "snapshotInterval",
        "offset": 0,
        "slot": "1",
        "type": "t_uint256"
      },
      {
        "astId": 6413,
        "contract": "contracts/oracles/WeETHAccountantOracle.sol:WeETHAccountantOracle",
        "label": "snapshotMaxExchangeRate",
        "offset": 0,
        "slot": "2",
        "type": "t_uint256"
      },
      {
        "astId": 6416,
        "contract": "contracts/oracles/WeETHAccountantOracle.sol:WeETHAccountantOracle",
        "label": "snapshotTimestamp",
        "offset": 0,
        "slot": "3",
        "type": "t_uint256"
      },
      {
        "astId": 6419,
        "contract": "contracts/oracles/WeETHAccountantOracle.sol:WeETHAccountantOracle",
        "label": "snapshotGap",
        "offset": 0,
        "slot": "4",
        "type": "t_uint256"
      }
    ],
    "types": {
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      }
    }
  }
}
