# Migrating from v1

> Migration guide for dApps moving from FTSOv1 to FTSOv2.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.

Source: https://dev.flare.network/ftso/migration

This guide is for applications moving from FTSOv1 to FTSOv2. Briefly, FTSOv2 comprises of:

-   **[Block-Latency Feeds](/ftso/feeds)**: These feeds are updated with each new block, approximately every 1.8 seconds. They can be accessed through [FtsoV2Interface](/ftso/solidity-reference/FtsoV2Interface) and are available directly onchain.
-   **[Anchor Feeds](/ftso/scaling/anchor-feeds)**: These feeds are provided through [Scaling](/ftso/scaling/overview) with a latency of 90 seconds. Feeds can be verified using [FtsoV2Interface](/ftso/solidity-reference/FtsoV2Interface) but are not immediately available onchain.

A key difference between the two is the introduction of a payment mechanism for data access. This system helps prevent unnecessary data requests and ensures sustainable funding. For more details, refer to the [`IFeeCalculator`](/ftso/solidity-reference/IFeeCalculator) contract, which calculates fees for data access using the [`calculateFeeByIds`](/ftso/solidity-reference/IFeeCalculator#calculatefeebyids) method.

Additionally, a new Long Term Support (LTS) system has been launched to ensure continued access to essential data and metadata within the Flare ecosystem. A series of [LTS interfaces](#lts-interfaces) have been introduced, each aligned with a specific product in the Flare ecosystem. It is strongly recommended to use these LTS contracts for data access instead of querying individual contracts or interfaces, as they are designed for long-term stability, even as underlying protocols evolve or migrate.

## Deprecated contracts (v1)[​](#deprecated-contracts-v1 "Direct link to Deprecated contracts (v1)")

### PriceSubmitter[​](#pricesubmitter "Direct link to PriceSubmitter")

The `PriceSubmitter` contract (`IPriceSubmitter`) is being deprecated as part of the transition to the new version of the FTSO system.

If you were using `PriceSubmitter` for the following purposes, here are the recommended alternatives:

-   **Accessing other important contracts**: Use the [`FlareContractRegistry`](/network/solidity-reference/IFlareContractRegistry) instead.
    
-   **Voting-related functionalities**: These are now integrated into the new FTSO system.
    
-   **Random number generation** (`getCurrentRandom` or `getRandom`, applicable to Flare only): Switch to the new [`RandomNumberV2Interface`](#lts-interfaces). The new protocol updates random numbers every 90 seconds (aligned with the voting epoch duration, as returned by `votingEpochDurationSeconds`). This setting is immutable but could change if the protocol configuration is updated. In contrast, the old protocol updated random numbers every 180 seconds.
    

#### Required Changes:[​](#required-changes "Direct link to Required Changes:")

-   Use `RandomNumberV2` instead of `PriceSubmitter` (ensure you update to the new contract address and interface).
-   **Method updates**:
    -   `getCurrentRandom` → `getRandomNumber`
    -   `getRandom(epochId)` → `getRandomNumberHistorical(epochId)`

### FTSO[​](#ftso "Direct link to FTSO")

The legacy `FTSO` contract is being deprecated and replaced. A minimal proxy will be deployed at the same address to provide basic backward compatibility. The replacement will be [`FtsoProxy`](#ftsoproxy), which will respond to a limited subset of calls that the old `FTSO` contract handled. Although the addresses will change, the `FTSORegistry` will be updated to point to the new contract addresses.

#### Recommended Changes:[​](#recommended-changes "Direct link to Recommended Changes:")

-   **Random number retrieval**: Switch to the new [`RandomNumberV2Interface`](#lts-interfaces). The proxy contract will still return current and historical random numbers, but they will be uniform across all `FTSO` contracts, and randomness will be sourced from the new provider.
    
-   **Fetching the current price**: For methods like `getCurrentPrice`, `getCurrentPriceDetails`, or `getCurrentPriceWithDecimals`, switch to the [`FTSOv2Interface`](#lts-interfaces). While the proxy interface will continue to function temporarily, it will not receive future updates.
    
-   **Fetching historical prices**: For methods such as `getEpochPrice`, or retrieving prices for specific voters or trusted data providers, the proxy contract **WILL REVERT**. It is essential to migrate to the new `FTSOv2Interface` for these functionalities.
    

### FTSORegistry[​](#ftsoregistry "Direct link to FTSORegistry")

The `FTSORegistry` (`IFTSORegistry`) is being deprecated. While you can continue to use it temporarily with its backward-compatible methods, it is strongly recommended to transition to the new interfaces as soon as possible, as `FTSORegistry` will no longer be maintained in the future.

#### Recommended Changes:[​](#recommended-changes-1 "Direct link to Recommended Changes:")

-   **Getting FTSOs**: The methods `getFtso`, `getFtsoBySymbol`, `getFtsoIndex`, `getFtsoSymbol`, and `getSupportedIndices/Symbols/Ftsos` are now deprecated. They will still return the proxy implementation of FTSO, but these proxies will not be maintained moving forward. It is recommended to update your code to use the [FTSOv2Interface](#lts-interfaces) for price retrieval. Additional details like decimals and timestamps for individual FTSOs are now considered deprecated and can be obtained by querying prices directly through `FTSOv2`.
    
-   **Reading prices** using methods such as `getCurrentPrice(_ftso_index/_symbol)` or their array and decimal implementations is also deprecated. Although these methods will still return correct values, they will not be updated in the future. Use the [FTSOv2Interface](#lts-interfaces) instead to ensure future compatibility.
    
-   **Getting supported FTSOs**: This function will return correct results for legacy price pairs but will not be updated for new pairs introduced in the FTSOv2 system. To retrieve information about available pairs in the new system, you should transition to the [FTSOv2Interface](#lts-interfaces) interface.
    
-   **Read prices directly from `FtsoV2Interface`**: This will give you up-to-date prices and more detailed information. Additionally, the `FtsoV2Interface` is part of the Long Term Support (LTS) system, ensuring it will be maintained for an extended period.
    
-   **New system indexing and ID scheme**:
    
    -   The indexing and ID scheme has changed. Old indices are now invalid, so do not use the previous `getFeedByIndex` method with the old indices.
    -   IDs in the new system are 21-byte values, formatted as `"${OLD_FEED_NAME}/USD"` and zero-padded.
    -   Use the `getFeedById` method in the new interface to retrieve old prices with this format: `getFeedById(bytes21(bytes.concat(bytes1(1), bytes(string.concat(OLD_FEED_NAME, "/USD")))))`.

### FTSORewardManager[​](#ftsorewardmanager "Direct link to FTSORewardManager")

The reward system is undergoing significant changes. While an implementation of the old `FTSORewardManager` contract is provided, it will only support the most basic claim types and require pre-provided reward proofs.

#### Recommended Changes:[​](#recommended-changes-2 "Direct link to Recommended Changes:")

-   **Claiming rewards**: Switch to the new [`RewardsV2Interface`](#lts-interfaces). The proxy contract will still allow you to claim rewards from the FTSO system, but it will not support claiming fees for data providers.
    
-   **Claiming rewards when delegating by amount**: This feature is no longer supported in the new system.
    

## LTS interfaces[​](#lts-interfaces "Direct link to LTS interfaces")

The primary goal of the Long Term Support (LTS) interfaces is to offer a stable and reliable way to access essential data and metadata within the Flare ecosystem. These interfaces are designed for long-term maintenance, ensuring continuity even as underlying contracts evolve or protocols migrate to new versions. Each LTS interface is aligned with a specific product within the Flare ecosystem, providing consistency and ease of use over time.

**Interface**

**Contract registry name**

**Notes**

[ProtocolsV2Interface](/network/solidity-reference/ProtocolsV2Interface)

`ProtocolsV2`

Primary interface for managing protocol related metadata.

[RewardsV2Interface](/network/solidity-reference/RewardsV2Interface)

`RewardsV2`

Primary interface for managing all protocol rewards.

[RandomNumberV2Interface](/network/solidity-reference/RandomNumberV2Interface)

`RandomNumberV2`

Primary interface for random number generation.

[FtsoV2Interface](/ftso/solidity-reference/FtsoV2Interface)

`FtsoV2`

Primary interface for interacting with FTSOv2.

warning

-   **RandomNumberV2Interface:** In addition to providing random numbers, the new methods also return a `_isSecureRandom` flag. Learn more about this flag in the guide on [Secure Random Numbers](/network/guides/secure-random-numbers).
-   **FtsoV2Interface:** Provides access to fetching block-latency feeds onchain, and verifying anchor feeds onchain. You can retrieve feeds using the [`getFeedById`](/ftso/solidity-reference/FtsoV2Interface#getfeedbyid) or [`getFeedsById`](/ftso/solidity-reference/FtsoV2Interface#getfeedsbyid) methods. These methods are now payable, and while the current fee is set to `0`, it is advisable to use [`FeeCalculator`](/ftso/solidity-reference/IFeeCalculator) to calculate the fee and be prepared for potential future changes.

## Migration proxies[​](#migration-proxies "Direct link to Migration proxies")

For the time being, a set of proxy contracts is provided to allow access to the old data and reward systems.

Do not use for new developments

These proxies offer a temporary solution to ensure that previously deployed contracts can continue functioning until they are fully updated.

### FtsoProxy[​](#ftsoproxy "Direct link to FtsoProxy")

The `FtsoProxy` contract is designed to maintain backward compatibility with the old FTSO contract. While it will be deployed at different addresses from the original FTSO contract, the `FTSORegistry` will be updated to point to these new addresses.

<details>
<summary>Methods in FtsoProxy</summary>

Methods in `FtsoProxy`

FtsoProxy.sol

```
   /**     * Always return true, as the proxy is always active.     */    function active() external pure returns (bool) {        return true;    }    /**     * Will return the current epoch id correctly as defined by FSP     */    function getCurrentEpochId() external view returns (uint256) {    }    /**     * Will return the epoch id correctly as defined by FSP.     * Beware, the function will produce different results than the old FTSO contract.     */    function getEpochId(uint256 _timestamp) external view returns (uint256) {    }    /**     * Will return the current random correctly     */    function getRandom(uint256 _votingRoundId) external view returns (uint256 _randomNumber) {    }    /**     * @dev Deprecated - reverts     */    function getEpochPrice(uint256) external pure returns (uint256) {        revert("not supported");    }    /**     * Will return current price epoch data as defined by FSP     */    function getPriceEpochData() external view        returns (            uint256 _epochId,            uint256 _epochSubmitEndTime,            uint256 _epochRevealEndTime,            uint256 _votePowerBlock,            bool _fallbackMode        )    {    }    /**     * Will return the price epoch configuration as defined by FSP     */    function getPriceEpochConfiguration() external view        returns (            uint256 _firstEpochStartTs,            uint256 _submitPeriodSeconds,            uint256 _revealPeriodSeconds        )    {    }    /**     * @dev Deprecated - reverts     */    function getEpochPriceForVoter(uint256, address) external pure returns (uint256) {        revert("not supported");    }    /**     * Will return the current price correctly     */    function getCurrentPrice() external view returns (uint256, uint256) {    }    /**     * Will return the current price with decimals correctly     */    function getCurrentPriceWithDecimals()        external view        returns (            uint256 _value,            uint256 _timestamp,            uint256 _decimals        )    {    }    /**     * Will return the current price with details correctly     */    function getCurrentPriceDetails()        external view        returns (            uint256,            uint256,            PriceFinalizationType,            uint256,            PriceFinalizationType        )    {    }    /**     * @dev Deprecated - reverts     */    function getCurrentPriceFromTrustedProviders() external pure returns (uint256, uint256) {        revert("not supported");    }    /**     * @dev Deprecated - reverts     */    function getCurrentPriceWithDecimalsFromTrustedProviders() external pure returns (uint256, uint256, uint256) {        revert("not supported");    }    /**     * Will return the current random correctly     */    function getCurrentRandom() external view returns (uint256 _currentRandom) {    }
```

</details>

### FtsoRewardManagerProxy[​](#ftsorewardmanagerproxy "Direct link to FtsoRewardManagerProxy")

The `FtsoRewardManagerProxy` contract is designed to maintain backward compatibility with the old `FTSORewardManager` contract. It will be deployed at a different address than the original contract.

This proxy only supports the most basic reward claim types and requires that reward proofs be provided in advance.

<details>
<summary>Methods in FtsoRewardManagerProxy</summary>

Methods in `FtsoRewardManagerProxy`

FtsoRewardManagerProxy.sol

```
    /**     * @dev Claims rewards correctly for delegation fees, assuming the proofs were already provided.     */    function claimReward(        address payable _recipient,        uint256[] calldata _rewardEpochs    )        external        returns (uint256 _rewardAmount)    {    }    /**     * @dev Claims rewards correctly for delegation fees, assuming the proofs were already provided.     */    function claim(        address _rewardOwner,        address payable _recipient,        uint256 _rewardEpoch,        bool _wrap    )        external        returns (uint256 _rewardAmount)    {    }    /**     * @dev Returns the current fee percentage for the data provider.     */    function getDataProviderCurrentFeePercentage(address _dataProvider)        external view        returns (uint256 _feePercentageBIPS)    {    }    /**     * @dev Returns the fee percentage for the data provider for the given reward epoch.     */    function getDataProviderFeePercentage(        address _dataProvider,        uint256 _rewardEpoch    )        external view        returns (uint256 _feePercentageBIPS)    {    }    /**     * @dev Returns the fee percentage changes for the data provider.     */    function getDataProviderScheduledFeePercentageChanges(address _dataProvider) external view        returns (            uint256[] memory _feePercentageBIPS,            uint256[] memory _validFromEpoch,            bool[] memory _fixed        )    {    }    /**     * @dev Returns the epoch reward correctly     */    function getEpochReward(uint256 _rewardEpoch) external view        returns (uint256 _totalReward, uint256 _claimedReward)    {    }    /**     * @dev Returns the reward state correctly     */    function getStateOfRewards(        address _beneficiary,        uint256 _rewardEpoch    )        external view        returns (            address[] memory _dataProviders,            uint256[] memory _rewardAmounts,            bool[] memory _claimed,            bool _claimable        )    {    }    /**     * @dev Returns the epochs with claimable rewards correctly     */    function getEpochsWithClaimableRewards() external view        returns (uint256 _startEpochId, uint256 _endEpochId)    {    }    /**     * @dev Returns the next claimable reward epoch correctly     */    function nextClaimableRewardEpoch(address _rewardOwner) external view returns (uint256) {    }    /**     * @dev Returns the epochs with unclaimed rewards correctly     */    function getEpochsWithUnclaimedRewards(address _beneficiary) external view        returns (uint256[] memory _epochIds)    {    }    /**     * @dev Returns the claimed rewardr correctly     */    function getClaimedReward(        uint256 _rewardEpoch,        address _dataProvider,        address _claimer    )        external view        returns (            bool _claimed,            uint256 _amount        )    {    }    /**     * @dev Returns the reward epoch to expire next correctly     */    function getRewardEpochToExpireNext() external view returns (uint256) {    }    /**     * @dev Returns the reward epoch vote power block correctly     */    function getRewardEpochVotePowerBlock(uint256 _rewardEpoch) external view returns (uint256) {    }    /**     * @inheritdoc IFtsoRewardManager     */    function getCurrentRewardEpoch() external view returns (uint256) {        return rewardManager.getCurrentRewardEpochId();    }    /**     * @inheritdoc IFtsoRewardManager     */    function getInitialRewardEpoch() external view returns (uint256 _initialRewardEpoch) {        return rewardManager.getInitialRewardEpochId();    }    /**     * @inheritdoc IFtsoRewardManager     * @dev Deprecated     */    function claimRewardFromDataProviders(        address payable,        uint256[] calldata,        address[] calldata    )        external pure returns (uint256)    {        // return 0    }    /**     * @inheritdoc IFtsoRewardManager     * @dev Deprecated     */    function claimFromDataProviders(        address,        address payable,        uint256[] calldata,        address[] calldata,        bool    )        external pure returns (uint256)    {        // return 0    }    /**     * @inheritdoc IFtsoRewardManager     * @dev Deprecated - reverts     */    function autoClaim(address[] calldata, uint256) external pure {        revert("not supported, use RewardManager");    }    /**     * @inheritdoc IFtsoRewardManager     * @dev Deprecated - reverts     */    function setDataProviderFeePercentage(uint256)        external pure        returns (uint256)    {        revert("not supported, use WNatDelegationFee");    }    /**     * @dev Deprecated - returns empty array, empty array, false     */    function getStateOfRewardsFromDataProviders(        address,        uint256,        address[] calldata    )        external pure        returns (            uint256[] memory,            bool[] memory,            bool        )    {    }    /**     * Deprecated - returns 0, 0     */    function getDataProviderPerformanceInfo(        uint256,        address    )        external pure        returns (            uint256,            uint256        )    {    }
```

</details>

## Usable existing interfaces[​](#usable-existing-interfaces "Direct link to Usable existing interfaces")

**Interface**

**Description**

[`FlareContractRegistry`](/network/solidity-reference/IFlareContractRegistry)

Provides access to the addresses of all essential contracts within the Flare ecosystem. It is deployed at a fixed address across all networks, with updates to addresses managed through governance. This registry is the recommended entry point for contract interactions on all Flare networks. For easier use, consider utilizing the `ContractLibrary` from the [flare-periphery-contracts](https://www.npmjs.com/package/@flarenetwork/flare-periphery-contracts?activeTab=readme) package, which wraps the IFlareContractRegistry and simplifies interactions with Flare's smart contracts.

[`FeeCalculator`](/ftso/solidity-reference/IFeeCalculator)

Onchain prices are now subject to potential fees, though initial fees are set to `0`. The `FeeCalculator` contract is designed to be flexible, allowing for the introduction of fees in future use cases. It calculates fees for accessing data using the `calculateFeeByIds` and `calculateFeeByIndices` methods. To stay prepared for future updates to the fee structure, it is advisable to use the FeeCalculator contract in relevant applications.

## Example migration contract[​](#example-migration-contract "Direct link to Example migration contract")

FtsoV2MigrationExample.sol

```
// SPDX-License-Identifier: MITpragma solidity >=0.7.6 <0.9.0;import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";import {TestFtsoV2Interface} from "@flarenetwork/flare-periphery-contracts/coston2/TestFtsoV2Interface.sol";contract FtsoV2FeedConsumer {    TestFtsoV2Interface internal ftsoV2;    /**     * @dev Converts a feed name to a bytes21 ID with a fixed category (1) and USD quote.     * @param _name The name of the feed, e.g. FLR.     * @return A bytes21 ID representing the feed with USD quote.     */    function convertToFeedId(        string memory _name    ) internal pure returns (bytes21) {        return            bytes21(                bytes.concat(                    bytes1(uint8(1)), // Category 1 for crypto feeds                    bytes(string.concat(_name, "/USD")) // Append "/USD" to the feed name                )            );    }    /**     * @dev Fetches the current feed values, decimals, and timestamp from FtsoV2 for the specified feeds.     * @param _feedNames An array of feed names.     * @return _feedValues The current values of the specified feeds.     * @return _decimals The number of decimals for each feed.     * @return _timestamp The timestamp of the latest update for the feeds.     */    function getFtsoV2CurrentFeedValues(        string[] memory _feedNames    )        external        payable        returns (            uint256[] memory _feedValues,            int8[] memory _decimals,            uint64 _timestamp        )    {        bytes21[] memory feedIds = new bytes21[](_feedNames.length);        // Preprocess feed names to feed IDs        for (uint256 i = 0; i < _feedNames.length; i++) {            feedIds[i] = convertToFeedId(_feedNames[i]);        }        /* THIS IS A TEST METHOD, in production use: ftsoV2 = ContractRegistry.getFtsoV2(); */        ftsoV2 = ContractRegistry.getTestFtsoV2();        // Fetch feed data from the FtsoV2 contract        (            uint256[] memory feedValues,            int8[] memory decimals,            uint64 timestamp        ) = ftsoV2.getFeedsById(feedIds);        return (feedValues, decimals, timestamp);    }    /**     * @dev Fetches the current feed values in Wei (adjusted for decimals) and timestamp from FtsoV2 for the specified feeds.     * @param _feedNames An array of feed names.     * @return _feedValues The current values in Wei.     * @return _timestamp The timestamp of the latest update for the feeds.     */    function getFtsoV2CurrentFeedValuesInWei(        string[] memory _feedNames    )        external        payable        returns (uint256[] memory _feedValues, uint64 _timestamp)    {        bytes21[] memory feedIds = new bytes21[](_feedNames.length);        // Preprocess feed names to feed IDs        for (uint256 i = 0; i < _feedNames.length; i++) {            feedIds[i] = convertToFeedId(_feedNames[i]);        }        /* THIS IS A TEST METHOD, in production use: ftsoV2 = ContractRegistry.getFtsoV2(); */        ftsoV2 = ContractRegistry.getTestFtsoV2();        // Fetch feed values in Wei and timestamp from FtsoV2 contract        (uint256[] memory feedValues, uint64 timestamp) = ftsoV2            .getFeedsByIdInWei(feedIds);        return (feedValues, timestamp);    }}
```
