Skip to content

Commit

Permalink
Merge pull request #51 from morpho-org/feat/interfaces
Browse files Browse the repository at this point in the history
feat(ifc): add interfaces
  • Loading branch information
Rubilmax authored Dec 5, 2023
2 parents ac9b8ba + 467d380 commit 1ed0ca4
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 15 deletions.
28 changes: 18 additions & 10 deletions src/ChainlinkOracle.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity 0.8.21;

import {IChainlinkOracle} from "./interfaces/IChainlinkOracle.sol";
import {IOracle} from "../lib/morpho-blue/src/interfaces/IOracle.sol";

import {AggregatorV3Interface, ChainlinkDataFeedLib} from "./libraries/ChainlinkDataFeedLib.sol";
Expand All @@ -12,27 +13,32 @@ import {Math} from "../lib/openzeppelin-contracts/contracts/utils/math/Math.sol"
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Morpho Blue oracle using Chainlink-compliant feeds.
contract ChainlinkOracle is IOracle {
contract ChainlinkOracle is IChainlinkOracle {
using Math for uint256;
using VaultLib for IERC4626;
using ChainlinkDataFeedLib for AggregatorV3Interface;

/* IMMUTABLES */

/// @notice Vault.
/// @inheritdoc IChainlinkOracle
IERC4626 public immutable VAULT;
/// @notice Vault conversion sample. The sample amount of shares used to convert to the underlying asset.
/// @notice Should be chosen such that converting `VAULT_CONVERSION_SAMPLE` to assets has enough precision.

/// @inheritdoc IChainlinkOracle
uint256 public immutable VAULT_CONVERSION_SAMPLE;
/// @notice First base feed.

/// @inheritdoc IChainlinkOracle
AggregatorV3Interface public immutable BASE_FEED_1;
/// @notice Second base feed.

/// @inheritdoc IChainlinkOracle
AggregatorV3Interface public immutable BASE_FEED_2;
/// @notice First quote feed.

/// @inheritdoc IChainlinkOracle
AggregatorV3Interface public immutable QUOTE_FEED_1;
/// @notice Second quote feed.

/// @inheritdoc IChainlinkOracle
AggregatorV3Interface public immutable QUOTE_FEED_2;
/// @notice Price scale factor, computed at contract creation.

/// @inheritdoc IChainlinkOracle
uint256 public immutable SCALE_FACTOR;

/* CONSTRUCTOR */
Expand All @@ -50,7 +56,9 @@ contract ChainlinkOracle is IOracle {
/// @param baseFeed2 Second base feed. Pass address zero if the price = 1.
/// @param quoteFeed1 First quote feed. Pass address zero if the price = 1.
/// @param quoteFeed2 Second quote feed. Pass address zero if the price = 1.
/// @param vaultConversionSample Vault conversion sample. Pass 1 if the oracle does not use a vault.
/// @param vaultConversionSample The sample amount of vault shares used to convert to the underlying asset.
/// Pass 1 if the oracle does not use a vault. Should be chosen such that converting `vaultConversionSample` to
/// assets has enough precision.
/// @param baseTokenDecimals Base token decimals.
/// @param quoteTokenDecimals Quote token decimals.
constructor(
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/AggregatorV3Interface.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
pragma solidity >=0.5.0;

/// @dev From
/// https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol.
Expand Down
29 changes: 29 additions & 0 deletions src/interfaces/IChainlinkOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

import {IERC4626} from "./IERC4626.sol";
import {AggregatorV3Interface} from "./AggregatorV3Interface.sol";
import {IOracle} from "../../lib/morpho-blue/src/interfaces/IOracle.sol";

interface IChainlinkOracle is IOracle {
/// @notice Returns the address of the ERC4626 vault.
function VAULT() external view returns (IERC4626);

/// @notice Returns the vault conversion sample.
function VAULT_CONVERSION_SAMPLE() external view returns (uint256);

/// @notice Returns the address of the first Chainlink base feed.
function BASE_FEED_1() external view returns (AggregatorV3Interface);

/// @notice Returns the address of the second Chainlink base feed.
function BASE_FEED_2() external view returns (AggregatorV3Interface);

/// @notice Returns the address of the first Chainlink quote feed.
function QUOTE_FEED_1() external view returns (AggregatorV3Interface);

/// @notice Returns the address of the second Chainlink quote feed.
function QUOTE_FEED_2() external view returns (AggregatorV3Interface);

/// @notice Returns the price scale factor, calculated at contract creation.
function SCALE_FACTOR() external view returns (uint256);
}
2 changes: 1 addition & 1 deletion src/interfaces/IERC4626.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
pragma solidity >=0.5.0;

interface IERC4626 {
function convertToAssets(uint256) external view returns (uint256);
Expand Down
7 changes: 4 additions & 3 deletions test/ChainlinkOracleTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ contract ChainlinkOracleTest is Test {
}

function testOracleWbtcEth() public {
ChainlinkOracle oracle = new ChainlinkOracle(vaultZero,wBtcBtcFeed, btcEthFeed, feedZero, feedZero, 1, 8, 18);
ChainlinkOracle oracle = new ChainlinkOracle(vaultZero, wBtcBtcFeed, btcEthFeed, feedZero, feedZero, 1, 8, 18);
(, int256 firstBaseAnswer,,,) = wBtcBtcFeed.latestRoundData();
(, int256 secondBaseAnswer,,,) = btcEthFeed.latestRoundData();
assertEq(oracle.price(), (uint256(firstBaseAnswer) * uint256(secondBaseAnswer) * 10 ** (36 + 18 - 8 - 8 - 18)));
Expand Down Expand Up @@ -98,8 +98,9 @@ contract ChainlinkOracleTest is Test {
function testNegativeAnswer(int256 price) public {
price = bound(price, type(int256).min, -1);
ChainlinkAggregatorMock aggregator = new ChainlinkAggregatorMock();
ChainlinkOracle oracle =
new ChainlinkOracle(vaultZero, AggregatorV3Interface(address(aggregator)), feedZero, feedZero, feedZero, 1, 18, 0);
ChainlinkOracle oracle = new ChainlinkOracle(
vaultZero, AggregatorV3Interface(address(aggregator)), feedZero, feedZero, feedZero, 1, 18, 0
);
aggregator.setAnwser(price);
vm.expectRevert(bytes(ErrorsLib.NEGATIVE_ANSWER));
oracle.price();
Expand Down

0 comments on commit 1ed0ca4

Please sign in to comment.