Skip to content

Commit c7af322

Browse files
author
Sachin
authored
feat(Intefaces): Add basis trading module interfaces (#237)
* Add IPerpV2LeverageModuleV2 interface * Add IPerpV2BasisTradingModule interface * Remove IPerpV2LeverageModule.sol * Fix compilation: User IPerpV2LeverageModuleV2 in Perp veiwer * Remove unncessary imports
1 parent b99255f commit c7af322

File tree

3 files changed

+173
-22
lines changed

3 files changed

+173
-22
lines changed
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
Copyright 2022 Set Labs Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
SPDX-License-Identifier: Apache License, Version 2.0
17+
*/
18+
pragma solidity 0.6.10;
19+
pragma experimental "ABIEncoderV2";
20+
21+
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
22+
23+
import { IPerpV2LeverageModuleV2 } from "./IPerpV2LeverageModuleV2.sol";
24+
import { ISetToken } from "./ISetToken.sol";
25+
26+
/**
27+
* @title IPerpV2BasisTradingModule
28+
* @author Set Protocol
29+
*
30+
* Interface for the PerpV2BasisTradingModule. Only specifies Manager permissioned functions, events
31+
* and getters. PerpV2BasisTradingModule also inherits from ModuleBaseV2 and SetTokenAccessible which support
32+
* additional methods.
33+
*/
34+
interface IPerpV2BasisTradingModule is IPerpV2LeverageModuleV2 {
35+
36+
/* ============ Structs ============ */
37+
38+
struct FeeState {
39+
address feeRecipient; // Address to accrue fees to
40+
uint256 maxPerformanceFeePercentage; // Max performance fee manager commits to using (1% = 1e16, 100% = 1e18)
41+
uint256 performanceFeePercentage; // Performance fees accrued to manager (1% = 1e16, 100% = 1e18)
42+
}
43+
44+
/* ============ Events ============ */
45+
46+
/**
47+
* @dev Emitted on performance fee update
48+
* @param _setToken Instance of SetToken
49+
* @param _newPerformanceFee New performance fee percentage (1% = 1e16)
50+
*/
51+
event PerformanceFeeUpdated(ISetToken indexed _setToken, uint256 _newPerformanceFee);
52+
53+
/**
54+
* @dev Emitted on fee recipient update
55+
* @param _setToken Instance of SetToken
56+
* @param _newFeeRecipient New performance fee recipient
57+
*/
58+
event FeeRecipientUpdated(ISetToken indexed _setToken, address _newFeeRecipient);
59+
60+
/**
61+
* @dev Emitted on funding withdraw
62+
* @param _setToken Instance of SetToken
63+
* @param _collateralToken Token being withdrawn as funding (USDC)
64+
* @param _amountWithdrawn Amount of funding being withdrawn from Perp (USDC)
65+
* @param _managerFee Amount of performance fee accrued to manager (USDC)
66+
* @param _protocolFee Amount of performance fee accrued to protocol (USDC)
67+
*/
68+
event FundingWithdrawn(
69+
ISetToken indexed _setToken,
70+
IERC20 _collateralToken,
71+
uint256 _amountWithdrawn,
72+
uint256 _managerFee,
73+
uint256 _protocolFee
74+
);
75+
76+
/* ============ State Variable Getters ============ */
77+
78+
// Mapping to store fee settings for each SetToken
79+
function feeSettings(ISetToken _setToken) external view returns(FeeState memory);
80+
81+
// Mapping to store funding that has been settled on Perpetual Protocol due to actions via this module
82+
// and hasn't been withdrawn for reinvesting yet. Values are stored in precise units (10e18).
83+
function settledFunding(ISetToken _settledFunding) external view returns (uint256);
84+
85+
/* ============ External Functions ============ */
86+
87+
/**
88+
* @dev MANAGER ONLY: Initializes this module to the SetToken and sets fee settings. Either the SetToken needs to
89+
* be on the allowed list or anySetAllowed needs to be true.
90+
*
91+
* @param _setToken Instance of the SetToken to initialize
92+
*/
93+
function initialize(
94+
ISetToken _setToken,
95+
FeeState memory _settings
96+
)
97+
external;
98+
99+
/**
100+
* @dev MANAGER ONLY: Similar to PerpV2LeverageModuleV2#trade. Allows manager to buy or sell perps to change exposure
101+
* to the underlying baseToken. Any pending funding that would be settled during opening a position on Perpetual
102+
* protocol is added to (or subtracted from) `settledFunding[_setToken]` and can be withdrawn later using
103+
* `withdrawFundingAndAccrueFees` by the SetToken manager.
104+
* NOTE: Calling a `nonReentrant` function from another `nonReentrant` function is not supported. Hence, we can't
105+
* add the `nonReentrant` modifier here because `PerpV2LeverageModuleV2#trade` function has a reentrancy check.
106+
* NOTE: This method doesn't update the externalPositionUnit because it is a function of UniswapV3 virtual
107+
* token market prices and needs to be generated on the fly to be meaningful.
108+
*
109+
* @param _setToken Instance of the SetToken
110+
* @param _baseToken Address virtual token being traded
111+
* @param _baseQuantityUnits Quantity of virtual token to trade in position units
112+
* @param _quoteBoundQuantityUnits Max/min of vQuote asset to pay/receive when buying or selling
113+
*/
114+
function tradeAndTrackFunding(
115+
ISetToken _setToken,
116+
address _baseToken,
117+
int256 _baseQuantityUnits,
118+
uint256 _quoteBoundQuantityUnits
119+
)
120+
external;
121+
122+
/**
123+
* @dev MANAGER ONLY: Withdraws tracked settled funding (in USDC) from the PerpV2 Vault to a default position
124+
* on the SetToken. Collects manager and protocol performance fees on the withdrawn amount.
125+
* This method is useful when withdrawing funding to be reinvested into the Basis Trading product.
126+
*
127+
* NOTE: Within PerpV2, `withdraw` settles `owedRealizedPnl` and any pending funding payments
128+
* to the Perp vault prior to transfer.
129+
*
130+
* @param _setToken Instance of the SetToken
131+
* @param _notionalFunding Notional amount of funding to withdraw (in USDC decimals)
132+
*/
133+
function withdrawFundingAndAccrueFees(
134+
ISetToken _setToken,
135+
uint256 _notionalFunding
136+
)
137+
external;
138+
139+
/**
140+
* @dev MANAGER ONLY. Update performance fee percentage.
141+
*
142+
* @param _setToken Instance of SetToken
143+
* @param _newFee New performance fee percentage in precise units (1e16 = 1%)
144+
*/
145+
function updatePerformanceFee(
146+
ISetToken _setToken,
147+
uint256 _newFee
148+
)
149+
external;
150+
151+
/**
152+
* @dev MANAGER ONLY. Update performance fee recipient (address to which performance fees are sent).
153+
*
154+
* @param _setToken Instance of SetToken
155+
* @param _newFeeRecipient Address of new fee recipient
156+
*/
157+
function updateFeeRecipient(ISetToken _setToken, address _newFeeRecipient)
158+
external;
159+
}

contracts/interfaces/IPerpV2LeverageModule.sol renamed to contracts/interfaces/IPerpV2LeverageModuleV2.sol

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2021 Set Labs Inc.
2+
Copyright 2022 Set Labs Inc.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -31,14 +31,14 @@ import { IMarketRegistry } from "./external/perp-v2/IMarketRegistry.sol";
3131
import { PerpV2Positions } from "../protocol/integration/lib/PerpV2Positions.sol";
3232

3333
/**
34-
* @title IPerpV2LeverageModule
34+
* @title IPerpV2LeverageModuleV2
3535
* @author Set Protocol
3636
*
37-
* Interface for the PerpV2LeverageModule. Only specifies Manager permissioned functions, events
38-
* and getters. PerpV2LeverageModule also inherits from ModuleBase and SetTokenAccessible which support
37+
* Interface for the PerpV2LeverageModuleV2. Only specifies Manager permissioned functions, events
38+
* and getters. PerpV2LeverageModuleV2 also inherits from ModuleBase and SetTokenAccessible which support
3939
* additional methods.
4040
*/
41-
interface IPerpV2LeverageModule {
41+
interface IPerpV2LeverageModuleV2 {
4242

4343
/* ============ Structs ============ */
4444

@@ -121,7 +121,7 @@ interface IPerpV2LeverageModule {
121121

122122
// Decimals of collateral token. We set this in the constructor for later reading
123123
function collateralDecimals() external view returns(uint8);
124-
124+
125125
/* ============ External Functions ============ */
126126

127127
/**
@@ -269,12 +269,4 @@ interface IPerpV2LeverageModule {
269269
* + net quote balance (10**18)
270270
*/
271271
function getAccountInfo(ISetToken _setToken) external view returns (AccountInfo memory accountInfo);
272-
273-
/**
274-
* @dev Gets the mid-point price of a virtual asset from UniswapV3 markets maintained by Perp Protocol
275-
*
276-
* @param _baseToken Address of virtual token to price
277-
* @return price Mid-point price of virtual token in UniswapV3 AMM market
278-
*/
279-
function getAMMSpotPrice(address _baseToken) external view returns (uint256 price);
280272
}

contracts/protocol-viewers/PerpV2LeverageModuleViewer.sol

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { SignedSafeMath } from "@openzeppelin/contracts/math/SignedSafeMath.sol"
2828
import { IAccountBalance } from "../interfaces/external/perp-v2/IAccountBalance.sol";
2929
import { IClearingHouseConfig } from "../interfaces/external/perp-v2/IClearingHouseConfig.sol";
3030
import { IIndexPrice } from "../interfaces/external/perp-v2/IIndexPrice.sol";
31-
import { IPerpV2LeverageModule } from "../interfaces/IPerpV2LeverageModule.sol";
31+
import { IPerpV2LeverageModuleV2 } from "../interfaces/IPerpV2LeverageModuleV2.sol";
3232
import { ISetToken } from "../interfaces/ISetToken.sol";
3333
import { PerpV2Positions } from "../protocol/integration/lib/PerpV2Positions.sol";
3434
import { PreciseUnitMath } from "../lib/PreciseUnitMath.sol";
@@ -39,7 +39,7 @@ import { PreciseUnitMath } from "../lib/PreciseUnitMath.sol";
3939
* @author Set Protocol
4040
*
4141
* PerpV2LeverageModuleViewer enables queries of information regarding open PerpV2 positions
42-
* specifically for leverage ratios and issuance maximums.
42+
* specifically for leverage ratios and issuance maximums.
4343
*/
4444
contract PerpV2LeverageModuleViewer {
4545
using SafeCast for int256;
@@ -61,7 +61,7 @@ contract PerpV2LeverageModuleViewer {
6161

6262
/* ============ State Variables ============ */
6363

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

222222
return accountInfo.collateralBalance
223223
.add(accountInfo.owedRealizedPnl)

0 commit comments

Comments
 (0)