> For the complete documentation index, see [llms.txt](https://docs.bouncebit.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bouncebit.io/infrastructure/oracle/onchain-price-feed.md).

# Onchain Price Feed

Bracle Price feeds continuously stream price updates to blockchains, with each feed stored within a smart contract. Application developers can easily pass these contracts on their own, then deserialize the data to read the current feed value. Bracle Price Feeds also offer a "pull" model for price updates, where users are responsible for posting updates to the chain as needed. For more information on this model and its implications for integrators, refer to [Bracles documentation](https://docs.bracle.network/price-feeds/pull-model). In the pull model, developers should integrate Bracle into both their onchain and offchain code:

* Onchain programs should read prices from the Bracle program deployed on the same chain.

Bracle provides BounceBit-specific SDK to assist with the integration process, both onchain and off-chain. The simplest way to utilize Bracle price feeds is to integrate the relevant SDKs into your application."

### Reading data feeds onchain <a href="#reading-data-feeds-on-chain" id="reading-data-feeds-on-chain"></a>

To consume price data, your smart contract should reference `IAggregator.sol`, which defines the external functions implemented by Data Feeds.

`IAggregator.sol`

```solidity
// SPDX-License-Identifier: LGPL-3.0
pragma solidity 0.8.20;

interface IAggregator {
  /**
   * @notice median from the most recent report
   */
  function latestAnswer() external view returns (int256);

  /**
   * @notice timestamp of block in which last report was transmitted
   */
  function latestTimestamp() external view returns (uint256);

  /**
   * @notice Aggregator round (NOT OCR round) in which last report was transmitted
   */
  function latestRound() external view returns (uint256);

  /**
   * @notice median of report from given aggregator round (NOT OCR round)
   * @param _roundId the aggregator round of the target report
   */
  function getAnswer(uint256 _roundId) external view returns (int256);

  /**
   * @notice timestamp of block in which report from given aggregator round was transmitted
   * @param _roundId aggregator round (NOT OCR round) of target report
   */
  function getTimestamp(uint256 _roundId) external view returns (uint256);

  /**
   * @return answers are stored in fixed-point format, with this many digits of precision
   */
  function decimals() external view returns (uint8);

  /**
   * @notice human-readable description of observable this contract is reporting on
   */
  function description() external view returns (string memory);

  /**
   * @notice aggregator contract version
   */
  function version() external view returns (uint256);

  /**
   * @notice details for the given aggregator round
   * @param _roundId target aggregator round (NOT OCR round). Must fit in uint32
   * @return roundId _roundId
   * @return answer median of report from given _roundId
   * @return startedAt timestamp of block in which report from given _roundId was transmitted
   * @return updatedAt timestamp of block in which report from given _roundId was transmitted
   * @return answeredInRound _roundId
   */
  function getRoundData(
    uint80 _roundId
  ) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);

  /**
   * @notice aggregator details for the most recently transmitted report
   * @return roundId aggregator round of latest report (NOT OCR round)
   * @return answer median of latest report
   * @return startedAt timestamp of block containing latest report
   * @return updatedAt timestamp of block containing latest report
   * @return answeredInRound aggregator round of latest report
   */
  function latestRoundData()
    external
    view
    returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}
```

#### Example <a href="#example" id="example"></a>

```solidity
// SPDX-License-Identifier: LGPL-3.0
pragma solidity 0.8.20;

import {IAggregator} from "../interfaces/IAggregator.sol";

/**
 * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED
 * VALUES FOR CLARITY.
 * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
 * DO NOT USE THIS CODE IN PRODUCTION.
 */
contract DataConsumer {
    IAggregator internal dataFeed;

    /**
     * Network: BounceBit
     * Aggregator: BBTC/USD
     * Address: 0xf136f4Af2F431034C8803C4c892609292D915A46
     */
    constructor() {
        dataFeed = IAggregator(
            0xf136f4Af2F431034C8803C4c892609292D915A46
        );
    }

    /**
     * Returns the latest answer.
     */
    function getBracleDataFeedLatestAnswer() public view returns (int) {
        // prettier-ignore
        (
            /* uint80 roundID */,
            int answer,
            /*uint startedAt*/,
            /*uint timeStamp*/,
            /*uint80 answeredInRound*/
        ) = dataFeed.latestRoundData();
        return answer;
    }
}
```
