diff --git a/contracts/oracles/WstETHOracle.sol b/contracts/oracles/WstETHOracle.sol index 3d1b9be5..33cce0e1 100755 --- a/contracts/oracles/WstETHOracle.sol +++ b/contracts/oracles/WstETHOracle.sol @@ -5,6 +5,7 @@ import { OracleInterface } from "../interfaces/OracleInterface.sol"; import { IStETH } from "../interfaces/IStETH.sol"; import { ensureNonzeroAddress } from "@venusprotocol/solidity-utilities/contracts/validators.sol"; import { EXP_SCALE } from "@venusprotocol/solidity-utilities/contracts/constants.sol"; +import { WrappedLiquidStakedTokenOracle } from "./common/WrappedLiquidStakedTokenOracle.sol"; /** * @title WstETHOracle @@ -12,64 +13,30 @@ import { EXP_SCALE } from "@venusprotocol/solidity-utilities/contracts/constants * @notice Depending on the equivalence flag price is either based on assumption that 1 stETH = 1 ETH * or the price of stETH/USD (secondary market price) is obtained from the oracle. */ -contract WstETHOracle is OracleInterface { - /// @notice A flag assuming 1:1 price equivalence between stETH/ETH - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - bool public immutable ASSUME_STETH_ETH_EQUIVALENCE; - - /// @notice Address of stETH - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - IStETH public immutable STETH; - - /// @notice Address of wstETH - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address public immutable WSTETH_ADDRESS; - - /// @notice Address of WETH - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - address public immutable WETH_ADDRESS; - - /// @notice Address of Resilient Oracle - /// @custom:oz-upgrades-unsafe-allow state-variable-immutable - OracleInterface public immutable RESILIENT_ORACLE; - +contract WstETHOracle is WrappedLiquidStakedTokenOracle { /// @notice Constructor for the implementation contract. /// @custom:oz-upgrades-unsafe-allow constructor constructor( - address wstETHAddress, address wETHAddress, address stETHAddress, + address wstETHAddress, address resilientOracleAddress, bool assumeEquivalence - ) { - ensureNonzeroAddress(wstETHAddress); - ensureNonzeroAddress(wETHAddress); - ensureNonzeroAddress(stETHAddress); - ensureNonzeroAddress(resilientOracleAddress); - WSTETH_ADDRESS = wstETHAddress; - WETH_ADDRESS = wETHAddress; - STETH = IStETH(stETHAddress); - RESILIENT_ORACLE = OracleInterface(resilientOracleAddress); - ASSUME_STETH_ETH_EQUIVALENCE = assumeEquivalence; - } + ) + WrappedLiquidStakedTokenOracle( + wETHAddress, + stETHAddress, + wstETHAddress, + resilientOracleAddress, + assumeEquivalence + ) + {} /** - * @notice Gets the USD price of wstETH asset - * @dev Depending on the equivalence flag price is either based on assumption that 1 stETH = 1 ETH - * or the price of stETH/USD (secondary market price) is obtained from the oracle - * @param asset Address of wstETH - * @return wstETH Price in USD scaled by 1e18 + * @notice Gets the stETH for 1 wstETH + * @return amount Amount of stETH */ - function getPrice(address asset) public view returns (uint256) { - if (asset != WSTETH_ADDRESS) revert("wrong wstETH address"); - - // get stETH amount for 1 wstETH scaled by 1e18 - uint256 stETHAmount = STETH.getPooledEthByShares(1 ether); - - // price is scaled 1e18 (oracle returns 36 - asset decimal scale) - uint256 stETHUSDPrice = RESILIENT_ORACLE.getPrice(ASSUME_STETH_ETH_EQUIVALENCE ? WETH_ADDRESS : address(STETH)); - - // stETHAmount (for 1 wstETH) * stETHUSDPrice / 1e18 - return (stETHAmount * stETHUSDPrice) / EXP_SCALE; + function getRebaseTokenAmount() internal view override returns (uint256) { + return IStETH(REBASE_TOKEN).getPooledEthByShares(1 ether); } } diff --git a/test/WstETHOracle.ts b/test/WstETHOracle.ts index 4644ee30..cd2f4c4a 100755 --- a/test/WstETHOracle.ts +++ b/test/WstETHOracle.ts @@ -39,31 +39,31 @@ describe("WstETHOracle unit tests", () => { describe("deployment", () => { it("revert if wstETH address is 0", async () => { - await expect(WsETHOracleFactory.deploy(addr0000, WETH, stETHMock.address, resilientOracleMock.address, true)).to + await expect(WsETHOracleFactory.deploy(WETH, stETHMock.address, addr0000, resilientOracleMock.address, true)).to .be.reverted; }); it("revert if WETH address is 0", async () => { - await expect(WsETHOracleFactory.deploy(WSTETH, addr0000, stETHMock.address, resilientOracleMock.address, true)).to + await expect(WsETHOracleFactory.deploy(addr0000, stETHMock.address, WSTETH, resilientOracleMock.address, true)).to .be.reverted; }); it("revert if stETH address is 0", async () => { - await expect(WsETHOracleFactory.deploy(WSTETH, WETH, addr0000, resilientOracleMock.address, true)).to.be.reverted; + await expect(WsETHOracleFactory.deploy(WETH, addr0000, WSTETH, resilientOracleMock.address, true)).to.be.reverted; }); it("revert if ResilientOracle address is 0", async () => { - await expect(WsETHOracleFactory.deploy(WSTETH, WETH, stETHMock.address, addr0000, true)).to.be.reverted; + await expect(WsETHOracleFactory.deploy(WETH, stETHMock.address, WSTETH, addr0000, true)).to.be.reverted; }); it("should deploy contract", async () => { wstETHOracleEquivalentRatio = await WsETHOracleFactory.deploy( - WSTETH, WETH, stETHMock.address, + WSTETH, resilientOracleMock.address, true, ); wstETHOracleNonEquivalentRatio = await WsETHOracleFactory.deploy( - WSTETH, WETH, stETHMock.address, + WSTETH, resilientOracleMock.address, false, ); @@ -72,7 +72,7 @@ describe("WstETHOracle unit tests", () => { describe("getPrice", () => { it("revert if wstETH address is wrong", async () => { - await expect(wstETHOracleEquivalentRatio.getPrice(addr0000)).to.be.revertedWith("wrong wstETH address"); + await expect(wstETHOracleEquivalentRatio.getPrice(addr0000)).to.be.revertedWith("wrong token address"); }); it("should get correct price assuming 1/1 ratio", async () => {