Skip to content

Commit 126a3fb

Browse files
authored
Merge pull request #102 from SetProtocol/add-perp-viewer/will
Create new PerpV2LeverageViewerAPI for PerpModule Viewer contract
2 parents c86243e + 92f06f6 commit 126a3fb

15 files changed

+521
-63
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/set.js/.npmrc
2727
- run:
2828
name: Inject Truffle
29-
command: yarn global add truffle
29+
command: yarn global add truffle --ignore-engines
3030
- run:
3131
name: Fetch Dependencies
3232
command: yarn install --network-concurrency 1

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "set.js",
3-
"version": "0.4.10",
3+
"version": "0.4.11",
44
"description": "A javascript library for interacting with the Set Protocol v2",
55
"keywords": [
66
"set.js",
@@ -58,7 +58,7 @@
5858
"@0xproject/types": "^1.1.4",
5959
"@0xproject/typescript-typings": "^3.0.2",
6060
"@0xproject/utils": "^2.0.2",
61-
"@setprotocol/set-protocol-v2": "^0.1.9",
61+
"@setprotocol/set-protocol-v2": "^0.1.10",
6262
"@types/chai-as-promised": "^7.1.3",
6363
"@types/jest": "^26.0.5",
6464
"@types/web3": "^1.2.2",

src/Set.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ import {
3131
DebtIssuanceAPI,
3232
DebtIssuanceV2API,
3333
SlippageIssuanceAPI,
34+
PerpV2LeverageAPI,
35+
PerpV2LeverageViewerAPI,
3436
} from './api/index';
35-
import PerpV2LeverageAPI from './api/PerpV2LeverageAPI';
3637

3738
const ethersProviders = require('ethers').providers;
3839

@@ -116,10 +117,17 @@ class Set {
116117
/**
117118
* An instance of the PerpV2LeverageAPI class. Contains getters for fetching
118119
* positional (per Set) and notional (across all Sets) units for collateral, vAssets, and debt.
119-
* Initially used for Perpetual Leverage Tokens.
120+
* Getters return low level data; for more abstracted data use the PerpV2LeverageViewerAPI.
120121
*/
121122
public perpV2Leverage: PerpV2LeverageAPI;
122123

124+
/**
125+
* An instance of the PerpV2LeverageViewerAPI class. Contains getters for fetching total
126+
* collateral balance (which includes PnL and funding), virtual component leverage ratios,
127+
* and maximum issuance quantity computed from token supply.
128+
*/
129+
public perpV2LeverageViewer: PerpV2LeverageViewerAPI;
130+
123131
/**
124132
* An instance of the BlockchainAPI class. Contains interfaces for
125133
* interacting with the blockchain
@@ -154,6 +162,7 @@ class Set {
154162
this.debtIssuanceV2 = new DebtIssuanceV2API(ethersProvider, config.debtIssuanceModuleV2Address);
155163
this.slippageIssuance = new SlippageIssuanceAPI(ethersProvider, config.slippageIssuanceModuleAddress);
156164
this.perpV2Leverage = new PerpV2LeverageAPI(ethersProvider, config.perpV2LeverageModuleAddress);
165+
this.perpV2LeverageViewer = new PerpV2LeverageViewerAPI(ethersProvider, config.perpV2LeverageModuleViewerAddress);
157166
this.blockchain = new BlockchainAPI(ethersProvider, assertions);
158167
}
159168
}

src/api/PerpV2LeverageAPI.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,6 @@ export default class PerpV2LeverageAPI {
8080
return await this.perpV2LeverageModuleWrapper.collateralToken(callerAddress);
8181
}
8282

83-
/**
84-
* Gets decimals of the collateral token
85-
*
86-
* @param callerAddress The address of user transferring from (optional)
87-
* @return The decimals of the ERC20 collateral token
88-
*/
89-
public async getCollateralDecimalsAsync(
90-
callerAddress: Address = undefined,
91-
): Promise<Number> {
92-
return await this.perpV2LeverageModuleWrapper.collateralDecimals(callerAddress);
93-
}
94-
9583
/**
9684
* Returns a tuple of arrays representing all positions open for the SetToken.
9785
*

src/api/PerpV2LeverageViewerAPI.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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+
17+
'use strict';
18+
19+
import { Provider } from '@ethersproject/providers';
20+
import { Address } from '@setprotocol/set-protocol-v2/utils/types';
21+
import { BigNumber } from 'ethers/lib/ethers';
22+
import { VAssetDisplayInfo } from '../types';
23+
24+
import PerpV2LeverageModuleViewerWrapper from '../wrappers/set-protocol-v2/PerpV2LeverageModuleViewerWrapper';
25+
import Assertions from '../assertions';
26+
27+
/**
28+
* @title PerpV2LeverageViewerAPI
29+
* @author Set Protocol
30+
*
31+
* The PerpV2LeverageViewerAPI exposes issue and redeem functionality for Sets that contain poitions that accrue
32+
* interest per block. The getter function syncs the position balance to the current block, so subsequent blocks
33+
* will cause the position value to be slightly out of sync (a buffer is needed). This API is primarily used for Sets
34+
* that rely on the ALM contracts to manage debt. The manager can define arbitrary issuance logic
35+
* in the manager hook, as well as specify issue and redeem fees.
36+
*
37+
*/
38+
export default class PerpV2LeverageViewerAPI {
39+
private perpV2LeverageModuleViewerWrapper: PerpV2LeverageModuleViewerWrapper;
40+
private assert: Assertions;
41+
42+
public constructor(provider: Provider, perpV2LeverageModuleViewerAddress: Address, assertions?: Assertions) {
43+
this.perpV2LeverageModuleViewerWrapper = new PerpV2LeverageModuleViewerWrapper(
44+
provider,
45+
perpV2LeverageModuleViewerAddress
46+
);
47+
this.assert = assertions || new Assertions();
48+
}
49+
50+
/**
51+
* Gets the address of the collateral token
52+
*
53+
* @param callerAddress The address of user transferring from (optional)
54+
* @return The address of the ERC20 collateral token
55+
*/
56+
public async getCollateralTokenAsync(
57+
callerAddress: Address = undefined,
58+
): Promise<Address> {
59+
return await this.perpV2LeverageModuleViewerWrapper.collateralToken(callerAddress);
60+
}
61+
62+
/**
63+
* Returns the maximum amount of Sets that can be issued. Because upon issuance we lever up the Set
64+
* before depositing collateral there is a ceiling on the amount of Sets that can be issued before the max
65+
* leverage ratio is met. In order to accurately predict this amount the user must pass in an expected
66+
* slippage amount, this amount should be calculated relative to Index price(s) of vAssets held by the Set,
67+
* not the mid-market prices. The formulas used here are based on the "conservative" definition of free
68+
* collateral as defined in PerpV2's docs.
69+
*
70+
* @param setTokenAddress Instance of SetToken
71+
* @param slippage Expected slippage from entering position in precise units (1% = 10^16)
72+
* @param callerAddress Address of the method caller
73+
*
74+
* @return Maximum amount of Sets that can be issued
75+
*/
76+
public async getMaximumSetTokenIssueAmountAsync(
77+
setTokenAddress: Address,
78+
slippage: BigNumber,
79+
callerAddress: Address = undefined,
80+
): Promise<BigNumber> {
81+
this.assert.schema.isValidAddress('setTokenAddress', setTokenAddress);
82+
83+
return await this.perpV2LeverageModuleViewerWrapper.getMaximumSetTokenIssueAmount(
84+
setTokenAddress,
85+
slippage,
86+
callerAddress,
87+
);
88+
}
89+
90+
/**
91+
* Returns the position unit for total collateral value as defined by Perpetual Protocol.
92+
*
93+
* @param setTokenAddress Instance of SetToken
94+
* @param callerAddress Address of the method caller
95+
*
96+
* @return Collateral token address
97+
* @return Total collateral value position unit
98+
*/
99+
public async getTotalCollateralUnitAsync(
100+
setTokenAddress: Address,
101+
callerAddress: Address = undefined,
102+
): Promise<[Address, BigNumber]> {
103+
this.assert.schema.isValidAddress('setTokenAddress', setTokenAddress);
104+
105+
return await this.perpV2LeverageModuleViewerWrapper.getTotalCollateralUnit(
106+
setTokenAddress,
107+
callerAddress,
108+
);
109+
}
110+
111+
/**
112+
* Returns relevant data for displaying current positions. Identifying info for each position plus current
113+
* size, index price, and leverage of each vAsset with an open position is returned. The sum quantity of vUSDC
114+
* is returned along with identifying info in last index of array.
115+
*
116+
* @param setTokenAddress Instance of the SetToken
117+
* @param callerAddress Address of the method caller
118+
*
119+
* @return Array of info concerning size and leverage of current vAsset positions
120+
*/
121+
public async getVirtualAssetsDisplayInfoAsync(
122+
setTokenAddress: Address,
123+
callerAddress: Address = undefined,
124+
): Promise<VAssetDisplayInfo[]> {
125+
this.assert.schema.isValidAddress('setTokenAddress', setTokenAddress);
126+
127+
return await this.perpV2LeverageModuleViewerWrapper.getVirtualAssetsDisplayInfo(
128+
setTokenAddress,
129+
callerAddress,
130+
);
131+
}
132+
}

src/api/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import DebtIssuanceAPI from './DebtIssuanceAPI';
1111
import DebtIssuanceV2API from './DebtIssuanceV2API';
1212
import SlippageIssuanceAPI from './SlippageIssuanceAPI';
1313
import PerpV2LeverageAPI from './PerpV2LeverageAPI';
14+
import PerpV2LeverageViewerAPI from './PerpV2LeverageViewerAPI';
1415
import {
1516
TradeQuoter,
1617
CoinGeckoDataService,
@@ -31,6 +32,7 @@ export {
3132
DebtIssuanceV2API,
3233
SlippageIssuanceAPI,
3334
PerpV2LeverageAPI,
35+
PerpV2LeverageViewerAPI,
3436
TradeQuoter,
3537
CoinGeckoDataService,
3638
GasOracleService

src/types/common.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export interface SetJSConfig {
2222
debtIssuanceModuleV2Address: Address;
2323
slippageIssuanceModuleAddress: Address;
2424
perpV2LeverageModuleAddress: Address;
25+
perpV2LeverageModuleViewerAddress: Address;
2526
}
2627

2728
export type SetDetails = {
@@ -89,3 +90,12 @@ export enum ModuleState {
8990
'PENDING',
9091
'INITIALIZED',
9192
}
93+
94+
// For PerpV2LeverageModuleViewerWrapper
95+
export type VAssetDisplayInfo = {
96+
symbol: string;
97+
vAssetAddress: Address;
98+
positionUnit: BigNumber; // 10^18 decimals
99+
indexPrice: BigNumber; // 10^18 decimals
100+
currentLeverageRatio: BigNumber; // 10^18 decimals
101+
};

src/wrappers/set-protocol-v2/ContractWrapper.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
TradeModule,
3434
NavIssuanceModule,
3535
PerpV2LeverageModule,
36+
PerpV2LeverageModuleViewer,
3637
PriceOracle,
3738
} from '@setprotocol/set-protocol-v2/typechain';
3839
import { BasicIssuanceModule__factory } from '@setprotocol/set-protocol-v2/dist/typechain/factories/BasicIssuanceModule__factory';
@@ -48,6 +49,7 @@ import { StreamingFeeModule__factory } from '@setprotocol/set-protocol-v2/dist/t
4849
import { TradeModule__factory } from '@setprotocol/set-protocol-v2/dist/typechain/factories/TradeModule__factory';
4950
import { NavIssuanceModule__factory } from '@setprotocol/set-protocol-v2/dist/typechain/factories/NavIssuanceModule__factory';
5051
import { PerpV2LeverageModule__factory } from '@setprotocol/set-protocol-v2/dist/typechain/factories/PerpV2LeverageModule__factory';
52+
import { PerpV2LeverageModuleViewer__factory } from '@setprotocol/set-protocol-v2/dist/typechain/factories/PerpV2LeverageModuleViewer__factory';
5153
import { PriceOracle__factory } from '@setprotocol/set-protocol-v2/dist/typechain/factories/PriceOracle__factory';
5254

5355
/**
@@ -450,4 +452,31 @@ export default class ContractWrapper {
450452
return perpV2LeverageModuleContract;
451453
}
452454
}
455+
456+
/**
457+
* Load PerpV2LeverageModuleViewer contract
458+
*
459+
* @param perpV2LeverageModuleViewerAddress Address of the Perp V2 Leverage module viewer
460+
* @param callerAddress Address of caller, uses first one on node if none provided.
461+
* @return PerpV2LeverageModuleViewer contract instance
462+
*/
463+
public async loadPerpV2LeverageModuleViewerAsync(
464+
perpV2LeverageModuleViewerAddress: Address,
465+
callerAddress?: Address,
466+
): Promise<PerpV2LeverageModuleViewer> {
467+
const signer = (this.provider as JsonRpcProvider).getSigner(callerAddress);
468+
const cacheKey = `PerpV2LeverageModuleViewer_${perpV2LeverageModuleViewerAddress}_${await signer.getAddress()}`;
469+
470+
if (cacheKey in this.cache) {
471+
return this.cache[cacheKey] as PerpV2LeverageModuleViewer;
472+
} else {
473+
const perpV2LeverageModuleViewerContract = PerpV2LeverageModuleViewer__factory.connect(
474+
perpV2LeverageModuleViewerAddress,
475+
signer
476+
);
477+
478+
this.cache[cacheKey] = perpV2LeverageModuleViewerContract;
479+
return perpV2LeverageModuleViewerContract;
480+
}
481+
}
453482
}

0 commit comments

Comments
 (0)