The Chainlink Feed Registry is an on-chain mapping of assets to feeds. It enables you to query Chainlink price feeds from a pair of asset and denomination addresses directly, without needing to know the feed contract addresses. They enable smart contracts to retrieve the latest price of an asset in a single call, from a single contract.
DeFi protocols that use Chainlink often implement their own on-chain registry of token addresses to Chainlink feeds. To speed up integration and ensure that protocols use the correct feeds, the Feed Registry provides a canonical on-chain registry of assets to feeds.
The Feed Registry consists of the following contracts:
FeedRegistryis an on-chain mapping of(address base, address quote)pairs to Chainlink aggregator contracts.PairReadAccessControlleris an access controller contract to allowlist specific contracts from reading the feed registry.Denominationsis an external library contract containing base and quote identifiers for assets that do not have a canonical Ethereum address.
The FeedRegistry implements a similar interface as the AggregatorProxy contract, except it takes in two additional inputs: base and quote.
interface FeedRegistryInterface {
function latestAnswer(
address base,
address quote
)
external
view
returns (
int256 answer
);
... other getters
}The address type is used for base and quote after gathering feedback from multiple users. These base and quote address represent a specific pair. For example, to query the LINK / USD feed, you call:
latestAnswer(address base, address quote)by supplying an base and quote parameter, with the LINK token address and the Denominations.USD address respectively.
The FeedRegistry contract has the following setters to add / update / remove feeds to / from the registry:
proposeFeed()confirmFeed()
These functions follow the same 2-step design that exists in other Chainlink contracts, such as AggregatorProxy and ConfirmedOwner.
A set of round helper functions help to simplify the process of querying historical round data, by surfacing more round information previously not captured in AggregatorProxy Phases:
getRoundFeed()returns the underlying aggregator for a specific roundgetPhaseRange()returns the starting and ending round ids of a phasegetPreviousRoundId()andgetNextRoundId()provides hypermedia-like links to query previous and next rounds even across multiple phases.
$ yarn installCreate a .env following the .env.example:
INFURA_API_KEY=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
MNEMONIC=here is where your twelve words mnemonic should be put my friend
Compile the smart contracts with Hardhat:
$ yarn compileCompile the smart contracts and generate TypeChain artifacts:
$ yarn typechainLint the Solidity code:
$ yarn lint:solLint the TypeScript code:
$ yarn lint:tsRun the Mocha tests:
$ yarn testTo run a single test:
$ yarn test test/FeedRegistry.test.tsGenerate the code coverage report:
$ yarn coverageDelete the smart contract artifacts, the coverage reports and the Hardhat cache:
$ yarn clean- Hardhat: compile and run the smart contracts on a local development network
- TypeChain: generate TypeScript types for smart contracts
- Ethers: renowned Ethereum library and wallet implementation
- Waffle: tooling for writing comprehensive smart contract tests
- Solhint: linter
- Solcover code coverage
- Prettier Plugin Solidity: code formatter