Chainlink Price Feed Guide

Oracle data for EVM dApps

How to read Chainlink price feeds, use data feeds in your contracts, and follow best practices. A concise technical reference for EVM developers.

Feed Registry

Find the right price feed address using the Chainlink Feed Registry or documentation. Each feed returns a quote currency (usually USD) per unit of the base asset.

// AggregatorV3Interface at feed address
address feed = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; // ETH/USD

Read Price

Use latestRoundData() to fetch the current price and round metadata.

function getPrice() external view returns (int) {
    AggregatorV3Interface feed = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);
    (, int price, , , ) = feed.latestRoundData();
    return price;
}

Price Validation

Check round completeness, staleness, and price > 0 before using the data.

function validatePrice() external view returns (uint) {
    (, int price, uint startedAt, uint updatedAt, uint answeredInRound) =
        feed.latestRoundData();
    require(price > 0, "negative price");
    require(answeredInRound >= roundId, "stale round");
    require(block.timestamp - updatedAt < 1 hours, "stale feed");
    return uint(price);
}

Multi-feed Aggregation

Compute a TWAP-like median across multiple feeds for resilience against manipulation.

function aggregatePrice(address[] memory feeds) external view returns (uint) {
    uint[] memory prices = new uint[](feeds.length);
    for (uint i; i < feeds.length; i++) {
        (, int p, , , ) = AggregatorV3Interface(feeds[i]).latestRoundData();
        prices[i] = uint(p);
    }
    return median(prices);
}

L2 Feeds

Arbitrum, Optimism, and Polygon use sequencer-enabled feeds. Check the sequencer uptime feed before reading prices.

function getL2Price() external view returns (uint) {
    (, int seq, , uint last, ) = sequencerUptime.latestRoundData();
    require(seq == 0, "sequencer down");
    require(last != 0, "no data");
    (, int price, , , ) = feed.latestRoundData();
    return uint(price);
}

Gas Considerations

Cache feed addresses, batch reads, and avoid unnecessary rounds in loops. Price feeds update every ~1 hour on mainnet.

// Cache feeds in constructor, not per-call
AggregatorV3Interface immutable ethUsd;
uint immutable heartbeat = 1 hours;
What you get PDF with 15+ feed integration patterns, validation logic, multi-feed strategies, and L2-specific guidance.
Payment Send exactly $1 in ETH or USDC (ERC-20) to:
0x0D42B32D6E21F496082104BFC8d7213081474577