-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix/chainlight remediations #81
Changes from all commits
e7ce3ea
0d05691
e79673a
5b4827a
50da798
902146b
feb42a8
8c4caf6
fd750fe
5d2988a
4b59605
8969f36
5d95cd6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
pragma solidity ^0.8.23; | ||
|
||
import "@openzeppelin/contracts/access/Ownable.sol"; | ||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
import "./IOracleAggregator.sol"; | ||
import "./FeedInterface.sol"; | ||
|
||
|
@@ -14,10 +15,10 @@ abstract contract OracleAggregator is Ownable, IOracleAggregator { | |
|
||
function setTokenOracle( | ||
address token, | ||
uint8 tokenDecimals, | ||
address tokenOracle, | ||
address nativeOracle, | ||
bool isDerivedFeed | ||
bool isDerivedFeed, | ||
uint24 priceUpdateThreshold | ||
) external onlyOwner { | ||
if (tokenOracle == address(0)) revert OracleAddressCannotBeZero(); | ||
if (nativeOracle == address(0)) revert OracleAddressCannotBeZero(); | ||
|
@@ -27,8 +28,9 @@ abstract contract OracleAggregator is Ownable, IOracleAggregator { | |
if (decimals1 != decimals2) revert MismatchInBaseAndQuoteDecimals(); | ||
tokensInfo[token].tokenOracle = tokenOracle; | ||
tokensInfo[token].nativeOracle = nativeOracle; | ||
tokensInfo[token].tokenDecimals = tokenDecimals; | ||
tokensInfo[token].tokenDecimals = ERC20(token).decimals(); | ||
tokensInfo[token].isDerivedFeed = isDerivedFeed; | ||
tokensInfo[token].priceUpdateThreshold = priceUpdateThreshold; | ||
Comment on lines
+31
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Current function I'll suggest to pass TokenInfo directly and update map once. Saves SSTORE operation
This way we use less gas There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we do this as part of another PR? first I will check gas consumptions on forge. this also requires major changes again in scripts |
||
} | ||
|
||
/** | ||
|
@@ -50,18 +52,19 @@ abstract contract OracleAggregator is Ownable, IOracleAggregator { | |
view | ||
returns (uint256 tokenPrice, uint8 tokenOracleDecimals, uint8 tokenDecimals, bool isError) | ||
{ | ||
TokenInfo storage tokenInfo = tokensInfo[token]; | ||
TokenInfo memory tokenInfo = tokensInfo[token]; | ||
tokenDecimals = tokenInfo.tokenDecimals; | ||
uint24 priceUpdateThreshold = tokenInfo.priceUpdateThreshold; | ||
|
||
if (tokenInfo.isDerivedFeed) { | ||
(uint256 price1, bool isError1) = fetchPrice(FeedInterface(tokenInfo.nativeOracle)); | ||
(uint256 price2, bool isError2) = fetchPrice(FeedInterface(tokenInfo.tokenOracle)); | ||
(uint256 price1, bool isError1) = fetchPrice(FeedInterface(tokenInfo.nativeOracle), priceUpdateThreshold); | ||
(uint256 price2, bool isError2) = fetchPrice(FeedInterface(tokenInfo.tokenOracle), priceUpdateThreshold); | ||
isError = isError1 || isError2; | ||
if (isError) return (0, 0, 0, isError); | ||
tokenPrice = (price2 * (10 ** 18)) / price1; | ||
tokenOracleDecimals = 18; | ||
} else { | ||
(tokenPrice, isError) = fetchPrice(FeedInterface(tokenInfo.tokenOracle)); | ||
(tokenPrice, isError) = fetchPrice(FeedInterface(tokenInfo.tokenOracle), priceUpdateThreshold); | ||
tokenOracleDecimals = FeedInterface(tokenInfo.tokenOracle).decimals(); | ||
} | ||
} | ||
|
@@ -70,17 +73,18 @@ abstract contract OracleAggregator is Ownable, IOracleAggregator { | |
* @dev This function is used to get the latest price from the tokenOracle or nativeOracle. | ||
* @notice Fetches the latest price from the given Oracle. | ||
* @param _oracle The Oracle contract to fetch the price from. | ||
* @param _priceUpdateThreshold The time after which the price is considered stale. | ||
* @return price The latest price fetched from the Oracle. | ||
*/ | ||
function fetchPrice(FeedInterface _oracle) internal view returns (uint256 price, bool isError) { | ||
function fetchPrice(FeedInterface _oracle, uint24 _priceUpdateThreshold) internal view returns (uint256 price, bool isError) { | ||
try _oracle.latestRoundData() returns ( | ||
uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound | ||
) { | ||
// validateRound | ||
if (answer <= 0) return (0, true); | ||
// 2 days old price is considered stale since the price is updated every 24 hours | ||
if (updatedAt < block.timestamp - 60 * 60 * 24 * 2) return (0, true); | ||
if (answeredInRound < roundId) return (0, true); | ||
// price older than set _priceUpdateThreshold is considered stale | ||
// _priceUpdateThreshold for oracle feed is usually heartbeat interval + block time + buffer | ||
if (updatedAt < block.timestamp - _priceUpdateThreshold) return (0, true); | ||
price = uint256(answer); | ||
return (price, false); | ||
} catch Error(string memory reason) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure
_amount
should beindexed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can index 3 params and I think it's fine. also out of scope of remediations PR