Oracle Maker
Liquidity provision is whitelisted until initial beta testing has completed.
Overview
Oracle maker uses price feeds from Pyth and may employ feeds from Chainlink and other providers as they become available/needed.
Each market backed by an oracle maker has a discrete liquidity pool.
Market orders with oracle pools are fill-or-kill, ie. no partial fills unless this logic is handled at a higher layer in the stack (e.g. by the Order Gateway for limit orders filled by oracle maker pools).
All orders sent to an oracle maker pool must include a delay for front running protection - this can be handled by the order gateway.
Filling taker orders
Order filled event
Deposit liquidity
Deposits are managed via the Vault contract. Only collateral supported by the vault can be used by makers (LPs).
Withdraw liquidity
LP holds a share of the global Maker account value, and can withdraw according to the value of their share.
Example:
Maker account value = 100 USDC
accountValue = margin + positionSize * price + openNotional
price = abs(fillOrder(positionSize) / positionSize)
LP withdraw 10% of liquidity
withdraw(share)
sharePrice = accountValue / totalSupply()
LP gets 10 USDC (
share * sharePrice
)
Pricing
Quote Token
At launch, all prices are in USD
Dynamic Premium (spread calculation)
A spread is added to trades to offset makers' risk exposure. Risk exposure potentially includes:
Long/short skew
Entry price
Funding (however, impacts should be minimal because the maker aims to have zero positions over a long period of time)
Risk mitigation:
Minimize inventory risk (e.g. target position size = 0)
One-sided circuit breaker when maximum risk exposure is reached (stop taking more long or short, but accept trades that reduce exposure)
Dynamic premium is modeled on a simplified Avellaneda-Stoikov model.
Givens
midPrice = oraclePrice
: Traditionally in a CLOB,midPrice
is the midpoint of max bid & min ask; inPythOracleMaker
we letoraclePrice
assume this role because you can think of it as the center of bid & ask when spread = 0.reservationPrice
: Risk-adjusted price for market making. It is a function ofmidPrice
(oraclePrice
), the maker’s risk exposure, and the configurables below. The premium is the difference betweenreservationPrice
andmidPrice
reservationPrice = midPrice * (1 - maxSpread * makerPosition / maxAbsPosition)
bid = min(midPrice, reservationPrice)
ask = max(midPrice, reservationPrice)
Configurables
maxSpread
: Sensitivity of the maker’s price premium to its risk exposure. This is modeled as the maximum price difference allowed betweenmidPrice
andreservationPrice
. The largermaxSpread
is, the faster the maker increases the premium in response to higher risk exposure.maxAbsPosition
: Position size cap where the maker would stop taking more positions. We also use it to calculatereservationPrice
. The max position is a safety threshold and should be configured so that it is not reached too often, because once it is reached, the maker would stop providing liquidity on one side.
Contracts
See Order Gatewayfor more details about interacting with oracle maker pools.
OracleMaker.sol
Event
Public functions (write)
Public functions (read)
Numeric Representation
Pyth uses fixed-point numeric representation.
PythOracleMaker
will translate Pyth price into its own native numeric representation:wei
Assumes
oraclePrice >= 0
Run-time Dependencies
Last updated