Раз уж в прошлом посты мы познакомились с протоколом Morpho, то сейчас можно разобрать еще один их репо, в котором показано как работать с оракулами Chainlink и писать тесты для них.
Вот ссылка на сам репо.
https://github.com/morpho-org/morpho-blue-oracles
Кратко описывая работу контракта можно сказать, что это реализация создана исключительно для работы сервиса Morpho и просто так использовать его в своем протоколе не получится.
Контракт наследует от интерфейса IOracle, подключает служебные библиотеки, а также использует Chainlink Data Feed для получения актуальных цен на токены.
В контракте всего одна функция и конструктор, в который передаются адреса контрактов Chainlink, с который мы хотим получить информацию.
Функции price() просто возвращает немного измененную цену на токен. Тут происходят преобразования суммы (scale) для последующей работы с ней в основном контракте Morpho.
Теперь разберем файл теста.
https://github.com/morpho-org/morpho-blue-oracles/blob/main/test/ChainlinkOracleTest.sol
Здесь подключаются необходимые библиотеки и указываются адреса необходимых контрактов Chainlink, расположенных в основной сети.
Далее в функции setUp() мы создаем подключение и делаем форк сети:
function setUp() public {
vm.createSelectFork(vm.envString("ETH_RPC_URL"));
} ETH_RPC_URL - переменная среды, в которую нам нужно определить нашу rpc ссылку и сохранить в файле .env.
Далее можно писать функции для тестирования:
function testOracleWbtcUsdc() public {
ChainlinkOracle oracle = new ChainlinkOracle(vaultZero, wBtcBtcFeed, btcUsdFeed, usdcUsdFeed, feedZero, 1, 8, 6);
(, int256 firstBaseAnswer,,,) = wBtcBtcFeed.latestRoundData();
(, int256 secondBaseAnswer,,,) = btcUsdFeed.latestRoundData();
(, int256 quoteAnswer,,,) = usdcUsdFeed.latestRoundData();
assertEq(
oracle.price(),
(uint256(firstBaseAnswer) * uint256(secondBaseAnswer) * 10 ** (36 + 8 + 6 - 8 - 8 - 8))
/ uint256(quoteAnswer)
);
}В целом, все довольно просто.
Вы также можете создать специальный скрипт для деплоя в разные сети и указать адреса контрактов Chainlink там. Пример этого вы можете найти в позапрошлом посте.
#foundry #lesson33