Smart Contract Integrations
You can find the deployed contract addresses here: Contracts
The following actions are useful when directly interacting with the markets. To make life easier, Perennial has built an Operator contract called: MultiInvoker
which can be used to simplify/abstract much of this flow. See more about it here
Market Operations (Market.sol)
The following are common actions you might need to undertake to interact with an instance of a market contract.
Source code: here
Get a Market's Global Position
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 positionmaker
- 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 Payoff function
Call
global()
Returns:
pAccumulator
- The current PAccumulator statelatestPrice
- The latest valid price
Helpful calculations:
Funding Rate - using
pAccumulator
Interest Rate - using
long
,short
&maker
Get an Account's Market Position
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 positionmaker
- 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
* The value of the position denominated in units of the Payoff function
^ Only used for pending positions
Update Your Position (Make a Trade)
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 marketCall
update()
Arguments:
account
- The account to operate onnewMaker
- 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:
* This is the absolute value of the position denominated in units of the Payoff function.
^ Positive number to add collateral, negative to remove.
Calculating Available Liquidity:
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 positionmaker
- 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 Payoff function
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
Confirming Position Update
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 anupdated()
.Call
Market.versions(timestamp)
using the timestamp from the event.Returns a struct with the property
valid
. If the value istrue
then your update was successful.If the value is
false
, you can check to see if thetimestamp
from theUpdate()
event is after thetimestamp
returned in thelatest()
call in Market's Oracle. If this is the case, theupdate()
has failed and needs to be resubmitted.
Example Contract Integration: Vaults
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.
See the codebase here
Make sure to check out the Considerations section before building a direct integration!
Last updated