From 5d2a173d72d2d6ff05020892421c43fa0a1552d0 Mon Sep 17 00:00:00 2001 From: MerlinEgalite Date: Tue, 27 Feb 2024 17:18:42 +0100 Subject: [PATCH 1/5] refactor: clarify exchange rate --- ...l => WstEthStEthExchangeRateChainlinkAdapter.sol} | 8 ++++---- ... WstEthStEthExchangeRateChainlinkAdapterTest.sol} | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) rename src/wsteth-exchange-rate-adapter/{WstEthEthExchangeRateChainlinkAdapter.sol => WstEthStEthExchangeRateChainlinkAdapter.sol} (77%) rename test/{WstEthEthExchangeRateChainlinkAdapterTest.sol => WstEthStEthExchangeRateChainlinkAdapterTest.sol} (80%) diff --git a/src/wsteth-exchange-rate-adapter/WstEthEthExchangeRateChainlinkAdapter.sol b/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol similarity index 77% rename from src/wsteth-exchange-rate-adapter/WstEthEthExchangeRateChainlinkAdapter.sol rename to src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol index acd753e..470ca6a 100644 --- a/src/wsteth-exchange-rate-adapter/WstEthEthExchangeRateChainlinkAdapter.sol +++ b/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol @@ -4,14 +4,14 @@ pragma solidity 0.8.21; import {IStEth} from "./interfaces/IStEth.sol"; import {MinimalAggregatorV3Interface} from "./interfaces/MinimalAggregatorV3Interface.sol"; -/// @title WstEthEthExchangeRateChainlinkAdapter +/// @title WstEthStEthExchangeRateChainlinkAdapter /// @author Morpho Labs /// @custom:contact security@morpho.org -/// @notice wstETH/ETH exchange rate price feed. +/// @notice wstETH/stETH exchange rate price feed. /// @dev This contract should only be used as price feed for `ChainlinkOracle`. -contract WstEthEthExchangeRateChainlinkAdapter is MinimalAggregatorV3Interface { +contract WstEthStEthExchangeRateChainlinkAdapter is MinimalAggregatorV3Interface { uint8 public constant decimals = 18; - string public constant description = "wstETH/ETH exchange rate"; + string public constant description = "wstETH/stETH exchange rate"; IStEth public constant ST_ETH = IStEth(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84); /// @dev Silently overflows if `getPooledEthByShares`'s return value is greater than `type(int256).max`. diff --git a/test/WstEthEthExchangeRateChainlinkAdapterTest.sol b/test/WstEthStEthExchangeRateChainlinkAdapterTest.sol similarity index 80% rename from test/WstEthEthExchangeRateChainlinkAdapterTest.sol rename to test/WstEthStEthExchangeRateChainlinkAdapterTest.sol index ec01d42..0ee91ef 100644 --- a/test/WstEthEthExchangeRateChainlinkAdapterTest.sol +++ b/test/WstEthStEthExchangeRateChainlinkAdapterTest.sol @@ -4,17 +4,17 @@ pragma solidity ^0.8.0; import "./helpers/Constants.sol"; import "../lib/forge-std/src/Test.sol"; import {ChainlinkOracle} from "../src/morpho-chainlink-v1/ChainlinkOracle.sol"; -import "../src/wsteth-exchange-rate-adapter/WstEthEthExchangeRateChainlinkAdapter.sol"; +import "../src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol"; -contract WstEthEthExchangeRateChainlinkAdapterTest is Test { +contract WstEthStEthExchangeRateChainlinkAdapterTest is Test { IStEth internal constant ST_ETH = IStEth(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84); - WstEthEthExchangeRateChainlinkAdapter internal oracle; + WstEthStEthExchangeRateChainlinkAdapter internal oracle; ChainlinkOracle internal chainlinkOracle; function setUp() public { vm.createSelectFork(vm.envString("ETH_RPC_URL")); - oracle = new WstEthEthExchangeRateChainlinkAdapter(); + oracle = new WstEthStEthExchangeRateChainlinkAdapter(); chainlinkOracle = new ChainlinkOracle( vaultZero, AggregatorV3Interface(address(oracle)), feedZero, feedZero, feedZero, 1, 18, 18 ); @@ -25,7 +25,7 @@ contract WstEthEthExchangeRateChainlinkAdapterTest is Test { } function testDescription() public { - assertEq(oracle.description(), "wstETH/ETH exchange rate"); + assertEq(oracle.description(), "wstETH/stETH exchange rate"); } function testLatestRoundData() public { @@ -44,7 +44,7 @@ contract WstEthEthExchangeRateChainlinkAdapterTest is Test { assertLe(uint256(answer), 1.5e18); // Max bounds of the exchange rate. Should work for a long enough time. } - function testOracleWstEthEthExchangeRate() public { + function testOracleWstEthStEthExchangeRate() public { (, int256 expectedPrice,,,) = oracle.latestRoundData(); assertEq(chainlinkOracle.price(), uint256(expectedPrice) * 10 ** (36 + 18 - 18 - 18)); } From 7d8d3216cac9a4ce13ed64ba186f1eba852a6dc6 Mon Sep 17 00:00:00 2001 From: MerlinEgalite Date: Tue, 27 Feb 2024 17:33:59 +0100 Subject: [PATCH 2/5] docs: fix and add missing natspecs --- .../WstEthStEthExchangeRateChainlinkAdapter.sol | 8 +++++++- .../interfaces/MinimalAggregatorV3Interface.sol | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol b/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol index 470ca6a..0b469d2 100644 --- a/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol +++ b/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol @@ -8,12 +8,18 @@ import {MinimalAggregatorV3Interface} from "./interfaces/MinimalAggregatorV3Inte /// @author Morpho Labs /// @custom:contact security@morpho.org /// @notice wstETH/stETH exchange rate price feed. -/// @dev This contract should only be used as price feed for `ChainlinkOracle`. +/// @dev This contract should only be used as price feed for `MorphoChainlinkOracleV2`. contract WstEthStEthExchangeRateChainlinkAdapter is MinimalAggregatorV3Interface { + /// @inheritdoc MinimalAggregatorV3Interface uint8 public constant decimals = 18; + + /// @notice The description of the price feed. string public constant description = "wstETH/stETH exchange rate"; + + /// @notice The address of stETH on Mainnet. IStEth public constant ST_ETH = IStEth(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84); + /// @inheritdoc MinimalAggregatorV3Interface /// @dev Silently overflows if `getPooledEthByShares`'s return value is greater than `type(int256).max`. function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80) { // It is assumed that `getPooledEthByShares` returns a price with 18 decimals precision. diff --git a/src/wsteth-exchange-rate-adapter/interfaces/MinimalAggregatorV3Interface.sol b/src/wsteth-exchange-rate-adapter/interfaces/MinimalAggregatorV3Interface.sol index 30a9bae..0920f03 100644 --- a/src/wsteth-exchange-rate-adapter/interfaces/MinimalAggregatorV3Interface.sol +++ b/src/wsteth-exchange-rate-adapter/interfaces/MinimalAggregatorV3Interface.sol @@ -3,9 +3,13 @@ pragma solidity >=0.5.0; /// @dev Inspired by /// https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol +/// @dev This is the minimal feed interface required by `MorphoChainlinkOracleV2`. interface MinimalAggregatorV3Interface { + /// @notice Returns the number of decimals precision. function decimals() external view returns (uint8); + /// @notice Returns Chainlink's `latestRoundData` return values. + /// @notice Only the `answer` field is used by `MorphoChainlinkOracleV2`. function latestRoundData() external view From c251bedc146b359ad655cc1f40a4752093f6d521 Mon Sep 17 00:00:00 2001 From: Merlin Egalite <44097430+MerlinEgalite@users.noreply.github.com> Date: Wed, 28 Feb 2024 09:23:32 +0100 Subject: [PATCH 3/5] docs: apply suggestions Co-authored-by: MathisGD <74971347+MathisGD@users.noreply.github.com> Signed-off-by: Merlin Egalite <44097430+MerlinEgalite@users.noreply.github.com> --- .../WstEthStEthExchangeRateChainlinkAdapter.sol | 3 ++- .../interfaces/MinimalAggregatorV3Interface.sol | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol b/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol index 0b469d2..7334daa 100644 --- a/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol +++ b/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol @@ -16,10 +16,11 @@ contract WstEthStEthExchangeRateChainlinkAdapter is MinimalAggregatorV3Interface /// @notice The description of the price feed. string public constant description = "wstETH/stETH exchange rate"; - /// @notice The address of stETH on Mainnet. + /// @notice The address of stETH on Ethereum. IStEth public constant ST_ETH = IStEth(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84); /// @inheritdoc MinimalAggregatorV3Interface + /// @dev Returns zero for roundId, startedAt, updatedAt and answeredInRound. /// @dev Silently overflows if `getPooledEthByShares`'s return value is greater than `type(int256).max`. function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80) { // It is assumed that `getPooledEthByShares` returns a price with 18 decimals precision. diff --git a/src/wsteth-exchange-rate-adapter/interfaces/MinimalAggregatorV3Interface.sol b/src/wsteth-exchange-rate-adapter/interfaces/MinimalAggregatorV3Interface.sol index 0920f03..22887af 100644 --- a/src/wsteth-exchange-rate-adapter/interfaces/MinimalAggregatorV3Interface.sol +++ b/src/wsteth-exchange-rate-adapter/interfaces/MinimalAggregatorV3Interface.sol @@ -5,7 +5,7 @@ pragma solidity >=0.5.0; /// https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol /// @dev This is the minimal feed interface required by `MorphoChainlinkOracleV2`. interface MinimalAggregatorV3Interface { - /// @notice Returns the number of decimals precision. + /// @notice Returns the precision of the feed. function decimals() external view returns (uint8); /// @notice Returns Chainlink's `latestRoundData` return values. From 999a24306b637579c1e1b2b75c91027ba753fb3c Mon Sep 17 00:00:00 2001 From: MerlinEgalite Date: Wed, 28 Feb 2024 11:47:50 +0000 Subject: [PATCH 4/5] docs: add contract only deployable on ethereum comment --- .../WstEthStEthExchangeRateChainlinkAdapter.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol b/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol index 0b469d2..12b3086 100644 --- a/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol +++ b/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol @@ -8,7 +8,7 @@ import {MinimalAggregatorV3Interface} from "./interfaces/MinimalAggregatorV3Inte /// @author Morpho Labs /// @custom:contact security@morpho.org /// @notice wstETH/stETH exchange rate price feed. -/// @dev This contract should only be used as price feed for `MorphoChainlinkOracleV2`. +/// @dev This contract should only be deployed on Ethereum and used as price feed for `MorphoChainlinkOracleV2`. contract WstEthStEthExchangeRateChainlinkAdapter is MinimalAggregatorV3Interface { /// @inheritdoc MinimalAggregatorV3Interface uint8 public constant decimals = 18; From f98468278036378b66a35e102e0b8a5fdbd1b648 Mon Sep 17 00:00:00 2001 From: MerlinEgalite Date: Wed, 28 Feb 2024 20:07:40 +0000 Subject: [PATCH 5/5] docs: apply suggestions --- .../WstEthStEthExchangeRateChainlinkAdapter.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol b/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol index ea588db..96ca5f3 100644 --- a/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol +++ b/src/wsteth-exchange-rate-adapter/WstEthStEthExchangeRateChainlinkAdapter.sol @@ -8,7 +8,7 @@ import {MinimalAggregatorV3Interface} from "./interfaces/MinimalAggregatorV3Inte /// @author Morpho Labs /// @custom:contact security@morpho.org /// @notice wstETH/stETH exchange rate price feed. -/// @dev This contract should only be deployed on Ethereum and used as price feed for `MorphoChainlinkOracleV2`. +/// @dev This contract should only be deployed on Ethereum and used as a price feed for Morpho oracles. contract WstEthStEthExchangeRateChainlinkAdapter is MinimalAggregatorV3Interface { /// @inheritdoc MinimalAggregatorV3Interface uint8 public constant decimals = 18;