Skip to content

Commit 5d354fb

Browse files
committed
refactor: create minimal CL interface
1 parent 935744b commit 5d354fb

8 files changed

+33
-65
lines changed

src/ChainlinkOracle.sol

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pragma solidity 0.8.21;
44
import {IChainlinkOracle} from "./interfaces/IChainlinkOracle.sol";
55
import {IOracle} from "../lib/morpho-blue/src/interfaces/IOracle.sol";
66

7-
import {AggregatorV3Interface, ChainlinkDataFeedLib} from "./libraries/ChainlinkDataFeedLib.sol";
7+
import {MinimalAggregatorV3Interface, ChainlinkDataFeedLib} from "./libraries/ChainlinkDataFeedLib.sol";
88
import {IERC4626, VaultLib} from "./libraries/VaultLib.sol";
99
import {ErrorsLib} from "./libraries/ErrorsLib.sol";
1010
import {Math} from "../lib/openzeppelin-contracts/contracts/utils/math/Math.sol";
@@ -16,7 +16,7 @@ import {Math} from "../lib/openzeppelin-contracts/contracts/utils/math/Math.sol"
1616
contract ChainlinkOracle is IChainlinkOracle {
1717
using Math for uint256;
1818
using VaultLib for IERC4626;
19-
using ChainlinkDataFeedLib for AggregatorV3Interface;
19+
using ChainlinkDataFeedLib for MinimalAggregatorV3Interface;
2020

2121
/* IMMUTABLES */
2222

@@ -27,16 +27,16 @@ contract ChainlinkOracle is IChainlinkOracle {
2727
uint256 public immutable VAULT_CONVERSION_SAMPLE;
2828

2929
/// @inheritdoc IChainlinkOracle
30-
AggregatorV3Interface public immutable BASE_FEED_1;
30+
MinimalAggregatorV3Interface public immutable BASE_FEED_1;
3131

3232
/// @inheritdoc IChainlinkOracle
33-
AggregatorV3Interface public immutable BASE_FEED_2;
33+
MinimalAggregatorV3Interface public immutable BASE_FEED_2;
3434

3535
/// @inheritdoc IChainlinkOracle
36-
AggregatorV3Interface public immutable QUOTE_FEED_1;
36+
MinimalAggregatorV3Interface public immutable QUOTE_FEED_1;
3737

3838
/// @inheritdoc IChainlinkOracle
39-
AggregatorV3Interface public immutable QUOTE_FEED_2;
39+
MinimalAggregatorV3Interface public immutable QUOTE_FEED_2;
4040

4141
/// @inheritdoc IChainlinkOracle
4242
uint256 public immutable SCALE_FACTOR;
@@ -63,10 +63,10 @@ contract ChainlinkOracle is IChainlinkOracle {
6363
/// @param quoteTokenDecimals Quote token decimals.
6464
constructor(
6565
IERC4626 vault,
66-
AggregatorV3Interface baseFeed1,
67-
AggregatorV3Interface baseFeed2,
68-
AggregatorV3Interface quoteFeed1,
69-
AggregatorV3Interface quoteFeed2,
66+
MinimalAggregatorV3Interface baseFeed1,
67+
MinimalAggregatorV3Interface baseFeed2,
68+
MinimalAggregatorV3Interface quoteFeed1,
69+
MinimalAggregatorV3Interface quoteFeed2,
7070
uint256 vaultConversionSample,
7171
uint256 baseTokenDecimals,
7272
uint256 quoteTokenDecimals

src/adapters/WstEthEthExchangeRateChainlinkAdapter.sol

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
pragma solidity 0.8.21;
33

44
import {IStEth} from "../interfaces/IStEth.sol";
5-
import {AggregatorV3Interface} from "../interfaces/AggregatorV3Interface.sol";
5+
import {MinimalAggregatorV3Interface} from "../interfaces/MinimalAggregatorV3Interface.sol";
66

77
import {ErrorsLib} from "../libraries/ErrorsLib.sol";
88

@@ -11,9 +11,8 @@ import {ErrorsLib} from "../libraries/ErrorsLib.sol";
1111
/// @custom:contact [email protected]
1212
/// @notice wstETH/ETH exchange rate price feed.
1313
/// @dev This contract should only be used as price feed for `ChainlinkOracle`.
14-
contract WstEthEthExchangeRateChainlinkAdapter is AggregatorV3Interface {
14+
contract WstEthEthExchangeRateChainlinkAdapter is MinimalAggregatorV3Interface {
1515
uint8 public constant decimals = 18;
16-
string public constant description = "wstETH/ETH exchange rate";
1716

1817
IStEth public immutable ST_ETH;
1918

@@ -22,16 +21,6 @@ contract WstEthEthExchangeRateChainlinkAdapter is AggregatorV3Interface {
2221
ST_ETH = IStEth(stEth);
2322
}
2423

25-
/// @notice Reverts as no Chainlink aggregator is used.
26-
function version() external pure returns (uint256) {
27-
revert();
28-
}
29-
30-
/// @notice Reverts as it's not necessary for the ChainlinkOracle contract.
31-
function getRoundData(uint80) external pure returns (uint80, int256, uint256, uint256, uint80) {
32-
revert();
33-
}
34-
3524
function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80) {
3625
uint256 answer = ST_ETH.getPooledEthByShares(10 ** decimals);
3726
return (0, int256(answer), 0, 0, 0);

src/interfaces/IChainlinkOracle.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
pragma solidity >=0.5.0;
33

44
import {IERC4626} from "./IERC4626.sol";
5-
import {AggregatorV3Interface} from "./AggregatorV3Interface.sol";
65
import {IOracle} from "../../lib/morpho-blue/src/interfaces/IOracle.sol";
6+
import {MinimalAggregatorV3Interface} from "./MinimalAggregatorV3Interface.sol";
77

88
/// @title IChainlinkOracle
99
/// @author Morpho Labs
@@ -17,16 +17,16 @@ interface IChainlinkOracle is IOracle {
1717
function VAULT_CONVERSION_SAMPLE() external view returns (uint256);
1818

1919
/// @notice Returns the address of the first Chainlink base feed.
20-
function BASE_FEED_1() external view returns (AggregatorV3Interface);
20+
function BASE_FEED_1() external view returns (MinimalAggregatorV3Interface);
2121

2222
/// @notice Returns the address of the second Chainlink base feed.
23-
function BASE_FEED_2() external view returns (AggregatorV3Interface);
23+
function BASE_FEED_2() external view returns (MinimalAggregatorV3Interface);
2424

2525
/// @notice Returns the address of the first Chainlink quote feed.
26-
function QUOTE_FEED_1() external view returns (AggregatorV3Interface);
26+
function QUOTE_FEED_1() external view returns (MinimalAggregatorV3Interface);
2727

2828
/// @notice Returns the address of the second Chainlink quote feed.
29-
function QUOTE_FEED_2() external view returns (AggregatorV3Interface);
29+
function QUOTE_FEED_2() external view returns (MinimalAggregatorV3Interface);
3030

3131
/// @notice Returns the price scale factor, calculated at contract creation.
3232
function SCALE_FACTOR() external view returns (uint256);

src/interfaces/AggregatorV3Interface.sol renamed to src/interfaces/MinimalAggregatorV3Interface.sol

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,11 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity >=0.5.0;
33

4-
/// @dev From
4+
/// @dev Inspired
55
/// https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol
6-
interface AggregatorV3Interface {
6+
interface MinimalAggregatorV3Interface {
77
function decimals() external view returns (uint8);
88

9-
function description() external view returns (string memory);
10-
11-
function version() external view returns (uint256);
12-
13-
function getRoundData(uint80 _roundId)
14-
external
15-
view
16-
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
17-
189
function latestRoundData()
1910
external
2011
view

src/libraries/ChainlinkDataFeedLib.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0-or-later
22
pragma solidity ^0.8.0;
33

4-
import {AggregatorV3Interface} from "../interfaces/AggregatorV3Interface.sol";
4+
import {MinimalAggregatorV3Interface} from "../interfaces/MinimalAggregatorV3Interface.sol";
55

66
import {ErrorsLib} from "./ErrorsLib.sol";
77

@@ -17,7 +17,7 @@ library ChainlinkDataFeedLib {
1717
/// - Staleness is not checked because it's assumed that the Chainlink feed keeps its promises on this.
1818
/// - The price is not checked to be in the min/max bounds because it's assumed that the Chainlink feed keeps its
1919
/// promises on this.
20-
function getPrice(AggregatorV3Interface feed) internal view returns (uint256) {
20+
function getPrice(MinimalAggregatorV3Interface feed) internal view returns (uint256) {
2121
if (address(feed) == address(0)) return 1;
2222

2323
(, int256 answer,,,) = feed.latestRoundData();
@@ -28,7 +28,7 @@ library ChainlinkDataFeedLib {
2828

2929
/// @dev Returns the number of decimals of a `feed`.
3030
/// @dev When `feed` is the address zero, returns 0.
31-
function getDecimals(AggregatorV3Interface feed) internal view returns (uint256) {
31+
function getDecimals(MinimalAggregatorV3Interface feed) internal view returns (uint256) {
3232
if (address(feed) == address(0)) return 0;
3333

3434
return feed.decimals();

test/ChainlinkOracleTest.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ contract ChainlinkOracleTest is Test {
7979
price = bound(price, type(int256).min, -1);
8080
ChainlinkAggregatorMock aggregator = new ChainlinkAggregatorMock();
8181
ChainlinkOracle oracle = new ChainlinkOracle(
82-
vaultZero, AggregatorV3Interface(address(aggregator)), feedZero, feedZero, feedZero, 1, 18, 0
82+
vaultZero, MinimalAggregatorV3Interface(address(aggregator)), feedZero, feedZero, feedZero, 1, 18, 0
8383
);
8484
aggregator.setAnwser(price);
8585
vm.expectRevert(bytes(ErrorsLib.NEGATIVE_ANSWER));

test/WstEthEthExchangeRateChainlinkAdapterTest.sol

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,11 @@ contract WstEthEthExchangeRateChainlinkAdapterTest is Test {
2424
assertEq(oracle.decimals(), uint8(18));
2525
}
2626

27-
function testDescription() public {
28-
assertEq(oracle.description(), "wstETH/ETH exchange rate");
29-
}
30-
3127
function testDeployZeroAddress() public {
3228
vm.expectRevert(bytes(ErrorsLib.ZERO_ADDRESS));
3329
new WstEthEthExchangeRateChainlinkAdapter(address(0));
3430
}
3531

36-
function testReverts() public {
37-
vm.expectRevert();
38-
oracle.version();
39-
40-
vm.expectRevert();
41-
oracle.getRoundData(0);
42-
}
43-
4432
function testLatestRoundData() public {
4533
(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) =
4634
oracle.latestRoundData();

test/helpers/Constants.sol

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
// SPDX-License-Identifier: GPL-2.0-or-later
22
pragma solidity ^0.8.0;
33

4-
import {IERC4626, AggregatorV3Interface} from "../../src/ChainlinkOracle.sol";
4+
import {IERC4626, MinimalAggregatorV3Interface} from "../../src/ChainlinkOracle.sol";
55

6-
AggregatorV3Interface constant feedZero = AggregatorV3Interface(address(0));
6+
MinimalAggregatorV3Interface constant feedZero = MinimalAggregatorV3Interface(address(0));
77
// 8 decimals of precision
8-
AggregatorV3Interface constant btcUsdFeed = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);
8+
MinimalAggregatorV3Interface constant btcUsdFeed = MinimalAggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);
99
// 8 decimals of precision
10-
AggregatorV3Interface constant usdcUsdFeed = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);
10+
MinimalAggregatorV3Interface constant usdcUsdFeed = MinimalAggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);
1111
// 18 decimals of precision
12-
AggregatorV3Interface constant btcEthFeed = AggregatorV3Interface(0xdeb288F737066589598e9214E782fa5A8eD689e8);
12+
MinimalAggregatorV3Interface constant btcEthFeed = MinimalAggregatorV3Interface(0xdeb288F737066589598e9214E782fa5A8eD689e8);
1313
// 8 decimals of precision
14-
AggregatorV3Interface constant wBtcBtcFeed = AggregatorV3Interface(0xfdFD9C85aD200c506Cf9e21F1FD8dd01932FBB23);
14+
MinimalAggregatorV3Interface constant wBtcBtcFeed = MinimalAggregatorV3Interface(0xfdFD9C85aD200c506Cf9e21F1FD8dd01932FBB23);
1515
// 18 decimals of precision
16-
AggregatorV3Interface constant stEthEthFeed = AggregatorV3Interface(0x86392dC19c0b719886221c78AB11eb8Cf5c52812);
16+
MinimalAggregatorV3Interface constant stEthEthFeed = MinimalAggregatorV3Interface(0x86392dC19c0b719886221c78AB11eb8Cf5c52812);
1717
// 18 decimals of precision
18-
AggregatorV3Interface constant usdcEthFeed = AggregatorV3Interface(0x986b5E1e1755e3C2440e960477f25201B0a8bbD4);
18+
MinimalAggregatorV3Interface constant usdcEthFeed = MinimalAggregatorV3Interface(0x986b5E1e1755e3C2440e960477f25201B0a8bbD4);
1919
// 8 decimals of precision
20-
AggregatorV3Interface constant ethUsdFeed = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);
20+
MinimalAggregatorV3Interface constant ethUsdFeed = MinimalAggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);
2121
// 18 decimals of precision
22-
AggregatorV3Interface constant daiEthFeed = AggregatorV3Interface(0x773616E4d11A78F511299002da57A0a94577F1f4);
22+
MinimalAggregatorV3Interface constant daiEthFeed = MinimalAggregatorV3Interface(0x773616E4d11A78F511299002da57A0a94577F1f4);
2323

2424
IERC4626 constant vaultZero = IERC4626(address(0));
2525
IERC4626 constant sDaiVault = IERC4626(0x83F20F44975D03b1b09e64809B757c47f942BEeA);

0 commit comments

Comments
 (0)