Token Oracles
How the token oracles work
The asset prices that help determine the target balances, and the total and individual token values for the Index are obtained via a combination of Chainlink oracles and the GMX Reader contract. These contract calls happen inside getPrice()
on each token’s Oracle contract.
constructor
At deployment, the Oracle contract stores the token’s GMX market _symbol
, the GMX market address, the market's decimal adjustment used by GMX architecture, the feed address and heartbeat for the asset's Chainlink Price Feed, Chainlink's arbSequencerUptimeFeed
, Chainlink's usdcPriceFeed
, the gmxDataStore
, and the gmxReader
. Lastly, it sets msg.sender
as the owner (hereafter referred to as Admin).
Parameters:
_symbol
string
The symbol of the Oracle's GM asset
_gmxAssetMarket
address
The address of the GM market token
_assetPriceFeed
address
The address of the long asset's Chainlink price feed
_assetHeartbeat
uint256
The max time interval between updates of the long asset's Chainlink price feed
_decAdjustment
uint256
Decimal adjustment needed for GMX contract logic.
updateSequencerUptimeFeed
Updates/stores the Chainlink Arbitrum Sequencer Uptime Feed and the desired grace period that must pass after the Sequencer comes back online . Only the Admin can call this function. The Sequencer Uptime Feed address is typecast to the AggregatorV3Interface
type. Upon success, the call emits a SequencerFeedUpdated
event.
Parameters:
_sequencerUptimeFeed
address
The address for the Chainlink Arbitrum Sequencer Uptime Feed
_gracePeriod
uint256
After the Sequencer comes back online, this period must pass before the Oracle contract can return prices again.
updatePriceFeed
Updates/stores the price _feed
, _heartbeat
, and _decAdjust
for one asset of the GM token pair. If the boolean assetIsUSDC
is set to true, the function updates the USDC Price Feed, along with its heartbeat. Only the Admin can call this function. The Sequencer Uptime Feed address is typecast to the AggregatorV3Interface
type. Upon success, the call emits a PriceFeedUpdated
event.
Parameters:
_feed
address
The address of the Chainlink price feed
usdcFeedHeartbeat
uint256
The heartbeat of the Chainlink price feed
_decAdjust
uint256
The decimal adjustment needed for GMX contract logic interaction.
assetIsUSDC
boolean
If true, USDC variables will change. If false, the GM asset's variables will change.
getAssetInfo
Retrieves the Chainlink price feed address, feed heartbeat, and decimal adjustment for the asset or USDC.
Parameters:
_isUSDC
boolean
true, USDC variables will change. If false, the GM asset's variables will change.
Returns:
assetPriceFeed
address
The address of the Chainlink price feed
usdcFeedHeartbeat
uint256
The heartbeat of the Chainlink price feed
assetDecimalAdjust
uint256
The decimal adjustment needed for GMX contract logic interaction.
getPrice
Retrieves the current price of the GM token each specific oracle belongs to.
Before calculating the price, a series of checks must be passed. An internal function calls to the Chainlink Arbitrum Sequencer Uptime Feed to make sure the Sequencer is online. If not, the function call chain reverts.
The call chain proceeds to retrieve both the *asset's price and USDC's price from Chainlink. If either of the prices are stale (the time elapsed since the last price update is greater than the heartbeat interval of the feed), the call chain reverts.
After price decimal adjustments, the call chain retrieves marketProps
from the GMX reader
by calling the getMarket()
function. Finally, getMarketTokenPrice()
is called with marketProps
pricing, and other necessary variables as arguments to retrieve the token's current price. After a type conversion and another decimal conversion, the final price
is returned by the function.
For more info on getMarket()
and getMarketTokenPrice()
, please see the GMX documentation.
*If the asset is gmUSDC-USDT-SWAP, the call chain includes this _getUSDCUSDTPrice
.
price
uint256 (x2)
The price of the GM token, determined by the GMX reader
contract
_sequenceUptimeCheck
This function calls latestRoundData()
on the Sequencer Uptime Feed instance to retrieve the latest uptimeAnswer
and startedAt
. If uptimeAnswer
does not equal 0, the Arbitrum Sequencer is down, and the function call reverts. If uptimeAnswer
equals 0, then the Arb Sequencer is up. If the sequencer has just gone down, but was started back up, calls made within the sequencerGracePeriod
will revert. Once the sequencer has been up for longer than an hour, calls will function normally.
_getUSDCUSDTPrice
After the GMX market token balances of USDC and USDT are obtained, this internal function obtains their prices from Chainlink. The final gmUSDC-USDT-SWAP price is determined as follows:
where totalSupply
is the total supply of gmUSDC-USDT-SWAP market tokens.
Returns:
price
uint256 (x2)
The calculated price of the gmUSDC-USDT-SWAP token.
_getPriceFromChainlink
This internal function calls latestRoundData()
on the price feed instance to retrieve the latest answer
and updatedAt
time. If updatedAt
is less than block.timestamp - usdcFeedHeartbeat
, the returned price is considered "stale," and the function will revert.
If the Arbitrum Sequencer is up and the Price Feed price is not stale, the price is returned by the call chain.
Parameters:
_dataFeed
AggregatorV3Interface
The AggregatorV3Interface instance of the Chainlink price feed
_heartbeat
uint256
The max time interval between updates of the asset's Chainlink price feed
Returns:
answer
uint256
The Oracle-returned price of the token. (Returned decimals will vary.)
Last updated