PerpV2BasisTradingModule

Smart contract that extends functionality offered by PerpV2LeverageModuleV2. It tracks funding that is settled due to actions on Perpetual protocol and allows it to be withdrawn by the manager. The withdrawn funding can be reinvested in the Set to create a yield generating basis trading product. The manager can also collect performance fees on the withdrawn funding. NOTE: 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. The current value can be calculated from getPositionNotionalInfo.

Structs

FeeState

struct FeeState {
    address feeRecipient;                     // Address to accrue fees to
    uint256 maxPerformanceFeePercentage;      // Max performance fee manager commits to using (1% = 1e16, 100% = 1e18)
    uint256 performanceFeePercentage;         // Performance fees accrued to manager (1% = 1e16, 100% = 1e18)
}

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).

struct AccountInfo {
  int256 collateralBalance;       // Quantity of collateral deposited in Perp vault in 10**18 decimals
  int256 owedRealizedPnl;         // USDC quantity of profit and loss in 10**18 decimals not yet settled to vault
  int256 pendingFundingPayments;  // USDC quantity of pending funding payments in 10**18 decimals
  int256 netQuoteBalance;         // USDC quantity of net quote balance for all open positions in Perp account
}

Select Methods

trade()

function trade(
    ISetToken _setToken,
    address _baseToken,
    int256 _baseQuantityUnits,
    uint256 _quoteBoundQuantityUnits
)

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

quoteBoundQuantity

baseQuantityUnits

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:

TypeActionGoalquoteBoundQuantitybaseQuantityUnits

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 nameTypeDescription

_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

tradeAndTrackFunding()

MANAGER ONLY: Similar to trade(). Allows manager to buy or sell perps to change exposure to the underlying baseToken. Any pending funding that would be settled during opening a position on Perpetual protocol is added to (or subtracted from) settledFunding[_setToken] and can be withdrawn later using withdrawFundingAndAccrueFees by the SetToken manager.

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.

function tradeAndTrackFunding(
    ISetToken _setToken,
    address _baseToken,
    int256 _baseQuantityUnits,
    uint256 _quoteBoundQuantityUnits
)

Parameters

Parameter nameTypeDescription

_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.

function deposit(
    ISetToken _setToken,
    uint256 _collateralQuantityUnits
)

Parameters

Parameter nameTypeDescription

_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. Any pending funding that would be settled during withdrawl on Perpetual protocol is added to (or subtracted from) settledFunding[_setToken] and can be withdrawn later using withdrawFundingAndAccrueFees by the SetToken manager.

NOTE: Within PerpV2, withdraw settles owedRealizedPnl and any pending funding payments to the Perp vault prior to transfer.

function withdraw(
    ISetToken _setToken,
    uint256 _collateralQuantityUnits
)

Parameters

Parameter nameTypeDescription

_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)

withdrawFundingAndAccrueFees()

MANAGER ONLY: Withdraws tracked settled funding (in USDC) from the PerpV2 Vault to a default position on the SetToken. Collects manager and protocol performance fees on the withdrawn amount. This method is useful when withdrawing funding to be reinvested into the Basis Trading product. Allows the manager to withdraw entire funding accrued by setting _notionalFunding to MAX_UINT_256.

NOTE: Within PerpV2, withdraw settles owedRealizedPnl and any pending funding payments to the Perp vault prior to transfer.

function withdrawFundingAndAccrueFees(
    ISetToken _setToken,
    uint256 _notionalFunding
)

Parameters

Parameter nameTypeDescription

_setToken

ISetToken

Instance of the SetToken

_notionalFunding

uint256

Notional amount of funding to withdraw (in USDC decimals)

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. Any pending funding payment that would be settled during trading into positions on Perpetual protocol is added to (or subtracted from) settledFunding[_setToken] and can be withdrawn later by the manager.

function moduleIssueHook(
    ISetToken _setToken,
    uint256 _setTokenQuantity
)

Parameters

Parameter nameTypeDescription

_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 withdrawable 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) net performance fees to be paid by the redeemer for his share of positive funding yield. 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. Any pending funding payment that would be settled during trading out of positions on Perpetual protocol is added to (or subtracted from) settledFunding[_setToken] and can be withdrawn later by the manager.

function moduleRedeemHook(
    ISetToken _setToken,
    uint256 _setTokenQuantity
)

Parameters

Parameter nameTypeDescription

_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.

function componentIssueHook(
    ISetToken _setToken,
    uint256 _setTokenQuantity,
    IERC20 _component,
    bool _isEquity
)

Parameters

Parameter nameTypeDescription

_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.

function componentRedeemHook(
    ISetToken _setToken,
    uint256 _setTokenQuantity,
    IERC20 _component,
    bool _isEquity
)

Parameters

Parameter nameTypeDescription

_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

updatePerformanceFee()

MANAGER ONLY. Update performance fee percentage.

Note: This function requires settled funding (in USD) to be zero. Call withdrawFundingAndAccrueFees() with _notionalAmount equals MAX_UINT_256 to withdraw all existing settled funding and set settled funding to zero. Funding accrues slowly, so calling this function within a reasonable duration after withdrawFundingAndAccrueFees is called, should work in practice.

function updatePerformanceFee(
    ISetToken _setToken,
    uint256 _newFee
)

Parameters

Parameter nameTypeDescription

_setToken

ISetToken

Instance of the SetToken

_newFee

uint256

New performance fee percentage in precise units (1e16 = 1%)

updateFeeRecipient()

MANAGER ONLY. Update performance fee recipient (address to which performance fees are sent).

function updateFeeRecipient(ISetToken _setToken, address _newFeeRecipient)

Parameters

Parameter nameTypeDescription

_setToken

ISetToken

Instance of the SetToken

_newFeeRecipient

address

Address of new fee recipient

getIssuanceAdjustments()

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.

function getIssuanceAdjustments(
    ISetToken _setToken,
    uint256 _setTokenQuantity
)

Parameters

Parameter nameTypeDescription

_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.

function getIssuanceAdjustments(
    ISetToken _setToken,
    uint256 _setTokenQuantity
)

Parameters

Parameter nameTypeDescription

_setToken

ISetToken

Instance of the SetToken

_setTokenQuantity

uint256

Quantity of Set to redeem

getUpdatedSettledFunding()

Adds pending funding payment to tracked settled funding. Returns updated settled funding value in precise units (10e18).

NOTE: Tracked settled funding value can not be less than zero, hence it is reset to zero if pending funding payment is negative and |pending funding payment| >= |settledFunding[_setToken]|.

function getUpdatedSettledFunding(
    ISetToken _setToken
)

Parameters

Parameter nameTypeDescription

_setToken

ISetToken

Instance of the SetToken

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)

function getPositionNotionalInfo(ISetToken _setToken) view 

Parameters

Parameter nameTypeDescription

_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)

function getPositionUnitInfo(ISetToken _setToken) view

Parameters

Parameter nameTypeDescription

_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)

function getAccountInfo(ISetToken _setToken) view

Parameters

Parameter nameTypeDescription

_setToken

ISetToken

Instance of the SetToken

Last updated