PerpV2LeverageModule
The PerpV2LeverageModule enables leveraged trading using the PerpV2 Protocol. It allows a SetToken to manage a Perp account as a positive equity external position that has value equal to the net Perp account denominated in USDC. The Perp account can manage multiple long or short positions simultaneously using any virtual assets supported by Perp.
Notes:
Unlike other more common position types, this module does not EXACTLY replicate issuance and redemption positions since a trade is necessary to enter/exit the position on behalf of the issuer/redeemer.
The cost of entering/exiting the position (slippage) is carried by the issuer/redeemer. Any pending funding costs or PnL is carried by the current token holders
For safety (to prevent sandwich attacks), this module MUST issue using the SlippageIssuanceModule which allows users to specify slippage thresholds for issuance and redemption.
The external position unit is only updated on an as-needed basis during issuance/redemption. It does not reflect the current value of the Set's perpetual position. To retrieve a dynamically calculated value for a SetToken with a Perp position you can call SlippageIssuanceModule's getRequiredComponentIssuanceUnitsOffChain method as a static call using the ethers javascript library.
Important: Due to low Optimism block gas limit, and high Perp V2 gas costs for trading, currently SetTokens are restricted by governance to two open perp positions per account. This is to ensure that Sets can be minted and redeemed using the Slippage Issuance Module with no issues of hitting the block gas limit. Therefore to manage multiple positions, you can create multiple SetTokens each with a maximum of two positions - effectively enabling isolated and dual markets only. This restriction can be loosened as Optimism raises its max gas and Perpetual Protocol optimizes gas for trading.
Examples of allowed: SOL1x, SOL-2x, LUNA5x, SOL1x+BTC2x
Examples of not allowed: SOL1x+BTC2x+ETH-1x
Structs
PositionNotionalInfo
PositionUnitInfo
AccountInfo
NOTE: when pendingFundingPayments
is positive it will be credited to account on settlement, when negative it's a debt owed that will be repaid on settlement. (PerpProtocol.Exchange returns the value with the opposite meaning, e.g positively signed payments are owed by account to system).
Select Methods
trade()
MANAGER ONLY: Allows manager to buy or sell virtual positions to change exposure to the underlying baseToken. Providing a positive value for _baseQuantityUnits
buys baseToken
on UniswapV3 via Perp's ClearingHouse, Providing a negative value sells the token. _quoteBoundQuantityUnits
defines a min-receive-like slippage bound for the amount of vUSDC quote asset the trade will either pay or receive as a result of the action.
NOTE: This method doesn't update the externalPositionUnit because it is a function of UniswapV3 virtual token market prices and needs to be generated on the fly to be meaningful.
As a user when levering, e.g increasing the magnitude of your position, you'd trade as below:
Type | Action | Goal |
|
|
Long | Buy | pay least amt. of vQuote | upper bound of input quote | positive |
Short | Sell | get most amt. of vQuote | lower bound of output quote | negative |
As a user when delevering, e.g decreasing the magnitude of your position, you'd trade as below:
Type | Action | Goal | quoteBoundQuantity | baseQuantityUnits |
---|---|---|---|---|
Long | Sell | get most amt. of vQuote | upper bound of input quote | negative |
Short | Buy | pay least amt. of vQuote | lower bound of output quote | positive |
Parameters
Parameter name | Type | Description |
---|---|---|
_setToken | ISetToken | Instance of the SetToken |
_baseToken | address | Address virtual token being traded |
_baseQuantityUnits | int256 | Quantity of virtual token to trade in position units |
_quoteBoundQuantityUnits | int256 | Max/min of vQuote asset to pay/receive when buying or selling |
deposit()
MANAGER ONLY: Deposits default position collateral token (USDC) into the PerpV2 Vault, increasing the size of the Perp account external position. This method is useful for establishing initial collateralization ratios, e.g the flow when setting up a 2X external position would be to deposit 100 units of USDC and execute a lever trade for ~200 vUSDC worth of vBaseToken with the difference between these made up as automatically "issued" margin debt in the PerpV2 system.
Parameters
Parameter name | Type | Description |
---|---|---|
_setToken | ISetToken | Instance of the SetToken |
_collateralQuantityUnits | uint256 | Quantity of collateral to deposit in position units (in the collateral asset's decimals, e.g. USDC = 6) |
withdraw()
MANAGER ONLY: Withdraws collateral token from the PerpV2 Vault to a default position on the SetToken. This method is useful when adjusting the overall composition of a Set which has a Perp account external position as one of several components.
NOTE: Within PerpV2, withdraw
settles owedRealizedPnl
and any pending funding payments to the Perp vault prior to transfer.
Parameters
Parameter name | Type | Description |
---|---|---|
_setToken | ISetToken | Instance of the SetToken |
_collateralQuantityUnits | uint256 | Quantity of collateral to withdraw in position units (in the collateral asset's decimals, e.g. USDC = 6) |
moduleIssueHook()
MODULE ONLY: Hook called prior to issuance. Only callable by valid module. Should only be called ONCE during issue. Trades into current positions and sets the collateralToken's externalPositionUnit so that issuance module can transfer in the right amount of collateral accounting for accrued fees/pnl and slippage incurred during issuance. Any pending funding payments and accrued owedRealizedPnl
are attributed to current Set holders.
Parameters
Parameter name | Type | Description |
---|---|---|
_setToken | ISetToken | Instance of the SetToken |
_setTokenQuantity | uint256 | Quantity of Set to issue |
moduleRedeemHook()
MODULE ONLY: Hook called prior to redemption in the issuance module. Trades out of existing positions to make redemption capital withdraw-able from PerpV2 vault. Sets the externalPositionUnit
equal to the realizable value of account in position units (as measured by the trade outcomes for this redemption). Any owedRealizedPnl
and pending funding payments are socialized in this step so that redeemer pays/receives their share of them. Should only be called ONCE during redeem.
Parameters
Parameter name | Type | Description |
---|---|---|
_setToken | ISetToken | Instance of the SetToken |
_setTokenQuantity | uint256 | Quantity of Set to redeem |
componentIssueHook()
MODULE ONLY: Hook called prior to looping through each component on issuance. Deposits collateral into Perp protocol from SetToken default position.
Parameters
Parameter name | Type | Description |
---|---|---|
_setToken | ISetToken | Instance of the SetToken |
_setTokenQuantity | uint256 | Quantity of Set to issue |
_component | address | Address of deposit collateral component |
_isEquity | bool | True if componentHook called from issuance module for equity flow, false otherwise |
componentRedeemHook()
MODULE ONLY: Hook called prior to looping through each component on redemption. Withdraws collateral from Perp protocol to SetToken default position without updating the default position unit. Called by issuance module's resolveEquityPositions
method which immediately transfers the collateral component from SetToken to redeemer after this hook executes.
Parameters
Parameter name | Type | Description |
---|---|---|
_setToken | ISetToken | Instance of the SetToken |
_setTokenQuantity | uint256 | Quantity of Set to redeem |
_component | address | Address of deposit collateral component |
_isEquity | bool | True if componentHook called from issuance module for equity flow, false otherwise |
getIssuanceAdjustments()
Gets the positive equity collateral externalPositionUnit
that would be calculated for issuing a quantity of SetToken, representing the amount of collateral that would need to be transferred in per SetToken. Values in the returned arrays map to the same index in the SetToken's components array.
Parameters
Parameter name | Type | Description |
---|---|---|
_setToken | ISetToken | Instance of the SetToken |
_setTokenQuantity | uint256 | Quantity of Set to issue |
getRedemptionAdjustments()
Gets the positive equity collateral externalPositionUnit that would be calculated for redeeming a quantity of SetToken representing the amount of collateral returned per SetToken. Values in the returned arrays map to the same index in the SetToken's components array.
Parameters
Parameter name | Type | Description |
---|---|---|
_setToken | ISetToken | Instance of the SetToken |
_setTokenQuantity | uint256 | Quantity of Set to redeem |
getPositionNotionalInfo()
Returns a PositionUnitNotionalInfo
array representing all positions open for the SetToken. Each element of the array has the following properties:
baseToken: address
baseBalance: baseToken balance as notional quantity (10**18)
quoteBalance: USDC quote asset balance as notional quantity (10**18)
Parameters
Parameter name | Type | Description |
---|---|---|
_setToken | ISetToken | Instance of the SetToken |
getPositionUnitInfo()
Returns a PositionUnitUnitInfo
array representing all positions open for the SetToken. Each element of the array has the following properties:
baseToken: address
baseBalance: baseToken balance as position unit (10**18)
quoteBalance: USDC quote asset balance as position unit (10**18)
Parameters
Parameter name | Type | Description |
---|---|---|
_setToken | ISetToken | Instance of the SetToken |
getAccountInfo()
Gets Perp account info for SetToken. Returns an AccountInfo struct containing account wide (rather than position specific) balance info.
collateralBalance: collateral balance in vault (10^18, regardless of underlying collateral decimals)
owedRealizedPnl: owed realized PnL that accrued as a result of trading or liquidation but has not yet settled in the vault as a result of withdrawal (10^18)
pendingFundingPayments: funding payments which have not yet accrued to
owedRealizedPnl
as a result of trading (10^18)netQuoteBalance: the net quote balance of all open positions, long and short (10^18)
Parameters
Parameter name | Type | Description |
---|---|---|
_setToken | ISetToken | Instance of the SetToken |
getAMMSpotPrice()
Gets the mid-point price of a virtual asset from UniswapV3 markets maintained by Perp Protocol.
Returns the price as 10^18.
Parameters
Parameter name | Type | Description |
---|---|---|
_baseToken | Address | Address of virtual token to price |
Last updated