From e1daa535ebecd38684c860bedc7d2a51d95c01b2 Mon Sep 17 00:00:00 2001 From: GitGuru7 Date: Mon, 29 Sep 2025 21:00:16 +0530 Subject: [PATCH 1/4] feat: deploy PT-xSolvBTC and PT-SolvBTC.BNB oracles on bsctestnet --- deploy/25-deploy-bsc-pendle-oracle.ts | 111 +++ ...PendleOracle-PT-SolvBTC.BNB-18DEC2025.json | 785 ++++++++++++++++++ .../PendleOracle-PT-xSolvBTC-18DEC2025.json | 785 ++++++++++++++++++ helpers/deploymentConfig.ts | 2 + 4 files changed, 1683 insertions(+) create mode 100644 deploy/25-deploy-bsc-pendle-oracle.ts create mode 100644 deployments/bsctestnet/PendleOracle-PT-SolvBTC.BNB-18DEC2025.json create mode 100644 deployments/bsctestnet/PendleOracle-PT-xSolvBTC-18DEC2025.json diff --git a/deploy/25-deploy-bsc-pendle-oracle.ts b/deploy/25-deploy-bsc-pendle-oracle.ts new file mode 100644 index 00000000..ef82d446 --- /dev/null +++ b/deploy/25-deploy-bsc-pendle-oracle.ts @@ -0,0 +1,111 @@ +import { ethers } from "hardhat"; +import { DeployFunction } from "hardhat-deploy/dist/types"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; + +import { ADDRESSES } from "../helpers/deploymentConfig"; +import { isMainnet } from "../helpers/deploymentUtils"; + +enum PendleRateKind { + PT_TO_ASSET = 0, + PT_TO_SY = 1, +} + +type OracleConfig = { + TokenSymbol: string; + marketFallback: string; + underlyingToken: string; + TWAPDuration: number; + primaryRateKind: PendleRateKind; +}[]; + +const func: DeployFunction = async ({ getNamedAccounts, deployments, network }: HardhatRuntimeEnvironment) => { + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + + const resilientOracle = await ethers.getContract("ResilientOracle"); + const addresses = ADDRESSES[network.name]; + const ptOracleAddress = addresses.PTOracle || (await ethers.getContract("MockPendlePtOracle")).address; + + const oracleConfig: OracleConfig = [ + { + TokenSymbol: "PT-xSolvBTC-18DEC2025", + marketFallback: "0x0000000000000000000000000000000000000005", + underlyingToken: addresses.xSolvBTC, + TWAPDuration: 1800, + primaryRateKind: PendleRateKind.PT_TO_SY, + }, + { + TokenSymbol: "PT-SolvBTC.BNB-18DEC2025", + marketFallback: "0x0000000000000000000000000000000000000006", + underlyingToken: addresses["SolvBTC.BBN"], + TWAPDuration: 1800, + primaryRateKind: PendleRateKind.PT_TO_SY, + }, + ]; + + const commonParams = { + from: deployer, + log: true, + deterministicDeployment: false, + skipIfAlreadyDeployed: true, + waitConfirmations: 1, + }; + + for (const oracle of oracleConfig) { + await deploy(`PendleOracle-${oracle.TokenSymbol}`, { + contract: "PendleOracle", + args: [ + { + market: addresses[`${oracle.TokenSymbol}_Market`] || oracle.marketFallback, + ptOracle: ptOracleAddress, + rateKind: oracle.primaryRateKind, + ptToken: addresses[oracle.TokenSymbol], + underlyingToken: oracle.underlyingToken, + resilientOracle: resilientOracle.address, + twapDuration: oracle.TWAPDuration, + annualGrowthRate: 0, + snapshotInterval: 0, + initialSnapshotMaxExchangeRate: 0, + initialSnapshotTimestamp: 0, + accessControlManager: addresses.acm, + snapshotGap: 0, + }, + ], + ...commonParams, + }); + + if (isMainnet(network)) { + const referenceRateKind = + oracle.primaryRateKind === PendleRateKind.PT_TO_ASSET ? PendleRateKind.PT_TO_SY : PendleRateKind.PT_TO_ASSET; + await deploy("PendleOracle-PT-USDe-30OCT2025_Reference_PtToAsset", { + contract: "PendleOracle", + from: deployer, + log: true, + deterministicDeployment: false, + args: [ + { + market: addresses[`${oracle.TokenSymbol}_Market`] || oracle.marketFallback, + ptOracle: ptOracleAddress, + rateKind: referenceRateKind, + ptToken: addresses[oracle.TokenSymbol], + underlyingToken: oracle.underlyingToken, + resilientOracle: resilientOracle.address, + twapDuration: oracle.TWAPDuration, + annualGrowthRate: 0, + snapshotInterval: 0, + initialSnapshotMaxExchangeRate: 0, + initialSnapshotTimestamp: 0, + accessControlManager: addresses.acm, + snapshotGap: 0, + }, + ], + skipIfAlreadyDeployed: true, + }); + } + } +}; + +export default func; +func.tags = ["PT-Oracle"]; +func.skip = async (hre: HardhatRuntimeEnvironment) => + hre.network.name !== "bsctestnet" && hre.network.name !== "bscmainnet"; diff --git a/deployments/bsctestnet/PendleOracle-PT-SolvBTC.BNB-18DEC2025.json b/deployments/bsctestnet/PendleOracle-PT-SolvBTC.BNB-18DEC2025.json new file mode 100644 index 00000000..3b423181 --- /dev/null +++ b/deployments/bsctestnet/PendleOracle-PT-SolvBTC.BNB-18DEC2025.json @@ -0,0 +1,785 @@ +{ + "address": "0x137cbEf31e76e6aF6818Fb50f52D3f7cF1d46d55", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "address", + "name": "ptOracle", + "type": "address" + }, + { + "internalType": "enum PendleOracle.RateKind", + "name": "rateKind", + "type": "uint8" + }, + { + "internalType": "address", + "name": "ptToken", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "resilientOracle", + "type": "address" + }, + { + "internalType": "uint32", + "name": "twapDuration", + "type": "uint32" + }, + { + "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" + } + ], + "internalType": "struct PendleOracle.ConstructorParams", + "name": "params", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "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" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "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": "CORRELATED_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MARKET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_ORACLE", + "outputs": [ + { + "internalType": "contract IPendlePtOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_KIND", + "outputs": [ + { + "internalType": "enum PendleOracle.RateKind", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RESILIENT_ORACLE", + "outputs": [ + { + "internalType": "contract ResilientOracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TWAP_DURATION", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_DECIMALS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "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": "0x93d93020741e068f2520221b6ace7b4115edada47be88cca1b922f144f0b5c74", + "receipt": { + "to": null, + "from": "0xe2a089cA69a90f1E27E723EFD339Cff4c4701AcC", + "contractAddress": "0x137cbEf31e76e6aF6818Fb50f52D3f7cF1d46d55", + "transactionIndex": 0, + "gasUsed": "941190", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xc5600913f916e8587bc657d2e5520c365c7792e5ff8e0051c67127d268d4f33b", + "transactionHash": "0x93d93020741e068f2520221b6ace7b4115edada47be88cca1b922f144f0b5c74", + "logs": [], + "blockNumber": 67071209, + "cumulativeGasUsed": "941190", + "status": 1, + "byzantium": true + }, + "args": [ + { + "market": "0x0000000000000000000000000000000000000006", + "ptOracle": "0xa37A9127C302fEc17d456a6E1a5643a18a1779aD", + "rateKind": 1, + "ptToken": "0x666DeDB281A49C2cA493b7766311467062F11f09", + "underlyingToken": "0x8FD14481C1616d9AdA7195Be60f9d8d0994b9AE1", + "resilientOracle": "0x3cD69251D04A28d887Ac14cbe2E14c52F3D57823", + "twapDuration": 1800, + "annualGrowthRate": 0, + "snapshotInterval": 0, + "initialSnapshotMaxExchangeRate": 0, + "initialSnapshotTimestamp": 0, + "accessControlManager": "0x45f8a08F534f34A97187626E05d4b6648Eeaa9AA", + "snapshotGap": 0 + } + ], + "numDeployments": 1, + "solcInputHash": "eb7ae6b5763315e358adb74172778b7c", + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ptOracle\",\"type\":\"address\"},{\"internalType\":\"enum PendleOracle.RateKind\",\"name\":\"rateKind\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"ptToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"underlyingToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resilientOracle\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"twapDuration\",\"type\":\"uint32\"},{\"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\"}],\"internalType\":\"struct PendleOracle.ConstructorParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidDuration\",\"type\":\"error\"},{\"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\"},{\"inputs\":[],\"name\":\"ZeroValueNotAllowed\",\"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\":\"CORRELATED_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MARKET\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PT_ORACLE\",\"outputs\":[{\"internalType\":\"contract IPendlePtOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RATE_KIND\",\"outputs\":[{\"internalType\":\"enum PendleOracle.RateKind\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RESILIENT_ORACLE\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TWAP_DURATION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UNDERLYING_DECIMALS\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"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\",\"details\":\"As a base price the oracle uses either the price of the Pendle market's asset (in this case PT_TO_ASSET rate should be used) or the price of the Pendle market's interest bearing token (e.g. wstETH for stETH; in this case PT_TO_SY rate should be used). Technically, interest bearing token is different from standardized yield (SY) token, but since SY is a wrapper around an interest bearing token, we can safely assume the prices of the two are equal. This is not always true for asset price though: using PT_TO_ASSET rate assumes that the yield token can be seamlessly redeemed for the underlying asset. In reality, this might not always be the case. For more details, see https://docs.pendle.finance/Developers/Contracts/StandardizedYield\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:error\":\"InvalidDuration Thrown if the duration is invalid\"},\"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 The amount of underlying token (either the market's asset or the yield token) for 1 PT, adjusted for decimals such that the result has the same precision as the underlying token\"}},\"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\"}},\"stateVariables\":{\"UNDERLYING_DECIMALS\":{\"details\":\"We make an assumption that the underlying decimals will not change throughout the lifetime of the Pendle market\"}},\"title\":\"PendleOracle\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidDuration()\":[{\"notice\":\"Thrown if the duration is invalid\"}],\"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\"}],\"ZeroValueNotAllowed()\":[{\"notice\":\"Thrown if the supplied value is 0 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\"},\"CORRELATED_TOKEN()\":{\"notice\":\"Address of the correlated token\"},\"MARKET()\":{\"notice\":\"Address of the market\"},\"PT_ORACLE()\":{\"notice\":\"Address of the PT oracle\"},\"RATE_KIND()\":{\"notice\":\"Whether to use PT/SY (standardized yield token) rate or PT/market asset rate\"},\"RESILIENT_ORACLE()\":{\"notice\":\"Address of Resilient Oracle\"},\"TWAP_DURATION()\":{\"notice\":\"Twap duration for the oracle\"},\"UNDERLYING_DECIMALS()\":{\"notice\":\"Decimals of the underlying token\"},\"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\":\"Fetches the amount of underlying token for 1 PT\"},\"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 a pendle token\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracles/PendleOracle.sol\":\"PendleOracle\"},\"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/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/IPendlePtOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\ninterface IPendlePtOracle {\\n function getPtToAssetRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getPtToSyRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getOracleState(\\n address market,\\n uint32 duration\\n )\\n external\\n view\\n returns (bool increaseCardinalityRequired, uint16 cardinalityRequired, bool oldestObservationSatisfied);\\n}\\n\",\"keccak256\":\"0x14d96d7f75397e4291288ef6367053bd970d95fc0c3e2a028b077f6342e0160a\",\"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/PendleOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { IPendlePtOracle } from \\\"../interfaces/IPendlePtOracle.sol\\\";\\nimport { CorrelatedTokenOracle } from \\\"./common/CorrelatedTokenOracle.sol\\\";\\nimport { ensureNonzeroAddress, ensureNonzeroValue } from \\\"@venusprotocol/solidity-utilities/contracts/validators.sol\\\";\\nimport { IERC20Metadata } from \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\n/**\\n * @title PendleOracle\\n * @author Venus\\n * @notice This oracle fetches the price of a pendle token\\n * @dev As a base price the oracle uses either the price of the Pendle\\n * market's asset (in this case PT_TO_ASSET rate should be used) or\\n * the price of the Pendle market's interest bearing token (e.g. wstETH\\n * for stETH; in this case PT_TO_SY rate should be used). Technically,\\n * interest bearing token is different from standardized yield (SY) token,\\n * but since SY is a wrapper around an interest bearing token, we can safely\\n * assume the prices of the two are equal. This is not always true for asset\\n * price though: using PT_TO_ASSET rate assumes that the yield token can\\n * be seamlessly redeemed for the underlying asset. In reality, this might\\n * not always be the case. For more details, see\\n * https://docs.pendle.finance/Developers/Contracts/StandardizedYield\\n */\\ncontract PendleOracle is CorrelatedTokenOracle {\\n struct ConstructorParams {\\n /// @notice Pendle market\\n address market;\\n /// @notice Pendle oracle\\n address ptOracle;\\n /// @notice Either PT_TO_ASSET or PT_TO_SY\\n RateKind rateKind;\\n /// @notice Pendle PT token\\n address ptToken;\\n /// @notice Underlying token, can be either the market's asset or the interest bearing token\\n address underlyingToken;\\n /// @notice Resilient oracle to get the underlying token price from\\n address resilientOracle;\\n /// @notice TWAP duration to call Pendle oracle with\\n uint32 twapDuration;\\n /// @notice Annual growth rate of the underlying token\\n uint256 annualGrowthRate;\\n /// @notice Snapshot interval for the oracle\\n uint256 snapshotInterval;\\n /// @notice Initial exchange rate of the underlying token\\n uint256 initialSnapshotMaxExchangeRate;\\n /// @notice Initial timestamp of the underlying token\\n uint256 initialSnapshotTimestamp;\\n /// @notice Access control manager\\n address accessControlManager;\\n /// @notice Gap to add when updating the snapshot\\n uint256 snapshotGap;\\n }\\n\\n /// @notice Which asset to use as a base for the returned PT\\n /// price. Can be either a standardized yield token (SY), in\\n /// this case PT/SY price is returned, or the Pendle\\n /// market's asset directly.\\n enum RateKind {\\n PT_TO_ASSET,\\n PT_TO_SY\\n }\\n\\n /// @notice Address of the PT oracle\\n IPendlePtOracle public immutable PT_ORACLE;\\n\\n /// @notice Whether to use PT/SY (standardized yield token) rate\\n /// or PT/market asset rate\\n RateKind public immutable RATE_KIND;\\n\\n /// @notice Address of the market\\n address public immutable MARKET;\\n\\n /// @notice Twap duration for the oracle\\n uint32 public immutable TWAP_DURATION;\\n\\n /// @notice Decimals of the underlying token\\n /// @dev We make an assumption that the underlying decimals will\\n /// not change throughout the lifetime of the Pendle market\\n uint8 public immutable UNDERLYING_DECIMALS;\\n\\n /// @notice Thrown if the duration is invalid\\n error InvalidDuration();\\n\\n /**\\n * @notice Constructor for the implementation contract.\\n * @custom:error InvalidDuration Thrown if the duration is invalid\\n */\\n constructor(\\n ConstructorParams memory params\\n )\\n CorrelatedTokenOracle(\\n params.ptToken,\\n params.underlyingToken,\\n params.resilientOracle,\\n params.annualGrowthRate,\\n params.snapshotInterval,\\n params.initialSnapshotMaxExchangeRate,\\n params.initialSnapshotTimestamp,\\n params.accessControlManager,\\n params.snapshotGap\\n )\\n {\\n ensureNonzeroAddress(params.market);\\n ensureNonzeroAddress(params.ptOracle);\\n ensureNonzeroValue(params.twapDuration);\\n\\n MARKET = params.market;\\n PT_ORACLE = IPendlePtOracle(params.ptOracle);\\n RATE_KIND = params.rateKind;\\n TWAP_DURATION = params.twapDuration;\\n UNDERLYING_DECIMALS = IERC20Metadata(UNDERLYING_TOKEN).decimals();\\n\\n (bool increaseCardinalityRequired, , bool oldestObservationSatisfied) = PT_ORACLE.getOracleState(\\n MARKET,\\n TWAP_DURATION\\n );\\n if (increaseCardinalityRequired || !oldestObservationSatisfied) {\\n revert InvalidDuration();\\n }\\n }\\n\\n /// @notice Fetches the amount of underlying token for 1 PT\\n /// @return amount The amount of underlying token (either the market's asset\\n /// or the yield token) for 1 PT, adjusted for decimals such that the result\\n /// has the same precision as the underlying token\\n function getUnderlyingAmount() public view override returns (uint256) {\\n uint256 rate;\\n if (RATE_KIND == RateKind.PT_TO_SY) {\\n rate = PT_ORACLE.getPtToSyRate(MARKET, TWAP_DURATION);\\n } else {\\n rate = PT_ORACLE.getPtToAssetRate(MARKET, TWAP_DURATION);\\n }\\n return ((10 ** UNDERLYING_DECIMALS) * rate) / 1e18;\\n }\\n}\\n\",\"keccak256\":\"0xaa7963ac7657ea62079c2162cb4fc45524f8ffbbc6e84f89a5d4e54b71dc6025\",\"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": "0x6101a0604052348015610010575f80fd5b5060405161155938038061155983398101604081905261002f916103a6565b6060810151608082015160a083015160e084015161010085015161012086015161014087015161016088015161018089015161006f6301e1338087610481565b5f81905515801561007f57505f85115b8061009357505f8054118015610093575084155b156100b1576040516353b7e64560e11b815260040160405180910390fd5b8315806100bc575082155b80156100c757505f85115b156100e55760405163b8a5589b60e01b815260040160405180910390fd5b6100ee896102eb565b6100f7886102eb565b610100876102eb565b610109826102eb565b6001600160a01b0398891660805296881660a05294871660c052600192909255600255600355506004919091551660e0528051610145906102eb565b6020810151610153906102eb565b60c08101516101679063ffffffff16610315565b80516001600160a01b03908116610140526020820151166101005260408101516001811115610198576101986104a0565b6101208160018111156101ad576101ad6104a0565b815250508060c0015163ffffffff166101608163ffffffff168152505060a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610208573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061022c91906104b4565b60ff166101805261010051610140516101605160405162439f4b60e91b81526001600160a01b03928316600482015263ffffffff90911660248201525f928392169063873e960090604401606060405180830381865afa158015610292573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102b691906104ea565b925050915081806102c5575080155b156102e357604051637616640160e01b815260040160405180910390fd5b505050610532565b6001600160a01b038116610312576040516342bcdf7f60e11b815260040160405180910390fd5b50565b805f036103125760405163273e150360e21b815260040160405180910390fd5b6040516101a081016001600160401b038111828210171561036457634e487b7160e01b5f52604160045260245ffd5b60405290565b80516001600160a01b0381168114610380575f80fd5b919050565b805160028110610380575f80fd5b805163ffffffff81168114610380575f80fd5b5f6101a082840312156103b7575f80fd5b6103bf610335565b6103c88361036a565b81526103d66020840161036a565b60208201526103e760408401610385565b60408201526103f86060840161036a565b60608201526104096080840161036a565b608082015261041a60a0840161036a565b60a082015261042b60c08401610393565b60c082015260e0838101519082015261010080840151908201526101208084015190820152610140808401519082015261016061046981850161036a565b90820152610180928301519281019290925250919050565b5f8261049b57634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52602160045260245ffd5b5f602082840312156104c4575f80fd5b815160ff811681146104d4575f80fd5b9392505050565b80518015158114610380575f80fd5b5f805f606084860312156104fc575f80fd5b610505846104db565b9250602084015161ffff8116811461051b575f80fd5b9150610529604085016104db565b90509250925092565b60805160a05160c05160e0516101005161012051610140516101605161018051610f596106005f395f81816101d9015261099d01525f81816103070152818161081b01526108f601525f818161038b015281816107f301526108ce01525f818161014601526107a701525f81816102e001528181610847015261092201525f818161022e0152610b9a01525f818161034c0152818161069c0152610a6d01525f818161019a015281816106740152610a4101525f81816102a6015281816103b00152610adb0152610f595ff3fe608060405234801561000f575f80fd5b506004361061013d575f3560e01c806369240426116100b45780639c43eb54116100795780639c43eb541461033e578063a4edcd4c14610347578063abb856131461036e578063ac5a693e14610376578063bdf13af21461037e578063f46f16c214610386575f80fd5b8063692404261461029957806369818a35146102a15780637fc4e4a0146102c8578063809d7b31146102db578063879ac8f814610302575f80fd5b806341976e091161010557806341976e091461021657806345be2dc7146102295780635213f9c814610250578063596efe6f14610265578063643d813d1461026e578063671528d414610281575f80fd5b806302125d091461014157806307d0413c1461017e57806329db1be6146101955780633dae7c22146101d45780634169d2451461020d575b5f80fd5b6101687f000000000000000000000000000000000000000000000000000000000000000081565b6040516101759190610c57565b60405180910390f35b61018760015481565b604051908152602001610175565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610175565b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610175565b61018760045481565b610187610224366004610c7d565b6103ad565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b61026361025e366004610ca3565b61045e565b005b61018760025481565b61026361027c366004610cba565b6104cf565b6102896105a5565b6040519015158152602001610175565b6102636105e0565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6102636102d6366004610cba565b610729565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b61018760035481565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6101876107a1565b6101875f5481565b6101876109dd565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461040057604051630f58058360e11b815260040160405180910390fd5b5f6104096107a1565b90506001545f036104245761041d81610a2a565b9392505050565b5f61042d6109dd565b90505f818311801561043e57508115155b610448578261044a565b815b905061045581610a2a565b95945050505050565b61049c6040518060400160405280601781526020017f736574536e617073686f744761702875696e7432353629000000000000000000815250610b81565b6004546040518291907feb3716d3f8388c182853c1dc98b18931f3a600bbab31f2ff48631f6412e4997f905f90a3600455565b61050d6040518060400160405280601e81526020017f73657447726f777468526174652875696e743235362c75696e74323536290000815250610b81565b5f5461051d6301e1338084610cee565b5f81905515801561052d57505f82115b8061054157505f8054118015610541575081155b1561055f576040516353b7e64560e11b815260040160405180910390fd5b6001545f54827fa65cbeb0e28a8803a912daac67c472c160aa01e2c988755fa424f290321de6088560405161059691815260200190565b60405180910390a45060015550565b5f6001545f036105b457505f90565b5f6105bd6109dd565b9050805f036105cd575f91505090565b5f6105d66107a1565b9190911192915050565b6001546003546105f09042610d0d565b10806105fc5750600154155b1561060357565b5f61060c6107a1565b90505f6106176109dd565b9050600454818311610629578261062b565b815b6106359190610d26565b6002819055426003555f0361065d57604051635f18388760e01b815260040160405180910390fd5b60405163b62cad6960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b62cad69906024015f604051808303815f87803b1580156106dd575f80fd5b505af11580156106ef573d5f803e3d5ffd5b505050506003546002547f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d60405160405180910390a35050565b6107676040518060400160405280601c81526020017f736574536e617073686f742875696e743235362c75696e743235362900000000815250610b81565b60028290556003819055604051819083907f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d905f90a35050565b5f8060017f000000000000000000000000000000000000000000000000000000000000000060018111156107d7576107d7610c43565b036108b75760405163a31426d160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a31426d190604401602060405180830381865afa15801561088c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b09190610d39565b905061098e565b60405163abca0eab60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa158015610967573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098b9190610d39565b90505b670de0b6b3a7640000816109c37f0000000000000000000000000000000000000000000000000000000000000000600a610e30565b6109cd9190610e3e565b6109d79190610cee565b91505090565b5f80600354426109ed9190610d0d565b90505f670de0b6b3a7640000825f54600254610a099190610e3e565b610a139190610e3e565b610a1d9190610cee565b60025461041d9190610d26565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa158015610ab2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad69190610d39565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b39573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5d9190610e55565b60ff169050610b6d81600a610e75565b610b778487610e3e565b6104559190610cee565b6040516318c5e8ab60e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906318c5e8ab90610bd19033908690600401610eae565b602060405180830381865afa158015610bec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c109190610ed9565b905080610c3f57333083604051634a3fa29360e01b8152600401610c3693929190610ef8565b60405180910390fd5b5050565b634e487b7160e01b5f52602160045260245ffd5b6020810160028310610c7757634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215610c8d575f80fd5b81356001600160a01b038116811461041d575f80fd5b5f60208284031215610cb3575f80fd5b5035919050565b5f8060408385031215610ccb575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f82610d0857634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610d2057610d20610cda565b92915050565b80820180821115610d2057610d20610cda565b5f60208284031215610d49575f80fd5b5051919050565b600181815b80851115610d8a57815f1904821115610d7057610d70610cda565b80851615610d7d57918102915b93841c9390800290610d55565b509250929050565b5f82610da057506001610d20565b81610dac57505f610d20565b8160018114610dc25760028114610dcc57610de8565b6001915050610d20565b60ff841115610ddd57610ddd610cda565b50506001821b610d20565b5060208310610133831016604e8410600b8410161715610e0b575081810a610d20565b610e158383610d50565b805f1904821115610e2857610e28610cda565b029392505050565b5f61041d60ff841683610d92565b8082028115828204841417610d2057610d20610cda565b5f60208284031215610e65575f80fd5b815160ff8116811461041d575f80fd5b5f61041d8383610d92565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03831681526040602082018190525f90610ed190830184610e80565b949350505050565b5f60208284031215610ee9575f80fd5b8151801515811461041d575f80fd5b6001600160a01b038481168252831660208201526060604082018190525f9061045590830184610e8056fea2646970667358221220dd4434cf5ec982b81a2a3a25f96ea3d5d76d95704500f208da19253bd6abc73b64736f6c63430008190033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b506004361061013d575f3560e01c806369240426116100b45780639c43eb54116100795780639c43eb541461033e578063a4edcd4c14610347578063abb856131461036e578063ac5a693e14610376578063bdf13af21461037e578063f46f16c214610386575f80fd5b8063692404261461029957806369818a35146102a15780637fc4e4a0146102c8578063809d7b31146102db578063879ac8f814610302575f80fd5b806341976e091161010557806341976e091461021657806345be2dc7146102295780635213f9c814610250578063596efe6f14610265578063643d813d1461026e578063671528d414610281575f80fd5b806302125d091461014157806307d0413c1461017e57806329db1be6146101955780633dae7c22146101d45780634169d2451461020d575b5f80fd5b6101687f000000000000000000000000000000000000000000000000000000000000000081565b6040516101759190610c57565b60405180910390f35b61018760015481565b604051908152602001610175565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610175565b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610175565b61018760045481565b610187610224366004610c7d565b6103ad565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b61026361025e366004610ca3565b61045e565b005b61018760025481565b61026361027c366004610cba565b6104cf565b6102896105a5565b6040519015158152602001610175565b6102636105e0565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6102636102d6366004610cba565b610729565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b61018760035481565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6101876107a1565b6101875f5481565b6101876109dd565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461040057604051630f58058360e11b815260040160405180910390fd5b5f6104096107a1565b90506001545f036104245761041d81610a2a565b9392505050565b5f61042d6109dd565b90505f818311801561043e57508115155b610448578261044a565b815b905061045581610a2a565b95945050505050565b61049c6040518060400160405280601781526020017f736574536e617073686f744761702875696e7432353629000000000000000000815250610b81565b6004546040518291907feb3716d3f8388c182853c1dc98b18931f3a600bbab31f2ff48631f6412e4997f905f90a3600455565b61050d6040518060400160405280601e81526020017f73657447726f777468526174652875696e743235362c75696e74323536290000815250610b81565b5f5461051d6301e1338084610cee565b5f81905515801561052d57505f82115b8061054157505f8054118015610541575081155b1561055f576040516353b7e64560e11b815260040160405180910390fd5b6001545f54827fa65cbeb0e28a8803a912daac67c472c160aa01e2c988755fa424f290321de6088560405161059691815260200190565b60405180910390a45060015550565b5f6001545f036105b457505f90565b5f6105bd6109dd565b9050805f036105cd575f91505090565b5f6105d66107a1565b9190911192915050565b6001546003546105f09042610d0d565b10806105fc5750600154155b1561060357565b5f61060c6107a1565b90505f6106176109dd565b9050600454818311610629578261062b565b815b6106359190610d26565b6002819055426003555f0361065d57604051635f18388760e01b815260040160405180910390fd5b60405163b62cad6960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b62cad69906024015f604051808303815f87803b1580156106dd575f80fd5b505af11580156106ef573d5f803e3d5ffd5b505050506003546002547f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d60405160405180910390a35050565b6107676040518060400160405280601c81526020017f736574536e617073686f742875696e743235362c75696e743235362900000000815250610b81565b60028290556003819055604051819083907f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d905f90a35050565b5f8060017f000000000000000000000000000000000000000000000000000000000000000060018111156107d7576107d7610c43565b036108b75760405163a31426d160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a31426d190604401602060405180830381865afa15801561088c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b09190610d39565b905061098e565b60405163abca0eab60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa158015610967573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098b9190610d39565b90505b670de0b6b3a7640000816109c37f0000000000000000000000000000000000000000000000000000000000000000600a610e30565b6109cd9190610e3e565b6109d79190610cee565b91505090565b5f80600354426109ed9190610d0d565b90505f670de0b6b3a7640000825f54600254610a099190610e3e565b610a139190610e3e565b610a1d9190610cee565b60025461041d9190610d26565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa158015610ab2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad69190610d39565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b39573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5d9190610e55565b60ff169050610b6d81600a610e75565b610b778487610e3e565b6104559190610cee565b6040516318c5e8ab60e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906318c5e8ab90610bd19033908690600401610eae565b602060405180830381865afa158015610bec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c109190610ed9565b905080610c3f57333083604051634a3fa29360e01b8152600401610c3693929190610ef8565b60405180910390fd5b5050565b634e487b7160e01b5f52602160045260245ffd5b6020810160028310610c7757634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215610c8d575f80fd5b81356001600160a01b038116811461041d575f80fd5b5f60208284031215610cb3575f80fd5b5035919050565b5f8060408385031215610ccb575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f82610d0857634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610d2057610d20610cda565b92915050565b80820180821115610d2057610d20610cda565b5f60208284031215610d49575f80fd5b5051919050565b600181815b80851115610d8a57815f1904821115610d7057610d70610cda565b80851615610d7d57918102915b93841c9390800290610d55565b509250929050565b5f82610da057506001610d20565b81610dac57505f610d20565b8160018114610dc25760028114610dcc57610de8565b6001915050610d20565b60ff841115610ddd57610ddd610cda565b50506001821b610d20565b5060208310610133831016604e8410600b8410161715610e0b575081810a610d20565b610e158383610d50565b805f1904821115610e2857610e28610cda565b029392505050565b5f61041d60ff841683610d92565b8082028115828204841417610d2057610d20610cda565b5f60208284031215610e65575f80fd5b815160ff8116811461041d575f80fd5b5f61041d8383610d92565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03831681526040602082018190525f90610ed190830184610e80565b949350505050565b5f60208284031215610ee9575f80fd5b8151801515811461041d575f80fd5b6001600160a01b038481168252831660208201526060604082018190525f9061045590830184610e8056fea2646970667358221220dd4434cf5ec982b81a2a3a25f96ea3d5d76d95704500f208da19253bd6abc73b64736f6c63430008190033", + "devdoc": { + "author": "Venus", + "details": "As a base price the oracle uses either the price of the Pendle market's asset (in this case PT_TO_ASSET rate should be used) or the price of the Pendle market's interest bearing token (e.g. wstETH for stETH; in this case PT_TO_SY rate should be used). Technically, interest bearing token is different from standardized yield (SY) token, but since SY is a wrapper around an interest bearing token, we can safely assume the prices of the two are equal. This is not always true for asset price though: using PT_TO_ASSET rate assumes that the yield token can be seamlessly redeemed for the underlying asset. In reality, this might not always be the case. For more details, see https://docs.pendle.finance/Developers/Contracts/StandardizedYield", + "kind": "dev", + "methods": { + "constructor": { + "custom:error": "InvalidDuration Thrown if the duration is invalid" + }, + "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 The amount of underlying token (either the market's asset or the yield token) for 1 PT, adjusted for decimals such that the result has the same precision as the underlying token" + } + }, + "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" + } + }, + "stateVariables": { + "UNDERLYING_DECIMALS": { + "details": "We make an assumption that the underlying decimals will not change throughout the lifetime of the Pendle market" + } + }, + "title": "PendleOracle", + "version": 1 + }, + "userdoc": { + "errors": { + "InvalidDuration()": [ + { + "notice": "Thrown if the duration is invalid" + } + ], + "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" + } + ], + "ZeroValueNotAllowed()": [ + { + "notice": "Thrown if the supplied value is 0 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" + }, + "CORRELATED_TOKEN()": { + "notice": "Address of the correlated token" + }, + "MARKET()": { + "notice": "Address of the market" + }, + "PT_ORACLE()": { + "notice": "Address of the PT oracle" + }, + "RATE_KIND()": { + "notice": "Whether to use PT/SY (standardized yield token) rate or PT/market asset rate" + }, + "RESILIENT_ORACLE()": { + "notice": "Address of Resilient Oracle" + }, + "TWAP_DURATION()": { + "notice": "Twap duration for the oracle" + }, + "UNDERLYING_DECIMALS()": { + "notice": "Decimals of the underlying token" + }, + "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": "Fetches the amount of underlying token for 1 PT" + }, + "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 a pendle token", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6602, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "growthRatePerSecond", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 6605, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotInterval", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 6608, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotMaxExchangeRate", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 6611, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotTimestamp", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 6614, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotGap", + "offset": 0, + "slot": "4", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/bsctestnet/PendleOracle-PT-xSolvBTC-18DEC2025.json b/deployments/bsctestnet/PendleOracle-PT-xSolvBTC-18DEC2025.json new file mode 100644 index 00000000..0307c9e5 --- /dev/null +++ b/deployments/bsctestnet/PendleOracle-PT-xSolvBTC-18DEC2025.json @@ -0,0 +1,785 @@ +{ + "address": "0x2dE6EC714173e92D7A0138d0Eee4EA09FCF11965", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "address", + "name": "ptOracle", + "type": "address" + }, + { + "internalType": "enum PendleOracle.RateKind", + "name": "rateKind", + "type": "uint8" + }, + { + "internalType": "address", + "name": "ptToken", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "resilientOracle", + "type": "address" + }, + { + "internalType": "uint32", + "name": "twapDuration", + "type": "uint32" + }, + { + "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" + } + ], + "internalType": "struct PendleOracle.ConstructorParams", + "name": "params", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "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" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "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": "CORRELATED_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MARKET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_ORACLE", + "outputs": [ + { + "internalType": "contract IPendlePtOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_KIND", + "outputs": [ + { + "internalType": "enum PendleOracle.RateKind", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RESILIENT_ORACLE", + "outputs": [ + { + "internalType": "contract ResilientOracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TWAP_DURATION", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_DECIMALS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "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": "0x3da66557a63a977725a8b8261edb42cb844359fe45d4b1c98e85fc6df23c4e4d", + "receipt": { + "to": null, + "from": "0xe2a089cA69a90f1E27E723EFD339Cff4c4701AcC", + "contractAddress": "0x2dE6EC714173e92D7A0138d0Eee4EA09FCF11965", + "transactionIndex": 0, + "gasUsed": "941190", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd05b7c0844aeb109942cb8b528a58aba02c3551034b9c5173a68078be15fa5b9", + "transactionHash": "0x3da66557a63a977725a8b8261edb42cb844359fe45d4b1c98e85fc6df23c4e4d", + "logs": [], + "blockNumber": 67071188, + "cumulativeGasUsed": "941190", + "status": 1, + "byzantium": true + }, + "args": [ + { + "market": "0x0000000000000000000000000000000000000005", + "ptOracle": "0xa37A9127C302fEc17d456a6E1a5643a18a1779aD", + "rateKind": 1, + "ptToken": "0xb786A97032ea5A1Bcfe02341f34599C6DfEA6351", + "underlyingToken": "0x3ea87323806586A0282b50377e0FEa76070F532B", + "resilientOracle": "0x3cD69251D04A28d887Ac14cbe2E14c52F3D57823", + "twapDuration": 1800, + "annualGrowthRate": 0, + "snapshotInterval": 0, + "initialSnapshotMaxExchangeRate": 0, + "initialSnapshotTimestamp": 0, + "accessControlManager": "0x45f8a08F534f34A97187626E05d4b6648Eeaa9AA", + "snapshotGap": 0 + } + ], + "numDeployments": 1, + "solcInputHash": "eb7ae6b5763315e358adb74172778b7c", + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ptOracle\",\"type\":\"address\"},{\"internalType\":\"enum PendleOracle.RateKind\",\"name\":\"rateKind\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"ptToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"underlyingToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resilientOracle\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"twapDuration\",\"type\":\"uint32\"},{\"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\"}],\"internalType\":\"struct PendleOracle.ConstructorParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidDuration\",\"type\":\"error\"},{\"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\"},{\"inputs\":[],\"name\":\"ZeroValueNotAllowed\",\"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\":\"CORRELATED_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MARKET\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PT_ORACLE\",\"outputs\":[{\"internalType\":\"contract IPendlePtOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RATE_KIND\",\"outputs\":[{\"internalType\":\"enum PendleOracle.RateKind\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RESILIENT_ORACLE\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TWAP_DURATION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UNDERLYING_DECIMALS\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"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\",\"details\":\"As a base price the oracle uses either the price of the Pendle market's asset (in this case PT_TO_ASSET rate should be used) or the price of the Pendle market's interest bearing token (e.g. wstETH for stETH; in this case PT_TO_SY rate should be used). Technically, interest bearing token is different from standardized yield (SY) token, but since SY is a wrapper around an interest bearing token, we can safely assume the prices of the two are equal. This is not always true for asset price though: using PT_TO_ASSET rate assumes that the yield token can be seamlessly redeemed for the underlying asset. In reality, this might not always be the case. For more details, see https://docs.pendle.finance/Developers/Contracts/StandardizedYield\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:error\":\"InvalidDuration Thrown if the duration is invalid\"},\"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 The amount of underlying token (either the market's asset or the yield token) for 1 PT, adjusted for decimals such that the result has the same precision as the underlying token\"}},\"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\"}},\"stateVariables\":{\"UNDERLYING_DECIMALS\":{\"details\":\"We make an assumption that the underlying decimals will not change throughout the lifetime of the Pendle market\"}},\"title\":\"PendleOracle\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidDuration()\":[{\"notice\":\"Thrown if the duration is invalid\"}],\"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\"}],\"ZeroValueNotAllowed()\":[{\"notice\":\"Thrown if the supplied value is 0 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\"},\"CORRELATED_TOKEN()\":{\"notice\":\"Address of the correlated token\"},\"MARKET()\":{\"notice\":\"Address of the market\"},\"PT_ORACLE()\":{\"notice\":\"Address of the PT oracle\"},\"RATE_KIND()\":{\"notice\":\"Whether to use PT/SY (standardized yield token) rate or PT/market asset rate\"},\"RESILIENT_ORACLE()\":{\"notice\":\"Address of Resilient Oracle\"},\"TWAP_DURATION()\":{\"notice\":\"Twap duration for the oracle\"},\"UNDERLYING_DECIMALS()\":{\"notice\":\"Decimals of the underlying token\"},\"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\":\"Fetches the amount of underlying token for 1 PT\"},\"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 a pendle token\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracles/PendleOracle.sol\":\"PendleOracle\"},\"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/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/IPendlePtOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\ninterface IPendlePtOracle {\\n function getPtToAssetRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getPtToSyRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getOracleState(\\n address market,\\n uint32 duration\\n )\\n external\\n view\\n returns (bool increaseCardinalityRequired, uint16 cardinalityRequired, bool oldestObservationSatisfied);\\n}\\n\",\"keccak256\":\"0x14d96d7f75397e4291288ef6367053bd970d95fc0c3e2a028b077f6342e0160a\",\"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/PendleOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { IPendlePtOracle } from \\\"../interfaces/IPendlePtOracle.sol\\\";\\nimport { CorrelatedTokenOracle } from \\\"./common/CorrelatedTokenOracle.sol\\\";\\nimport { ensureNonzeroAddress, ensureNonzeroValue } from \\\"@venusprotocol/solidity-utilities/contracts/validators.sol\\\";\\nimport { IERC20Metadata } from \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\n/**\\n * @title PendleOracle\\n * @author Venus\\n * @notice This oracle fetches the price of a pendle token\\n * @dev As a base price the oracle uses either the price of the Pendle\\n * market's asset (in this case PT_TO_ASSET rate should be used) or\\n * the price of the Pendle market's interest bearing token (e.g. wstETH\\n * for stETH; in this case PT_TO_SY rate should be used). Technically,\\n * interest bearing token is different from standardized yield (SY) token,\\n * but since SY is a wrapper around an interest bearing token, we can safely\\n * assume the prices of the two are equal. This is not always true for asset\\n * price though: using PT_TO_ASSET rate assumes that the yield token can\\n * be seamlessly redeemed for the underlying asset. In reality, this might\\n * not always be the case. For more details, see\\n * https://docs.pendle.finance/Developers/Contracts/StandardizedYield\\n */\\ncontract PendleOracle is CorrelatedTokenOracle {\\n struct ConstructorParams {\\n /// @notice Pendle market\\n address market;\\n /// @notice Pendle oracle\\n address ptOracle;\\n /// @notice Either PT_TO_ASSET or PT_TO_SY\\n RateKind rateKind;\\n /// @notice Pendle PT token\\n address ptToken;\\n /// @notice Underlying token, can be either the market's asset or the interest bearing token\\n address underlyingToken;\\n /// @notice Resilient oracle to get the underlying token price from\\n address resilientOracle;\\n /// @notice TWAP duration to call Pendle oracle with\\n uint32 twapDuration;\\n /// @notice Annual growth rate of the underlying token\\n uint256 annualGrowthRate;\\n /// @notice Snapshot interval for the oracle\\n uint256 snapshotInterval;\\n /// @notice Initial exchange rate of the underlying token\\n uint256 initialSnapshotMaxExchangeRate;\\n /// @notice Initial timestamp of the underlying token\\n uint256 initialSnapshotTimestamp;\\n /// @notice Access control manager\\n address accessControlManager;\\n /// @notice Gap to add when updating the snapshot\\n uint256 snapshotGap;\\n }\\n\\n /// @notice Which asset to use as a base for the returned PT\\n /// price. Can be either a standardized yield token (SY), in\\n /// this case PT/SY price is returned, or the Pendle\\n /// market's asset directly.\\n enum RateKind {\\n PT_TO_ASSET,\\n PT_TO_SY\\n }\\n\\n /// @notice Address of the PT oracle\\n IPendlePtOracle public immutable PT_ORACLE;\\n\\n /// @notice Whether to use PT/SY (standardized yield token) rate\\n /// or PT/market asset rate\\n RateKind public immutable RATE_KIND;\\n\\n /// @notice Address of the market\\n address public immutable MARKET;\\n\\n /// @notice Twap duration for the oracle\\n uint32 public immutable TWAP_DURATION;\\n\\n /// @notice Decimals of the underlying token\\n /// @dev We make an assumption that the underlying decimals will\\n /// not change throughout the lifetime of the Pendle market\\n uint8 public immutable UNDERLYING_DECIMALS;\\n\\n /// @notice Thrown if the duration is invalid\\n error InvalidDuration();\\n\\n /**\\n * @notice Constructor for the implementation contract.\\n * @custom:error InvalidDuration Thrown if the duration is invalid\\n */\\n constructor(\\n ConstructorParams memory params\\n )\\n CorrelatedTokenOracle(\\n params.ptToken,\\n params.underlyingToken,\\n params.resilientOracle,\\n params.annualGrowthRate,\\n params.snapshotInterval,\\n params.initialSnapshotMaxExchangeRate,\\n params.initialSnapshotTimestamp,\\n params.accessControlManager,\\n params.snapshotGap\\n )\\n {\\n ensureNonzeroAddress(params.market);\\n ensureNonzeroAddress(params.ptOracle);\\n ensureNonzeroValue(params.twapDuration);\\n\\n MARKET = params.market;\\n PT_ORACLE = IPendlePtOracle(params.ptOracle);\\n RATE_KIND = params.rateKind;\\n TWAP_DURATION = params.twapDuration;\\n UNDERLYING_DECIMALS = IERC20Metadata(UNDERLYING_TOKEN).decimals();\\n\\n (bool increaseCardinalityRequired, , bool oldestObservationSatisfied) = PT_ORACLE.getOracleState(\\n MARKET,\\n TWAP_DURATION\\n );\\n if (increaseCardinalityRequired || !oldestObservationSatisfied) {\\n revert InvalidDuration();\\n }\\n }\\n\\n /// @notice Fetches the amount of underlying token for 1 PT\\n /// @return amount The amount of underlying token (either the market's asset\\n /// or the yield token) for 1 PT, adjusted for decimals such that the result\\n /// has the same precision as the underlying token\\n function getUnderlyingAmount() public view override returns (uint256) {\\n uint256 rate;\\n if (RATE_KIND == RateKind.PT_TO_SY) {\\n rate = PT_ORACLE.getPtToSyRate(MARKET, TWAP_DURATION);\\n } else {\\n rate = PT_ORACLE.getPtToAssetRate(MARKET, TWAP_DURATION);\\n }\\n return ((10 ** UNDERLYING_DECIMALS) * rate) / 1e18;\\n }\\n}\\n\",\"keccak256\":\"0xaa7963ac7657ea62079c2162cb4fc45524f8ffbbc6e84f89a5d4e54b71dc6025\",\"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": "0x6101a0604052348015610010575f80fd5b5060405161155938038061155983398101604081905261002f916103a6565b6060810151608082015160a083015160e084015161010085015161012086015161014087015161016088015161018089015161006f6301e1338087610481565b5f81905515801561007f57505f85115b8061009357505f8054118015610093575084155b156100b1576040516353b7e64560e11b815260040160405180910390fd5b8315806100bc575082155b80156100c757505f85115b156100e55760405163b8a5589b60e01b815260040160405180910390fd5b6100ee896102eb565b6100f7886102eb565b610100876102eb565b610109826102eb565b6001600160a01b0398891660805296881660a05294871660c052600192909255600255600355506004919091551660e0528051610145906102eb565b6020810151610153906102eb565b60c08101516101679063ffffffff16610315565b80516001600160a01b03908116610140526020820151166101005260408101516001811115610198576101986104a0565b6101208160018111156101ad576101ad6104a0565b815250508060c0015163ffffffff166101608163ffffffff168152505060a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610208573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061022c91906104b4565b60ff166101805261010051610140516101605160405162439f4b60e91b81526001600160a01b03928316600482015263ffffffff90911660248201525f928392169063873e960090604401606060405180830381865afa158015610292573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102b691906104ea565b925050915081806102c5575080155b156102e357604051637616640160e01b815260040160405180910390fd5b505050610532565b6001600160a01b038116610312576040516342bcdf7f60e11b815260040160405180910390fd5b50565b805f036103125760405163273e150360e21b815260040160405180910390fd5b6040516101a081016001600160401b038111828210171561036457634e487b7160e01b5f52604160045260245ffd5b60405290565b80516001600160a01b0381168114610380575f80fd5b919050565b805160028110610380575f80fd5b805163ffffffff81168114610380575f80fd5b5f6101a082840312156103b7575f80fd5b6103bf610335565b6103c88361036a565b81526103d66020840161036a565b60208201526103e760408401610385565b60408201526103f86060840161036a565b60608201526104096080840161036a565b608082015261041a60a0840161036a565b60a082015261042b60c08401610393565b60c082015260e0838101519082015261010080840151908201526101208084015190820152610140808401519082015261016061046981850161036a565b90820152610180928301519281019290925250919050565b5f8261049b57634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52602160045260245ffd5b5f602082840312156104c4575f80fd5b815160ff811681146104d4575f80fd5b9392505050565b80518015158114610380575f80fd5b5f805f606084860312156104fc575f80fd5b610505846104db565b9250602084015161ffff8116811461051b575f80fd5b9150610529604085016104db565b90509250925092565b60805160a05160c05160e0516101005161012051610140516101605161018051610f596106005f395f81816101d9015261099d01525f81816103070152818161081b01526108f601525f818161038b015281816107f301526108ce01525f818161014601526107a701525f81816102e001528181610847015261092201525f818161022e0152610b9a01525f818161034c0152818161069c0152610a6d01525f818161019a015281816106740152610a4101525f81816102a6015281816103b00152610adb0152610f595ff3fe608060405234801561000f575f80fd5b506004361061013d575f3560e01c806369240426116100b45780639c43eb54116100795780639c43eb541461033e578063a4edcd4c14610347578063abb856131461036e578063ac5a693e14610376578063bdf13af21461037e578063f46f16c214610386575f80fd5b8063692404261461029957806369818a35146102a15780637fc4e4a0146102c8578063809d7b31146102db578063879ac8f814610302575f80fd5b806341976e091161010557806341976e091461021657806345be2dc7146102295780635213f9c814610250578063596efe6f14610265578063643d813d1461026e578063671528d414610281575f80fd5b806302125d091461014157806307d0413c1461017e57806329db1be6146101955780633dae7c22146101d45780634169d2451461020d575b5f80fd5b6101687f000000000000000000000000000000000000000000000000000000000000000081565b6040516101759190610c57565b60405180910390f35b61018760015481565b604051908152602001610175565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610175565b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610175565b61018760045481565b610187610224366004610c7d565b6103ad565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b61026361025e366004610ca3565b61045e565b005b61018760025481565b61026361027c366004610cba565b6104cf565b6102896105a5565b6040519015158152602001610175565b6102636105e0565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6102636102d6366004610cba565b610729565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b61018760035481565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6101876107a1565b6101875f5481565b6101876109dd565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461040057604051630f58058360e11b815260040160405180910390fd5b5f6104096107a1565b90506001545f036104245761041d81610a2a565b9392505050565b5f61042d6109dd565b90505f818311801561043e57508115155b610448578261044a565b815b905061045581610a2a565b95945050505050565b61049c6040518060400160405280601781526020017f736574536e617073686f744761702875696e7432353629000000000000000000815250610b81565b6004546040518291907feb3716d3f8388c182853c1dc98b18931f3a600bbab31f2ff48631f6412e4997f905f90a3600455565b61050d6040518060400160405280601e81526020017f73657447726f777468526174652875696e743235362c75696e74323536290000815250610b81565b5f5461051d6301e1338084610cee565b5f81905515801561052d57505f82115b8061054157505f8054118015610541575081155b1561055f576040516353b7e64560e11b815260040160405180910390fd5b6001545f54827fa65cbeb0e28a8803a912daac67c472c160aa01e2c988755fa424f290321de6088560405161059691815260200190565b60405180910390a45060015550565b5f6001545f036105b457505f90565b5f6105bd6109dd565b9050805f036105cd575f91505090565b5f6105d66107a1565b9190911192915050565b6001546003546105f09042610d0d565b10806105fc5750600154155b1561060357565b5f61060c6107a1565b90505f6106176109dd565b9050600454818311610629578261062b565b815b6106359190610d26565b6002819055426003555f0361065d57604051635f18388760e01b815260040160405180910390fd5b60405163b62cad6960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b62cad69906024015f604051808303815f87803b1580156106dd575f80fd5b505af11580156106ef573d5f803e3d5ffd5b505050506003546002547f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d60405160405180910390a35050565b6107676040518060400160405280601c81526020017f736574536e617073686f742875696e743235362c75696e743235362900000000815250610b81565b60028290556003819055604051819083907f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d905f90a35050565b5f8060017f000000000000000000000000000000000000000000000000000000000000000060018111156107d7576107d7610c43565b036108b75760405163a31426d160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a31426d190604401602060405180830381865afa15801561088c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b09190610d39565b905061098e565b60405163abca0eab60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa158015610967573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098b9190610d39565b90505b670de0b6b3a7640000816109c37f0000000000000000000000000000000000000000000000000000000000000000600a610e30565b6109cd9190610e3e565b6109d79190610cee565b91505090565b5f80600354426109ed9190610d0d565b90505f670de0b6b3a7640000825f54600254610a099190610e3e565b610a139190610e3e565b610a1d9190610cee565b60025461041d9190610d26565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa158015610ab2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad69190610d39565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b39573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5d9190610e55565b60ff169050610b6d81600a610e75565b610b778487610e3e565b6104559190610cee565b6040516318c5e8ab60e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906318c5e8ab90610bd19033908690600401610eae565b602060405180830381865afa158015610bec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c109190610ed9565b905080610c3f57333083604051634a3fa29360e01b8152600401610c3693929190610ef8565b60405180910390fd5b5050565b634e487b7160e01b5f52602160045260245ffd5b6020810160028310610c7757634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215610c8d575f80fd5b81356001600160a01b038116811461041d575f80fd5b5f60208284031215610cb3575f80fd5b5035919050565b5f8060408385031215610ccb575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f82610d0857634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610d2057610d20610cda565b92915050565b80820180821115610d2057610d20610cda565b5f60208284031215610d49575f80fd5b5051919050565b600181815b80851115610d8a57815f1904821115610d7057610d70610cda565b80851615610d7d57918102915b93841c9390800290610d55565b509250929050565b5f82610da057506001610d20565b81610dac57505f610d20565b8160018114610dc25760028114610dcc57610de8565b6001915050610d20565b60ff841115610ddd57610ddd610cda565b50506001821b610d20565b5060208310610133831016604e8410600b8410161715610e0b575081810a610d20565b610e158383610d50565b805f1904821115610e2857610e28610cda565b029392505050565b5f61041d60ff841683610d92565b8082028115828204841417610d2057610d20610cda565b5f60208284031215610e65575f80fd5b815160ff8116811461041d575f80fd5b5f61041d8383610d92565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03831681526040602082018190525f90610ed190830184610e80565b949350505050565b5f60208284031215610ee9575f80fd5b8151801515811461041d575f80fd5b6001600160a01b038481168252831660208201526060604082018190525f9061045590830184610e8056fea2646970667358221220dd4434cf5ec982b81a2a3a25f96ea3d5d76d95704500f208da19253bd6abc73b64736f6c63430008190033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b506004361061013d575f3560e01c806369240426116100b45780639c43eb54116100795780639c43eb541461033e578063a4edcd4c14610347578063abb856131461036e578063ac5a693e14610376578063bdf13af21461037e578063f46f16c214610386575f80fd5b8063692404261461029957806369818a35146102a15780637fc4e4a0146102c8578063809d7b31146102db578063879ac8f814610302575f80fd5b806341976e091161010557806341976e091461021657806345be2dc7146102295780635213f9c814610250578063596efe6f14610265578063643d813d1461026e578063671528d414610281575f80fd5b806302125d091461014157806307d0413c1461017e57806329db1be6146101955780633dae7c22146101d45780634169d2451461020d575b5f80fd5b6101687f000000000000000000000000000000000000000000000000000000000000000081565b6040516101759190610c57565b60405180910390f35b61018760015481565b604051908152602001610175565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610175565b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610175565b61018760045481565b610187610224366004610c7d565b6103ad565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b61026361025e366004610ca3565b61045e565b005b61018760025481565b61026361027c366004610cba565b6104cf565b6102896105a5565b6040519015158152602001610175565b6102636105e0565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6102636102d6366004610cba565b610729565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b61018760035481565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6101876107a1565b6101875f5481565b6101876109dd565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461040057604051630f58058360e11b815260040160405180910390fd5b5f6104096107a1565b90506001545f036104245761041d81610a2a565b9392505050565b5f61042d6109dd565b90505f818311801561043e57508115155b610448578261044a565b815b905061045581610a2a565b95945050505050565b61049c6040518060400160405280601781526020017f736574536e617073686f744761702875696e7432353629000000000000000000815250610b81565b6004546040518291907feb3716d3f8388c182853c1dc98b18931f3a600bbab31f2ff48631f6412e4997f905f90a3600455565b61050d6040518060400160405280601e81526020017f73657447726f777468526174652875696e743235362c75696e74323536290000815250610b81565b5f5461051d6301e1338084610cee565b5f81905515801561052d57505f82115b8061054157505f8054118015610541575081155b1561055f576040516353b7e64560e11b815260040160405180910390fd5b6001545f54827fa65cbeb0e28a8803a912daac67c472c160aa01e2c988755fa424f290321de6088560405161059691815260200190565b60405180910390a45060015550565b5f6001545f036105b457505f90565b5f6105bd6109dd565b9050805f036105cd575f91505090565b5f6105d66107a1565b9190911192915050565b6001546003546105f09042610d0d565b10806105fc5750600154155b1561060357565b5f61060c6107a1565b90505f6106176109dd565b9050600454818311610629578261062b565b815b6106359190610d26565b6002819055426003555f0361065d57604051635f18388760e01b815260040160405180910390fd5b60405163b62cad6960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b62cad69906024015f604051808303815f87803b1580156106dd575f80fd5b505af11580156106ef573d5f803e3d5ffd5b505050506003546002547f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d60405160405180910390a35050565b6107676040518060400160405280601c81526020017f736574536e617073686f742875696e743235362c75696e743235362900000000815250610b81565b60028290556003819055604051819083907f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d905f90a35050565b5f8060017f000000000000000000000000000000000000000000000000000000000000000060018111156107d7576107d7610c43565b036108b75760405163a31426d160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a31426d190604401602060405180830381865afa15801561088c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b09190610d39565b905061098e565b60405163abca0eab60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa158015610967573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098b9190610d39565b90505b670de0b6b3a7640000816109c37f0000000000000000000000000000000000000000000000000000000000000000600a610e30565b6109cd9190610e3e565b6109d79190610cee565b91505090565b5f80600354426109ed9190610d0d565b90505f670de0b6b3a7640000825f54600254610a099190610e3e565b610a139190610e3e565b610a1d9190610cee565b60025461041d9190610d26565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa158015610ab2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad69190610d39565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b39573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5d9190610e55565b60ff169050610b6d81600a610e75565b610b778487610e3e565b6104559190610cee565b6040516318c5e8ab60e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906318c5e8ab90610bd19033908690600401610eae565b602060405180830381865afa158015610bec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c109190610ed9565b905080610c3f57333083604051634a3fa29360e01b8152600401610c3693929190610ef8565b60405180910390fd5b5050565b634e487b7160e01b5f52602160045260245ffd5b6020810160028310610c7757634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215610c8d575f80fd5b81356001600160a01b038116811461041d575f80fd5b5f60208284031215610cb3575f80fd5b5035919050565b5f8060408385031215610ccb575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f82610d0857634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610d2057610d20610cda565b92915050565b80820180821115610d2057610d20610cda565b5f60208284031215610d49575f80fd5b5051919050565b600181815b80851115610d8a57815f1904821115610d7057610d70610cda565b80851615610d7d57918102915b93841c9390800290610d55565b509250929050565b5f82610da057506001610d20565b81610dac57505f610d20565b8160018114610dc25760028114610dcc57610de8565b6001915050610d20565b60ff841115610ddd57610ddd610cda565b50506001821b610d20565b5060208310610133831016604e8410600b8410161715610e0b575081810a610d20565b610e158383610d50565b805f1904821115610e2857610e28610cda565b029392505050565b5f61041d60ff841683610d92565b8082028115828204841417610d2057610d20610cda565b5f60208284031215610e65575f80fd5b815160ff8116811461041d575f80fd5b5f61041d8383610d92565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03831681526040602082018190525f90610ed190830184610e80565b949350505050565b5f60208284031215610ee9575f80fd5b8151801515811461041d575f80fd5b6001600160a01b038481168252831660208201526060604082018190525f9061045590830184610e8056fea2646970667358221220dd4434cf5ec982b81a2a3a25f96ea3d5d76d95704500f208da19253bd6abc73b64736f6c63430008190033", + "devdoc": { + "author": "Venus", + "details": "As a base price the oracle uses either the price of the Pendle market's asset (in this case PT_TO_ASSET rate should be used) or the price of the Pendle market's interest bearing token (e.g. wstETH for stETH; in this case PT_TO_SY rate should be used). Technically, interest bearing token is different from standardized yield (SY) token, but since SY is a wrapper around an interest bearing token, we can safely assume the prices of the two are equal. This is not always true for asset price though: using PT_TO_ASSET rate assumes that the yield token can be seamlessly redeemed for the underlying asset. In reality, this might not always be the case. For more details, see https://docs.pendle.finance/Developers/Contracts/StandardizedYield", + "kind": "dev", + "methods": { + "constructor": { + "custom:error": "InvalidDuration Thrown if the duration is invalid" + }, + "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 The amount of underlying token (either the market's asset or the yield token) for 1 PT, adjusted for decimals such that the result has the same precision as the underlying token" + } + }, + "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" + } + }, + "stateVariables": { + "UNDERLYING_DECIMALS": { + "details": "We make an assumption that the underlying decimals will not change throughout the lifetime of the Pendle market" + } + }, + "title": "PendleOracle", + "version": 1 + }, + "userdoc": { + "errors": { + "InvalidDuration()": [ + { + "notice": "Thrown if the duration is invalid" + } + ], + "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" + } + ], + "ZeroValueNotAllowed()": [ + { + "notice": "Thrown if the supplied value is 0 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" + }, + "CORRELATED_TOKEN()": { + "notice": "Address of the correlated token" + }, + "MARKET()": { + "notice": "Address of the market" + }, + "PT_ORACLE()": { + "notice": "Address of the PT oracle" + }, + "RATE_KIND()": { + "notice": "Whether to use PT/SY (standardized yield token) rate or PT/market asset rate" + }, + "RESILIENT_ORACLE()": { + "notice": "Address of Resilient Oracle" + }, + "TWAP_DURATION()": { + "notice": "Twap duration for the oracle" + }, + "UNDERLYING_DECIMALS()": { + "notice": "Decimals of the underlying token" + }, + "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": "Fetches the amount of underlying token for 1 PT" + }, + "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 a pendle token", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6602, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "growthRatePerSecond", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 6605, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotInterval", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 6608, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotMaxExchangeRate", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 6611, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotTimestamp", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 6614, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotGap", + "offset": 0, + "slot": "4", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/helpers/deploymentConfig.ts b/helpers/deploymentConfig.ts index 1356e6a2..fb6164f3 100644 --- a/helpers/deploymentConfig.ts +++ b/helpers/deploymentConfig.ts @@ -100,6 +100,8 @@ export const ADDRESSES: PreconfiguredAddresses = { "PT-clisBNB-24APR2025": "0x14AECeEc177085fd09EA07348B4E1F7Fcc030fA1", "PT-sUSDE-26JUN2025": "0x95e58161BA2423c3034658d957F3f5b94DeAbf81", "PT-USDe-30OCT2025": "0x0c98334aCF440b9936D9cc1d99dc1A77bf26a93B", + "PT-xSolvBTC-18DEC2025": "0xb786A97032ea5A1Bcfe02341f34599C6DfEA6351", + "PT-SolvBTC.BNB-18DEC2025": "0x666DeDB281A49C2cA493b7766311467062F11f09", sUSDe: "0xcFec590e417Abb378cfEfE6296829E35fa25cEbd", USDe: "0x986C30591f5aAb401ea3aa63aFA595608721B1B9", xSolvBTC: "0x3ea87323806586A0282b50377e0FEa76070F532B", From b5026274efb1b956a73ff5c11d755baab4eafd72 Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Mon, 29 Sep 2025 15:37:14 +0000 Subject: [PATCH 2/4] feat: updating deployment files --- deployments/bsctestnet.json | 1436 +++++++++++++++++++++---- deployments/bsctestnet_addresses.json | 2 + 2 files changed, 1224 insertions(+), 214 deletions(-) diff --git a/deployments/bsctestnet.json b/deployments/bsctestnet.json index fff94d38..b3114a20 100644 --- a/deployments/bsctestnet.json +++ b/deployments/bsctestnet.json @@ -6539,8 +6539,8 @@ } ] }, - "PendleOracle-PT-USDe-30Oct2025": { - "address": "0x9d223177a0Ea5505EbF3665f950093091f04739b", + "PendleOracle-PT-SolvBTC.BNB-18DEC2025": { + "address": "0x137cbEf31e76e6aF6818Fb50f52D3f7cF1d46d55", "abi": [ { "inputs": [ @@ -7043,39 +7043,172 @@ } ] }, - "PendleOracle-PT-clisBNB-24APR2025": { - "address": "0xeF663663e802Ff4510aDE14975820FFB5d2EE9E8", + "PendleOracle-PT-USDe-30Oct2025": { + "address": "0x9d223177a0Ea5505EbF3665f950093091f04739b", "abi": [ { - "anonymous": false, "inputs": [ { - "indexed": false, + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "address", + "name": "ptOracle", + "type": "address" + }, + { + "internalType": "enum PendleOracle.RateKind", + "name": "rateKind", + "type": "uint8" + }, + { + "internalType": "address", + "name": "ptToken", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "resilientOracle", + "type": "address" + }, + { + "internalType": "uint32", + "name": "twapDuration", + "type": "uint32" + }, + { + "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" + } + ], + "internalType": "struct PendleOracle.ConstructorParams", + "name": "params", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidGrowthRate", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialSnapshot", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSnapshotMaxExchangeRate", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTokenAddress", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", - "name": "previousAdmin", + "name": "sender", "type": "address" }, { - "indexed": false, "internalType": "address", - "name": "newAdmin", + "name": "calledContract", "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" } ], - "name": "AdminChanged", - "type": "event" + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "type": "error" }, { "anonymous": false, "inputs": [ { "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "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": "BeaconUpgraded", + "name": "GrowthRateUpdated", "type": "event" }, { @@ -7083,107 +7216,138 @@ "inputs": [ { "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256", + "name": "oldSnapshotGap", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "newSnapshotGap", + "type": "uint256" } ], - "name": "Upgraded", + "name": "SnapshotGapUpdated", "type": "event" }, { - "stateMutability": "payable", - "type": "fallback" + "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": "admin", + "name": "ACCESS_CONTROL_MANAGER", "outputs": [ { - "internalType": "address", - "name": "admin_", + "internalType": "contract IAccessControlManagerV8", + "name": "", "type": "address" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [], - "name": "implementation", + "name": "CORRELATED_TOKEN", "outputs": [ { "internalType": "address", - "name": "implementation_", + "name": "", "type": "address" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "MARKET", + "outputs": [ { "internalType": "address", - "name": "newImplementation", + "name": "", "type": "address" } ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "PT_ORACLE", + "outputs": [ { - "internalType": "address", - "name": "newImplementation", + "internalType": "contract IPendlePtOracle", + "name": "", "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" } ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - }, - { - "inputs": [], - "name": "InvalidDuration", - "type": "error" - }, { "inputs": [], - "name": "InvalidTokenAddress", - "type": "error" + "name": "RATE_KIND", + "outputs": [ + { + "internalType": "enum PendleOracle.RateKind", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" }, { "inputs": [], - "name": "ZeroAddressNotAllowed", - "type": "error" + "name": "RESILIENT_ORACLE", + "outputs": [ + { + "internalType": "contract ResilientOracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" }, { "inputs": [], - "name": "ZeroValueNotAllowed", - "type": "error" + "name": "TWAP_DURATION", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" }, { "inputs": [], - "name": "CORRELATED_TOKEN", + "name": "UNDERLYING_DECIMALS", "outputs": [ { - "internalType": "address", + "internalType": "uint8", "name": "", - "type": "address" + "type": "uint8" } ], "stateMutability": "view", @@ -7191,7 +7355,7 @@ }, { "inputs": [], - "name": "MARKET", + "name": "UNDERLYING_TOKEN", "outputs": [ { "internalType": "address", @@ -7204,25 +7368,44 @@ }, { "inputs": [], - "name": "PT_ORACLE", + "name": "getMaxAllowedExchangeRate", "outputs": [ { - "internalType": "contract IPendlePtOracle", + "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": "RATE_KIND", + "name": "getUnderlyingAmount", "outputs": [ { - "internalType": "enum PendleOracle.RateKind", + "internalType": "uint256", "name": "", - "type": "uint8" + "type": "uint256" } ], "stateMutability": "view", @@ -7230,12 +7413,12 @@ }, { "inputs": [], - "name": "RESILIENT_ORACLE", + "name": "growthRatePerSecond", "outputs": [ { - "internalType": "contract OracleInterface", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", @@ -7243,25 +7426,74 @@ }, { "inputs": [], - "name": "TWAP_DURATION", + "name": "isCapped", "outputs": [ { - "internalType": "uint32", + "internalType": "bool", "name": "", - "type": "uint32" + "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": "UNDERLYING_DECIMALS", + "name": "snapshotGap", "outputs": [ { - "internalType": "uint8", + "internalType": "uint256", "name": "", - "type": "uint8" + "type": "uint256" } ], "stateMutability": "view", @@ -7269,26 +7501,33 @@ }, { "inputs": [], - "name": "UNDERLYING_TOKEN", + "name": "snapshotInterval", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "snapshotMaxExchangeRate", + "outputs": [ { - "internalType": "address", - "name": "asset", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "getPrice", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "snapshotTimestamp", "outputs": [ { "internalType": "uint256", @@ -7300,91 +7539,836 @@ "type": "function" }, { + "inputs": [], + "name": "updateSnapshot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + }, + "PendleOracle-PT-clisBNB-24APR2025": { + "address": "0xeF663663e802Ff4510aDE14975820FFB5d2EE9E8", + "abi": [ + { + "anonymous": false, "inputs": [ { + "indexed": false, "internalType": "address", - "name": "_logic", + "name": "previousAdmin", "type": "address" }, { + "indexed": false, "internalType": "address", - "name": "admin_", + "name": "newAdmin", "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" } ], - "stateMutability": "payable", - "type": "constructor" - } - ] - }, - "PendleOracle-PT-clisBNB-24APR2025_Implementation": { - "address": "0x6d8b4d49238ffc3Ad23239fbC3045307B98D6F76", - "abi": [ + "name": "AdminChanged", + "type": "event" + }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "market", + "name": "beacon", "type": "address" - }, + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { + "indexed": true, "internalType": "address", - "name": "ptOracle", + "name": "implementation", "type": "address" - }, + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ { - "internalType": "enum PendleOracle.RateKind", - "name": "rateKind", - "type": "uint8" - }, + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ { "internalType": "address", - "name": "ptToken", + "name": "implementation_", "type": "address" - }, + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", - "name": "underlyingToken", + "name": "newImplementation", "type": "address" - }, + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", - "name": "resilientOracle", + "name": "newImplementation", "type": "address" }, { - "internalType": "uint32", - "name": "twapDuration", - "type": "uint32" + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTokenAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "CORRELATED_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MARKET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_ORACLE", + "outputs": [ + { + "internalType": "contract IPendlePtOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_KIND", + "outputs": [ + { + "internalType": "enum PendleOracle.RateKind", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RESILIENT_ORACLE", + "outputs": [ + { + "internalType": "contract OracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TWAP_DURATION", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_DECIMALS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "PendleOracle-PT-clisBNB-24APR2025_Implementation": { + "address": "0x6d8b4d49238ffc3Ad23239fbC3045307B98D6F76", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "address", + "name": "ptOracle", + "type": "address" + }, + { + "internalType": "enum PendleOracle.RateKind", + "name": "rateKind", + "type": "uint8" + }, + { + "internalType": "address", + "name": "ptToken", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "resilientOracle", + "type": "address" + }, + { + "internalType": "uint32", + "name": "twapDuration", + "type": "uint32" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTokenAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "CORRELATED_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MARKET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_ORACLE", + "outputs": [ + { + "internalType": "contract IPendlePtOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_KIND", + "outputs": [ + { + "internalType": "enum PendleOracle.RateKind", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RESILIENT_ORACLE", + "outputs": [ + { + "internalType": "contract OracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TWAP_DURATION", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_DECIMALS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "PendleOracle-PT-clisBNB-24APR2025_Proxy": { + "address": "0xeF663663e802Ff4510aDE14975820FFB5d2EE9E8", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "PendleOracle-PT-sUSDe-26JUN2025": { + "address": "0x85201328baa52061E6648d9b4c285529411Cd33B", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "address", + "name": "ptOracle", + "type": "address" + }, + { + "internalType": "enum PendleOracle.RateKind", + "name": "rateKind", + "type": "uint8" + }, + { + "internalType": "address", + "name": "ptToken", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "resilientOracle", + "type": "address" + }, + { + "internalType": "uint32", + "name": "twapDuration", + "type": "uint32" + }, + { + "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" + } + ], + "internalType": "struct PendleOracle.ConstructorParams", + "name": "params", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "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" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "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" } ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "InvalidDuration", - "type": "error" + "name": "GrowthRateUpdated", + "type": "event" }, { - "inputs": [], - "name": "InvalidTokenAddress", - "type": "error" + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "oldSnapshotGap", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "newSnapshotGap", + "type": "uint256" + } + ], + "name": "SnapshotGapUpdated", + "type": "event" }, { - "inputs": [], - "name": "ZeroAddressNotAllowed", - "type": "error" + "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": "ZeroValueNotAllowed", - "type": "error" + "name": "ACCESS_CONTROL_MANAGER", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" }, { "inputs": [], @@ -7443,7 +8427,7 @@ "name": "RESILIENT_ORACLE", "outputs": [ { - "internalType": "contract OracleInterface", + "internalType": "contract ResilientOracleInterface", "name": "", "type": "address" } @@ -7490,6 +8474,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getMaxAllowedExchangeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -7508,147 +8505,158 @@ ], "stateMutability": "view", "type": "function" - } - ] - }, - "PendleOracle-PT-clisBNB-24APR2025_Proxy": { - "address": "0xeF663663e802Ff4510aDE14975820FFB5d2EE9E8", - "abi": [ + }, { - "inputs": [ + "inputs": [], + "name": "getUnderlyingAmount", + "outputs": [ { - "internalType": "address", - "name": "_logic", - "type": "address" - }, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "growthRatePerSecond", + "outputs": [ { - "internalType": "address", - "name": "admin_", - "type": "address" - }, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isCapped", + "outputs": [ { - "internalType": "bytes", - "name": "_data", - "type": "bytes" + "internalType": "bool", + "name": "", + "type": "bool" } ], - "stateMutability": "payable", - "type": "constructor" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "_annualGrowthRate", + "type": "uint256" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "_snapshotInterval", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "setGrowthRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "_snapshotMaxExchangeRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_snapshotTimestamp", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" + "name": "setSnapshot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256", + "name": "_snapshotGap", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "name": "setSnapshotGap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [], - "name": "admin", + "name": "snapshotGap", "outputs": [ { - "internalType": "address", - "name": "admin_", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [], - "name": "implementation", + "name": "snapshotInterval", "outputs": [ { - "internalType": "address", - "name": "implementation_", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "snapshotMaxExchangeRate", + "outputs": [ { - "internalType": "address", - "name": "newImplementation", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - }, + "inputs": [], + "name": "snapshotTimestamp", + "outputs": [ { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { - "stateMutability": "payable", - "type": "receive" + "inputs": [], + "name": "updateSnapshot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ] }, - "PendleOracle-PT-sUSDe-26JUN2025": { - "address": "0x85201328baa52061E6648d9b4c285529411Cd33B", + "PendleOracle-PT-xSolvBTC-18DEC2025": { + "address": "0x2dE6EC714173e92D7A0138d0Eee4EA09FCF11965", "abi": [ { "inputs": [ diff --git a/deployments/bsctestnet_addresses.json b/deployments/bsctestnet_addresses.json index c76ea3c1..9879c70a 100644 --- a/deployments/bsctestnet_addresses.json +++ b/deployments/bsctestnet_addresses.json @@ -23,11 +23,13 @@ "PendleOracle-PT-SolvBTC.BBN-27MAR2025": "0x31B78f0Ef6A87cF0E812197226306954a65907d5", "PendleOracle-PT-SolvBTC.BBN-27MAR2025_Implementation": "0x2EC23cBc3A111D4265d9fE7dcf319b2Ff4F23f2D", "PendleOracle-PT-SolvBTC.BBN-27MAR2025_Proxy": "0x31B78f0Ef6A87cF0E812197226306954a65907d5", + "PendleOracle-PT-SolvBTC.BNB-18DEC2025": "0x137cbEf31e76e6aF6818Fb50f52D3f7cF1d46d55", "PendleOracle-PT-USDe-30Oct2025": "0x9d223177a0Ea5505EbF3665f950093091f04739b", "PendleOracle-PT-clisBNB-24APR2025": "0xeF663663e802Ff4510aDE14975820FFB5d2EE9E8", "PendleOracle-PT-clisBNB-24APR2025_Implementation": "0x6d8b4d49238ffc3Ad23239fbC3045307B98D6F76", "PendleOracle-PT-clisBNB-24APR2025_Proxy": "0xeF663663e802Ff4510aDE14975820FFB5d2EE9E8", "PendleOracle-PT-sUSDe-26JUN2025": "0x85201328baa52061E6648d9b4c285529411Cd33B", + "PendleOracle-PT-xSolvBTC-18DEC2025": "0x2dE6EC714173e92D7A0138d0Eee4EA09FCF11965", "PythOracle": "0x94E1534c14e0736BB24decA625f2F5364B198E0C", "PythOracle_Implementation": "0xb8a450101DF8ab770c8F8521E189a4B39e7Cf5f5", "PythOracle_Proxy": "0x94E1534c14e0736BB24decA625f2F5364B198E0C", From e89bb38d8e098ac445c7751b0ec56b914eb8b348 Mon Sep 17 00:00:00 2001 From: GitGuru7 Date: Tue, 30 Sep 2025 17:25:41 +0530 Subject: [PATCH 3/4] feat: deploy PT-xSolvBTC and PT-SolvBTC.BNB oracles on bscmainnet --- ...PendleOracle-PT-SolvBTC.BNB-18DEC2025.json | 785 ++++++++++++++++++ .../PendleOracle-PT-xSolvBTC-18DEC2025.json | 785 ++++++++++++++++++ helpers/deploymentConfig.ts | 6 +- 3 files changed, 1575 insertions(+), 1 deletion(-) create mode 100644 deployments/bscmainnet/PendleOracle-PT-SolvBTC.BNB-18DEC2025.json create mode 100644 deployments/bscmainnet/PendleOracle-PT-xSolvBTC-18DEC2025.json diff --git a/deployments/bscmainnet/PendleOracle-PT-SolvBTC.BNB-18DEC2025.json b/deployments/bscmainnet/PendleOracle-PT-SolvBTC.BNB-18DEC2025.json new file mode 100644 index 00000000..55dddfda --- /dev/null +++ b/deployments/bscmainnet/PendleOracle-PT-SolvBTC.BNB-18DEC2025.json @@ -0,0 +1,785 @@ +{ + "address": "0x9B353103f6da8FCb67B2e5bB129fC5c63691AbF8", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "address", + "name": "ptOracle", + "type": "address" + }, + { + "internalType": "enum PendleOracle.RateKind", + "name": "rateKind", + "type": "uint8" + }, + { + "internalType": "address", + "name": "ptToken", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "resilientOracle", + "type": "address" + }, + { + "internalType": "uint32", + "name": "twapDuration", + "type": "uint32" + }, + { + "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" + } + ], + "internalType": "struct PendleOracle.ConstructorParams", + "name": "params", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "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" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "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": "CORRELATED_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MARKET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_ORACLE", + "outputs": [ + { + "internalType": "contract IPendlePtOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_KIND", + "outputs": [ + { + "internalType": "enum PendleOracle.RateKind", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RESILIENT_ORACLE", + "outputs": [ + { + "internalType": "contract ResilientOracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TWAP_DURATION", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_DECIMALS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "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": "0x8a8c9534cf08bcfdcd1a5d0f3b70148e55233d0e32fd19cc945493d410dd6ca7", + "receipt": { + "to": null, + "from": "0x14A1c22EF6d2eF6cE33c0b018d8A34D02021e5c8", + "contractAddress": "0x9B353103f6da8FCb67B2e5bB129fC5c63691AbF8", + "transactionIndex": 217, + "gasUsed": "970708", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x0840650a3c9712368d48983229ee40ef8c333dcd17a908464dd9c2391b17b4fd", + "transactionHash": "0x8a8c9534cf08bcfdcd1a5d0f3b70148e55233d0e32fd19cc945493d410dd6ca7", + "logs": [], + "blockNumber": 62969799, + "cumulativeGasUsed": "31862981", + "status": 1, + "byzantium": true + }, + "args": [ + { + "market": "0x527be6fa23ff71e3faf5c2c1511b0531b67a701d", + "ptOracle": "0x9a9fa8338dd5e5b2188006f1cd2ef26d921650c2", + "rateKind": 1, + "ptToken": "0xee61a49a180cd23c3e629c5a70c1ee6539c004bd", + "underlyingToken": "0x6c948a4c31d013515d871930fe3807276102f25d", + "resilientOracle": "0x6592b5DE802159F3E74B2486b091D11a8256ab8A", + "twapDuration": 1800, + "annualGrowthRate": 0, + "snapshotInterval": 0, + "initialSnapshotMaxExchangeRate": 0, + "initialSnapshotTimestamp": 0, + "accessControlManager": "0x4788629abc6cfca10f9f969efdeaa1cf70c23555", + "snapshotGap": 0 + } + ], + "numDeployments": 1, + "solcInputHash": "eb7ae6b5763315e358adb74172778b7c", + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ptOracle\",\"type\":\"address\"},{\"internalType\":\"enum PendleOracle.RateKind\",\"name\":\"rateKind\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"ptToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"underlyingToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resilientOracle\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"twapDuration\",\"type\":\"uint32\"},{\"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\"}],\"internalType\":\"struct PendleOracle.ConstructorParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidDuration\",\"type\":\"error\"},{\"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\"},{\"inputs\":[],\"name\":\"ZeroValueNotAllowed\",\"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\":\"CORRELATED_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MARKET\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PT_ORACLE\",\"outputs\":[{\"internalType\":\"contract IPendlePtOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RATE_KIND\",\"outputs\":[{\"internalType\":\"enum PendleOracle.RateKind\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RESILIENT_ORACLE\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TWAP_DURATION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UNDERLYING_DECIMALS\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"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\",\"details\":\"As a base price the oracle uses either the price of the Pendle market's asset (in this case PT_TO_ASSET rate should be used) or the price of the Pendle market's interest bearing token (e.g. wstETH for stETH; in this case PT_TO_SY rate should be used). Technically, interest bearing token is different from standardized yield (SY) token, but since SY is a wrapper around an interest bearing token, we can safely assume the prices of the two are equal. This is not always true for asset price though: using PT_TO_ASSET rate assumes that the yield token can be seamlessly redeemed for the underlying asset. In reality, this might not always be the case. For more details, see https://docs.pendle.finance/Developers/Contracts/StandardizedYield\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:error\":\"InvalidDuration Thrown if the duration is invalid\"},\"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 The amount of underlying token (either the market's asset or the yield token) for 1 PT, adjusted for decimals such that the result has the same precision as the underlying token\"}},\"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\"}},\"stateVariables\":{\"UNDERLYING_DECIMALS\":{\"details\":\"We make an assumption that the underlying decimals will not change throughout the lifetime of the Pendle market\"}},\"title\":\"PendleOracle\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidDuration()\":[{\"notice\":\"Thrown if the duration is invalid\"}],\"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\"}],\"ZeroValueNotAllowed()\":[{\"notice\":\"Thrown if the supplied value is 0 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\"},\"CORRELATED_TOKEN()\":{\"notice\":\"Address of the correlated token\"},\"MARKET()\":{\"notice\":\"Address of the market\"},\"PT_ORACLE()\":{\"notice\":\"Address of the PT oracle\"},\"RATE_KIND()\":{\"notice\":\"Whether to use PT/SY (standardized yield token) rate or PT/market asset rate\"},\"RESILIENT_ORACLE()\":{\"notice\":\"Address of Resilient Oracle\"},\"TWAP_DURATION()\":{\"notice\":\"Twap duration for the oracle\"},\"UNDERLYING_DECIMALS()\":{\"notice\":\"Decimals of the underlying token\"},\"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\":\"Fetches the amount of underlying token for 1 PT\"},\"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 a pendle token\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracles/PendleOracle.sol\":\"PendleOracle\"},\"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/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/IPendlePtOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\ninterface IPendlePtOracle {\\n function getPtToAssetRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getPtToSyRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getOracleState(\\n address market,\\n uint32 duration\\n )\\n external\\n view\\n returns (bool increaseCardinalityRequired, uint16 cardinalityRequired, bool oldestObservationSatisfied);\\n}\\n\",\"keccak256\":\"0x14d96d7f75397e4291288ef6367053bd970d95fc0c3e2a028b077f6342e0160a\",\"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/PendleOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { IPendlePtOracle } from \\\"../interfaces/IPendlePtOracle.sol\\\";\\nimport { CorrelatedTokenOracle } from \\\"./common/CorrelatedTokenOracle.sol\\\";\\nimport { ensureNonzeroAddress, ensureNonzeroValue } from \\\"@venusprotocol/solidity-utilities/contracts/validators.sol\\\";\\nimport { IERC20Metadata } from \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\n/**\\n * @title PendleOracle\\n * @author Venus\\n * @notice This oracle fetches the price of a pendle token\\n * @dev As a base price the oracle uses either the price of the Pendle\\n * market's asset (in this case PT_TO_ASSET rate should be used) or\\n * the price of the Pendle market's interest bearing token (e.g. wstETH\\n * for stETH; in this case PT_TO_SY rate should be used). Technically,\\n * interest bearing token is different from standardized yield (SY) token,\\n * but since SY is a wrapper around an interest bearing token, we can safely\\n * assume the prices of the two are equal. This is not always true for asset\\n * price though: using PT_TO_ASSET rate assumes that the yield token can\\n * be seamlessly redeemed for the underlying asset. In reality, this might\\n * not always be the case. For more details, see\\n * https://docs.pendle.finance/Developers/Contracts/StandardizedYield\\n */\\ncontract PendleOracle is CorrelatedTokenOracle {\\n struct ConstructorParams {\\n /// @notice Pendle market\\n address market;\\n /// @notice Pendle oracle\\n address ptOracle;\\n /// @notice Either PT_TO_ASSET or PT_TO_SY\\n RateKind rateKind;\\n /// @notice Pendle PT token\\n address ptToken;\\n /// @notice Underlying token, can be either the market's asset or the interest bearing token\\n address underlyingToken;\\n /// @notice Resilient oracle to get the underlying token price from\\n address resilientOracle;\\n /// @notice TWAP duration to call Pendle oracle with\\n uint32 twapDuration;\\n /// @notice Annual growth rate of the underlying token\\n uint256 annualGrowthRate;\\n /// @notice Snapshot interval for the oracle\\n uint256 snapshotInterval;\\n /// @notice Initial exchange rate of the underlying token\\n uint256 initialSnapshotMaxExchangeRate;\\n /// @notice Initial timestamp of the underlying token\\n uint256 initialSnapshotTimestamp;\\n /// @notice Access control manager\\n address accessControlManager;\\n /// @notice Gap to add when updating the snapshot\\n uint256 snapshotGap;\\n }\\n\\n /// @notice Which asset to use as a base for the returned PT\\n /// price. Can be either a standardized yield token (SY), in\\n /// this case PT/SY price is returned, or the Pendle\\n /// market's asset directly.\\n enum RateKind {\\n PT_TO_ASSET,\\n PT_TO_SY\\n }\\n\\n /// @notice Address of the PT oracle\\n IPendlePtOracle public immutable PT_ORACLE;\\n\\n /// @notice Whether to use PT/SY (standardized yield token) rate\\n /// or PT/market asset rate\\n RateKind public immutable RATE_KIND;\\n\\n /// @notice Address of the market\\n address public immutable MARKET;\\n\\n /// @notice Twap duration for the oracle\\n uint32 public immutable TWAP_DURATION;\\n\\n /// @notice Decimals of the underlying token\\n /// @dev We make an assumption that the underlying decimals will\\n /// not change throughout the lifetime of the Pendle market\\n uint8 public immutable UNDERLYING_DECIMALS;\\n\\n /// @notice Thrown if the duration is invalid\\n error InvalidDuration();\\n\\n /**\\n * @notice Constructor for the implementation contract.\\n * @custom:error InvalidDuration Thrown if the duration is invalid\\n */\\n constructor(\\n ConstructorParams memory params\\n )\\n CorrelatedTokenOracle(\\n params.ptToken,\\n params.underlyingToken,\\n params.resilientOracle,\\n params.annualGrowthRate,\\n params.snapshotInterval,\\n params.initialSnapshotMaxExchangeRate,\\n params.initialSnapshotTimestamp,\\n params.accessControlManager,\\n params.snapshotGap\\n )\\n {\\n ensureNonzeroAddress(params.market);\\n ensureNonzeroAddress(params.ptOracle);\\n ensureNonzeroValue(params.twapDuration);\\n\\n MARKET = params.market;\\n PT_ORACLE = IPendlePtOracle(params.ptOracle);\\n RATE_KIND = params.rateKind;\\n TWAP_DURATION = params.twapDuration;\\n UNDERLYING_DECIMALS = IERC20Metadata(UNDERLYING_TOKEN).decimals();\\n\\n (bool increaseCardinalityRequired, , bool oldestObservationSatisfied) = PT_ORACLE.getOracleState(\\n MARKET,\\n TWAP_DURATION\\n );\\n if (increaseCardinalityRequired || !oldestObservationSatisfied) {\\n revert InvalidDuration();\\n }\\n }\\n\\n /// @notice Fetches the amount of underlying token for 1 PT\\n /// @return amount The amount of underlying token (either the market's asset\\n /// or the yield token) for 1 PT, adjusted for decimals such that the result\\n /// has the same precision as the underlying token\\n function getUnderlyingAmount() public view override returns (uint256) {\\n uint256 rate;\\n if (RATE_KIND == RateKind.PT_TO_SY) {\\n rate = PT_ORACLE.getPtToSyRate(MARKET, TWAP_DURATION);\\n } else {\\n rate = PT_ORACLE.getPtToAssetRate(MARKET, TWAP_DURATION);\\n }\\n return ((10 ** UNDERLYING_DECIMALS) * rate) / 1e18;\\n }\\n}\\n\",\"keccak256\":\"0xaa7963ac7657ea62079c2162cb4fc45524f8ffbbc6e84f89a5d4e54b71dc6025\",\"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": "0x6101a0604052348015610010575f80fd5b5060405161155938038061155983398101604081905261002f916103a6565b6060810151608082015160a083015160e084015161010085015161012086015161014087015161016088015161018089015161006f6301e1338087610481565b5f81905515801561007f57505f85115b8061009357505f8054118015610093575084155b156100b1576040516353b7e64560e11b815260040160405180910390fd5b8315806100bc575082155b80156100c757505f85115b156100e55760405163b8a5589b60e01b815260040160405180910390fd5b6100ee896102eb565b6100f7886102eb565b610100876102eb565b610109826102eb565b6001600160a01b0398891660805296881660a05294871660c052600192909255600255600355506004919091551660e0528051610145906102eb565b6020810151610153906102eb565b60c08101516101679063ffffffff16610315565b80516001600160a01b03908116610140526020820151166101005260408101516001811115610198576101986104a0565b6101208160018111156101ad576101ad6104a0565b815250508060c0015163ffffffff166101608163ffffffff168152505060a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610208573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061022c91906104b4565b60ff166101805261010051610140516101605160405162439f4b60e91b81526001600160a01b03928316600482015263ffffffff90911660248201525f928392169063873e960090604401606060405180830381865afa158015610292573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102b691906104ea565b925050915081806102c5575080155b156102e357604051637616640160e01b815260040160405180910390fd5b505050610532565b6001600160a01b038116610312576040516342bcdf7f60e11b815260040160405180910390fd5b50565b805f036103125760405163273e150360e21b815260040160405180910390fd5b6040516101a081016001600160401b038111828210171561036457634e487b7160e01b5f52604160045260245ffd5b60405290565b80516001600160a01b0381168114610380575f80fd5b919050565b805160028110610380575f80fd5b805163ffffffff81168114610380575f80fd5b5f6101a082840312156103b7575f80fd5b6103bf610335565b6103c88361036a565b81526103d66020840161036a565b60208201526103e760408401610385565b60408201526103f86060840161036a565b60608201526104096080840161036a565b608082015261041a60a0840161036a565b60a082015261042b60c08401610393565b60c082015260e0838101519082015261010080840151908201526101208084015190820152610140808401519082015261016061046981850161036a565b90820152610180928301519281019290925250919050565b5f8261049b57634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52602160045260245ffd5b5f602082840312156104c4575f80fd5b815160ff811681146104d4575f80fd5b9392505050565b80518015158114610380575f80fd5b5f805f606084860312156104fc575f80fd5b610505846104db565b9250602084015161ffff8116811461051b575f80fd5b9150610529604085016104db565b90509250925092565b60805160a05160c05160e0516101005161012051610140516101605161018051610f596106005f395f81816101d9015261099d01525f81816103070152818161081b01526108f601525f818161038b015281816107f301526108ce01525f818161014601526107a701525f81816102e001528181610847015261092201525f818161022e0152610b9a01525f818161034c0152818161069c0152610a6d01525f818161019a015281816106740152610a4101525f81816102a6015281816103b00152610adb0152610f595ff3fe608060405234801561000f575f80fd5b506004361061013d575f3560e01c806369240426116100b45780639c43eb54116100795780639c43eb541461033e578063a4edcd4c14610347578063abb856131461036e578063ac5a693e14610376578063bdf13af21461037e578063f46f16c214610386575f80fd5b8063692404261461029957806369818a35146102a15780637fc4e4a0146102c8578063809d7b31146102db578063879ac8f814610302575f80fd5b806341976e091161010557806341976e091461021657806345be2dc7146102295780635213f9c814610250578063596efe6f14610265578063643d813d1461026e578063671528d414610281575f80fd5b806302125d091461014157806307d0413c1461017e57806329db1be6146101955780633dae7c22146101d45780634169d2451461020d575b5f80fd5b6101687f000000000000000000000000000000000000000000000000000000000000000081565b6040516101759190610c57565b60405180910390f35b61018760015481565b604051908152602001610175565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610175565b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610175565b61018760045481565b610187610224366004610c7d565b6103ad565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b61026361025e366004610ca3565b61045e565b005b61018760025481565b61026361027c366004610cba565b6104cf565b6102896105a5565b6040519015158152602001610175565b6102636105e0565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6102636102d6366004610cba565b610729565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b61018760035481565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6101876107a1565b6101875f5481565b6101876109dd565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461040057604051630f58058360e11b815260040160405180910390fd5b5f6104096107a1565b90506001545f036104245761041d81610a2a565b9392505050565b5f61042d6109dd565b90505f818311801561043e57508115155b610448578261044a565b815b905061045581610a2a565b95945050505050565b61049c6040518060400160405280601781526020017f736574536e617073686f744761702875696e7432353629000000000000000000815250610b81565b6004546040518291907feb3716d3f8388c182853c1dc98b18931f3a600bbab31f2ff48631f6412e4997f905f90a3600455565b61050d6040518060400160405280601e81526020017f73657447726f777468526174652875696e743235362c75696e74323536290000815250610b81565b5f5461051d6301e1338084610cee565b5f81905515801561052d57505f82115b8061054157505f8054118015610541575081155b1561055f576040516353b7e64560e11b815260040160405180910390fd5b6001545f54827fa65cbeb0e28a8803a912daac67c472c160aa01e2c988755fa424f290321de6088560405161059691815260200190565b60405180910390a45060015550565b5f6001545f036105b457505f90565b5f6105bd6109dd565b9050805f036105cd575f91505090565b5f6105d66107a1565b9190911192915050565b6001546003546105f09042610d0d565b10806105fc5750600154155b1561060357565b5f61060c6107a1565b90505f6106176109dd565b9050600454818311610629578261062b565b815b6106359190610d26565b6002819055426003555f0361065d57604051635f18388760e01b815260040160405180910390fd5b60405163b62cad6960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b62cad69906024015f604051808303815f87803b1580156106dd575f80fd5b505af11580156106ef573d5f803e3d5ffd5b505050506003546002547f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d60405160405180910390a35050565b6107676040518060400160405280601c81526020017f736574536e617073686f742875696e743235362c75696e743235362900000000815250610b81565b60028290556003819055604051819083907f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d905f90a35050565b5f8060017f000000000000000000000000000000000000000000000000000000000000000060018111156107d7576107d7610c43565b036108b75760405163a31426d160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a31426d190604401602060405180830381865afa15801561088c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b09190610d39565b905061098e565b60405163abca0eab60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa158015610967573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098b9190610d39565b90505b670de0b6b3a7640000816109c37f0000000000000000000000000000000000000000000000000000000000000000600a610e30565b6109cd9190610e3e565b6109d79190610cee565b91505090565b5f80600354426109ed9190610d0d565b90505f670de0b6b3a7640000825f54600254610a099190610e3e565b610a139190610e3e565b610a1d9190610cee565b60025461041d9190610d26565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa158015610ab2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad69190610d39565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b39573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5d9190610e55565b60ff169050610b6d81600a610e75565b610b778487610e3e565b6104559190610cee565b6040516318c5e8ab60e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906318c5e8ab90610bd19033908690600401610eae565b602060405180830381865afa158015610bec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c109190610ed9565b905080610c3f57333083604051634a3fa29360e01b8152600401610c3693929190610ef8565b60405180910390fd5b5050565b634e487b7160e01b5f52602160045260245ffd5b6020810160028310610c7757634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215610c8d575f80fd5b81356001600160a01b038116811461041d575f80fd5b5f60208284031215610cb3575f80fd5b5035919050565b5f8060408385031215610ccb575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f82610d0857634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610d2057610d20610cda565b92915050565b80820180821115610d2057610d20610cda565b5f60208284031215610d49575f80fd5b5051919050565b600181815b80851115610d8a57815f1904821115610d7057610d70610cda565b80851615610d7d57918102915b93841c9390800290610d55565b509250929050565b5f82610da057506001610d20565b81610dac57505f610d20565b8160018114610dc25760028114610dcc57610de8565b6001915050610d20565b60ff841115610ddd57610ddd610cda565b50506001821b610d20565b5060208310610133831016604e8410600b8410161715610e0b575081810a610d20565b610e158383610d50565b805f1904821115610e2857610e28610cda565b029392505050565b5f61041d60ff841683610d92565b8082028115828204841417610d2057610d20610cda565b5f60208284031215610e65575f80fd5b815160ff8116811461041d575f80fd5b5f61041d8383610d92565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03831681526040602082018190525f90610ed190830184610e80565b949350505050565b5f60208284031215610ee9575f80fd5b8151801515811461041d575f80fd5b6001600160a01b038481168252831660208201526060604082018190525f9061045590830184610e8056fea2646970667358221220dd4434cf5ec982b81a2a3a25f96ea3d5d76d95704500f208da19253bd6abc73b64736f6c63430008190033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b506004361061013d575f3560e01c806369240426116100b45780639c43eb54116100795780639c43eb541461033e578063a4edcd4c14610347578063abb856131461036e578063ac5a693e14610376578063bdf13af21461037e578063f46f16c214610386575f80fd5b8063692404261461029957806369818a35146102a15780637fc4e4a0146102c8578063809d7b31146102db578063879ac8f814610302575f80fd5b806341976e091161010557806341976e091461021657806345be2dc7146102295780635213f9c814610250578063596efe6f14610265578063643d813d1461026e578063671528d414610281575f80fd5b806302125d091461014157806307d0413c1461017e57806329db1be6146101955780633dae7c22146101d45780634169d2451461020d575b5f80fd5b6101687f000000000000000000000000000000000000000000000000000000000000000081565b6040516101759190610c57565b60405180910390f35b61018760015481565b604051908152602001610175565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610175565b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610175565b61018760045481565b610187610224366004610c7d565b6103ad565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b61026361025e366004610ca3565b61045e565b005b61018760025481565b61026361027c366004610cba565b6104cf565b6102896105a5565b6040519015158152602001610175565b6102636105e0565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6102636102d6366004610cba565b610729565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b61018760035481565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6101876107a1565b6101875f5481565b6101876109dd565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461040057604051630f58058360e11b815260040160405180910390fd5b5f6104096107a1565b90506001545f036104245761041d81610a2a565b9392505050565b5f61042d6109dd565b90505f818311801561043e57508115155b610448578261044a565b815b905061045581610a2a565b95945050505050565b61049c6040518060400160405280601781526020017f736574536e617073686f744761702875696e7432353629000000000000000000815250610b81565b6004546040518291907feb3716d3f8388c182853c1dc98b18931f3a600bbab31f2ff48631f6412e4997f905f90a3600455565b61050d6040518060400160405280601e81526020017f73657447726f777468526174652875696e743235362c75696e74323536290000815250610b81565b5f5461051d6301e1338084610cee565b5f81905515801561052d57505f82115b8061054157505f8054118015610541575081155b1561055f576040516353b7e64560e11b815260040160405180910390fd5b6001545f54827fa65cbeb0e28a8803a912daac67c472c160aa01e2c988755fa424f290321de6088560405161059691815260200190565b60405180910390a45060015550565b5f6001545f036105b457505f90565b5f6105bd6109dd565b9050805f036105cd575f91505090565b5f6105d66107a1565b9190911192915050565b6001546003546105f09042610d0d565b10806105fc5750600154155b1561060357565b5f61060c6107a1565b90505f6106176109dd565b9050600454818311610629578261062b565b815b6106359190610d26565b6002819055426003555f0361065d57604051635f18388760e01b815260040160405180910390fd5b60405163b62cad6960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b62cad69906024015f604051808303815f87803b1580156106dd575f80fd5b505af11580156106ef573d5f803e3d5ffd5b505050506003546002547f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d60405160405180910390a35050565b6107676040518060400160405280601c81526020017f736574536e617073686f742875696e743235362c75696e743235362900000000815250610b81565b60028290556003819055604051819083907f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d905f90a35050565b5f8060017f000000000000000000000000000000000000000000000000000000000000000060018111156107d7576107d7610c43565b036108b75760405163a31426d160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a31426d190604401602060405180830381865afa15801561088c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b09190610d39565b905061098e565b60405163abca0eab60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa158015610967573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098b9190610d39565b90505b670de0b6b3a7640000816109c37f0000000000000000000000000000000000000000000000000000000000000000600a610e30565b6109cd9190610e3e565b6109d79190610cee565b91505090565b5f80600354426109ed9190610d0d565b90505f670de0b6b3a7640000825f54600254610a099190610e3e565b610a139190610e3e565b610a1d9190610cee565b60025461041d9190610d26565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa158015610ab2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad69190610d39565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b39573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5d9190610e55565b60ff169050610b6d81600a610e75565b610b778487610e3e565b6104559190610cee565b6040516318c5e8ab60e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906318c5e8ab90610bd19033908690600401610eae565b602060405180830381865afa158015610bec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c109190610ed9565b905080610c3f57333083604051634a3fa29360e01b8152600401610c3693929190610ef8565b60405180910390fd5b5050565b634e487b7160e01b5f52602160045260245ffd5b6020810160028310610c7757634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215610c8d575f80fd5b81356001600160a01b038116811461041d575f80fd5b5f60208284031215610cb3575f80fd5b5035919050565b5f8060408385031215610ccb575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f82610d0857634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610d2057610d20610cda565b92915050565b80820180821115610d2057610d20610cda565b5f60208284031215610d49575f80fd5b5051919050565b600181815b80851115610d8a57815f1904821115610d7057610d70610cda565b80851615610d7d57918102915b93841c9390800290610d55565b509250929050565b5f82610da057506001610d20565b81610dac57505f610d20565b8160018114610dc25760028114610dcc57610de8565b6001915050610d20565b60ff841115610ddd57610ddd610cda565b50506001821b610d20565b5060208310610133831016604e8410600b8410161715610e0b575081810a610d20565b610e158383610d50565b805f1904821115610e2857610e28610cda565b029392505050565b5f61041d60ff841683610d92565b8082028115828204841417610d2057610d20610cda565b5f60208284031215610e65575f80fd5b815160ff8116811461041d575f80fd5b5f61041d8383610d92565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03831681526040602082018190525f90610ed190830184610e80565b949350505050565b5f60208284031215610ee9575f80fd5b8151801515811461041d575f80fd5b6001600160a01b038481168252831660208201526060604082018190525f9061045590830184610e8056fea2646970667358221220dd4434cf5ec982b81a2a3a25f96ea3d5d76d95704500f208da19253bd6abc73b64736f6c63430008190033", + "devdoc": { + "author": "Venus", + "details": "As a base price the oracle uses either the price of the Pendle market's asset (in this case PT_TO_ASSET rate should be used) or the price of the Pendle market's interest bearing token (e.g. wstETH for stETH; in this case PT_TO_SY rate should be used). Technically, interest bearing token is different from standardized yield (SY) token, but since SY is a wrapper around an interest bearing token, we can safely assume the prices of the two are equal. This is not always true for asset price though: using PT_TO_ASSET rate assumes that the yield token can be seamlessly redeemed for the underlying asset. In reality, this might not always be the case. For more details, see https://docs.pendle.finance/Developers/Contracts/StandardizedYield", + "kind": "dev", + "methods": { + "constructor": { + "custom:error": "InvalidDuration Thrown if the duration is invalid" + }, + "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 The amount of underlying token (either the market's asset or the yield token) for 1 PT, adjusted for decimals such that the result has the same precision as the underlying token" + } + }, + "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" + } + }, + "stateVariables": { + "UNDERLYING_DECIMALS": { + "details": "We make an assumption that the underlying decimals will not change throughout the lifetime of the Pendle market" + } + }, + "title": "PendleOracle", + "version": 1 + }, + "userdoc": { + "errors": { + "InvalidDuration()": [ + { + "notice": "Thrown if the duration is invalid" + } + ], + "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" + } + ], + "ZeroValueNotAllowed()": [ + { + "notice": "Thrown if the supplied value is 0 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" + }, + "CORRELATED_TOKEN()": { + "notice": "Address of the correlated token" + }, + "MARKET()": { + "notice": "Address of the market" + }, + "PT_ORACLE()": { + "notice": "Address of the PT oracle" + }, + "RATE_KIND()": { + "notice": "Whether to use PT/SY (standardized yield token) rate or PT/market asset rate" + }, + "RESILIENT_ORACLE()": { + "notice": "Address of Resilient Oracle" + }, + "TWAP_DURATION()": { + "notice": "Twap duration for the oracle" + }, + "UNDERLYING_DECIMALS()": { + "notice": "Decimals of the underlying token" + }, + "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": "Fetches the amount of underlying token for 1 PT" + }, + "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 a pendle token", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6602, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "growthRatePerSecond", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 6605, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotInterval", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 6608, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotMaxExchangeRate", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 6611, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotTimestamp", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 6614, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotGap", + "offset": 0, + "slot": "4", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/bscmainnet/PendleOracle-PT-xSolvBTC-18DEC2025.json b/deployments/bscmainnet/PendleOracle-PT-xSolvBTC-18DEC2025.json new file mode 100644 index 00000000..28612704 --- /dev/null +++ b/deployments/bscmainnet/PendleOracle-PT-xSolvBTC-18DEC2025.json @@ -0,0 +1,785 @@ +{ + "address": "0xfbaC497147EF27f155f27aaB1172666dce09820E", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "address", + "name": "ptOracle", + "type": "address" + }, + { + "internalType": "enum PendleOracle.RateKind", + "name": "rateKind", + "type": "uint8" + }, + { + "internalType": "address", + "name": "ptToken", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "resilientOracle", + "type": "address" + }, + { + "internalType": "uint32", + "name": "twapDuration", + "type": "uint32" + }, + { + "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" + } + ], + "internalType": "struct PendleOracle.ConstructorParams", + "name": "params", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "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" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "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": "CORRELATED_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MARKET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_ORACLE", + "outputs": [ + { + "internalType": "contract IPendlePtOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_KIND", + "outputs": [ + { + "internalType": "enum PendleOracle.RateKind", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RESILIENT_ORACLE", + "outputs": [ + { + "internalType": "contract ResilientOracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TWAP_DURATION", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_DECIMALS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "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": "0x9b2e054ef805c9f372f8f133d5fa59885bd5c82cdc446cabce4d29d29a85062d", + "receipt": { + "to": null, + "from": "0x14A1c22EF6d2eF6cE33c0b018d8A34D02021e5c8", + "contractAddress": "0xfbaC497147EF27f155f27aaB1172666dce09820E", + "transactionIndex": 204, + "gasUsed": "973866", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x329a9594c474e513f4104b3a061d426b535ef96fb238f501503ad09c1aa77ee9", + "transactionHash": "0x9b2e054ef805c9f372f8f133d5fa59885bd5c82cdc446cabce4d29d29a85062d", + "logs": [], + "blockNumber": 62969796, + "cumulativeGasUsed": "28037311", + "status": 1, + "byzantium": true + }, + "args": [ + { + "market": "0xe616d50e441aa2f6d6cd43eba1b1632ab1b046e6", + "ptOracle": "0x9a9fa8338dd5e5b2188006f1cd2ef26d921650c2", + "rateKind": 1, + "ptToken": "0x154b13a628e947034ca69378ee0acde9d973d868", + "underlyingToken": "0x1346b618dC92810EC74163e4c27004c921D446a5", + "resilientOracle": "0x6592b5DE802159F3E74B2486b091D11a8256ab8A", + "twapDuration": 1800, + "annualGrowthRate": 0, + "snapshotInterval": 0, + "initialSnapshotMaxExchangeRate": 0, + "initialSnapshotTimestamp": 0, + "accessControlManager": "0x4788629abc6cfca10f9f969efdeaa1cf70c23555", + "snapshotGap": 0 + } + ], + "numDeployments": 1, + "solcInputHash": "eb7ae6b5763315e358adb74172778b7c", + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ptOracle\",\"type\":\"address\"},{\"internalType\":\"enum PendleOracle.RateKind\",\"name\":\"rateKind\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"ptToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"underlyingToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resilientOracle\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"twapDuration\",\"type\":\"uint32\"},{\"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\"}],\"internalType\":\"struct PendleOracle.ConstructorParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidDuration\",\"type\":\"error\"},{\"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\"},{\"inputs\":[],\"name\":\"ZeroValueNotAllowed\",\"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\":\"CORRELATED_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MARKET\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PT_ORACLE\",\"outputs\":[{\"internalType\":\"contract IPendlePtOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RATE_KIND\",\"outputs\":[{\"internalType\":\"enum PendleOracle.RateKind\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RESILIENT_ORACLE\",\"outputs\":[{\"internalType\":\"contract ResilientOracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TWAP_DURATION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UNDERLYING_DECIMALS\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"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\",\"details\":\"As a base price the oracle uses either the price of the Pendle market's asset (in this case PT_TO_ASSET rate should be used) or the price of the Pendle market's interest bearing token (e.g. wstETH for stETH; in this case PT_TO_SY rate should be used). Technically, interest bearing token is different from standardized yield (SY) token, but since SY is a wrapper around an interest bearing token, we can safely assume the prices of the two are equal. This is not always true for asset price though: using PT_TO_ASSET rate assumes that the yield token can be seamlessly redeemed for the underlying asset. In reality, this might not always be the case. For more details, see https://docs.pendle.finance/Developers/Contracts/StandardizedYield\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:error\":\"InvalidDuration Thrown if the duration is invalid\"},\"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 The amount of underlying token (either the market's asset or the yield token) for 1 PT, adjusted for decimals such that the result has the same precision as the underlying token\"}},\"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\"}},\"stateVariables\":{\"UNDERLYING_DECIMALS\":{\"details\":\"We make an assumption that the underlying decimals will not change throughout the lifetime of the Pendle market\"}},\"title\":\"PendleOracle\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidDuration()\":[{\"notice\":\"Thrown if the duration is invalid\"}],\"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\"}],\"ZeroValueNotAllowed()\":[{\"notice\":\"Thrown if the supplied value is 0 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\"},\"CORRELATED_TOKEN()\":{\"notice\":\"Address of the correlated token\"},\"MARKET()\":{\"notice\":\"Address of the market\"},\"PT_ORACLE()\":{\"notice\":\"Address of the PT oracle\"},\"RATE_KIND()\":{\"notice\":\"Whether to use PT/SY (standardized yield token) rate or PT/market asset rate\"},\"RESILIENT_ORACLE()\":{\"notice\":\"Address of Resilient Oracle\"},\"TWAP_DURATION()\":{\"notice\":\"Twap duration for the oracle\"},\"UNDERLYING_DECIMALS()\":{\"notice\":\"Decimals of the underlying token\"},\"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\":\"Fetches the amount of underlying token for 1 PT\"},\"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 a pendle token\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracles/PendleOracle.sol\":\"PendleOracle\"},\"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/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/IPendlePtOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\ninterface IPendlePtOracle {\\n function getPtToAssetRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getPtToSyRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getOracleState(\\n address market,\\n uint32 duration\\n )\\n external\\n view\\n returns (bool increaseCardinalityRequired, uint16 cardinalityRequired, bool oldestObservationSatisfied);\\n}\\n\",\"keccak256\":\"0x14d96d7f75397e4291288ef6367053bd970d95fc0c3e2a028b077f6342e0160a\",\"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/PendleOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { IPendlePtOracle } from \\\"../interfaces/IPendlePtOracle.sol\\\";\\nimport { CorrelatedTokenOracle } from \\\"./common/CorrelatedTokenOracle.sol\\\";\\nimport { ensureNonzeroAddress, ensureNonzeroValue } from \\\"@venusprotocol/solidity-utilities/contracts/validators.sol\\\";\\nimport { IERC20Metadata } from \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\n/**\\n * @title PendleOracle\\n * @author Venus\\n * @notice This oracle fetches the price of a pendle token\\n * @dev As a base price the oracle uses either the price of the Pendle\\n * market's asset (in this case PT_TO_ASSET rate should be used) or\\n * the price of the Pendle market's interest bearing token (e.g. wstETH\\n * for stETH; in this case PT_TO_SY rate should be used). Technically,\\n * interest bearing token is different from standardized yield (SY) token,\\n * but since SY is a wrapper around an interest bearing token, we can safely\\n * assume the prices of the two are equal. This is not always true for asset\\n * price though: using PT_TO_ASSET rate assumes that the yield token can\\n * be seamlessly redeemed for the underlying asset. In reality, this might\\n * not always be the case. For more details, see\\n * https://docs.pendle.finance/Developers/Contracts/StandardizedYield\\n */\\ncontract PendleOracle is CorrelatedTokenOracle {\\n struct ConstructorParams {\\n /// @notice Pendle market\\n address market;\\n /// @notice Pendle oracle\\n address ptOracle;\\n /// @notice Either PT_TO_ASSET or PT_TO_SY\\n RateKind rateKind;\\n /// @notice Pendle PT token\\n address ptToken;\\n /// @notice Underlying token, can be either the market's asset or the interest bearing token\\n address underlyingToken;\\n /// @notice Resilient oracle to get the underlying token price from\\n address resilientOracle;\\n /// @notice TWAP duration to call Pendle oracle with\\n uint32 twapDuration;\\n /// @notice Annual growth rate of the underlying token\\n uint256 annualGrowthRate;\\n /// @notice Snapshot interval for the oracle\\n uint256 snapshotInterval;\\n /// @notice Initial exchange rate of the underlying token\\n uint256 initialSnapshotMaxExchangeRate;\\n /// @notice Initial timestamp of the underlying token\\n uint256 initialSnapshotTimestamp;\\n /// @notice Access control manager\\n address accessControlManager;\\n /// @notice Gap to add when updating the snapshot\\n uint256 snapshotGap;\\n }\\n\\n /// @notice Which asset to use as a base for the returned PT\\n /// price. Can be either a standardized yield token (SY), in\\n /// this case PT/SY price is returned, or the Pendle\\n /// market's asset directly.\\n enum RateKind {\\n PT_TO_ASSET,\\n PT_TO_SY\\n }\\n\\n /// @notice Address of the PT oracle\\n IPendlePtOracle public immutable PT_ORACLE;\\n\\n /// @notice Whether to use PT/SY (standardized yield token) rate\\n /// or PT/market asset rate\\n RateKind public immutable RATE_KIND;\\n\\n /// @notice Address of the market\\n address public immutable MARKET;\\n\\n /// @notice Twap duration for the oracle\\n uint32 public immutable TWAP_DURATION;\\n\\n /// @notice Decimals of the underlying token\\n /// @dev We make an assumption that the underlying decimals will\\n /// not change throughout the lifetime of the Pendle market\\n uint8 public immutable UNDERLYING_DECIMALS;\\n\\n /// @notice Thrown if the duration is invalid\\n error InvalidDuration();\\n\\n /**\\n * @notice Constructor for the implementation contract.\\n * @custom:error InvalidDuration Thrown if the duration is invalid\\n */\\n constructor(\\n ConstructorParams memory params\\n )\\n CorrelatedTokenOracle(\\n params.ptToken,\\n params.underlyingToken,\\n params.resilientOracle,\\n params.annualGrowthRate,\\n params.snapshotInterval,\\n params.initialSnapshotMaxExchangeRate,\\n params.initialSnapshotTimestamp,\\n params.accessControlManager,\\n params.snapshotGap\\n )\\n {\\n ensureNonzeroAddress(params.market);\\n ensureNonzeroAddress(params.ptOracle);\\n ensureNonzeroValue(params.twapDuration);\\n\\n MARKET = params.market;\\n PT_ORACLE = IPendlePtOracle(params.ptOracle);\\n RATE_KIND = params.rateKind;\\n TWAP_DURATION = params.twapDuration;\\n UNDERLYING_DECIMALS = IERC20Metadata(UNDERLYING_TOKEN).decimals();\\n\\n (bool increaseCardinalityRequired, , bool oldestObservationSatisfied) = PT_ORACLE.getOracleState(\\n MARKET,\\n TWAP_DURATION\\n );\\n if (increaseCardinalityRequired || !oldestObservationSatisfied) {\\n revert InvalidDuration();\\n }\\n }\\n\\n /// @notice Fetches the amount of underlying token for 1 PT\\n /// @return amount The amount of underlying token (either the market's asset\\n /// or the yield token) for 1 PT, adjusted for decimals such that the result\\n /// has the same precision as the underlying token\\n function getUnderlyingAmount() public view override returns (uint256) {\\n uint256 rate;\\n if (RATE_KIND == RateKind.PT_TO_SY) {\\n rate = PT_ORACLE.getPtToSyRate(MARKET, TWAP_DURATION);\\n } else {\\n rate = PT_ORACLE.getPtToAssetRate(MARKET, TWAP_DURATION);\\n }\\n return ((10 ** UNDERLYING_DECIMALS) * rate) / 1e18;\\n }\\n}\\n\",\"keccak256\":\"0xaa7963ac7657ea62079c2162cb4fc45524f8ffbbc6e84f89a5d4e54b71dc6025\",\"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": "0x6101a0604052348015610010575f80fd5b5060405161155938038061155983398101604081905261002f916103a6565b6060810151608082015160a083015160e084015161010085015161012086015161014087015161016088015161018089015161006f6301e1338087610481565b5f81905515801561007f57505f85115b8061009357505f8054118015610093575084155b156100b1576040516353b7e64560e11b815260040160405180910390fd5b8315806100bc575082155b80156100c757505f85115b156100e55760405163b8a5589b60e01b815260040160405180910390fd5b6100ee896102eb565b6100f7886102eb565b610100876102eb565b610109826102eb565b6001600160a01b0398891660805296881660a05294871660c052600192909255600255600355506004919091551660e0528051610145906102eb565b6020810151610153906102eb565b60c08101516101679063ffffffff16610315565b80516001600160a01b03908116610140526020820151166101005260408101516001811115610198576101986104a0565b6101208160018111156101ad576101ad6104a0565b815250508060c0015163ffffffff166101608163ffffffff168152505060a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610208573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061022c91906104b4565b60ff166101805261010051610140516101605160405162439f4b60e91b81526001600160a01b03928316600482015263ffffffff90911660248201525f928392169063873e960090604401606060405180830381865afa158015610292573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102b691906104ea565b925050915081806102c5575080155b156102e357604051637616640160e01b815260040160405180910390fd5b505050610532565b6001600160a01b038116610312576040516342bcdf7f60e11b815260040160405180910390fd5b50565b805f036103125760405163273e150360e21b815260040160405180910390fd5b6040516101a081016001600160401b038111828210171561036457634e487b7160e01b5f52604160045260245ffd5b60405290565b80516001600160a01b0381168114610380575f80fd5b919050565b805160028110610380575f80fd5b805163ffffffff81168114610380575f80fd5b5f6101a082840312156103b7575f80fd5b6103bf610335565b6103c88361036a565b81526103d66020840161036a565b60208201526103e760408401610385565b60408201526103f86060840161036a565b60608201526104096080840161036a565b608082015261041a60a0840161036a565b60a082015261042b60c08401610393565b60c082015260e0838101519082015261010080840151908201526101208084015190820152610140808401519082015261016061046981850161036a565b90820152610180928301519281019290925250919050565b5f8261049b57634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52602160045260245ffd5b5f602082840312156104c4575f80fd5b815160ff811681146104d4575f80fd5b9392505050565b80518015158114610380575f80fd5b5f805f606084860312156104fc575f80fd5b610505846104db565b9250602084015161ffff8116811461051b575f80fd5b9150610529604085016104db565b90509250925092565b60805160a05160c05160e0516101005161012051610140516101605161018051610f596106005f395f81816101d9015261099d01525f81816103070152818161081b01526108f601525f818161038b015281816107f301526108ce01525f818161014601526107a701525f81816102e001528181610847015261092201525f818161022e0152610b9a01525f818161034c0152818161069c0152610a6d01525f818161019a015281816106740152610a4101525f81816102a6015281816103b00152610adb0152610f595ff3fe608060405234801561000f575f80fd5b506004361061013d575f3560e01c806369240426116100b45780639c43eb54116100795780639c43eb541461033e578063a4edcd4c14610347578063abb856131461036e578063ac5a693e14610376578063bdf13af21461037e578063f46f16c214610386575f80fd5b8063692404261461029957806369818a35146102a15780637fc4e4a0146102c8578063809d7b31146102db578063879ac8f814610302575f80fd5b806341976e091161010557806341976e091461021657806345be2dc7146102295780635213f9c814610250578063596efe6f14610265578063643d813d1461026e578063671528d414610281575f80fd5b806302125d091461014157806307d0413c1461017e57806329db1be6146101955780633dae7c22146101d45780634169d2451461020d575b5f80fd5b6101687f000000000000000000000000000000000000000000000000000000000000000081565b6040516101759190610c57565b60405180910390f35b61018760015481565b604051908152602001610175565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610175565b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610175565b61018760045481565b610187610224366004610c7d565b6103ad565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b61026361025e366004610ca3565b61045e565b005b61018760025481565b61026361027c366004610cba565b6104cf565b6102896105a5565b6040519015158152602001610175565b6102636105e0565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6102636102d6366004610cba565b610729565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b61018760035481565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6101876107a1565b6101875f5481565b6101876109dd565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461040057604051630f58058360e11b815260040160405180910390fd5b5f6104096107a1565b90506001545f036104245761041d81610a2a565b9392505050565b5f61042d6109dd565b90505f818311801561043e57508115155b610448578261044a565b815b905061045581610a2a565b95945050505050565b61049c6040518060400160405280601781526020017f736574536e617073686f744761702875696e7432353629000000000000000000815250610b81565b6004546040518291907feb3716d3f8388c182853c1dc98b18931f3a600bbab31f2ff48631f6412e4997f905f90a3600455565b61050d6040518060400160405280601e81526020017f73657447726f777468526174652875696e743235362c75696e74323536290000815250610b81565b5f5461051d6301e1338084610cee565b5f81905515801561052d57505f82115b8061054157505f8054118015610541575081155b1561055f576040516353b7e64560e11b815260040160405180910390fd5b6001545f54827fa65cbeb0e28a8803a912daac67c472c160aa01e2c988755fa424f290321de6088560405161059691815260200190565b60405180910390a45060015550565b5f6001545f036105b457505f90565b5f6105bd6109dd565b9050805f036105cd575f91505090565b5f6105d66107a1565b9190911192915050565b6001546003546105f09042610d0d565b10806105fc5750600154155b1561060357565b5f61060c6107a1565b90505f6106176109dd565b9050600454818311610629578261062b565b815b6106359190610d26565b6002819055426003555f0361065d57604051635f18388760e01b815260040160405180910390fd5b60405163b62cad6960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b62cad69906024015f604051808303815f87803b1580156106dd575f80fd5b505af11580156106ef573d5f803e3d5ffd5b505050506003546002547f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d60405160405180910390a35050565b6107676040518060400160405280601c81526020017f736574536e617073686f742875696e743235362c75696e743235362900000000815250610b81565b60028290556003819055604051819083907f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d905f90a35050565b5f8060017f000000000000000000000000000000000000000000000000000000000000000060018111156107d7576107d7610c43565b036108b75760405163a31426d160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a31426d190604401602060405180830381865afa15801561088c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b09190610d39565b905061098e565b60405163abca0eab60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa158015610967573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098b9190610d39565b90505b670de0b6b3a7640000816109c37f0000000000000000000000000000000000000000000000000000000000000000600a610e30565b6109cd9190610e3e565b6109d79190610cee565b91505090565b5f80600354426109ed9190610d0d565b90505f670de0b6b3a7640000825f54600254610a099190610e3e565b610a139190610e3e565b610a1d9190610cee565b60025461041d9190610d26565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa158015610ab2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad69190610d39565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b39573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5d9190610e55565b60ff169050610b6d81600a610e75565b610b778487610e3e565b6104559190610cee565b6040516318c5e8ab60e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906318c5e8ab90610bd19033908690600401610eae565b602060405180830381865afa158015610bec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c109190610ed9565b905080610c3f57333083604051634a3fa29360e01b8152600401610c3693929190610ef8565b60405180910390fd5b5050565b634e487b7160e01b5f52602160045260245ffd5b6020810160028310610c7757634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215610c8d575f80fd5b81356001600160a01b038116811461041d575f80fd5b5f60208284031215610cb3575f80fd5b5035919050565b5f8060408385031215610ccb575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f82610d0857634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610d2057610d20610cda565b92915050565b80820180821115610d2057610d20610cda565b5f60208284031215610d49575f80fd5b5051919050565b600181815b80851115610d8a57815f1904821115610d7057610d70610cda565b80851615610d7d57918102915b93841c9390800290610d55565b509250929050565b5f82610da057506001610d20565b81610dac57505f610d20565b8160018114610dc25760028114610dcc57610de8565b6001915050610d20565b60ff841115610ddd57610ddd610cda565b50506001821b610d20565b5060208310610133831016604e8410600b8410161715610e0b575081810a610d20565b610e158383610d50565b805f1904821115610e2857610e28610cda565b029392505050565b5f61041d60ff841683610d92565b8082028115828204841417610d2057610d20610cda565b5f60208284031215610e65575f80fd5b815160ff8116811461041d575f80fd5b5f61041d8383610d92565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03831681526040602082018190525f90610ed190830184610e80565b949350505050565b5f60208284031215610ee9575f80fd5b8151801515811461041d575f80fd5b6001600160a01b038481168252831660208201526060604082018190525f9061045590830184610e8056fea2646970667358221220dd4434cf5ec982b81a2a3a25f96ea3d5d76d95704500f208da19253bd6abc73b64736f6c63430008190033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b506004361061013d575f3560e01c806369240426116100b45780639c43eb54116100795780639c43eb541461033e578063a4edcd4c14610347578063abb856131461036e578063ac5a693e14610376578063bdf13af21461037e578063f46f16c214610386575f80fd5b8063692404261461029957806369818a35146102a15780637fc4e4a0146102c8578063809d7b31146102db578063879ac8f814610302575f80fd5b806341976e091161010557806341976e091461021657806345be2dc7146102295780635213f9c814610250578063596efe6f14610265578063643d813d1461026e578063671528d414610281575f80fd5b806302125d091461014157806307d0413c1461017e57806329db1be6146101955780633dae7c22146101d45780634169d2451461020d575b5f80fd5b6101687f000000000000000000000000000000000000000000000000000000000000000081565b6040516101759190610c57565b60405180910390f35b61018760015481565b604051908152602001610175565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610175565b6101fb7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610175565b61018760045481565b610187610224366004610c7d565b6103ad565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b61026361025e366004610ca3565b61045e565b005b61018760025481565b61026361027c366004610cba565b6104cf565b6102896105a5565b6040519015158152602001610175565b6102636105e0565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6102636102d6366004610cba565b610729565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b61018760035481565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b6101876107a1565b6101875f5481565b6101876109dd565b6101bc7f000000000000000000000000000000000000000000000000000000000000000081565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461040057604051630f58058360e11b815260040160405180910390fd5b5f6104096107a1565b90506001545f036104245761041d81610a2a565b9392505050565b5f61042d6109dd565b90505f818311801561043e57508115155b610448578261044a565b815b905061045581610a2a565b95945050505050565b61049c6040518060400160405280601781526020017f736574536e617073686f744761702875696e7432353629000000000000000000815250610b81565b6004546040518291907feb3716d3f8388c182853c1dc98b18931f3a600bbab31f2ff48631f6412e4997f905f90a3600455565b61050d6040518060400160405280601e81526020017f73657447726f777468526174652875696e743235362c75696e74323536290000815250610b81565b5f5461051d6301e1338084610cee565b5f81905515801561052d57505f82115b8061054157505f8054118015610541575081155b1561055f576040516353b7e64560e11b815260040160405180910390fd5b6001545f54827fa65cbeb0e28a8803a912daac67c472c160aa01e2c988755fa424f290321de6088560405161059691815260200190565b60405180910390a45060015550565b5f6001545f036105b457505f90565b5f6105bd6109dd565b9050805f036105cd575f91505090565b5f6105d66107a1565b9190911192915050565b6001546003546105f09042610d0d565b10806105fc5750600154155b1561060357565b5f61060c6107a1565b90505f6106176109dd565b9050600454818311610629578261062b565b815b6106359190610d26565b6002819055426003555f0361065d57604051635f18388760e01b815260040160405180910390fd5b60405163b62cad6960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063b62cad69906024015f604051808303815f87803b1580156106dd575f80fd5b505af11580156106ef573d5f803e3d5ffd5b505050506003546002547f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d60405160405180910390a35050565b6107676040518060400160405280601c81526020017f736574536e617073686f742875696e743235362c75696e743235362900000000815250610b81565b60028290556003819055604051819083907f2c8c8fcb8c77a0ca21dcc3ab8fc0ade761557e76b1240cb40ebbef9fcee00f7d905f90a35050565b5f8060017f000000000000000000000000000000000000000000000000000000000000000060018111156107d7576107d7610c43565b036108b75760405163a31426d160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a31426d190604401602060405180830381865afa15801561088c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b09190610d39565b905061098e565b60405163abca0eab60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa158015610967573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098b9190610d39565b90505b670de0b6b3a7640000816109c37f0000000000000000000000000000000000000000000000000000000000000000600a610e30565b6109cd9190610e3e565b6109d79190610cee565b91505090565b5f80600354426109ed9190610d0d565b90505f670de0b6b3a7640000825f54600254610a099190610e3e565b610a139190610e3e565b610a1d9190610cee565b60025461041d9190610d26565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f9182917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa158015610ab2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad69190610d39565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b39573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5d9190610e55565b60ff169050610b6d81600a610e75565b610b778487610e3e565b6104559190610cee565b6040516318c5e8ab60e01b81525f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906318c5e8ab90610bd19033908690600401610eae565b602060405180830381865afa158015610bec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c109190610ed9565b905080610c3f57333083604051634a3fa29360e01b8152600401610c3693929190610ef8565b60405180910390fd5b5050565b634e487b7160e01b5f52602160045260245ffd5b6020810160028310610c7757634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215610c8d575f80fd5b81356001600160a01b038116811461041d575f80fd5b5f60208284031215610cb3575f80fd5b5035919050565b5f8060408385031215610ccb575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52601160045260245ffd5b5f82610d0857634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610d2057610d20610cda565b92915050565b80820180821115610d2057610d20610cda565b5f60208284031215610d49575f80fd5b5051919050565b600181815b80851115610d8a57815f1904821115610d7057610d70610cda565b80851615610d7d57918102915b93841c9390800290610d55565b509250929050565b5f82610da057506001610d20565b81610dac57505f610d20565b8160018114610dc25760028114610dcc57610de8565b6001915050610d20565b60ff841115610ddd57610ddd610cda565b50506001821b610d20565b5060208310610133831016604e8410600b8410161715610e0b575081810a610d20565b610e158383610d50565b805f1904821115610e2857610e28610cda565b029392505050565b5f61041d60ff841683610d92565b8082028115828204841417610d2057610d20610cda565b5f60208284031215610e65575f80fd5b815160ff8116811461041d575f80fd5b5f61041d8383610d92565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b03831681526040602082018190525f90610ed190830184610e80565b949350505050565b5f60208284031215610ee9575f80fd5b8151801515811461041d575f80fd5b6001600160a01b038481168252831660208201526060604082018190525f9061045590830184610e8056fea2646970667358221220dd4434cf5ec982b81a2a3a25f96ea3d5d76d95704500f208da19253bd6abc73b64736f6c63430008190033", + "devdoc": { + "author": "Venus", + "details": "As a base price the oracle uses either the price of the Pendle market's asset (in this case PT_TO_ASSET rate should be used) or the price of the Pendle market's interest bearing token (e.g. wstETH for stETH; in this case PT_TO_SY rate should be used). Technically, interest bearing token is different from standardized yield (SY) token, but since SY is a wrapper around an interest bearing token, we can safely assume the prices of the two are equal. This is not always true for asset price though: using PT_TO_ASSET rate assumes that the yield token can be seamlessly redeemed for the underlying asset. In reality, this might not always be the case. For more details, see https://docs.pendle.finance/Developers/Contracts/StandardizedYield", + "kind": "dev", + "methods": { + "constructor": { + "custom:error": "InvalidDuration Thrown if the duration is invalid" + }, + "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 The amount of underlying token (either the market's asset or the yield token) for 1 PT, adjusted for decimals such that the result has the same precision as the underlying token" + } + }, + "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" + } + }, + "stateVariables": { + "UNDERLYING_DECIMALS": { + "details": "We make an assumption that the underlying decimals will not change throughout the lifetime of the Pendle market" + } + }, + "title": "PendleOracle", + "version": 1 + }, + "userdoc": { + "errors": { + "InvalidDuration()": [ + { + "notice": "Thrown if the duration is invalid" + } + ], + "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" + } + ], + "ZeroValueNotAllowed()": [ + { + "notice": "Thrown if the supplied value is 0 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" + }, + "CORRELATED_TOKEN()": { + "notice": "Address of the correlated token" + }, + "MARKET()": { + "notice": "Address of the market" + }, + "PT_ORACLE()": { + "notice": "Address of the PT oracle" + }, + "RATE_KIND()": { + "notice": "Whether to use PT/SY (standardized yield token) rate or PT/market asset rate" + }, + "RESILIENT_ORACLE()": { + "notice": "Address of Resilient Oracle" + }, + "TWAP_DURATION()": { + "notice": "Twap duration for the oracle" + }, + "UNDERLYING_DECIMALS()": { + "notice": "Decimals of the underlying token" + }, + "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": "Fetches the amount of underlying token for 1 PT" + }, + "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 a pendle token", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6602, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "growthRatePerSecond", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 6605, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotInterval", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 6608, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotMaxExchangeRate", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 6611, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotTimestamp", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 6614, + "contract": "contracts/oracles/PendleOracle.sol:PendleOracle", + "label": "snapshotGap", + "offset": 0, + "slot": "4", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/helpers/deploymentConfig.ts b/helpers/deploymentConfig.ts index fb6164f3..9ca0b4fe 100644 --- a/helpers/deploymentConfig.ts +++ b/helpers/deploymentConfig.ts @@ -129,7 +129,7 @@ export const ADDRESSES: PreconfiguredAddresses = { wstETH: "0x26c5e01524d2E6280A48F2c50fF6De7e52E9611C", weETH: "0x04c0599ae5a44757c0af6f9ec3b93da8976c150a", BTCB: "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c", - "SolvBTC.BBN": "0x1346b618dC92810EC74163e4c27004c921D446a5", + "SolvBTC.BBN": "0x6c948a4c31d013515d871930fe3807276102f25d", "PT-SolvBTC.BBN-27MAR2025": "0x541b5eeac7d4434c8f87e2d32019d67611179606", "PT-SolvBTC.BBN-27MAR2025_Market": "0x9dAA2878A8739E66e08e7ad35316C5143c0ea7C7", asBNB: "0x77734e70b6E88b4d82fE632a168EDf6e700912b6", @@ -139,6 +139,10 @@ export const ADDRESSES: PreconfiguredAddresses = { "PT-sUSDE-26JUN2025_Market": "0x8557D39d4BAB2b045ac5c2B7ea66d12139da9Af4", "PT-USDe-30OCT2025": "0x607c834cfb7fcbbb341cbe23f77a6e83bcf3f55c", "PT-USDe-30OCT2025_Market": "0xb5b56637810e4d090894785993f4cdd6875d927e", + "PT-xSolvBTC-18DEC2025": "0x154b13a628e947034ca69378ee0acde9d973d868", + "PT-xSolvBTC-18DEC2025_Market": "0xe616d50e441aa2f6d6cd43eba1b1632ab1b046e6", + "PT-SolvBTC.BNB-18DEC2025": "0xee61a49a180cd23c3e629c5a70c1ee6539c004bd", + "PT-SolvBTC.BNB-18DEC2025_Market": "0x527be6fa23ff71e3faf5c2c1511b0531b67a701d", sUSDe: "0x211Cc4DD073734dA055fbF44a2b4667d5E5fE5d2", USDe: "0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34", xSolvBTC: "0x1346b618dC92810EC74163e4c27004c921D446a5", From 006d8561f1ac0a8071d295a4d2ec1bab3c469e46 Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Tue, 30 Sep 2025 12:08:04 +0000 Subject: [PATCH 4/4] feat: updating deployment files --- deployments/bscmainnet.json | 2020 ++++++++++++++++++------- deployments/bscmainnet_addresses.json | 2 + 2 files changed, 1516 insertions(+), 506 deletions(-) diff --git a/deployments/bscmainnet.json b/deployments/bscmainnet.json index 02443822..f9bd6cf9 100644 --- a/deployments/bscmainnet.json +++ b/deployments/bscmainnet.json @@ -5861,8 +5861,8 @@ } ] }, - "PendleOracle-PT-USDe-30OCT2025": { - "address": "0xAa5138e86c078fd2859a929173B3870b5003EC30", + "PendleOracle-PT-SolvBTC.BNB-18DEC2025": { + "address": "0x9B353103f6da8FCb67B2e5bB129fC5c63691AbF8", "abi": [ { "inputs": [ @@ -6365,8 +6365,8 @@ } ] }, - "PendleOracle-PT-USDe-30OCT2025_Reference_PtToAsset": { - "address": "0xa1041218273BB5F3f0bdD8B2BbaDACE05e2CF567", + "PendleOracle-PT-USDe-30OCT2025": { + "address": "0xAa5138e86c078fd2859a929173B3870b5003EC30", "abi": [ { "inputs": [ @@ -6869,39 +6869,172 @@ } ] }, - "PendleOracle-PT-clisBNB-24APR2025": { - "address": "0xEa7a92D12196A325C76ED26DBd36629d7EC46459", + "PendleOracle-PT-USDe-30OCT2025_Reference_PtToAsset": { + "address": "0xa1041218273BB5F3f0bdD8B2BbaDACE05e2CF567", "abi": [ { - "anonymous": false, "inputs": [ { - "indexed": false, + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "address", + "name": "ptOracle", + "type": "address" + }, + { + "internalType": "enum PendleOracle.RateKind", + "name": "rateKind", + "type": "uint8" + }, + { + "internalType": "address", + "name": "ptToken", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "resilientOracle", + "type": "address" + }, + { + "internalType": "uint32", + "name": "twapDuration", + "type": "uint32" + }, + { + "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" + } + ], + "internalType": "struct PendleOracle.ConstructorParams", + "name": "params", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidGrowthRate", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialSnapshot", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSnapshotMaxExchangeRate", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTokenAddress", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", - "name": "previousAdmin", + "name": "sender", "type": "address" }, { - "indexed": false, "internalType": "address", - "name": "newAdmin", + "name": "calledContract", "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" } ], - "name": "AdminChanged", - "type": "event" + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "type": "error" }, { "anonymous": false, "inputs": [ { "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "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": "BeaconUpgraded", + "name": "GrowthRateUpdated", "type": "event" }, { @@ -6909,105 +7042,110 @@ "inputs": [ { "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256", + "name": "oldSnapshotGap", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "newSnapshotGap", + "type": "uint256" } ], - "name": "Upgraded", + "name": "SnapshotGapUpdated", "type": "event" }, { - "stateMutability": "payable", - "type": "fallback" + "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": "admin", + "name": "ACCESS_CONTROL_MANAGER", "outputs": [ { - "internalType": "address", - "name": "admin_", + "internalType": "contract IAccessControlManagerV8", + "name": "", "type": "address" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [], - "name": "implementation", + "name": "CORRELATED_TOKEN", "outputs": [ { "internalType": "address", - "name": "implementation_", + "name": "", "type": "address" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "MARKET", + "outputs": [ { "internalType": "address", - "name": "newImplementation", + "name": "", "type": "address" } ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "PT_ORACLE", + "outputs": [ { - "internalType": "address", - "name": "newImplementation", + "internalType": "contract IPendlePtOracle", + "name": "", "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" } ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, - { - "stateMutability": "payable", - "type": "receive" - }, { "inputs": [], - "name": "InvalidDuration", - "type": "error" + "name": "RATE_KIND", + "outputs": [ + { + "internalType": "enum PendleOracle.RateKind", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" }, { "inputs": [], - "name": "InvalidTokenAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddressNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValueNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "CORRELATED_TOKEN", + "name": "RESILIENT_ORACLE", "outputs": [ { - "internalType": "address", + "internalType": "contract ResilientOracleInterface", "name": "", "type": "address" } @@ -7017,12 +7155,12 @@ }, { "inputs": [], - "name": "MARKET", + "name": "TWAP_DURATION", "outputs": [ { - "internalType": "address", + "internalType": "uint32", "name": "", - "type": "address" + "type": "uint32" } ], "stateMutability": "view", @@ -7030,12 +7168,12 @@ }, { "inputs": [], - "name": "PT_ORACLE", + "name": "UNDERLYING_DECIMALS", "outputs": [ { - "internalType": "contract IPendlePtOracle", + "internalType": "uint8", "name": "", - "type": "address" + "type": "uint8" } ], "stateMutability": "view", @@ -7043,12 +7181,12 @@ }, { "inputs": [], - "name": "RATE_KIND", + "name": "UNDERLYING_TOKEN", "outputs": [ { - "internalType": "enum PendleOracle.RateKind", + "internalType": "address", "name": "", - "type": "uint8" + "type": "address" } ], "stateMutability": "view", @@ -7056,25 +7194,31 @@ }, { "inputs": [], - "name": "RESILIENT_ORACLE", + "name": "getMaxAllowedExchangeRate", "outputs": [ { - "internalType": "contract OracleInterface", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [], - "name": "TWAP_DURATION", + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPrice", "outputs": [ { - "internalType": "uint32", + "internalType": "uint256", "name": "", - "type": "uint32" + "type": "uint256" } ], "stateMutability": "view", @@ -7082,12 +7226,12 @@ }, { "inputs": [], - "name": "UNDERLYING_DECIMALS", + "name": "getUnderlyingAmount", "outputs": [ { - "internalType": "uint8", + "internalType": "uint256", "name": "", - "type": "uint8" + "type": "uint256" } ], "stateMutability": "view", @@ -7095,31 +7239,25 @@ }, { "inputs": [], - "name": "UNDERLYING_TOKEN", + "name": "growthRatePerSecond", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - } - ], - "name": "getPrice", + "inputs": [], + "name": "isCapped", "outputs": [ { - "internalType": "uint256", + "internalType": "bool", "name": "", - "type": "uint256" + "type": "bool" } ], "stateMutability": "view", @@ -7128,124 +7266,60 @@ { "inputs": [ { - "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", - "type": "address" + "internalType": "uint256", + "name": "_annualGrowthRate", + "type": "uint256" }, { - "internalType": "bytes", - "name": "_data", - "type": "bytes" + "internalType": "uint256", + "name": "_snapshotInterval", + "type": "uint256" } ], - "stateMutability": "payable", - "type": "constructor" - } - ] - }, - "PendleOracle-PT-clisBNB-24APR2025_Implementation": { - "address": "0x8A183a0d35290D849e8915710D3aEE7e463705E7", - "abi": [ + "name": "setGrowthRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { - "internalType": "address", - "name": "market", - "type": "address" - }, - { - "internalType": "address", - "name": "ptOracle", - "type": "address" - }, - { - "internalType": "enum PendleOracle.RateKind", - "name": "rateKind", - "type": "uint8" - }, - { - "internalType": "address", - "name": "ptToken", - "type": "address" - }, - { - "internalType": "address", - "name": "underlyingToken", - "type": "address" - }, - { - "internalType": "address", - "name": "resilientOracle", - "type": "address" + "internalType": "uint256", + "name": "_snapshotMaxExchangeRate", + "type": "uint256" }, { - "internalType": "uint32", - "name": "twapDuration", - "type": "uint32" + "internalType": "uint256", + "name": "_snapshotTimestamp", + "type": "uint256" } ], + "name": "setSnapshot", + "outputs": [], "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "InvalidDuration", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidTokenAddress", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddressNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroValueNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "CORRELATED_TOKEN", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", "type": "function" }, { - "inputs": [], - "name": "MARKET", - "outputs": [ + "inputs": [ { - "internalType": "address", - "name": "", - "type": "address" + "internalType": "uint256", + "name": "_snapshotGap", + "type": "uint256" } ], - "stateMutability": "view", + "name": "setSnapshotGap", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], - "name": "PT_ORACLE", + "name": "snapshotGap", "outputs": [ { - "internalType": "contract IPendlePtOracle", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", @@ -7253,12 +7327,12 @@ }, { "inputs": [], - "name": "RATE_KIND", + "name": "snapshotInterval", "outputs": [ { - "internalType": "enum PendleOracle.RateKind", + "internalType": "uint256", "name": "", - "type": "uint8" + "type": "uint256" } ], "stateMutability": "view", @@ -7266,12 +7340,12 @@ }, { "inputs": [], - "name": "RESILIENT_ORACLE", + "name": "snapshotMaxExchangeRate", "outputs": [ { - "internalType": "contract OracleInterface", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", @@ -7279,12 +7353,12 @@ }, { "inputs": [], - "name": "TWAP_DURATION", + "name": "snapshotTimestamp", "outputs": [ { - "internalType": "uint32", + "internalType": "uint256", "name": "", - "type": "uint32" + "type": "uint256" } ], "stateMutability": "view", @@ -7292,203 +7366,29 @@ }, { "inputs": [], - "name": "UNDERLYING_DECIMALS", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", + "name": "updateSnapshot", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" - }, + } + ] + }, + "PendleOracle-PT-clisBNB-24APR2025": { + "address": "0xEa7a92D12196A325C76ED26DBd36629d7EC46459", + "abi": [ { - "inputs": [], - "name": "UNDERLYING_TOKEN", - "outputs": [ + "anonymous": false, + "inputs": [ { + "indexed": false, "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "asset", - "type": "address" - } - ], - "name": "getPrice", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } - ] - }, - "PendleOracle-PT-clisBNB-24APR2025_Proxy": { - "address": "0xEa7a92D12196A325C76ED26DBd36629d7EC46459", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_logic", - "type": "address" - }, - { - "internalType": "address", - "name": "admin_", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } - ], - "name": "AdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" - } - ], - "name": "BeaconUpgraded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "admin_", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "implementation_", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - } - ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ] - }, - "PendleOracle-PT-clisBNB-24APR2025_Reference_PtToAsset": { - "address": "0x189BD17F0375589922faeDD56A86e53C42d82C0e", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", "type": "address" } ], @@ -7752,8 +7652,8 @@ } ] }, - "PendleOracle-PT-clisBNB-24APR2025_Reference_PtToAsset_Implementation": { - "address": "0xac9118c15B95bc9385CbfFe11035CB200E282bf4", + "PendleOracle-PT-clisBNB-24APR2025_Implementation": { + "address": "0x8A183a0d35290D849e8915710D3aEE7e463705E7", "abi": [ { "inputs": [ @@ -7783,38 +7683,1122 @@ "type": "address" }, { - "internalType": "address", - "name": "resilientOracle", - "type": "address" + "internalType": "address", + "name": "resilientOracle", + "type": "address" + }, + { + "internalType": "uint32", + "name": "twapDuration", + "type": "uint32" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTokenAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "CORRELATED_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MARKET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_ORACLE", + "outputs": [ + { + "internalType": "contract IPendlePtOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_KIND", + "outputs": [ + { + "internalType": "enum PendleOracle.RateKind", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RESILIENT_ORACLE", + "outputs": [ + { + "internalType": "contract OracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TWAP_DURATION", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_DECIMALS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "PendleOracle-PT-clisBNB-24APR2025_Proxy": { + "address": "0xEa7a92D12196A325C76ED26DBd36629d7EC46459", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "PendleOracle-PT-clisBNB-24APR2025_Reference_PtToAsset": { + "address": "0x189BD17F0375589922faeDD56A86e53C42d82C0e", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTokenAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "CORRELATED_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MARKET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_ORACLE", + "outputs": [ + { + "internalType": "contract IPendlePtOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_KIND", + "outputs": [ + { + "internalType": "enum PendleOracle.RateKind", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RESILIENT_ORACLE", + "outputs": [ + { + "internalType": "contract OracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TWAP_DURATION", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_DECIMALS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ] + }, + "PendleOracle-PT-clisBNB-24APR2025_Reference_PtToAsset_Implementation": { + "address": "0xac9118c15B95bc9385CbfFe11035CB200E282bf4", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "address", + "name": "ptOracle", + "type": "address" + }, + { + "internalType": "enum PendleOracle.RateKind", + "name": "rateKind", + "type": "uint8" + }, + { + "internalType": "address", + "name": "ptToken", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "resilientOracle", + "type": "address" + }, + { + "internalType": "uint32", + "name": "twapDuration", + "type": "uint32" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTokenAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "CORRELATED_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MARKET", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_ORACLE", + "outputs": [ + { + "internalType": "contract IPendlePtOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RATE_KIND", + "outputs": [ + { + "internalType": "enum PendleOracle.RateKind", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "RESILIENT_ORACLE", + "outputs": [ + { + "internalType": "contract OracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TWAP_DURATION", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_DECIMALS", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNDERLYING_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ] + }, + "PendleOracle-PT-clisBNB-24APR2025_Reference_PtToAsset_Proxy": { + "address": "0x189BD17F0375589922faeDD56A86e53C42d82C0e", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] + }, + "PendleOracle-PT-sUSDe-26JUN2025": { + "address": "0xC407403fa78Bce509821D776b6Be7f91cC04474f", + "abi": [ + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "address", + "name": "ptOracle", + "type": "address" + }, + { + "internalType": "enum PendleOracle.RateKind", + "name": "rateKind", + "type": "uint8" + }, + { + "internalType": "address", + "name": "ptToken", + "type": "address" + }, + { + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "resilientOracle", + "type": "address" + }, + { + "internalType": "uint32", + "name": "twapDuration", + "type": "uint32" + }, + { + "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" + } + ], + "internalType": "struct PendleOracle.ConstructorParams", + "name": "params", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidDuration", + "type": "error" + }, + { + "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" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "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" }, { - "internalType": "uint32", - "name": "twapDuration", - "type": "uint32" + "indexed": true, + "internalType": "uint256", + "name": "newSnapshotGap", + "type": "uint256" } ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "InvalidDuration", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidTokenAddress", - "type": "error" + "name": "SnapshotGapUpdated", + "type": "event" }, { - "inputs": [], - "name": "ZeroAddressNotAllowed", - "type": "error" + "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": "ZeroValueNotAllowed", - "type": "error" + "name": "ACCESS_CONTROL_MANAGER", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" }, { "inputs": [], @@ -7873,7 +8857,7 @@ "name": "RESILIENT_ORACLE", "outputs": [ { - "internalType": "contract OracleInterface", + "internalType": "contract ResilientOracleInterface", "name": "", "type": "address" } @@ -7920,6 +8904,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getMaxAllowedExchangeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -7938,147 +8935,158 @@ ], "stateMutability": "view", "type": "function" - } - ] - }, - "PendleOracle-PT-clisBNB-24APR2025_Reference_PtToAsset_Proxy": { - "address": "0x189BD17F0375589922faeDD56A86e53C42d82C0e", - "abi": [ + }, { - "inputs": [ + "inputs": [], + "name": "getUnderlyingAmount", + "outputs": [ { - "internalType": "address", - "name": "_logic", - "type": "address" - }, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "growthRatePerSecond", + "outputs": [ { - "internalType": "address", - "name": "admin_", - "type": "address" - }, + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isCapped", + "outputs": [ { - "internalType": "bytes", - "name": "_data", - "type": "bytes" + "internalType": "bool", + "name": "", + "type": "bool" } ], - "stateMutability": "payable", - "type": "constructor" + "stateMutability": "view", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": false, - "internalType": "address", - "name": "previousAdmin", - "type": "address" + "internalType": "uint256", + "name": "_annualGrowthRate", + "type": "uint256" }, { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" + "internalType": "uint256", + "name": "_snapshotInterval", + "type": "uint256" } ], - "name": "AdminChanged", - "type": "event" + "name": "setGrowthRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "beacon", - "type": "address" + "internalType": "uint256", + "name": "_snapshotMaxExchangeRate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_snapshotTimestamp", + "type": "uint256" } ], - "name": "BeaconUpgraded", - "type": "event" + "name": "setSnapshot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { - "anonymous": false, "inputs": [ { - "indexed": true, - "internalType": "address", - "name": "implementation", - "type": "address" + "internalType": "uint256", + "name": "_snapshotGap", + "type": "uint256" } ], - "name": "Upgraded", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" + "name": "setSnapshotGap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" }, { "inputs": [], - "name": "admin", + "name": "snapshotGap", "outputs": [ { - "internalType": "address", - "name": "admin_", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { "inputs": [], - "name": "implementation", + "name": "snapshotInterval", "outputs": [ { - "internalType": "address", - "name": "implementation_", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "snapshotMaxExchangeRate", + "outputs": [ { - "internalType": "address", - "name": "newImplementation", - "type": "address" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "upgradeTo", - "outputs": [], - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "newImplementation", - "type": "address" - }, + "inputs": [], + "name": "snapshotTimestamp", + "outputs": [ { - "internalType": "bytes", - "name": "data", - "type": "bytes" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "upgradeToAndCall", - "outputs": [], - "stateMutability": "payable", + "stateMutability": "view", "type": "function" }, { - "stateMutability": "payable", - "type": "receive" + "inputs": [], + "name": "updateSnapshot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ] }, - "PendleOracle-PT-sUSDe-26JUN2025": { - "address": "0xC407403fa78Bce509821D776b6Be7f91cC04474f", + "PendleOracle-PT-sUSDe-26JUN2025_Reference_PtToAsset": { + "address": "0xe4817DA70beE980fdBF0064c426086D4D72a6C72", "abi": [ { "inputs": [ @@ -8581,8 +9589,8 @@ } ] }, - "PendleOracle-PT-sUSDe-26JUN2025_Reference_PtToAsset": { - "address": "0xe4817DA70beE980fdBF0064c426086D4D72a6C72", + "PendleOracle-PT-xSolvBTC-18DEC2025": { + "address": "0xfbaC497147EF27f155f27aaB1172666dce09820E", "abi": [ { "inputs": [ diff --git a/deployments/bscmainnet_addresses.json b/deployments/bscmainnet_addresses.json index b8a3e3b5..85d03993 100644 --- a/deployments/bscmainnet_addresses.json +++ b/deployments/bscmainnet_addresses.json @@ -22,6 +22,7 @@ "PendleOracle-PT-SolvBTC.BBN-27MAR2025_Reference_PtToAsset": "0x3beC73E7A5385257981Cd50A147A32b0397d9cBB", "PendleOracle-PT-SolvBTC.BBN-27MAR2025_Reference_PtToAsset_Implementation": "0xe194B3A99B20BE368DEDDfe702820987Ef5c0E4A", "PendleOracle-PT-SolvBTC.BBN-27MAR2025_Reference_PtToAsset_Proxy": "0x3beC73E7A5385257981Cd50A147A32b0397d9cBB", + "PendleOracle-PT-SolvBTC.BNB-18DEC2025": "0x9B353103f6da8FCb67B2e5bB129fC5c63691AbF8", "PendleOracle-PT-USDe-30OCT2025": "0xAa5138e86c078fd2859a929173B3870b5003EC30", "PendleOracle-PT-USDe-30OCT2025_Reference_PtToAsset": "0xa1041218273BB5F3f0bdD8B2BbaDACE05e2CF567", "PendleOracle-PT-clisBNB-24APR2025": "0xEa7a92D12196A325C76ED26DBd36629d7EC46459", @@ -32,6 +33,7 @@ "PendleOracle-PT-clisBNB-24APR2025_Reference_PtToAsset_Proxy": "0x189BD17F0375589922faeDD56A86e53C42d82C0e", "PendleOracle-PT-sUSDe-26JUN2025": "0xC407403fa78Bce509821D776b6Be7f91cC04474f", "PendleOracle-PT-sUSDe-26JUN2025_Reference_PtToAsset": "0xe4817DA70beE980fdBF0064c426086D4D72a6C72", + "PendleOracle-PT-xSolvBTC-18DEC2025": "0xfbaC497147EF27f155f27aaB1172666dce09820E", "PythOracle": "0xb893E38162f55fb80B18Aa44da76FaDf8E9B2262", "PythOracle_Implementation": "0x1b8dE8fe17735B80E30e1bAbcD78A20F573a3e9e", "PythOracle_Proxy": "0xb893E38162f55fb80B18Aa44da76FaDf8E9B2262",