Skip to content

Commit

Permalink
feat(Intefaces): Add basis trading module interfaces (#237)
Browse files Browse the repository at this point in the history
* Add IPerpV2LeverageModuleV2 interface

* Add IPerpV2BasisTradingModule interface

* Remove IPerpV2LeverageModule.sol

* Fix compilation: User IPerpV2LeverageModuleV2 in Perp veiwer

* Remove unncessary imports
  • Loading branch information
Sachin authored Mar 28, 2022
1 parent b99255f commit c7af322
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 22 deletions.
159 changes: 159 additions & 0 deletions contracts/interfaces/IPerpV2BasisTradingModule.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
Copyright 2022 Set Labs Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache License, Version 2.0
*/
pragma solidity 0.6.10;
pragma experimental "ABIEncoderV2";

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import { IPerpV2LeverageModuleV2 } from "./IPerpV2LeverageModuleV2.sol";
import { ISetToken } from "./ISetToken.sol";

/**
* @title IPerpV2BasisTradingModule
* @author Set Protocol
*
* Interface for the PerpV2BasisTradingModule. Only specifies Manager permissioned functions, events
* and getters. PerpV2BasisTradingModule also inherits from ModuleBaseV2 and SetTokenAccessible which support
* additional methods.
*/
interface IPerpV2BasisTradingModule is IPerpV2LeverageModuleV2 {

/* ============ Structs ============ */

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

/* ============ Events ============ */

/**
* @dev Emitted on performance fee update
* @param _setToken Instance of SetToken
* @param _newPerformanceFee New performance fee percentage (1% = 1e16)
*/
event PerformanceFeeUpdated(ISetToken indexed _setToken, uint256 _newPerformanceFee);

/**
* @dev Emitted on fee recipient update
* @param _setToken Instance of SetToken
* @param _newFeeRecipient New performance fee recipient
*/
event FeeRecipientUpdated(ISetToken indexed _setToken, address _newFeeRecipient);

/**
* @dev Emitted on funding withdraw
* @param _setToken Instance of SetToken
* @param _collateralToken Token being withdrawn as funding (USDC)
* @param _amountWithdrawn Amount of funding being withdrawn from Perp (USDC)
* @param _managerFee Amount of performance fee accrued to manager (USDC)
* @param _protocolFee Amount of performance fee accrued to protocol (USDC)
*/
event FundingWithdrawn(
ISetToken indexed _setToken,
IERC20 _collateralToken,
uint256 _amountWithdrawn,
uint256 _managerFee,
uint256 _protocolFee
);

/* ============ State Variable Getters ============ */

// Mapping to store fee settings for each SetToken
function feeSettings(ISetToken _setToken) external view returns(FeeState memory);

// Mapping to store funding that has been settled on Perpetual Protocol due to actions via this module
// and hasn't been withdrawn for reinvesting yet. Values are stored in precise units (10e18).
function settledFunding(ISetToken _settledFunding) external view returns (uint256);

/* ============ External Functions ============ */

/**
* @dev MANAGER ONLY: Initializes this module to the SetToken and sets fee settings. Either the SetToken needs to
* be on the allowed list or anySetAllowed needs to be true.
*
* @param _setToken Instance of the SetToken to initialize
*/
function initialize(
ISetToken _setToken,
FeeState memory _settings
)
external;

/**
* @dev MANAGER ONLY: Similar to PerpV2LeverageModuleV2#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: Calling a `nonReentrant` function from another `nonReentrant` function is not supported. Hence, we can't
* add the `nonReentrant` modifier here because `PerpV2LeverageModuleV2#trade` function has a reentrancy check.
* 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.
*
* @param _setToken Instance of the SetToken
* @param _baseToken Address virtual token being traded
* @param _baseQuantityUnits Quantity of virtual token to trade in position units
* @param _quoteBoundQuantityUnits Max/min of vQuote asset to pay/receive when buying or selling
*/
function tradeAndTrackFunding(
ISetToken _setToken,
address _baseToken,
int256 _baseQuantityUnits,
uint256 _quoteBoundQuantityUnits
)
external;

/**
* @dev 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.
*
* NOTE: Within PerpV2, `withdraw` settles `owedRealizedPnl` and any pending funding payments
* to the Perp vault prior to transfer.
*
* @param _setToken Instance of the SetToken
* @param _notionalFunding Notional amount of funding to withdraw (in USDC decimals)
*/
function withdrawFundingAndAccrueFees(
ISetToken _setToken,
uint256 _notionalFunding
)
external;

/**
* @dev MANAGER ONLY. Update performance fee percentage.
*
* @param _setToken Instance of SetToken
* @param _newFee New performance fee percentage in precise units (1e16 = 1%)
*/
function updatePerformanceFee(
ISetToken _setToken,
uint256 _newFee
)
external;

/**
* @dev MANAGER ONLY. Update performance fee recipient (address to which performance fees are sent).
*
* @param _setToken Instance of SetToken
* @param _newFeeRecipient Address of new fee recipient
*/
function updateFeeRecipient(ISetToken _setToken, address _newFeeRecipient)
external;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2021 Set Labs Inc.
Copyright 2022 Set Labs Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -31,14 +31,14 @@ import { IMarketRegistry } from "./external/perp-v2/IMarketRegistry.sol";
import { PerpV2Positions } from "../protocol/integration/lib/PerpV2Positions.sol";

/**
* @title IPerpV2LeverageModule
* @title IPerpV2LeverageModuleV2
* @author Set Protocol
*
* Interface for the PerpV2LeverageModule. Only specifies Manager permissioned functions, events
* and getters. PerpV2LeverageModule also inherits from ModuleBase and SetTokenAccessible which support
* Interface for the PerpV2LeverageModuleV2. Only specifies Manager permissioned functions, events
* and getters. PerpV2LeverageModuleV2 also inherits from ModuleBase and SetTokenAccessible which support
* additional methods.
*/
interface IPerpV2LeverageModule {
interface IPerpV2LeverageModuleV2 {

/* ============ Structs ============ */

Expand Down Expand Up @@ -121,7 +121,7 @@ interface IPerpV2LeverageModule {

// Decimals of collateral token. We set this in the constructor for later reading
function collateralDecimals() external view returns(uint8);

/* ============ External Functions ============ */

/**
Expand Down Expand Up @@ -269,12 +269,4 @@ interface IPerpV2LeverageModule {
* + net quote balance (10**18)
*/
function getAccountInfo(ISetToken _setToken) external view returns (AccountInfo memory accountInfo);

/**
* @dev Gets the mid-point price of a virtual asset from UniswapV3 markets maintained by Perp Protocol
*
* @param _baseToken Address of virtual token to price
* @return price Mid-point price of virtual token in UniswapV3 AMM market
*/
function getAMMSpotPrice(address _baseToken) external view returns (uint256 price);
}
16 changes: 8 additions & 8 deletions contracts/protocol-viewers/PerpV2LeverageModuleViewer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { SignedSafeMath } from "@openzeppelin/contracts/math/SignedSafeMath.sol"
import { IAccountBalance } from "../interfaces/external/perp-v2/IAccountBalance.sol";
import { IClearingHouseConfig } from "../interfaces/external/perp-v2/IClearingHouseConfig.sol";
import { IIndexPrice } from "../interfaces/external/perp-v2/IIndexPrice.sol";
import { IPerpV2LeverageModule } from "../interfaces/IPerpV2LeverageModule.sol";
import { IPerpV2LeverageModuleV2 } from "../interfaces/IPerpV2LeverageModuleV2.sol";
import { ISetToken } from "../interfaces/ISetToken.sol";
import { PerpV2Positions } from "../protocol/integration/lib/PerpV2Positions.sol";
import { PreciseUnitMath } from "../lib/PreciseUnitMath.sol";
Expand All @@ -39,7 +39,7 @@ import { PreciseUnitMath } from "../lib/PreciseUnitMath.sol";
* @author Set Protocol
*
* PerpV2LeverageModuleViewer enables queries of information regarding open PerpV2 positions
* specifically for leverage ratios and issuance maximums.
* specifically for leverage ratios and issuance maximums.
*/
contract PerpV2LeverageModuleViewer {
using SafeCast for int256;
Expand All @@ -61,7 +61,7 @@ contract PerpV2LeverageModuleViewer {

/* ============ State Variables ============ */

IPerpV2LeverageModule public immutable perpModule; // PerpV2LeverageModule instance
IPerpV2LeverageModuleV2 public immutable perpModule; // PerpV2LeverageModule instance
IAccountBalance public immutable perpAccountBalance; // Perp's Account Balance contract
IClearingHouseConfig public immutable perpClearingHouseConfig; // PerpV2's ClearingHouseConfig contract
ERC20 public immutable vQuoteToken; // Virtual Quote asset for PerpV2 (vUSDC)
Expand All @@ -78,7 +78,7 @@ contract PerpV2LeverageModuleViewer {
* @param _vQuoteToken Address of virtual Quote asset for PerpV2 (vUSDC)
*/
constructor(
IPerpV2LeverageModule _perpModule,
IPerpV2LeverageModuleV2 _perpModule,
IAccountBalance _perpAccountBalance,
IClearingHouseConfig _perpClearingHouseConfig,
ERC20 _vQuoteToken
Expand All @@ -103,7 +103,7 @@ contract PerpV2LeverageModuleViewer {
* We want to find the point where freeCollateral = 0 after all trades have been executed.
* freeCollateral = 0 => totalDebt = min(totalCollateral, accountValue) / initialMarginRatio
* and, availableDebt = totalDebt - currentDebt
*
*
* Now, accountValue = totalCollateral + unrealizedPnl
* if unrealizedPnl >=0:
* min(totalCollateral, accountValue) = totalCollateral
Expand All @@ -113,7 +113,7 @@ contract PerpV2LeverageModuleViewer {
* availableDebt = ((totalCollateral + unrealizedPnl) / imRatio) - currentDebt
*
* We also know that any slippage gets accrued to unrealizedPnl BEFORE any new collateral is being deposited so
* we need to account for our expected slippage accrual impact on accountValue by subtracting our expected amount
* we need to account for our expected slippage accrual impact on accountValue by subtracting our expected amount
* of slippage divided by the imRatio from the availableDebt. We can then divide the availableDebtWithSlippage by
* the absolute value of our current position and multiply by our totalSupply to get the max issue amount.
*
Expand Down Expand Up @@ -162,7 +162,7 @@ contract PerpV2LeverageModuleViewer {
/**
* @dev Returns relevant data for displaying current positions. Identifying info for each position plus current
* size, index price, and leverage of each vAsset with an open position is returned. The sum quantity of vUSDC
* is returned along with identifying info in last index of array.
* is returned along with identifying info in last index of array.
*
* @param _setToken Instance of SetToken
*
Expand Down Expand Up @@ -217,7 +217,7 @@ contract PerpV2LeverageModuleViewer {
* @return Total collateral value attributed to SetToken
*/
function _calculateTotalCollateralValue(ISetToken _setToken) internal view returns (int256) {
IPerpV2LeverageModule.AccountInfo memory accountInfo = perpModule.getAccountInfo(_setToken);
IPerpV2LeverageModuleV2.AccountInfo memory accountInfo = perpModule.getAccountInfo(_setToken);

return accountInfo.collateralBalance
.add(accountInfo.owedRealizedPnl)
Expand Down

0 comments on commit c7af322

Please sign in to comment.