This repository contains contracts for first-party price feeds for EVM chains, using OpenZeppelin for access control. Those with a validator role can post numeric data to deployed contracts at any interval. Individual price feeds are compatible with Chainlink's V2 and V3 aggregator interface, and a factory contract is provided that is EIP-2362 compatible.
If you are a smart contract developer looking to utilize Flux price feeds, check out the live pairs on the documentation and copy the interface file contracts/interface/CLV2V3Interface.sol
to use within your project so your contracts know how to query a price feed contract. If you are interested in becoming a first-party data provider, deploy a price feed factory or individual price feed using the instructions in this repository and post data to it using the fpo-node.
Before running any command, you need to create a .env
file and set a BIP-39 compatible mnemonic as an environment
variable. Follow the example in .env.example
. If you don't already have a mnemonic, use this website to generate one.
Then, proceed with installing dependencies:
yarn install
Next, compile the smart contracts with Hardhat:
$ yarn compile
The price feed factory is deployed once and automatically handles the creation of individual price feeds and submitting values to them. It is recommended to deploy a factory contract for use with the fpo-node so that only one contract needs to be deployed rather than for each individual price feed.
The factory contract is ERC-2362 compatible while the price feed contracts it generates are compatible with Chainlink's V2 and V3 aggregator interface.
Deploy a price feed factory (e.g. to Aurora):
$ npx hardhat deploy:FluxPriceFeedFactory --network aurora
Save the deployed contract address outputted by the command above.
Optionally include --validator "0xMyAddress"
to grant a specific address the initial validator role rather than the deployer.
Using the mnemonic of the validator in the .env
file, update multiple values on a deployed contract:
$ npx hardhat multiPriceFeedTransmit --contract 0xMyFactory --pricepairs "Price-ETH/USD-3 Price-BTC/USD-3" --answers "3000 37000" --network aurora
The format for the name of a price pair is "Price-pair_name
-decimals
".
$ npx hardhat multiPriceFeedValueFor --contract 0xMyFactory --pricepair "Price-ETH/USD-3" --network aurora
Additionally by using the contract address of an individual price feed generated by the factory (one may find this address by checking the factory's event logs after transmitting an answer for a new pair), one may query an individual price feed with the latestAnswer
task described in the section below.
Deploy an individual price feed contract (e.g. to Aurora):
$ yarn deploy --decimals 8 --description "ETH / USD" --network aurora
Save the deployed contract address outputted by the command above.
Optionally include --validator "0xMyAddress"
to grant a specific address the initial validator role rather than the deployer.
Note: We deployed a price feed contract on Aurora at address 0x8BAac7F07c86895cd017C8a2c7d3C72cF9f1051F
with all role-based permissions removed. Feel free to try posting and fetching data on this contract without deploying your own!
Using the mnemonic of the validator in the .env
file, update the value on a deployed contract:
$ yarn transmit --contract "0xContractAddress" --answer 4200000000 --network aurora
$ yarn latestAnswer --contract "0xContractAddress" --network aurora
4200000000
FeedsRegistry.sol
mimicks the Chainlink Feed Registry interface to query the latest value from price feeds by only providing a pair of asset and denomination addresses, without needing to know each feed’s contract address.
Deploy a feed registry (e.g. to Aurora):
$ yarn deployFeedsRegistry --network aurora
Save the deployed contract address outputted by the command above.
Optionally include --admin "0xMyAddress"
to grant a specific address the initial validator role rather than the deployer.
The price aggregator contract pulls from multiple first-party price feeds to return an averaged price. A minimum delay time is set, and anyone is allowed to update the latest price on the aggregator by calling updatePrices()
. Similar to the first-party feed, the latest price is fetched using latestAnswer()
.
Deploy an aggregator contract (e.g. to Aurora):
$ yarn deployAggregator --oracles 0x201FA7D0838726f16e93fED5E456d50B93CA79b0,0x19f622DFCb93a52e06e45202534EDf6f81A71063,0x77Aa1441D9BBf2102824CD73e6C3E4a765161b82 --decimals 8 --description "ETH / USD" --network aurora
Save the deployed contract address outputted by the command above.
Separate oracles with a single comma. Optionally include --admin "0xMyAddress"
to grant a specific address the initial validator role rather than the deployer.
To loop through all oracles and average their price on the aggregator contract:
$ yarn updatePrices --contract "0xContractAddress" --network aurora
4200000000
$ yarn latestAnswer --contract "0xContractAddress" --network aurora
4200000000
Compile the smart contracts and generate TypeChain artifacts:
$ yarn typechain
Lint the Solidity code:
$ yarn lint:sol
Lint the TypeScript code:
$ yarn lint:ts
Run the Mocha tests:
$ yarn test
Generate the code coverage report:
$ yarn coverage
See the gas usage per unit test and average gas per method call:
$ REPORT_GAS=true yarn test
Delete the smart contract artifacts, the coverage reports and the Hardhat cache:
$ yarn clean
If you use VSCode, you can enjoy syntax highlighting for your Solidity code via the vscode-solidity extension. The recommended approach to set the compiler version is to add the following fields to your VSCode user settings:
{
"solidity.compileUsingRemoteVersion": "v0.8.4+commit.c7e474f2",
"solidity.defaultCompiler": "remote"
}
Where of course v0.8.4+commit.c7e474f2
can be replaced with any other version.