Change quote feed
This guide will show you how to fetch the latest feed values for two feeds and convert them to a new quote feed. For example, if you need the price of BTC/ETH
, you can fetch the latest feed values for BTC/USD
and ETH/USD
and calculate the price of BTC/ETH = (BTC/USD) / (ETH/USD)
.
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;
import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";
/* THIS IS A TEST IMPORT, in production use: import {FtsoV2Interface} from "@flarenetwork/flare-periphery-contracts/coston2/FtsoV2Interface.sol"; */
import {TestFtsoV2Interface} from "@flarenetwork/flare-periphery-contracts/coston2/TestFtsoV2Interface.sol";
/**
* THIS IS AN EXAMPLE CONTRACT.
* DO NOT USE THIS CODE IN PRODUCTION.
*/
contract FtsoV2ChangeQuoteFeed {
TestFtsoV2Interface internal ftsoV2;
/**
* Initializing an instance with FtsoV2Interface.
* The contract registry is used to fetch the contract address.
*/
constructor() {
/* THIS IS A TEST METHOD, in production use: ftsoV2 = ContractRegistry.getFtsoV2(); */
ftsoV2 = ContractRegistry.getTestFtsoV2();
}
/**
* @dev Internal function to scale the base feed value to match the decimals of the quote feed.
*/
function _scaleBaseFeedValue(
uint256 _baseFeedValue,
uint8 _baseFeedDecimals,
uint8 _quoteDecimals
) internal pure returns (uint256) {
if (_baseFeedDecimals < _quoteDecimals) {
// Scale up if base feed decimals are less than quote feed decimals
return
_baseFeedValue *
10 ** uint256(_quoteDecimals - _baseFeedDecimals);
} else if (_baseFeedDecimals > _quoteDecimals) {
// Scale down if base feed decimals are more than quote feed decimals
return
_baseFeedValue /
10 ** uint256(_baseFeedDecimals - _quoteDecimals);
} else {
// No scaling needed if decimals are equal
return _baseFeedValue;
}
}
/**
* @dev Function to compute the new quote feed value based on the base and quote feed values.
* @param _baseAndQuoteFeedIds Array containing the IDs of the base and quote feeds.
* @return The computed new quote feed value.
*/
function getNewQuoteFeedValue(
bytes21[] calldata _baseAndQuoteFeedIds
) external view returns (uint256) {
require(
_baseAndQuoteFeedIds.length == 2,
"Invalid feed indexes. Please provide exactly two indexes."
);
// Fetch current feeds
(uint256[] memory feedValues, int8[] memory decimals, ) = ftsoV2
.getFeedsById(_baseAndQuoteFeedIds);
uint8 newQuoteDecimals = uint8(decimals[1]);
// Scale the base feed value to match the quote feed decimals
uint256 scaledBaseFeedValue = _scaleBaseFeedValue(
feedValues[0],
uint8(decimals[0]),
newQuoteDecimals
);
// Prevent division by zero
require(feedValues[1] != 0, "Division by zero");
// Compute the new quote feed value
uint256 newQuoteFeedValue = (scaledBaseFeedValue *
10 ** uint256(newQuoteDecimals)) / feedValues[1];
return newQuoteFeedValue;
}
}
The TestFtsoV2Interface
is for testing only, with all methods as view
to allow rapid development without gas costs or state changes. For production, use FtsoV2Interface
, which includes payable
methods required for real transactions and state modifications.
Make the following changes to FtsoV2ChangeQuoteFeed.sol
:
- import {TestFtsoV2Interface} from "@flarenetwork/flare-periphery-contracts/coston2/TestFtsoV2Interface.sol";
+ import {FtsoV2Interface} from "@flarenetwork/flare-periphery-contracts/coston2/FtsoV2Interface.sol";
contract FtsoV2ChangeQuoteFeed {
constructor() {
- ftsoV2 = ContractRegistry.getTestFtsoV2();
+ ftsoV2 = ContractRegistry.getFtsoV2();
}
}
-
Using Remix: Set EVM version to
london
in the Advanced Configurations section of the Solidity Compiler tab: -
Using Hardhat or Foundry: Set EVM version to
london
in hardhat.config.ts or foundry.toml. -
Using Standard Solidity JSON: Set
evmVersion
tolondon
:{
"settings": {
"optimizer": {
/* ... */
},
"evmVersion": "london"
}
} -
Using
solc
CLI: Set--evm-version
tolondon
:solc --evm-version london <args>
Didn't understand the Solidity code?
-
Purpose: This contract interacts with the Flare Network to fetch feed values and compute a new quote feed value based on the base and quote feed values.
-
Dependencies:
ContractRegistry.sol
: Used to get the addresses of various contracts on the Flare network.TestFtsoV2Interface.sol
: This interface allows interaction with the FTSOv2 contract, which provides real-time price feeds for various assets.
-
State Variables:
ftsoV2
: This is a state variable of typeTestFtsoV2Interface
. It will hold the address of the FTSO V2 contract once initialized.
-
Constructor:
- The constructor is a special function that runs only once when the contract is deployed. It initializes the
ftsoV2
state variable by fetching the FTSO V2 contract address using theContractRegistry
.
- The constructor is a special function that runs only once when the contract is deployed. It initializes the
-
Internal Function
_scaleBaseFeedValue
:- Scales the base feed value to match the decimals of the quote feed.
- Adjusts the feed value by scaling up or down depending on the difference in decimals.
-
External Function
getNewQuoteFeedValue
:- Accepts an array of base and quote feed IDs.
- Fetches current feed values and decimals using
ftsoV2
. - Scales the base feed value to match the quote feed decimals.
- Computes and returns the new quote feed value by adjusting for the decimal differences and performing a calculation.
-
Key Validations:
- Ensures exactly two feed indexes are provided.
- Prevents division by zero during the computation of the new quote feed value.