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

Commit

Permalink
Merge pull request #45 from ionicprotocol/feat/redstone-oracle
Browse files Browse the repository at this point in the history
Redstone oracle
  • Loading branch information
vminkov authored Mar 8, 2024
2 parents 1b5701f + 333f67d commit 5a72159
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
12 changes: 12 additions & 0 deletions contracts/external/redstone/IRedstoneOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

interface IRedstoneOracle {
function priceOf(address asset) external view returns (uint256);

function priceOfETH() external view returns (uint256);

function getDataFeedIdForAsset(address asset) external view returns (bytes32);

function getDataFeedIds() external view returns (bytes32[] memory dataFeedIds);
}
64 changes: 64 additions & 0 deletions contracts/oracles/default/RedstoneAdapterPriceOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;

import "openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol";

import "../../external/redstone/IRedstoneOracle.sol";
import "../BasePriceOracle.sol";

/**
* @title RedstoneAdapterPriceOracle
* @notice Returns prices from Redstone.
* @dev Implements `BasePriceOracle`.
* @author Veliko Minkov <[email protected]> (https://github.com/vminkov)
*/
contract RedstoneAdapterPriceOracle is BasePriceOracle {
/**
* @notice The Redstone oracle contract
*/
IRedstoneOracle public REDSTONE_ORACLE;

/**
* @dev Constructor to set admin, wtoken address and native token USD price feed address
* @param redstoneOracle The Redstone oracle contract address
*/
constructor(address redstoneOracle) {
REDSTONE_ORACLE = IRedstoneOracle(redstoneOracle);
}

/**
* @notice Internal function returning the price in of `underlying`.
* @dev will return a price denominated in the native token
*/
function _price(address underlying) internal view returns (uint256) {
uint256 priceInUsd = REDSTONE_ORACLE.priceOf(underlying);
uint256 priceOfNativeInUsd = REDSTONE_ORACLE.priceOfETH();
return (priceInUsd * 1e18) / priceOfNativeInUsd;
}

/**
* @notice Returns the price in of `underlying` either in the
* native token (implements `BasePriceOracle`).
*/
function price(address underlying) external view override returns (uint256) {
return _price(underlying);
}

/**
* @notice Returns the price in WNATIVE of the token underlying `cToken`.
* @dev Implements the `BasePriceOracle` interface for Ionic pools (and Compound v2).
* @return Price in WNATIVE of the token underlying `cToken`, scaled by `10 ** (36 - underlyingDecimals)`.
*/
function getUnderlyingPrice(ICErc20 cToken) external view override returns (uint256) {
// Get underlying token address
address underlying = cToken.underlying();

uint256 oraclePrice = _price(underlying);

uint256 underlyingDecimals = uint256(ERC20Upgradeable(underlying).decimals());
return
underlyingDecimals <= 18
? uint256(oraclePrice) * (10**(18 - underlyingDecimals))
: uint256(oraclePrice) / (10**(underlyingDecimals - 18));
}
}
29 changes: 29 additions & 0 deletions contracts/test/oracles/RedstoneAdapterOracleTest.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;

import { TransparentUpgradeableProxy } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";

import { RedstoneAdapterPriceOracle } from "../../oracles/default/RedstoneAdapterPriceOracle.sol";

import { BaseTest } from "../config/BaseTest.t.sol";

contract RedstoneAdapterOracleTest is BaseTest {
RedstoneAdapterPriceOracle public oracle;
address public redstoneOracleAddress;
address MODE_USDC = 0xd988097fb8612cc24eeC14542bC03424c656005f;
address MODE_EZETH = 0x2416092f143378750bb29b79eD961ab195CcEea5;
address MODE_WBTC = 0xcDd475325D6F564d27247D1DddBb0DAc6fA0a5CF;

function afterForkSetUp() internal override {
if (block.chainid == MODE_MAINNET) {
redstoneOracleAddress = 0x7C1DAAE7BB0688C9bfE3A918A4224041c7177256;
}

oracle = new RedstoneAdapterPriceOracle(redstoneOracleAddress);
}

function testPrintPricesMode() public fork(MODE_MAINNET) {
emit log_named_uint("ezETH price (18 dec)", oracle.price(MODE_EZETH));
emit log_named_uint("WBTC price (8 dec)", oracle.price(MODE_WBTC));
}
}

0 comments on commit 5a72159

Please sign in to comment.