NFT Price Oracle

ParaSpace requires NFT prices from an off chain Oracle. Currently we are using a customized Oracle implementation that consists of an off-chain client and an on-chain contract.

On-Chain (Contract)

The ParaSpace money market can make use of prices by interacting with the following contracts
Name
Network
Address
NFTFloorOracle.sol
Mainnet
0x46573cb878208d82232e25c90671C9134030c167
NFTFloorOracle.sol
Goerli
0x1B47866866E3C9CE868c2F52861e77e07fA2FdE0
Simple Contract Interface
interface NFTOracle {
/// @param token The nft contract
/// @return twap The most recent twap on chain
function getTwap(address token) view external returns(uint128 twap)
/// @param token The nft contract
/// @return timestamp The timestamp of the last update for an asset
function getLastUpdateTime(address token) view external returns(uint128 timestamp)
}

Off-Chain (Client)

The off chain client collects NFT prices from various marketplaces to get a "Floor Price" this price is the lowest ask price that a NFT holder is willing to sell their asset.
The off-chain client collects these prices and uses them in the "pricing algorithm".
After the most recent values have been calculated we "conditionally write" the updates on chain.
A simplified visualization of the data can be seen below

Pricing Algorithm

ParaSpace uses a primary pricing metric to help stabilize the prices we report.
  1. 1.
    Time Weighted Average Price (TWAP)
Time Weighted Average Price
TWAP=at2at1t2t1TWAP = \frac{a_{t2} - a_{t1}}{t_{2}-t_{1}}
Where a_t is the cumulative price at time t, and t_2 is the time at time 2. Currently we are using a time frame of 1440 minutes (24 hours) to calculate TWAP. The rational for this value can be seen on the research page

Conditional Write

In order to be responsive and optimize gas, we want to minimize the number of on chain updates possible. Therefore we only update the on chain prices conditionally, when at least one of the following statements are true:
  1. 1.
    New price timestamp must be later than the value on-chain
  2. 2.
    The last update was greater than or equal to 8 hours ago (EXPIRATION_PERIOD)
  3. 3.
    The current values deviate greater than 3% from the values stored on chain

Price Expiration

If EXPIRATION_PERIOD is reached for a price, any operation of the lending protocol such as borrowing or liquidating won't be allowed until a new valid price is fed.

Access Control

Currently our Oracle is controlled uses Role based access control to control the accounts that can make updates to the prices on chain. This role is only granted to a small set of highly secured accounts.
Resources