visit
With developers in mind, dAPIs have been designed with a simple integration process that abstracts away the technical implementation of accessing data feeds. The API3 Market provides the ability to manage these data feeds while giving users access to a range of first-party data feeds. In the future, additional data feed services, such as capturing Oracle Extracted Value (OEV) will be accessible once a dAPI has been integrated.
pragma solidity ^0.8.17;
import "//github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/interfaces/LinkTokenInterface.sol";
import "//github.com/smartcontractkit/chainlink/blob/master/evm-contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
contract chainlinkOptions {
//Pricefeed interfaces
AggregatorV3Interface internal ethFeed;
AggregatorV3Interface internal linkFeed;
//Interface for LINK token functions
LinkTokenInterface internal LINK;
uint ethPrice;
uint linkPrice;
//Precomputing hash of strings
bytes32 ethHash = keccak256(abi.encodePacked("ETH"));
bytes32 linkHash = keccak256(abi.encodePacked("LINK"));
address payable contractAddr;
//Options stored in arrays of structs
struct option {
uint strike; //Price in USD (18 decimal places) option allows buyer to purchase tokens at
uint premium; //Fee in contract token that option writer charges
uint expiry; //Unix timestamp of expiration time
uint amount; //Amount of tokens the option contract is for
bool exercised; //Has option been exercised
bool canceled; //Has option been canceled
uint id; //Unique ID of option, also array index
uint latestCost; //Helper to show last updated cost to exercise
address payable writer; //Issuer of option
address payable buyer; //Buyer of option
}
option[] public ethOpts;
option[] public linkOpts;
//Kovan feeds: //docs.chain.link/docs/reference-contracts
constructor() public {
//ETH/USD Kovan feed
ethFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
//LINK/USD Kovan feed
linkFeed = AggregatorV3Interface(0x396c5E36DD0a0F5a5D33dae44368D4193f69a1F0);
//LINK token address on Kovan
LINK = LinkTokenInterface(0xa36085F69e2889c224210F603D836748e7dC0088);
contractAddr = payable(address(this));
}
//Returns the latest ETH price
function getEthPrice() public view returns (uint) {
(
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) = ethFeed.latestRoundData();
// If the round is not complete yet, timestamp is 0
require(timeStamp > 0, "Round not complete");
//Price should never be negative thus cast int to unit is ok
//Price is 8 decimal places and will require 1e10 correction later to 18 places
return uint(price);
}
//Returns the latest LINK price
function getLinkPrice() public view returns (uint) {
(
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) = linkFeed.latestRoundData();
// If the round is not complete yet, timestamp is 0
require(timeStamp > 0, "Round not complete");
//Price should never be negative thus cast int to unit is ok
//Price is 8 decimal places and will require 1e10 correction later to 18 places
return uint(price);
}
//Updates prices to latest
function updatePrices() internal {
ethPrice = getEthPrice();
linkPrice = getLinkPrice();
}
-----------------------
-----------------------
}
The contract initializes the AggregatorV3Interfaces via the constructor for both the Eth and Link datafeeds; these can later be used to fetch the price. The two functions getEthPrice()
and getLinkPrice()
use the AggregatorV3Interface to fetch the price and return it. The options
struct defines how options are stored when they are created, along with the ethOpts
and linkOpts
array to store the created options.
getEthPrice()
and the getLinkPrice()
logic with a .read()
function call to the proxy interface
pragma solidity ^0.8.17;
import "@api3/contracts/v0.8/interfaces/IProxy.sol";
contract Api3Options {
//Pricefeed proxies
address public ethProxy;
address public linkProxy;
uint ethPrice;
uint linkPrice;
//Precomputing hash of strings
bytes32 ethHash = keccak256(abi.encodePacked("ETH"));
bytes32 linkHash = keccak256(abi.encodePacked("LINK"));
address payable contractAddr;
//Options stored in arrays of structs
struct option {
uint strike; //Price in USD (18 decimal places) option allows buyer to purchase tokens at
uint premium; //Fee in contract token that option writer charges
uint expiry; //Unix timestamp of expiration time
uint amount; //Amount of tokens the option contract is for
bool exercised; //Has option been exercised
bool canceled; //Has option been canceled
uint id; //Unique ID of option, also array index
uint latestCost; //Helper to show last updated cost to exercise
address payable writer; //Issuer of option
address payable buyer; //Buyer of option
}
option[] public ethOpts;
option[] public linkOpts;
//Kovan feeds: //docs.chain.link/docs/reference-contracts
constructor(address _ethProxy, address _linkProxy) public {
//ETH/USD Proxy on Goerli
ethProxy = _ethProxy
//LINK/USD Proxy on Goerli
linkProxy = _linkProxy
contractAddr = payable(address(this));
}
//Returns the latest ETH price
function getEthPrice() public view returns (uint) {
(int224 value,uint32 timestamp) = IProxy(ethProxy).read();
// if the data feed is being updated with a one day-heartbeat
// interval, you may want to check for that.
require(
timestamp + 1 days > block.timestamp,
"Timestamp older than one day"
);
//Price should never be negative thus cast int to unit is ok
//Price is 18 decimal places
return uint(uint224(value));
}
//Returns the latest LINK price
function getLinkPrice() public view returns (uint) {
(int224 value,uint32 timestamp) = IProxy(linkProxy).read();
// if the data feed is being updated with a one day-heartbeat
// interval, you may want to check for that.
require(
timestamp + 1 days > block.timestamp,
"Timestamp older than one day"
);
//Price should never be negative thus cast int to unit is ok
//Price is 18 decimal places
return uint(uint224(value));
}
//Updates prices to latest
function updatePrices() internal {
ethPrice = getEthPrice();
linkPrice = getLinkPrice();
}
-----------------------
-----------------------
}
As you can see, we only needed to call .read()
on the IProxy(ethProxy)
interface to start reading from the datafeed. We ended up with lesser lines of code and a much simpler reading interface. You can try running the contract yourself on . (Note: The remix version only allows you to open and close options in ETH for simplicity).