Skip to content

Instantly share code, notes, and snippets.

@Picodes
Created September 9, 2022 12:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Picodes/04de56c46efe920672ca47322daf8ca7 to your computer and use it in GitHub Desktop.
Save Picodes/04de56c46efe920672ca47322daf8ca7 to your computer and use it in GitHub Desktop.
Oracle With Whitelisting
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "../../interfaces/IKeeperRegistry.sol";
import "../../interfaces/ICoreBorrow.sol";
/// @title ChainlinkUtilsWithKeeper
/// @author Angle Core Team
/// @notice Utility contract that is used across the different module contracts using Chainlink
abstract contract ChainlinkUtilsWithKeeper {
/// @notice Represent the maximum amount of time (in seconds) between each Chainlink update
/// before the price feed is considered stale
uint32 public stalePeriod;
/// @notice Represent the number of seconds during which the oracle needs to be paused
/// after each update
uint32 public pausingPeriod;
/// @notice Contracts holding a mapping of whitelisted keepers
IKeeperRegistry public keeperRegistry;
/// @notice Contracts handling access control
ICoreBorrow public coreBorrow;
error InvalidChainlinkRate();
error NotGovernorOrGuardianChainlink();
error NotGovernor();
error OraclePaused();
/// @notice Checks whether the `msg.sender` has the governor role or the guardian role
modifier onlyGovernorOrGuardian() {
if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardianChainlink();
_;
}
/// @notice Checks whether the `msg.sender` has the governor role
modifier onlyGovernor() {
if (!coreBorrow.isGovernor(msg.sender)) revert NotGovernor();
_;
}
/// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to
/// the out-currency
/// @param quoteAmount The amount for which to compute the price expressed with base decimal
/// @param feed Chainlink feed to query
/// @param pauseAfterUpdate Whether to pause the oracle after each update
/// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided
/// to the `quoteAmount`
/// @param decimals Number of decimals of the corresponding Chainlink pair
/// @param castedRatio Whether a previous rate has already been computed for this feed
/// This is mostly used in the `_changeUniswapNotFinal` function of the oracles
/// @return The `quoteAmount` converted in out-currency (computed using the second return value)
/// @return The value obtained with the Chainlink feed queried casted to uint
function _readChainlinkFeed(
uint256 quoteAmount,
AggregatorV3Interface feed,
uint8 pauseAfterUpdate,
uint8 multiplied,
uint256 decimals,
uint256 castedRatio
) internal view returns (uint256, uint256) {
if (castedRatio == 0) {
(uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();
if (
pauseAfterUpdate == 1 &&
updatedAt + pausingPeriod > block.timestamp &&
!keeperRegistry.isTrusted(tx.origin)
) revert OraclePaused();
if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)
revert InvalidChainlinkRate();
castedRatio = uint256(ratio);
}
// Checking whether we should multiply or divide by the ratio computed
if (multiplied == 1) quoteAmount = (quoteAmount * castedRatio) / (10**decimals);
else quoteAmount = (quoteAmount * (10**decimals)) / castedRatio;
return (quoteAmount, castedRatio);
}
/// @notice Changes the Stale Period
/// @param _stalePeriod New stale period (in seconds)
function changeStalePeriod(uint32 _stalePeriod) external onlyGovernorOrGuardian {
stalePeriod = _stalePeriod;
}
/// @notice Changes the Pausing Period
/// @param _pausingPeriod New period
function changePausingPeriod(uint32 _pausingPeriod) external onlyGovernorOrGuardian {
pausingPeriod = _pausingPeriod;
}
/// @notice Changes the Keeper Registry address
/// @param _keeperRegistry New registry
function changeKeeperRegistry(IKeeperRegistry _keeperRegistry) external onlyGovernorOrGuardian {
keeperRegistry = _keeperRegistry;
}
/// @notice Changes the CoreBorrow address
/// @param _coreBorrow New CoreBorrow
function changeCoreBorrow(ICoreBorrow _coreBorrow) external onlyGovernor {
coreBorrow = _coreBorrow;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment