Skip to content
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

Bugfix/fix collateral twap #844

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6801b47
test: add collateral TWAP test
gitcoindev Nov 23, 2023
9f8e2eb
test: example of using last prices from LUSD Curve contract
gitcoindev Nov 24, 2023
a4c0ba8
Merge branch 'ubiquity:development' into bugfix/fix-collateral-twap
gitcoindev Nov 29, 2023
8ad4be8
feat: add LibCollateralOracle skeleton
gitcoindev Dec 1, 2023
67bba2f
feat: getLatestPrice and getDecimals for priceFeed
gitcoindev Dec 1, 2023
84c1021
feat: emit CollateralPriceUpdated
gitcoindev Dec 1, 2023
bbcefb0
Merge branch 'development' into bugfix/fix-collateral-twap
gitcoindev Dec 4, 2023
cb96b9c
feat: register ChainLink price feed
gitcoindev Dec 4, 2023
8a1a471
feat: use ChainLink price feed in LibUibquityPool
gitcoindev Dec 8, 2023
061668c
chore: update setCollateralChainLinkPriceFeedAddress docs
gitcoindev Dec 8, 2023
ed19d1f
feat: update CollateralPriceFeedSet event to emit address
gitcoindev Dec 8, 2023
fd3e4e4
feat: add ChainLink price feed interface functions to IUbiquityPool
gitcoindev Dec 8, 2023
ab28a89
feat: remove LibCollateralOracle
gitcoindev Dec 8, 2023
4caaeb1
chore: remove unused LibCollateralOracle import
gitcoindev Dec 8, 2023
7363a27
test: implement ChainLink price feed mock
gitcoindev Dec 8, 2023
7f6de0f
test: implement updateMockParams in MockChainLinkFeed
gitcoindev Dec 9, 2023
45b6258
feat: switch to pure functcions in MockChainLinkFeed
gitcoindev Dec 9, 2023
e7b8f37
feat: initialize collateralPriceFeedAddress to 0 in addCollateralToken
gitcoindev Dec 9, 2023
dac1794
test: testCollateralPriceFeed verifies mocked ChainLink price
gitcoindev Dec 10, 2023
1073bb5
chore: install ChainLink npm package
gitcoindev Dec 15, 2023
3c67ec9
feat: remove unused ICollateralOracle.sol
gitcoindev Dec 15, 2023
9f9cc58
feat: switch to AggregatorV3Interface from smartcontractkit
gitcoindev Dec 15, 2023
5bdb7a3
feat: commit ChainLink contracts submodule
gitcoindev Dec 15, 2023
317e6e9
Merge branch 'development' into bugfix/fix-collateral-twap
gitcoindev Dec 15, 2023
e59ad40
feat: update ChainLink contracts remapping path
gitcoindev Dec 15, 2023
8c87bb2
feat: use collateralIndex instead of collateralAddressToIndex
gitcoindev Dec 15, 2023
eb9946f
feat: move updateChainLinkCollateralPrice to public functions
gitcoindev Dec 15, 2023
c825dfe
feat: update collateral price before collateral price related functions
gitcoindev Dec 15, 2023
5d4637d
test: set up mocked ChainLink price feed in UbiquityPoolFacet test
gitcoindev Dec 15, 2023
ccfe0e2
test: add testCollateralPriceFeed_ShouldWorkWithMultipleCollateralTokens
gitcoindev Dec 17, 2023
e275f64
test: enable second collateral in ShouldWorkWithMultipleCollateralTokens
gitcoindev Dec 17, 2023
9dfb15a
test: add skeleton for collateral twap test with mocked meta pool
gitcoindev Dec 18, 2023
390f9da
test: add temporary log to testCollateralTwap
gitcoindev Dec 18, 2023
4210e3d
refactor: refactor UbiquityPool
rndquu Dec 21, 2023
f08df5c
Merge pull request #10 from rndquu/feat/collateral-twap
rndquu Dec 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@
path = packages/contracts/lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
branch = release-v4.9
[submodule "packages/contracts/lib/chainlink-brownie-contracts"]
path = packages/contracts/lib/chainlink-brownie-contracts
url = https://github.com/smartcontractkit/chainlink-brownie-contracts
branch= main
1 change: 1 addition & 0 deletions packages/contracts/lib/chainlink-brownie-contracts
1 change: 1 addition & 0 deletions packages/contracts/remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ solidity-linked-list/=lib/solidity-linked-list
@uniswap/v3-periphery/contracts/=lib/Uniswap/v3-periphery/contracts
abdk/=lib/abdk-libraries-solidity/
operator-filter-registry/=lib/operator-filter-registry/src
@chainlink/=lib/chainlink-brownie-contracts/contracts/src/v0.8/
25 changes: 20 additions & 5 deletions packages/contracts/src/dollar/facets/UbiquityPoolFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ contract UbiquityPoolFacet is IUbiquityPool, Modifiers {
return LibUbiquityPool.collectRedemption(collateralIndex);
}

/// @inheritdoc IUbiquityPool
function updateChainLinkCollateralPrice(uint256 collateralIndex) external {
LibUbiquityPool.updateChainLinkCollateralPrice(collateralIndex);
}

//=========================
// AMO minters functions
//=========================
Expand All @@ -131,9 +136,14 @@ contract UbiquityPoolFacet is IUbiquityPool, Modifiers {
/// @inheritdoc IUbiquityPool
function addCollateralToken(
address collateralAddress,
address chainLinkPriceFeedAddress,
uint256 poolCeiling
) external onlyAdmin {
LibUbiquityPool.addCollateralToken(collateralAddress, poolCeiling);
LibUbiquityPool.addCollateralToken(
collateralAddress,
chainLinkPriceFeedAddress,
poolCeiling
);
}

/// @inheritdoc IUbiquityPool
Expand All @@ -142,11 +152,16 @@ contract UbiquityPoolFacet is IUbiquityPool, Modifiers {
}

/// @inheritdoc IUbiquityPool
function setCollateralPrice(
uint256 collateralIndex,
uint256 newPrice
function setCollateralChainLinkPriceFeed(
address collateralAddress,
address chainLinkPriceFeedAddress,
uint256 stalenessThreshold
) external onlyAdmin {
LibUbiquityPool.setCollateralPrice(collateralIndex, newPrice);
LibUbiquityPool.setCollateralChainLinkPriceFeed(
collateralAddress,
chainLinkPriceFeedAddress,
stalenessThreshold
);
}

/// @inheritdoc IUbiquityPool
Expand Down
22 changes: 16 additions & 6 deletions packages/contracts/src/dollar/interfaces/IUbiquityPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,12 @@ interface IUbiquityPool {
/**
* @notice Adds a new collateral token
* @param collateralAddress Collateral token address
* @param chainLinkPriceFeedAddress Chainlink's price feed address
* @param poolCeiling Max amount of available tokens for collateral
*/
function addCollateralToken(
address collateralAddress,
address chainLinkPriceFeedAddress,
uint256 poolCeiling
) external;

Expand All @@ -156,15 +158,23 @@ interface IUbiquityPool {
function removeAmoMinter(address amoMinterAddress) external;

/**
* @notice Sets collateral token price in USD
* @param collateralIndex Collateral token index
* @param newPrice New USD price (precision 1e6)
* @notice Sets collateral ChainLink price feed params
* @param collateralAddress Collateral token address
* @param chainLinkPriceFeedAddress ChainLink price feed address
* @param stalenessThreshold Threshold in seconds when chainlink answer should be considered stale
*/
function setCollateralPrice(
uint256 collateralIndex,
uint256 newPrice
function setCollateralChainLinkPriceFeed(
address collateralAddress,
address chainLinkPriceFeedAddress,
uint256 stalenessThreshold
) external;

/**
* @notice Updates collateral token price in USD from ChainLink price feed
* @param collateralIndex Collateral token index
*/
function updateChainLinkCollateralPrice(uint256 collateralIndex) external;

/**
* @notice Sets mint and redeem fees, 1_000_000 = 100%
* @param collateralIndex Collateral token index
Expand Down
123 changes: 111 additions & 12 deletions packages/contracts/src/dollar/libraries/LibUbiquityPool.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity 0.8.19;

import {AggregatorV3Interface} from "@chainlink/interfaces/AggregatorV3Interface.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
Expand Down Expand Up @@ -41,43 +42,47 @@
address[] collateralAddresses;
// collateral address -> collateral index
mapping(address collateralAddress => uint256 collateralIndex) collateralIndex;
// Stores price of the collateral, if price is paused. CONSIDER ORACLES EVENTUALLY!!!
// collateral index -> chainlink price feed addresses
address[] collateralPriceFeedAddresses;

Check warning on line 46 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Label diff

variable "collateralPrices" was renamed to "collateralPriceFeedAddresses". Is it intentional? (storage slot 0x0000000000000000000000000000000000000000000000000000000000000003, byte #0)
// collateral index -> threshold in seconds when chainlink answer should be considered stale
uint256[] collateralPriceFeedStalenessThresholds;

Check warning on line 48 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Label diff

variable "collateralSymbols" was renamed to "collateralPriceFeedStalenessThresholds". Is it intentional? (storage slot 0x0000000000000000000000000000000000000000000000000000000000000004, byte #0)
// collateral index -> collateral price
uint256[] collateralPrices;

Check failure on line 50 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Variable diff

variable "isCollateralEnabled" of type "Mapping" was replaced by variable "collateralPrices" of type "ArrayTypeName" (storage slot 0x0000000000000000000000000000000000000000000000000000000000000005, byte #0)
// array collateral symbols
string[] collateralSymbols;

Check warning on line 52 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Label diff

variable "missingDecimals" was renamed to "collateralSymbols". Is it intentional? (storage slot 0x0000000000000000000000000000000000000000000000000000000000000006, byte #0)
// collateral address -> is it enabled
mapping(address collateralAddress => bool isEnabled) isCollateralEnabled;

Check failure on line 54 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Variable diff

variable "poolCeilings" of type "ArrayTypeName" was replaced by variable "isCollateralEnabled" of type "Mapping" (storage slot 0x0000000000000000000000000000000000000000000000000000000000000007, byte #0)
// Number of decimals needed to get to E18. collateral index -> missing decimals
uint256[] missingDecimals;

Check failure on line 56 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Variable diff

variable "lastRedeemedBlock" of type "Mapping" was replaced by variable "missingDecimals" of type "ArrayTypeName" (storage slot 0x0000000000000000000000000000000000000000000000000000000000000008, byte #0)
// Total across all collaterals. Accounts for missing_decimals
uint256[] poolCeilings;

Check failure on line 58 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Variable diff

variable "mintPriceThreshold" of type "uint256" was replaced by variable "poolCeilings" of type "ArrayTypeName" (storage slot 0x0000000000000000000000000000000000000000000000000000000000000009, byte #0)
//====================
// Redeem related
//====================
// user -> block number (collateral independent)
mapping(address => uint256) lastRedeemedBlock;

Check failure on line 63 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Variable diff

variable "redeemPriceThreshold" of type "uint256" was replaced by variable "lastRedeemedBlock" of type "Mapping" (storage slot 0x000000000000000000000000000000000000000000000000000000000000000a, byte #0)
// 1010000 = $1.01
uint256 mintPriceThreshold;

Check failure on line 65 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Variable diff

variable "redeemCollateralBalances" of type "Mapping" was replaced by variable "mintPriceThreshold" of type "uint256" (storage slot 0x000000000000000000000000000000000000000000000000000000000000000b, byte #0)
// 990000 = $0.99
uint256 redeemPriceThreshold;

Check warning on line 67 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Label diff

variable "redemptionDelayBlocks" was renamed to "redeemPriceThreshold". Is it intentional? (storage slot 0x000000000000000000000000000000000000000000000000000000000000000c, byte #0)
// address -> collateral index -> balance
mapping(address user => mapping(uint256 collateralIndex => uint256 amount)) redeemCollateralBalances;

Check failure on line 69 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Variable diff

variable "unclaimedPoolCollateral" of type "ArrayTypeName" was replaced by variable "redeemCollateralBalances" of type "Mapping" (storage slot 0x000000000000000000000000000000000000000000000000000000000000000d, byte #0)
// number of blocks to wait before being able to collectRedemption()
uint256 redemptionDelayBlocks;

Check failure on line 71 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Variable diff

variable "mintingFee" of type "ArrayTypeName" was replaced by variable "redemptionDelayBlocks" of type "uint256" (storage slot 0x000000000000000000000000000000000000000000000000000000000000000e, byte #0)
// collateral index -> balance
uint256[] unclaimedPoolCollateral;

Check warning on line 73 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Label diff

variable "redemptionFee" was renamed to "unclaimedPoolCollateral". Is it intentional? (storage slot 0x000000000000000000000000000000000000000000000000000000000000000f, byte #0)
//================
// Fees related
//================
// minting fee of a particular collateral index, 1_000_000 = 100%
uint256[] mintingFee;

Check warning on line 78 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Label diff

variable "isBorrowPaused" was renamed to "mintingFee". Is it intentional? (storage slot 0x0000000000000000000000000000000000000000000000000000000000000010, byte #0)
// redemption fee of a particular collateral index, 1_000_000 = 100%
uint256[] redemptionFee;

Check warning on line 80 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Label diff

variable "isMintPaused" was renamed to "redemptionFee". Is it intentional? (storage slot 0x0000000000000000000000000000000000000000000000000000000000000011, byte #0)
//=================
// Pause related
//=================
// whether borrowing collateral by AMO minters is paused for a particular collateral index
bool[] isBorrowPaused;

Check warning on line 85 in packages/contracts/src/dollar/libraries/LibUbiquityPool.sol

View workflow job for this annotation

GitHub Actions / check_storage_layout (src/dollar/libraries/LibUbiquityPool.sol:LibUbiquityPool)

Label diff

variable "isRedeemPaused" was renamed to "isBorrowPaused". Is it intentional? (storage slot 0x0000000000000000000000000000000000000000000000000000000000000012, byte #0)
// whether minting is paused for a particular collateral index
bool[] isMintPaused;
// whether redeeming is paused for a particular collateral index
Expand All @@ -89,6 +94,8 @@
uint256 index;
string symbol;
address collateralAddress;
address collateralPriceFeedAddress;
uint256 collateralPriceFeedStalenessThreshold;
bool isEnabled;
uint256 missingDecimals;
uint256 price;
Expand Down Expand Up @@ -123,6 +130,12 @@
event AmoMinterAdded(address amoMinterAddress);
/// @notice Emitted when AMO minter is removed
event AmoMinterRemoved(address amoMinterAddress);
/// @notice Emitted on setting a chainlink's collateral price feed params
event CollateralPriceFeedSet(
uint256 collateralIndex,
address priceFeedAddress,
uint256 stalenessThreshold
);
/// @notice Emitted on setting a collateral price
event CollateralPriceSet(uint256 collateralIndex, uint256 newPrice);
/// @notice Emitted on enabling/disabling a particular collateral token
Expand Down Expand Up @@ -213,6 +226,8 @@
index,
poolStorage.collateralSymbols[index],
collateralAddress,
poolStorage.collateralPriceFeedAddresses[index],
poolStorage.collateralPriceFeedStalenessThresholds[index],
poolStorage.isCollateralEnabled[collateralAddress],
poolStorage.missingDecimals[index],
poolStorage.collateralPrices[index],
Expand Down Expand Up @@ -325,13 +340,18 @@
"Minting is paused"
);

// update Dollar price from Curve's Dollar Metapool
LibTWAPOracle.update();
// prevent unnecessary mints
require(
getDollarPriceUsd() >= poolStorage.mintPriceThreshold,
"Dollar price too low"
);

// get amount of collateral for incoming Dollars
// update collateral price
updateChainLinkCollateralPrice(collateralIndex);

// get amount of collateral for minting Dollars
collateralNeeded = getDollarInCollateral(collateralIndex, dollarAmount);

// subtract the minting fee
Expand Down Expand Up @@ -392,6 +412,8 @@
"Redeeming is paused"
);

// update Dollar price from Curve's Dollar Metapool
LibTWAPOracle.update();
// prevent unnecessary redemptions that could adversely affect the Dollar price
require(
getDollarPriceUsd() <= poolStorage.redeemPriceThreshold,
Expand All @@ -405,6 +427,11 @@
)
)
.div(UBIQUITY_POOL_PRICE_PRECISION);

// update collateral price
updateChainLinkCollateralPrice(collateralIndex);

// get collateral output for incoming Dollars
collateralOut = getDollarInCollateral(collateralIndex, dollarAfterFee);

// checks
Expand Down Expand Up @@ -489,6 +516,51 @@
}
}

/**
* @notice Updates collateral token price in USD from ChainLink price feed
* @param collateralIndex Collateral token index
*/
function updateChainLinkCollateralPrice(uint256 collateralIndex) internal {
UbiquityPoolStorage storage poolStorage = ubiquityPoolStorage();

AggregatorV3Interface priceFeed = AggregatorV3Interface(
poolStorage.collateralPriceFeedAddresses[collateralIndex]
);

// fetch latest price
(
,
// roundId
int256 answer, // startedAt
,
uint256 updatedAt,

) = // answeredInRound
priceFeed.latestRoundData();

// fetch number of decimals in chainlink feed
uint256 priceFeedDecimals = priceFeed.decimals();

// validation
require(answer > 0, "Invalid price");
require(
block.timestamp - updatedAt <
poolStorage.collateralPriceFeedStalenessThresholds[
collateralIndex
],
"Stale data"
);

// convert chainlink price to 6 decimals
uint256 price = uint256(answer).mul(UBIQUITY_POOL_PRICE_PRECISION).div(
10 ** priceFeedDecimals
);

poolStorage.collateralPrices[collateralIndex] = price;

emit CollateralPriceSet(collateralIndex, price);
}

//=========================
// AMO minters functions
//=========================
Expand Down Expand Up @@ -551,10 +623,12 @@
/**
* @notice Adds a new collateral token
* @param collateralAddress Collateral token address
* @param chainLinkPriceFeedAddress Chainlink's price feed address
* @param poolCeiling Max amount of available tokens for collateral
*/
function addCollateralToken(
address collateralAddress,
address chainLinkPriceFeedAddress,
uint256 poolCeiling
) internal {
UbiquityPoolStorage storage poolStorage = ubiquityPoolStorage();
Expand Down Expand Up @@ -593,8 +667,16 @@
poolStorage.isRedeemPaused.push(false);
poolStorage.isBorrowPaused.push(false);

// pool ceiling
// set pool ceiling
poolStorage.poolCeilings.push(poolCeiling);

// set price feed address
poolStorage.collateralPriceFeedAddresses.push(
chainLinkPriceFeedAddress
);

// set price feed staleness threshold in seconds
poolStorage.collateralPriceFeedStalenessThresholds.push(1 days);
}

/**
Expand All @@ -610,20 +692,37 @@
}

/**
* @notice Sets collateral token price in USD
* @param collateralIndex Collateral token index
* @param newPrice New USD price (precision 1e6)
* @notice Sets collateral ChainLink price feed params
* @param collateralAddress Collateral token address
* @param chainLinkPriceFeedAddress ChainLink price feed address
* @param stalenessThreshold Threshold in seconds when chainlink answer should be considered stale
*/
function setCollateralPrice(
uint256 collateralIndex,
uint256 newPrice
function setCollateralChainLinkPriceFeed(
address collateralAddress,
address chainLinkPriceFeedAddress,
uint256 stalenessThreshold
) internal {
UbiquityPoolStorage storage poolStorage = ubiquityPoolStorage();

// Notice: CONSIDER ORACLES EVENTUALLY!!!
poolStorage.collateralPrices[collateralIndex] = newPrice;
uint256 collateralIndex = poolStorage.collateralIndex[
collateralAddress
];

// set price feed address
poolStorage.collateralPriceFeedAddresses[
collateralIndex
] = chainLinkPriceFeedAddress;

emit CollateralPriceSet(collateralIndex, newPrice);
// set staleness threshold in seconds when chainlink answer should be considered stale
poolStorage.collateralPriceFeedStalenessThresholds[
collateralIndex
] = stalenessThreshold;

emit CollateralPriceFeedSet(
collateralIndex,
chainLinkPriceFeedAddress,
stalenessThreshold
);
}

/**
Expand Down
Loading
Loading