Skip to content
This repository was archived by the owner on Aug 26, 2024. It is now read-only.

Commit ff2a7b8

Browse files
committed
feat: add special case price oracle for weETH
1 parent 40943c1 commit ff2a7b8

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity >=0.8.0;
3+
4+
import "openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol";
5+
6+
import "../../external/redstone/IRedstoneOracle.sol";
7+
import "../BasePriceOracle.sol";
8+
9+
/**
10+
* @title RedstoneAdapterPriceOracle
11+
* @notice Returns prices from Redstone.
12+
* @dev Implements `BasePriceOracle`.
13+
* @author Veliko Minkov <[email protected]> (https://github.com/vminkov)
14+
*/
15+
contract RedstoneAdapterPriceOracleWeETH is BasePriceOracle {
16+
/**
17+
* @notice The Redstone oracle contract
18+
*/
19+
IRedstoneOracle public REDSTONE_ORACLE;
20+
21+
/**
22+
* @dev Constructor to set admin, wtoken address and native token USD price feed address
23+
* @param redstoneOracle The Redstone oracle contract address
24+
*/
25+
constructor(address redstoneOracle) {
26+
REDSTONE_ORACLE = IRedstoneOracle(redstoneOracle);
27+
}
28+
29+
/**
30+
* @notice Internal function returning the price in of `underlying`.
31+
* @dev will return a price denominated in the native token
32+
*/
33+
function _price(address underlying) internal view returns (uint256) {
34+
// special case for wrsETH
35+
// if input is wrsETH, we need to get the price of rsETH
36+
if (underlying == 0x04C0599Ae5A44757c0af6F9eC3b93da8976c150A) {
37+
underlying = 0x028227c4dd1e5419d11Bb6fa6e661920c519D4F5;
38+
}
39+
uint256 priceInUsd = REDSTONE_ORACLE.priceOf(underlying);
40+
uint256 priceOfNativeInUsd = REDSTONE_ORACLE.priceOfETH();
41+
return (priceInUsd * 1e18) / priceOfNativeInUsd;
42+
}
43+
44+
/**
45+
* @notice Returns the price in of `underlying` either in the
46+
* native token (implements `BasePriceOracle`).
47+
*/
48+
function price(address underlying) external view override returns (uint256) {
49+
return _price(underlying);
50+
}
51+
52+
/**
53+
* @notice Returns the price in WNATIVE of the token underlying `cToken`.
54+
* @dev Implements the `BasePriceOracle` interface for Ionic pools (and Compound v2).
55+
* @return Price in WNATIVE of the token underlying `cToken`, scaled by `10 ** (36 - underlyingDecimals)`.
56+
*/
57+
function getUnderlyingPrice(ICErc20 cToken) external view override returns (uint256) {
58+
// Get underlying token address
59+
address underlying = cToken.underlying();
60+
61+
uint256 oraclePrice = _price(underlying);
62+
63+
uint256 underlyingDecimals = uint256(ERC20Upgradeable(underlying).decimals());
64+
return
65+
underlyingDecimals <= 18
66+
? uint256(oraclePrice) * (10 ** (18 - underlyingDecimals))
67+
: uint256(oraclePrice) / (10 ** (underlyingDecimals - 18));
68+
}
69+
}

contracts/test/DevTesting.t.sol

+18
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { ICErc20 } from "../compound/CTokenInterfaces.sol";
1313
import { ISwapRouter } from "../external/uniswap/ISwapRouter.sol";
1414
import { RedstoneAdapterPriceOracle } from "../oracles/default/RedstoneAdapterPriceOracle.sol";
1515
import { RedstoneAdapterPriceOracleWrsETH } from "../oracles/default/RedstoneAdapterPriceOracleWrsETH.sol";
16+
import { RedstoneAdapterPriceOracleWeETH } from "../oracles/default/RedstoneAdapterPriceOracleWeETH.sol";
1617
import { MasterPriceOracle, BasePriceOracle } from "../oracles/MasterPriceOracle.sol";
1718
import { PoolLens } from "../PoolLens.sol";
1819
import { PoolLensSecondary } from "../PoolLensSecondary.sol";
@@ -427,6 +428,23 @@ contract DevTesting is BaseTest {
427428
emit log_named_uint("price of wrsEth", price);
428429
}
429430

431+
function testModeWeETH() public debuggingOnly forkAtBlock(MODE_MAINNET, 6861468) {
432+
address weEth = 0x04C0599Ae5A44757c0af6F9eC3b93da8976c150A;
433+
RedstoneAdapterPriceOracleWeETH oracle = new RedstoneAdapterPriceOracleWeETH(
434+
0x7C1DAAE7BB0688C9bfE3A918A4224041c7177256
435+
);
436+
MasterPriceOracle mpo = MasterPriceOracle(ap.getAddress("MasterPriceOracle"));
437+
438+
BasePriceOracle[] memory oracles = new BasePriceOracle[](1);
439+
oracles[0] = oracle;
440+
vm.prank(multisig);
441+
mpo.add(asArray(weEth), oracles);
442+
443+
uint256 price = mpo.price(weEth);
444+
emit log_named_uint("price of weEth", price);
445+
assertEq(price, 1036212437077011599);
446+
}
447+
430448
function _functionCall(
431449
address target,
432450
bytes memory data,

0 commit comments

Comments
 (0)