Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
bd60eb8
feat: could use different contracts to get the wstETH ratio
chechu Jun 11, 2025
6809779
fix: fixed ut
web3rover Jun 17, 2025
e4f1e16
fix: fixed deploy script
web3rover Jun 17, 2025
43179a0
fix: added caps
web3rover Jun 17, 2025
1d2cd33
docs: vwu-02
chechu Jun 23, 2025
dbf8fc5
docs: vwu-01
chechu Jun 23, 2025
afcbf4b
docs: add audit for WstETHOracleV2
chechu Jun 26, 2025
0d41742
fix: deployed oracle
web3rover Jun 30, 2025
549f763
fix: removed proxy
web3rover Jun 30, 2025
2541103
feat: updating deployment files
web3rover Jun 30, 2025
f3f6f78
Merge pull request #289 from VenusProtocol/main
chechu Jul 2, 2025
00296f9
Merge pull request #286 from VenusProtocol/feat/VEN-3625
web3rover Jul 11, 2025
cf0ff73
fix: removed berachain deployment
web3rover Aug 7, 2025
e165afc
fix: fixed yarn lock
web3rover Aug 7, 2025
23e3c28
Merge pull request #290 from VenusProtocol/feat/ven-3356
web3rover Aug 11, 2025
95eea27
chore(release): 2.14.0-dev.1 [skip ci]
toolsvenus Aug 11, 2025
de0e156
feat: add PT-USDe oracle deployemnts
GitGuru7 Sep 26, 2025
9179568
fix: yarn-lock updates
GitGuru7 Sep 26, 2025
9464757
feat: updating deployment files
GitGuru7 Sep 26, 2025
b443a93
fix: market naming case
GitGuru7 Sep 26, 2025
7a3baa3
feat: updating deployment files
GitGuru7 Sep 26, 2025
6dc42ad
fix: update PT-USDe oracle deployemnt
GitGuru7 Sep 26, 2025
7f6990a
feat: updating deployment files
GitGuru7 Sep 26, 2025
0428227
feat: add PT-USDe oracle deployemnts on bscmainnet
GitGuru7 Sep 26, 2025
f688009
feat: updating deployment files
GitGuru7 Sep 26, 2025
74f712a
Merge pull request #292 from VenusProtocol/vpd-150
GitGuru7 Sep 29, 2025
6c775e6
chore(release): 2.14.0-dev.2 [skip ci]
toolsvenus Sep 29, 2025
492a3de
chore: update dependencies
chechu Sep 29, 2025
eddea22
Merge pull request #293 from VenusProtocol/release/20250929
chechu Sep 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ ARCHIVE_NODE_ethereum=https://eth-mainnet.nodereal.io/v1/<YOUR_KEY_HERE>
#ARCHIVE_NODE_basemainnet=https://open-platform.nodereal.io/<YOUR_KEY_HERE>/base
#ARCHIVE_NODE_unichainsepolia=https://unichain-sepolia.g.alchemy.com/v2/<YOUR_KEY_HERE>
#ARCHIVE_NODE_unichainmainnet=https://unichain-mainnet.g.alchemy.com/v2/<YOUR_KEY_HERE>
#ARCHIVE_NODE_berachainbepolia=https://berachain-bepolia.g.alchemy.com/v2/<YOUR_KEY_HERE>

ETHERSCAN_API_KEY=
REPORT_GAS=
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ jobs:

- name: Export deployments
run: |
for NETWORK in bsctestnet bscmainnet ethereum sepolia opbnbtestnet opbnbmainnet arbitrumsepolia arbitrumone opsepolia opmainnet basesepolia basemainnet unichainsepolia unichainmainnet berachainbepolia; do
for NETWORK in bsctestnet bscmainnet ethereum sepolia opbnbtestnet opbnbmainnet arbitrumsepolia arbitrumone opsepolia opmainnet basesepolia basemainnet unichainsepolia unichainmainnet; do
EXPORT=true yarn hardhat export --network ${NETWORK} --export ./deployments/${NETWORK}.json
jq -M '{name, chainId, addresses: .contracts | map_values(.address)}' ./deployments/${NETWORK}.json > ./deployments/${NETWORK}_addresses.json
done
Expand Down
38 changes: 38 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
## [2.14.0-dev.2](https://github.com/VenusProtocol/oracle/compare/v2.14.0-dev.1...v2.14.0-dev.2) (2025-09-29)


### Features

* add PT-USDe oracle deployemnts ([de0e156](https://github.com/VenusProtocol/oracle/commit/de0e15690cad6b713069ea9200a7a4b2d359bfef))
* add PT-USDe oracle deployemnts on bscmainnet ([0428227](https://github.com/VenusProtocol/oracle/commit/042822727a1c95ef94978e32ea91333c6b6d7c0d))
* updating deployment files ([f688009](https://github.com/VenusProtocol/oracle/commit/f688009a686c6d56c5b9748e23b0826cabe64d52))
* updating deployment files ([7f6990a](https://github.com/VenusProtocol/oracle/commit/7f6990afe8886a559bc4a7efd8ec4794a5928e9a))
* updating deployment files ([7a3baa3](https://github.com/VenusProtocol/oracle/commit/7a3baa3c98561e02b8cfeb0ca3301f91882e3ab3))
* updating deployment files ([9464757](https://github.com/VenusProtocol/oracle/commit/946475775ff74d8d3fa502edb5759ad695c03f5d))


### Bug Fixes

* market naming case ([b443a93](https://github.com/VenusProtocol/oracle/commit/b443a930c4d50b80012689416c3db77ae5cd2231))
* update PT-USDe oracle deployemnt ([6dc42ad](https://github.com/VenusProtocol/oracle/commit/6dc42ad74f1edd9338371efdcfc81db5069e7ba8))
* yarn-lock updates ([9179568](https://github.com/VenusProtocol/oracle/commit/9179568a8c423e4207e8531406a09fb42389baf8))

## [2.14.0-dev.1](https://github.com/VenusProtocol/oracle/compare/v2.13.0...v2.14.0-dev.1) (2025-08-11)


### Features

* could use different contracts to get the wstETH ratio ([bd60eb8](https://github.com/VenusProtocol/oracle/commit/bd60eb88975228113195c0d4a1df3dabc61afb4d))
* updating deployment files ([2541103](https://github.com/VenusProtocol/oracle/commit/25411038a1c2afb632d5377874349f62b98e03eb))


### Bug Fixes

* added caps ([43179a0](https://github.com/VenusProtocol/oracle/commit/43179a0ddaaacb52ca3130efcbae9cd36246bb45))
* deployed oracle ([0d41742](https://github.com/VenusProtocol/oracle/commit/0d4174201e5570a60c612bd831acf2ffc57bc4a9))
* fixed deploy script ([e4f1e16](https://github.com/VenusProtocol/oracle/commit/e4f1e166b9edf8451caaac96e2abc12f04a1074c))
* fixed ut ([6809779](https://github.com/VenusProtocol/oracle/commit/6809779b51cd4a4db0ba6c8a6620738165129966))
* fixed yarn lock ([e165afc](https://github.com/VenusProtocol/oracle/commit/e165afcccf3dd5745dfff2942595aa3d72ae81a6))
* removed berachain deployment ([cf0ff73](https://github.com/VenusProtocol/oracle/commit/cf0ff73bc19f1f17e48366b8aebda1ca9130f4df))
* removed proxy ([549f763](https://github.com/VenusProtocol/oracle/commit/549f763fa34f4b0e708f9be6aa8649dcaae8a8cc))

## [2.13.0](https://github.com/VenusProtocol/oracle/compare/v2.12.0...v2.13.0) (2025-07-01)


Expand Down
Binary file added audits/137_wstETHOracleV2_certik_20250623.pdf
Binary file not shown.
22 changes: 16 additions & 6 deletions contracts/oracles/WstETHOracleV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,24 @@ pragma solidity 0.8.25;
import { IStETH } from "../interfaces/IStETH.sol";
import { CorrelatedTokenOracle } from "./common/CorrelatedTokenOracle.sol";
import { EXP_SCALE } from "@venusprotocol/solidity-utilities/contracts/constants.sol";
import { ensureNonzeroAddress } from "@venusprotocol/solidity-utilities/contracts/validators.sol";

/**
* @title WstETHOracleV2
* @author Venus
* @notice This oracle fetches the price of wstETH
*/
contract WstETHOracleV2 is CorrelatedTokenOracle {
/// @notice Address of stETH
IStETH public immutable STETH;

/// @notice Constructor for the implementation contract.
/// @dev The underlyingToken must be correlated so that 1 underlyingToken is equal to 1 stETH, because
/// getUnderlyingAmount() implicitly assumes that
constructor(
address wstETH,
address stETH,
address wstETH,
address underlyingToken,
address resilientOracle,
uint256 annualGrowthRate,
uint256 _snapshotInterval,
Expand All @@ -25,7 +32,7 @@ contract WstETHOracleV2 is CorrelatedTokenOracle {
)
CorrelatedTokenOracle(
wstETH,
stETH,
underlyingToken,
resilientOracle,
annualGrowthRate,
_snapshotInterval,
Expand All @@ -34,13 +41,16 @@ contract WstETHOracleV2 is CorrelatedTokenOracle {
accessControlManager,
_snapshotGap
)
{}
{
ensureNonzeroAddress(stETH);
STETH = IStETH(stETH);
}

/**
* @notice Gets the stETH for 1 wstETH
* @return amount Amount of stETH
* @notice Gets the amount of underlyingToken for 1 wstETH, assuming that 1 underlyingToken is equivalent to 1 stETH
* @return amount Amount of underlyingToken
*/
function getUnderlyingAmount() public view override returns (uint256) {
return IStETH(UNDERLYING_TOKEN).getPooledEthByShares(EXP_SCALE);
return STETH.getPooledEthByShares(EXP_SCALE);
}
}
82 changes: 82 additions & 0 deletions deploy/24-deploy-USDe-pendle-oracles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
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,
}

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 commonParams = {
from: deployer,
log: true,
deterministicDeployment: false,
skipIfAlreadyDeployed: true,
waitConfirmations: 1,
};

await deploy("PendleOracle-PT-USDe-30OCT2025", {
contract: "PendleOracle",
args: [
{
market: addresses["PT-USDe-30OCT2025_Market"] || "0x0000000000000000000000000000000000000004",
ptOracle: ptOracleAddress,
rateKind: PendleRateKind.PT_TO_SY,
ptToken: addresses["PT-USDe-30OCT2025"],
underlyingToken: addresses.USDe,
resilientOracle: resilientOracle.address,
twapDuration: 1800,
annualGrowthRate: 0,
snapshotInterval: 0,
initialSnapshotMaxExchangeRate: 0,
initialSnapshotTimestamp: 0,
accessControlManager: addresses.acm,
snapshotGap: 0,
},
],
...commonParams,
});

if (isMainnet(network)) {
await deploy("PendleOracle-PT-USDe-30OCT2025_Reference_PtToAsset", {
contract: "PendleOracle",
from: deployer,
log: true,
deterministicDeployment: false,
args: [
{
market: addresses["PT-USDe-30OCT2025_Market"] || "0x0000000000000000000000000000000000000004",
ptOracle: ptOracleAddress,
rateKind: PendleRateKind.PT_TO_ASSET,
ptToken: addresses["PT-USDe-30OCT2025"],
underlyingToken: addresses.USDe,
resilientOracle: resilientOracle.address,
twapDuration: 1800,
annualGrowthRate: 0,
snapshotInterval: 0,
initialSnapshotMaxExchangeRate: 0,
initialSnapshotTimestamp: 0,
accessControlManager: addresses.acm,
snapshotGap: 0,
},
],
skipIfAlreadyDeployed: true,
});
}
};

export default func;
func.tags = ["PT-USDe"];
func.skip = async (hre: HardhatRuntimeEnvironment) =>
hre.network.name !== "bsctestnet" && hre.network.name !== "bscmainnet";
121 changes: 75 additions & 46 deletions deploy/6-deploy-wstETH-oracle.ts
Original file line number Diff line number Diff line change
@@ -1,67 +1,96 @@
import { BigNumber } from "ethers";
import { parseUnits } from "ethers/lib/utils";
import { ethers } from "hardhat";
import { DeployFunction } from "hardhat-deploy/dist/types";
import { HardhatRuntimeEnvironment } from "hardhat/types";

import { ADDRESSES, addr0000, assets } from "../helpers/deploymentConfig";
import {
ADDRESSES,
DAYS_30,
addr0000,
assets,
getSnapshotGap,
increaseExchangeRateByPercentage,
} from "../helpers/deploymentConfig";

const func: DeployFunction = async ({
getNamedAccounts,
deployments,
network,
artifacts,
}: HardhatRuntimeEnvironment) => {
const func: DeployFunction = async ({ getNamedAccounts, deployments, network }: HardhatRuntimeEnvironment) => {
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();

console.log(`Deployer ${deployer}`);

const proxyOwnerAddress = network.live ? ADDRESSES[network.name].timelock : deployer;

const { stETHAddress, wstETHAddress } = ADDRESSES[network.name];
const { stETHAddress, wstETHAddress, acm } = ADDRESSES[network.name];
const WETHAsset = assets[network.name].find(asset => asset.token === "WETH");
const WETHAddress = WETHAsset?.address ?? addr0000;

const defaultProxyAdmin = await artifacts.readArtifact(
"hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol:ProxyAdmin",
);

const oracle = await ethers.getContract("ResilientOracle");

// Equivalence and NonEquivalence is related to if the oracle will
// assume 1/1 price ration between stETH/ETH or
// will get stETH/USD price from secondary market

await deploy("WstETHOracle_Equivalence", {
contract: "WstETHOracle",
from: deployer,
log: true,
deterministicDeployment: false,
args: [wstETHAddress, WETHAddress, stETHAddress, oracle.address, true],
proxy: {
owner: proxyOwnerAddress,
proxyContract: "OptimizedTransparentUpgradeableProxy",
viaAdminContract: {
name: "DefaultProxyAdmin",
artifact: defaultProxyAdmin,
},
},
});
const wstETH_ANNUAL_GROWTH_RATE = ethers.utils.parseUnits("0.067", 18); // 6.7%
const block = await ethers.provider.getBlock("latest");
const stETHContract = await ethers.getContractAt("IStETH", stETHAddress);
const exchangeRate = await stETHContract.getPooledEthByShares(parseUnits("1", 18));
const snapshotGap = BigNumber.from("55"); // 0.55%

if (network.name === "ethereum") {
await deploy("WstETHOracle_Equivalence", {
contract: "WstETHOracleV2",
from: deployer,
log: true,
deterministicDeployment: false,
args: [
stETHAddress,
wstETHAddress,
WETHAddress,
oracle.address,
wstETH_ANNUAL_GROWTH_RATE,
DAYS_30,
increaseExchangeRateByPercentage(exchangeRate, snapshotGap),
block.timestamp,
acm,
getSnapshotGap(exchangeRate, snapshotGap.toNumber()),
],
});

await deploy("WstETHOracle_NonEquivalence", {
contract: "WstETHOracle",
from: deployer,
log: true,
deterministicDeployment: false,
args: [wstETHAddress, WETHAddress, stETHAddress, oracle.address, false],
proxy: {
owner: proxyOwnerAddress,
proxyContract: "OptimizedTransparentUpgradeableProxy",
viaAdminContract: {
name: "DefaultProxyAdmin",
artifact: defaultProxyAdmin,
},
},
});
await deploy("WstETHOracle_NonEquivalence", {
contract: "WstETHOracleV2",
from: deployer,
log: true,
deterministicDeployment: false,
args: [
stETHAddress,
wstETHAddress,
stETHAddress,
oracle.address,
wstETH_ANNUAL_GROWTH_RATE,
DAYS_30,
increaseExchangeRateByPercentage(exchangeRate, snapshotGap),
block.timestamp,
acm,
getSnapshotGap(exchangeRate, snapshotGap.toNumber()),
],
});
} else {
await deploy("WstETHOracle", {
contract: "WstETHOracleV2",
from: deployer,
log: true,
deterministicDeployment: false,
args: [
stETHAddress,
wstETHAddress,
WETHAddress,
oracle.address,
wstETH_ANNUAL_GROWTH_RATE,
DAYS_30,
increaseExchangeRateByPercentage(exchangeRate, snapshotGap),
block.timestamp,
acm,
getSnapshotGap(exchangeRate, snapshotGap.toNumber()),
],
});
}
};

export default func;
Expand Down
Loading
Loading