Smart Contract Integrations
Last updated
Last updated
The following actions are useful when directly interacting with the markets. To make life easier, Perennial has built an contract called: MultiInvoker
which can be used to simplify/abstract much of this flow. See more about it
The following are common actions you might need to undertake to interact with an instance of a market contract.
Source code:
When interacting with a given market its useful to know the overall state. In order to find this you should call two functions: position()
& global()
. With these you can calculate things like open interest, skew, funding rate, interest rate etc.
Call position()
Returns
timestamp
- The timestamp of the position
maker
- The maker position size*
long
- The long position size*
short
- The short position size*
Notes
* - This is the aggregate value of all positions denominated in units of the function
Call global()
Returns:
pAccumulator
- The current PAccumulator state
latestPrice
- The latest valid price
Helpful calculations:
In order to read a particular account's position you can use the positions()
function. This returns a similar object to the global position()
call.
Call positions(address)
Returns
timestamp
- The timestamp of the position
maker
- The maker position size*
long
- The long position size*
short
- The short position size*
fee
- The fee for the position^
keeper
- The fixed settlement fee for the position^
collateral
- The collateral at the time of the position settlement^
delta
- The change in collateral during this position^
Notes
^ Only used for pending positions
In each Market, there is an update()
function which a user calls to modify their position. You can go long, short, make a market, deposit or withdraw collateral using this command.
Approve()
DSU (collateral) on specific market
Call update()
Arguments:
account
- The account to operate on
newMaker
- The new maker position for the account*
newLong
- The new long position for the account*
newShort
- The new short position for the account*
collateral
- The collateral amount to add or remove from the account^
protect
- Whether to put the account into a protected status for liquidations
Notes:
^ Positive number to add collateral, negative to remove.
When opening/closing a position the market is bound by available liquidity being provided by the Makers. In order to calculate this you can do the following:
Call position()
Returns
timestamp
- The timestamp of the position
maker
- The maker position size*
long
- The long position size*
short
- The short position size*
Notes
Calculate Liquidity in USD
\begin{align*} liqMajor &= maker + \min(long, short) - \max(long, short) \\ liqMinor &= liqMajor + maker \end{align*}
Note: availableMajor equal whichever side has more open interest
Call global()
Returns:
latestPrice
- The latest valid price
Calculate Liquidity in units of Payoff
Due to the delayed settlement flow of Perennial, while position updates are very likely to be settled there are rare cases where settlement might not occur. To check your position has been updated you can do the following:
Updated(account, context.currentTimestamp, ...)
is emitted when you submit an updated()
.
Call Market.versions(timestamp)
using the timestamp from the event.
Returns a struct with the property valid
. If the value is true
then your update was successful.
If the value is false
, you can check to see if the timestamp
from the Update()
event is after the timestamp
returned in the latest()
call in Market's Oracle. If this is the case, the update()
has failed and needs to be resubmitted.
The multi-market maker vault that is featured on the Perennial UI is a great example of a contract integration into the Perennial market contracts.
The vault is a standalone contract that acts as a normal user on configured markets. Whenever a user deposits into/withdraws from the vault contract it update the maker positions across the markets.
- using pAccumulator
- using long
, short
& maker
* The value of the position denominated in units of the function
* This is the absolute value of the position denominated in units of the function.
* - This is the aggregate value of all positions denominated in units of the function
See the codebase
Make sure to check out the section before building a direct integration!