-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ezETH/ETH, rsETH/ETH, swETH/ETH, rswETH/ETH, weETH/ETH exchange r…
…ate oracles
- Loading branch information
1 parent
61ad457
commit 4f80dc4
Showing
23 changed files
with
499 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
src/exchange-rate-adapters/EzEthToEthExchangeRateChainlinkAdapter.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity ^0.8.19; | ||
|
||
import {IRenzoRestakeManager} from "../interfaces/renzo/IRenzoRestakeManager.sol"; | ||
import {IRenzoOracle} from "../interfaces/renzo/IRenzoOracle.sol"; | ||
import {IERC20} from "../interfaces/IERC20.sol"; | ||
import {IMinimalAggregatorV3Interface} from "../interfaces/IMinimalAggregatorV3Interface.sol"; | ||
|
||
/// @title EzEthToEthExchangeRateChainlinkAdapter | ||
/// @author Morpho Labs | ||
/// @custom:contact [email protected] | ||
/// @notice ezETH/ETH exchange rate price feed. | ||
/// @dev This contract should only be deployed on Ethereum and used as a price feed for Morpho oracles. | ||
contract EzEthToEthExchangeRateChainlinkAdapter is IMinimalAggregatorV3Interface { | ||
/// @inheritdoc IMinimalAggregatorV3Interface | ||
// @dev The calculated price has 18 decimals precision, whatever the value of `decimals`. | ||
uint8 public override constant decimals = 18; | ||
|
||
/// @notice The description of the price feed. | ||
string public constant description = "ezETH/ETH exchange rate"; | ||
|
||
/// @notice The address of the Renzo restake manager in Ethereum. | ||
IRenzoRestakeManager public constant RENZO_RESTAKE_MANAGER = IRenzoRestakeManager(0x74a09653A083691711cF8215a6ab074BB4e99ef5); | ||
|
||
/// @notice The address of the Renzo ezETH token in Ethereum | ||
IERC20 public constant EZ_ETH = IERC20(0xbf5495Efe5DB9ce00f80364C8B423567e58d2110); | ||
|
||
/// @inheritdoc IMinimalAggregatorV3Interface | ||
/// @dev Returns zero for roundId, startedAt, updatedAt and answeredInRound. | ||
/// @dev Silently overflows if `calculateRedeemAmount`'s return value is greater than `type(int256).max`. | ||
function latestRoundData() external override view returns (uint80, int256, uint256, uint256, uint80) { | ||
(,, uint256 _currentValueInProtocol) = RENZO_RESTAKE_MANAGER.calculateTVLs(); | ||
|
||
// This returns the percentage of TVL that matches the percentage of ezETH being burned | ||
// baseAsset is safely assumed to be the ezETH ERC20 | ||
uint256 rate = IRenzoOracle(RENZO_RESTAKE_MANAGER.renzoOracle()).calculateRedeemAmount( | ||
1 ether, | ||
EZ_ETH.totalSupply(), | ||
_currentValueInProtocol | ||
); | ||
|
||
return (0, int256(rate), 0, 0, 0); | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
src/exchange-rate-adapters/RsEthToEthExchangeRateChainlinkAdapter.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity ^0.8.19; | ||
|
||
import {IKelpLRTConfig} from "../interfaces/kelp/IKelpLRTConfig.sol"; | ||
import {IKelpLRTOracle} from "../interfaces/kelp/IKelpLRTOracle.sol"; | ||
import {IMinimalAggregatorV3Interface} from "../interfaces/IMinimalAggregatorV3Interface.sol"; | ||
|
||
/// @title RsEthToEthExchangeRateChainlinkAdapter | ||
/// @author Morpho Labs | ||
/// @custom:contact [email protected] | ||
/// @notice rsETH/ETH exchange rate price feed. | ||
/// @dev This contract should only be deployed on Ethereum and used as a price feed for Morpho oracles. | ||
contract RsEthToEthExchangeRateChainlinkAdapter is IMinimalAggregatorV3Interface { | ||
/// @inheritdoc IMinimalAggregatorV3Interface | ||
// @dev The calculated price has 18 decimals precision, whatever the value of `decimals`. | ||
uint8 public override constant decimals = 18; | ||
|
||
/// @notice The description of the price feed. | ||
string public constant description = "rsETH/ETH exchange rate"; | ||
|
||
/// @notice The address of the Kelp LRT Config contract in Ethereum. | ||
IKelpLRTConfig public constant KELP_LRT_CONFIG = IKelpLRTConfig(0x947Cb49334e6571ccBFEF1f1f1178d8469D65ec7); | ||
|
||
bytes32 public constant LRT_ORACLE = keccak256("LRT_ORACLE"); | ||
|
||
/// @inheritdoc IMinimalAggregatorV3Interface | ||
/// @dev Returns zero for roundId, startedAt, updatedAt and answeredInRound. | ||
/// @dev Silently overflows if `rsETHPrice`'s return value is greater than `type(int256).max`. | ||
function latestRoundData() external override view returns (uint80, int256, uint256, uint256, uint80) { | ||
IKelpLRTOracle lrtOracle = IKelpLRTOracle(KELP_LRT_CONFIG.getContract(LRT_ORACLE)); | ||
uint256 rate = lrtOracle.rsETHPrice(); | ||
return (0, int256(rate), 0, 0, 0); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/exchange-rate-adapters/RswEthToEthExchangeRateChainlinkAdapter.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.8.19; | ||
|
||
import {IRswETH} from "../interfaces/swell/IRswETH.sol"; | ||
import {IMinimalAggregatorV3Interface} from "../interfaces/IMinimalAggregatorV3Interface.sol"; | ||
|
||
/// @title RswEthToEthExchangeRateChainlinkAdapter | ||
/// @author Morpho Labs | ||
/// @custom:contact [email protected] | ||
/// @notice rswETH/ETH exchange rate price feed. | ||
/// @dev This contract should only be deployed on Ethereum and used as a price feed for Morpho oracles. | ||
contract RswEthToEthExchangeRateChainlinkAdapter is IMinimalAggregatorV3Interface { | ||
/// @inheritdoc IMinimalAggregatorV3Interface | ||
// @dev The calculated price has 18 decimals precision, whatever the value of `decimals`. | ||
uint8 public override constant decimals = 18; | ||
|
||
/// @notice The description of the price feed. | ||
string public constant description = "rswETH/ETH exchange rate"; | ||
|
||
/// @notice The address of the Swell Network rswETH contract in Ethereum. | ||
IRswETH public constant RSWETH = IRswETH(0xFAe103DC9cf190eD75350761e95403b7b8aFa6c0); | ||
|
||
/// @inheritdoc IMinimalAggregatorV3Interface | ||
/// @dev Returns zero for roundId, startedAt, updatedAt and answeredInRound. | ||
/// @dev Silently overflows if `rswETHToETHRate`'s return value is greater than `type(int256).max`. | ||
function latestRoundData() external override view returns (uint80, int256, uint256, uint256, uint80) { | ||
return (0, int256(RSWETH.rswETHToETHRate()), 0, 0, 0); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/exchange-rate-adapters/SwEthToEthExchangeRateChainlinkAdapter.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.8.19; | ||
|
||
import {ISwETH} from "../interfaces/swell/ISwETH.sol"; | ||
import {IMinimalAggregatorV3Interface} from "../interfaces/IMinimalAggregatorV3Interface.sol"; | ||
|
||
/// @title SwEthToEthExchangeRateChainlinkAdapter | ||
/// @author Morpho Labs | ||
/// @custom:contact [email protected] | ||
/// @notice swETH/ETH exchange rate price feed. | ||
/// @dev This contract should only be deployed on Ethereum and used as a price feed for Morpho oracles. | ||
contract SwEthToEthExchangeRateChainlinkAdapter is IMinimalAggregatorV3Interface { | ||
/// @inheritdoc IMinimalAggregatorV3Interface | ||
// @dev The calculated price has 18 decimals precision, whatever the value of `decimals`. | ||
uint8 public override constant decimals = 18; | ||
|
||
/// @notice The description of the price feed. | ||
string public constant description = "swETH/ETH exchange rate"; | ||
|
||
/// @notice The address of the Swell Network swETH contract in Ethereum. | ||
ISwETH public constant SWETH = ISwETH(0xf951E335afb289353dc249e82926178EaC7DEd78); | ||
|
||
/// @inheritdoc IMinimalAggregatorV3Interface | ||
/// @dev Returns zero for roundId, startedAt, updatedAt and answeredInRound. | ||
/// @dev Silently overflows if `swETHToETHRate`'s return value is greater than `type(int256).max`. | ||
function latestRoundData() external override view returns (uint80, int256, uint256, uint256, uint80) { | ||
return (0, int256(SWETH.swETHToETHRate()), 0, 0, 0); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/exchange-rate-adapters/WeEthToEthExchangeRateChainlinkAdapter.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.8.19; | ||
|
||
import {IWeEth} from "../interfaces/etherfi/IWeEth.sol"; | ||
import {IMinimalAggregatorV3Interface} from "../interfaces/IMinimalAggregatorV3Interface.sol"; | ||
|
||
/// @title WeEthToEthExchangeRateChainlinkAdapter | ||
/// @author Morpho Labs | ||
/// @custom:contact [email protected] | ||
/// @notice weETH/ETH exchange rate price feed. | ||
/// @dev This contract should only be deployed on Ethereum and used as a price feed for Morpho oracles. | ||
contract WeEthToEthExchangeRateChainlinkAdapter is IMinimalAggregatorV3Interface { | ||
/// @inheritdoc IMinimalAggregatorV3Interface | ||
// @dev The calculated price has 18 decimals precision, whatever the value of `decimals`. | ||
uint8 public override constant decimals = 18; | ||
|
||
/// @notice The description of the price feed. | ||
string public constant description = "weETH/ETH exchange rate"; | ||
|
||
/// @notice The address of the weETH token on Ethereum. | ||
IWeEth public constant WEETH = IWeEth(0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee); | ||
|
||
/// @inheritdoc IMinimalAggregatorV3Interface | ||
/// @dev Returns zero for roundId, startedAt, updatedAt and answeredInRound. | ||
/// @dev Silently overflows if `getRate()`'s return value is greater than `type(int256).max`. | ||
function latestRoundData() external override view returns (uint80, int256, uint256, uint256, uint80) { | ||
return (0, int256(WEETH.getRate()), 0, 0, 0); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,16 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity 0.8.21; | ||
pragma solidity ^0.8.19; | ||
|
||
import {IStEth} from "./interfaces/IStEth.sol"; | ||
import {MinimalAggregatorV3Interface} from "./interfaces/MinimalAggregatorV3Interface.sol"; | ||
import {IStEth} from "../interfaces/lido/IStEth.sol"; | ||
import {IMinimalAggregatorV3Interface} from "../interfaces/IMinimalAggregatorV3Interface.sol"; | ||
|
||
/// @title WstEthStEthExchangeRateChainlinkAdapter | ||
/// @author Morpho Labs | ||
/// @custom:contact [email protected] | ||
/// @notice wstETH/stETH exchange rate price feed. | ||
/// @dev This contract should only be deployed on Ethereum and used as a price feed for Morpho oracles. | ||
contract WstEthStEthExchangeRateChainlinkAdapter is MinimalAggregatorV3Interface { | ||
/// @inheritdoc MinimalAggregatorV3Interface | ||
contract WstEthStEthExchangeRateChainlinkAdapter is IMinimalAggregatorV3Interface { | ||
/// @inheritdoc IMinimalAggregatorV3Interface | ||
// @dev The calculated price has 18 decimals precision, whatever the value of `decimals`. | ||
uint8 public constant decimals = 18; | ||
|
||
|
@@ -20,7 +20,7 @@ contract WstEthStEthExchangeRateChainlinkAdapter is MinimalAggregatorV3Interface | |
/// @notice The address of stETH on Ethereum. | ||
IStEth public constant ST_ETH = IStEth(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84); | ||
|
||
/// @inheritdoc MinimalAggregatorV3Interface | ||
/// @inheritdoc IMinimalAggregatorV3Interface | ||
/// @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) { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity >=0.5.0; | ||
|
||
interface IERC20 { | ||
function totalSupply() external view returns (uint256); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity >=0.5.0; | ||
|
||
interface IWeEth { | ||
// Amount of weETH for 1 eETH | ||
function getRate() external view returns (uint256); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity >=0.5.0; | ||
|
||
interface IKelpLRTConfig { | ||
function getContract(bytes32 contractId) external view returns (address); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity >=0.5.0; | ||
|
||
interface IKelpLRTOracle { | ||
function rsETHPrice() external view returns (uint256); | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity >=0.5.0; | ||
|
||
interface IRenzoOracle { | ||
function calculateRedeemAmount( | ||
uint256 _ezETHBeingBurned, | ||
uint256 _existingEzETHSupply, | ||
uint256 _currentValueInProtocol | ||
) external pure returns (uint256); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity >=0.5.0; | ||
|
||
interface IRenzoRestakeManager { | ||
function calculateTVLs() external view returns (uint256[][] memory, uint256[] memory, uint256); | ||
function renzoOracle() external view returns (address); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity >=0.5.0; | ||
|
||
interface IRswETH { | ||
function rswETHToETHRate() external view returns (uint256); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity >=0.5.0; | ||
|
||
interface ISwETH { | ||
function swETHToETHRate() external view returns (uint256); | ||
} |
62 changes: 62 additions & 0 deletions
62
test/exchange-rate-adapters/EzEthToEthExchangeRateChainlinkAdapter.t.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity ^0.8.19; | ||
|
||
import {vaultZero, feedZero} from "../helpers/Constants.sol"; | ||
import {Test} from "../../lib/forge-std/src/Test.sol"; | ||
import {MorphoChainlinkOracleV2} from "../../src/morpho-chainlink/MorphoChainlinkOracleV2.sol"; | ||
import {EzEthToEthExchangeRateChainlinkAdapter} from "../../src/exchange-rate-adapters/EzEthToEthExchangeRateChainlinkAdapter.sol"; | ||
import {IRenzoRestakeManager} from "../../src/interfaces/Renzo/IRenzoRestakeManager.sol"; | ||
import {IRenzoOracle} from "../../src/interfaces/Renzo/IRenzoOracle.sol"; | ||
import {IERC20} from "../../src/interfaces/IERC20.sol"; | ||
import {AggregatorV3Interface} from "../../src/morpho-chainlink/interfaces/AggregatorV3Interface.sol"; | ||
|
||
contract EzEthToEthExchangeRateChainlinkAdapterTest is Test { | ||
IRenzoRestakeManager public constant RENZO_RESTAKE_MANAGER = IRenzoRestakeManager(0x74a09653A083691711cF8215a6ab074BB4e99ef5); | ||
IERC20 public constant EZ_ETH = IERC20(0xbf5495Efe5DB9ce00f80364C8B423567e58d2110); | ||
|
||
EzEthToEthExchangeRateChainlinkAdapter internal adapter; | ||
MorphoChainlinkOracleV2 internal morphoOracle; | ||
|
||
function setUp() public { | ||
vm.createSelectFork(vm.envString("ETH_RPC_URL"), 20066000); | ||
require(block.chainid == 1, "chain isn't Ethereum"); | ||
adapter = new EzEthToEthExchangeRateChainlinkAdapter(); | ||
morphoOracle = new MorphoChainlinkOracleV2( | ||
vaultZero, 1, AggregatorV3Interface(address(adapter)), feedZero, 18, vaultZero, 1, feedZero, feedZero, 18 | ||
); | ||
} | ||
|
||
function test_decimals() public { | ||
assertEq(adapter.decimals(), uint8(18)); | ||
} | ||
|
||
function test_description() public { | ||
assertEq(adapter.description(), "ezETH/ETH exchange rate"); | ||
} | ||
|
||
function expectedRate() private view returns (uint256) { | ||
(,, uint256 _currentValueInProtocol) = RENZO_RESTAKE_MANAGER.calculateTVLs(); | ||
uint256 totalSupply = EZ_ETH.totalSupply(); | ||
return IRenzoOracle(RENZO_RESTAKE_MANAGER.renzoOracle()).calculateRedeemAmount( | ||
1 ether, | ||
totalSupply, | ||
_currentValueInProtocol | ||
); | ||
} | ||
|
||
function test_latestRoundData() public { | ||
(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) = | ||
adapter.latestRoundData(); | ||
assertEq(roundId, 0); | ||
assertEq(uint256(answer), expectedRate()); | ||
assertEq(answer, 1.011474492485111833e18); // Exchange rate queried at block 20066000 | ||
assertEq(startedAt, 0); | ||
assertEq(updatedAt, 0); | ||
assertEq(answeredInRound, 0); | ||
} | ||
|
||
function test_oracleEzEthToEthExchangeRate() public { | ||
(, int256 expectedPrice,,,) = adapter.latestRoundData(); | ||
assertEq(morphoOracle.price(), uint256(expectedPrice) * 10 ** (36 + 18 - 18 - 18)); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
test/exchange-rate-adapters/RsEthToEthExchangeRateChainlinkAdapter.t.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity ^0.8.19; | ||
|
||
import {vaultZero, feedZero} from "../helpers/Constants.sol"; | ||
import {Test} from "../../lib/forge-std/src/Test.sol"; | ||
import {MorphoChainlinkOracleV2} from "../../src/morpho-chainlink/MorphoChainlinkOracleV2.sol"; | ||
import {RsEthToEthExchangeRateChainlinkAdapter} from "../../src/exchange-rate-adapters/RsEthToEthExchangeRateChainlinkAdapter.sol"; | ||
import {AggregatorV3Interface} from "../../src/morpho-chainlink/interfaces/AggregatorV3Interface.sol"; | ||
import {IKelpLRTConfig} from "../../src/interfaces/kelp/IKelpLRTConfig.sol"; | ||
import {IKelpLRTOracle} from "../../src/interfaces/kelp/IKelpLRTOracle.sol"; | ||
|
||
contract RsEthToEthExchangeRateChainlinkAdapterTest is Test { | ||
IKelpLRTConfig public constant KELP_LRT_CONFIG = IKelpLRTConfig(0x947Cb49334e6571ccBFEF1f1f1178d8469D65ec7); | ||
bytes32 public constant LRT_ORACLE = keccak256("LRT_ORACLE"); | ||
|
||
RsEthToEthExchangeRateChainlinkAdapter internal adapter; | ||
MorphoChainlinkOracleV2 internal morphoOracle; | ||
|
||
function setUp() public { | ||
vm.createSelectFork(vm.envString("ETH_RPC_URL"), 20066000); | ||
require(block.chainid == 1, "chain isn't Ethereum"); | ||
adapter = new RsEthToEthExchangeRateChainlinkAdapter(); | ||
morphoOracle = new MorphoChainlinkOracleV2( | ||
vaultZero, 1, AggregatorV3Interface(address(adapter)), feedZero, 18, vaultZero, 1, feedZero, feedZero, 18 | ||
); | ||
} | ||
|
||
function test_decimals() public { | ||
assertEq(adapter.decimals(), uint8(18)); | ||
} | ||
|
||
function test_description() public { | ||
assertEq(adapter.description(), "rsETH/ETH exchange rate"); | ||
} | ||
|
||
function test_latestRoundData() public { | ||
IKelpLRTOracle lrtOracle = IKelpLRTOracle(KELP_LRT_CONFIG.getContract(LRT_ORACLE)); | ||
uint256 expectedRate = lrtOracle.rsETHPrice(); | ||
|
||
(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) = | ||
adapter.latestRoundData(); | ||
assertEq(roundId, 0); | ||
assertEq(uint256(answer), expectedRate); | ||
assertEq(uint256(answer), 1.014115456823606415e18); // Exchange rate queried at block 20066000 | ||
assertEq(startedAt, 0); | ||
assertEq(updatedAt, 0); | ||
assertEq(answeredInRound, 0); | ||
} | ||
|
||
function test_oracleRsEthToEthExchangeRate() public { | ||
(, int256 expectedPrice,,,) = adapter.latestRoundData(); | ||
assertEq(morphoOracle.price(), uint256(expectedPrice) * 10 ** (36 + 18 - 18 - 18)); | ||
} | ||
} |
Oops, something went wrong.