Skip to content

Commit 00296f9

Browse files
authored
Merge pull request #286 from VenusProtocol/feat/VEN-3625
[VEN-3265]: WstETHOracleV2 could use different contracts to get the wstETH ratio
2 parents f3f6f78 + 2541103 commit 00296f9

19 files changed

+2350
-2538
lines changed
3.23 MB
Binary file not shown.

contracts/oracles/WstETHOracleV2.sol

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,24 @@ pragma solidity 0.8.25;
44
import { IStETH } from "../interfaces/IStETH.sol";
55
import { CorrelatedTokenOracle } from "./common/CorrelatedTokenOracle.sol";
66
import { EXP_SCALE } from "@venusprotocol/solidity-utilities/contracts/constants.sol";
7+
import { ensureNonzeroAddress } from "@venusprotocol/solidity-utilities/contracts/validators.sol";
78

89
/**
910
* @title WstETHOracleV2
1011
* @author Venus
1112
* @notice This oracle fetches the price of wstETH
1213
*/
1314
contract WstETHOracleV2 is CorrelatedTokenOracle {
15+
/// @notice Address of stETH
16+
IStETH public immutable STETH;
17+
1418
/// @notice Constructor for the implementation contract.
19+
/// @dev The underlyingToken must be correlated so that 1 underlyingToken is equal to 1 stETH, because
20+
/// getUnderlyingAmount() implicitly assumes that
1521
constructor(
16-
address wstETH,
1722
address stETH,
23+
address wstETH,
24+
address underlyingToken,
1825
address resilientOracle,
1926
uint256 annualGrowthRate,
2027
uint256 _snapshotInterval,
@@ -25,7 +32,7 @@ contract WstETHOracleV2 is CorrelatedTokenOracle {
2532
)
2633
CorrelatedTokenOracle(
2734
wstETH,
28-
stETH,
35+
underlyingToken,
2936
resilientOracle,
3037
annualGrowthRate,
3138
_snapshotInterval,
@@ -34,13 +41,16 @@ contract WstETHOracleV2 is CorrelatedTokenOracle {
3441
accessControlManager,
3542
_snapshotGap
3643
)
37-
{}
44+
{
45+
ensureNonzeroAddress(stETH);
46+
STETH = IStETH(stETH);
47+
}
3848

3949
/**
40-
* @notice Gets the stETH for 1 wstETH
41-
* @return amount Amount of stETH
50+
* @notice Gets the amount of underlyingToken for 1 wstETH, assuming that 1 underlyingToken is equivalent to 1 stETH
51+
* @return amount Amount of underlyingToken
4252
*/
4353
function getUnderlyingAmount() public view override returns (uint256) {
44-
return IStETH(UNDERLYING_TOKEN).getPooledEthByShares(EXP_SCALE);
54+
return STETH.getPooledEthByShares(EXP_SCALE);
4555
}
4656
}

deploy/6-deploy-wstETH-oracle.ts

Lines changed: 75 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,96 @@
1+
import { BigNumber } from "ethers";
2+
import { parseUnits } from "ethers/lib/utils";
13
import { ethers } from "hardhat";
24
import { DeployFunction } from "hardhat-deploy/dist/types";
35
import { HardhatRuntimeEnvironment } from "hardhat/types";
46

5-
import { ADDRESSES, addr0000, assets } from "../helpers/deploymentConfig";
7+
import {
8+
ADDRESSES,
9+
DAYS_30,
10+
addr0000,
11+
assets,
12+
getSnapshotGap,
13+
increaseExchangeRateByPercentage,
14+
} from "../helpers/deploymentConfig";
615

7-
const func: DeployFunction = async ({
8-
getNamedAccounts,
9-
deployments,
10-
network,
11-
artifacts,
12-
}: HardhatRuntimeEnvironment) => {
16+
const func: DeployFunction = async ({ getNamedAccounts, deployments, network }: HardhatRuntimeEnvironment) => {
1317
const { deploy } = deployments;
1418
const { deployer } = await getNamedAccounts();
1519

16-
console.log(`Deployer ${deployer}`);
17-
18-
const proxyOwnerAddress = network.live ? ADDRESSES[network.name].timelock : deployer;
19-
20-
const { stETHAddress, wstETHAddress } = ADDRESSES[network.name];
20+
const { stETHAddress, wstETHAddress, acm } = ADDRESSES[network.name];
2121
const WETHAsset = assets[network.name].find(asset => asset.token === "WETH");
2222
const WETHAddress = WETHAsset?.address ?? addr0000;
2323

24-
const defaultProxyAdmin = await artifacts.readArtifact(
25-
"hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol:ProxyAdmin",
26-
);
27-
2824
const oracle = await ethers.getContract("ResilientOracle");
2925

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

34-
await deploy("WstETHOracle_Equivalence", {
35-
contract: "WstETHOracle",
36-
from: deployer,
37-
log: true,
38-
deterministicDeployment: false,
39-
args: [wstETHAddress, WETHAddress, stETHAddress, oracle.address, true],
40-
proxy: {
41-
owner: proxyOwnerAddress,
42-
proxyContract: "OptimizedTransparentUpgradeableProxy",
43-
viaAdminContract: {
44-
name: "DefaultProxyAdmin",
45-
artifact: defaultProxyAdmin,
46-
},
47-
},
48-
});
30+
const wstETH_ANNUAL_GROWTH_RATE = ethers.utils.parseUnits("0.067", 18); // 6.7%
31+
const block = await ethers.provider.getBlock("latest");
32+
const stETHContract = await ethers.getContractAt("IStETH", stETHAddress);
33+
const exchangeRate = await stETHContract.getPooledEthByShares(parseUnits("1", 18));
34+
const snapshotGap = BigNumber.from("55"); // 0.55%
35+
36+
if (network.name === "ethereum") {
37+
await deploy("WstETHOracle_Equivalence", {
38+
contract: "WstETHOracleV2",
39+
from: deployer,
40+
log: true,
41+
deterministicDeployment: false,
42+
args: [
43+
stETHAddress,
44+
wstETHAddress,
45+
WETHAddress,
46+
oracle.address,
47+
wstETH_ANNUAL_GROWTH_RATE,
48+
DAYS_30,
49+
increaseExchangeRateByPercentage(exchangeRate, snapshotGap),
50+
block.timestamp,
51+
acm,
52+
getSnapshotGap(exchangeRate, snapshotGap.toNumber()),
53+
],
54+
});
4955

50-
await deploy("WstETHOracle_NonEquivalence", {
51-
contract: "WstETHOracle",
52-
from: deployer,
53-
log: true,
54-
deterministicDeployment: false,
55-
args: [wstETHAddress, WETHAddress, stETHAddress, oracle.address, false],
56-
proxy: {
57-
owner: proxyOwnerAddress,
58-
proxyContract: "OptimizedTransparentUpgradeableProxy",
59-
viaAdminContract: {
60-
name: "DefaultProxyAdmin",
61-
artifact: defaultProxyAdmin,
62-
},
63-
},
64-
});
56+
await deploy("WstETHOracle_NonEquivalence", {
57+
contract: "WstETHOracleV2",
58+
from: deployer,
59+
log: true,
60+
deterministicDeployment: false,
61+
args: [
62+
stETHAddress,
63+
wstETHAddress,
64+
stETHAddress,
65+
oracle.address,
66+
wstETH_ANNUAL_GROWTH_RATE,
67+
DAYS_30,
68+
increaseExchangeRateByPercentage(exchangeRate, snapshotGap),
69+
block.timestamp,
70+
acm,
71+
getSnapshotGap(exchangeRate, snapshotGap.toNumber()),
72+
],
73+
});
74+
} else {
75+
await deploy("WstETHOracle", {
76+
contract: "WstETHOracleV2",
77+
from: deployer,
78+
log: true,
79+
deterministicDeployment: false,
80+
args: [
81+
stETHAddress,
82+
wstETHAddress,
83+
WETHAddress,
84+
oracle.address,
85+
wstETH_ANNUAL_GROWTH_RATE,
86+
DAYS_30,
87+
increaseExchangeRateByPercentage(exchangeRate, snapshotGap),
88+
block.timestamp,
89+
acm,
90+
getSnapshotGap(exchangeRate, snapshotGap.toNumber()),
91+
],
92+
});
93+
}
6594
};
6695

6796
export default func;

0 commit comments

Comments
 (0)