@drift-labs/sdk 0.1.36-master.4 → 0.1.36-master.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/accounts/bulkAccountLoader.d.ts +1 -0
- package/lib/accounts/bulkAccountLoader.js +4 -0
- package/lib/addresses.d.ts +1 -0
- package/lib/addresses.js +7 -1
- package/lib/admin.d.ts +5 -0
- package/lib/admin.js +68 -0
- package/lib/clearingHouse.d.ts +11 -3
- package/lib/clearingHouse.js +130 -4
- package/lib/clearingHouseUser.d.ts +5 -1
- package/lib/clearingHouseUser.js +28 -0
- package/lib/idl/clearing_house.json +988 -727
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/oracles.d.ts +3 -0
- package/lib/math/oracles.js +26 -0
- package/lib/math/position.d.ts +1 -0
- package/lib/math/position.js +19 -1
- package/lib/math/trade.d.ts +10 -6
- package/lib/math/trade.js +68 -13
- package/lib/oracles/pythClient.js +1 -0
- package/lib/oracles/switchboardClient.js +3 -0
- package/lib/oracles/types.d.ts +1 -0
- package/lib/settlement.d.ts +4 -0
- package/lib/settlement.js +10 -0
- package/lib/types.d.ts +11 -0
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.ts +5 -0
- package/src/addresses.ts +11 -0
- package/src/admin.ts +83 -0
- package/src/clearingHouse.ts +204 -4
- package/src/clearingHouseUser.ts +64 -1
- package/src/idl/clearing_house.json +988 -727
- package/src/index.ts +1 -0
- package/src/math/oracles.ts +36 -0
- package/src/math/position.ts +22 -0
- package/src/math/trade.ts +84 -16
- package/src/oracles/pythClient.ts +1 -0
- package/src/oracles/switchboardClient.ts +5 -0
- package/src/oracles/types.ts +1 -0
- package/src/settlement.ts +9 -0
- package/src/types.ts +12 -0
package/lib/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export * from './math/funding';
|
|
|
25
25
|
export * from './math/insuranceFund';
|
|
26
26
|
export * from './math/market';
|
|
27
27
|
export * from './math/position';
|
|
28
|
+
export * from './math/oracles';
|
|
28
29
|
export * from './math/amm';
|
|
29
30
|
export * from './math/trade';
|
|
30
31
|
export * from './math/orders';
|
package/lib/index.js
CHANGED
|
@@ -44,6 +44,7 @@ __exportStar(require("./math/funding"), exports);
|
|
|
44
44
|
__exportStar(require("./math/insuranceFund"), exports);
|
|
45
45
|
__exportStar(require("./math/market"), exports);
|
|
46
46
|
__exportStar(require("./math/position"), exports);
|
|
47
|
+
__exportStar(require("./math/oracles"), exports);
|
|
47
48
|
__exportStar(require("./math/amm"), exports);
|
|
48
49
|
__exportStar(require("./math/trade"), exports);
|
|
49
50
|
__exportStar(require("./math/orders"), exports);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isOracleValid = void 0;
|
|
4
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
5
|
+
const index_1 = require("../index");
|
|
6
|
+
function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
|
|
7
|
+
const isOraclePriceNonPositive = oraclePriceData.price.lt(numericConstants_1.ZERO);
|
|
8
|
+
const isOraclePriceTooVolatile = oraclePriceData.price
|
|
9
|
+
.div(index_1.BN.max(numericConstants_1.ONE, amm.lastOraclePriceTwap))
|
|
10
|
+
.gt(oracleGuardRails.validity.tooVolatileRatio) ||
|
|
11
|
+
amm.lastOraclePriceTwap
|
|
12
|
+
.div(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.price))
|
|
13
|
+
.gt(oracleGuardRails.validity.tooVolatileRatio);
|
|
14
|
+
const isConfidenceTooLarge = oraclePriceData.price
|
|
15
|
+
.div(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.confidence))
|
|
16
|
+
.lt(oracleGuardRails.validity.confidenceIntervalMaxSize);
|
|
17
|
+
const oracleIsStale = oraclePriceData.slot
|
|
18
|
+
.sub(new index_1.BN(slot))
|
|
19
|
+
.gt(oracleGuardRails.validity.slotsBeforeStale);
|
|
20
|
+
return !(!oraclePriceData.hasSufficientNumberOfDataPoints ||
|
|
21
|
+
oracleIsStale ||
|
|
22
|
+
isOraclePriceNonPositive ||
|
|
23
|
+
isOraclePriceTooVolatile ||
|
|
24
|
+
isConfidenceTooLarge);
|
|
25
|
+
}
|
|
26
|
+
exports.isOracleValid = isOracleValid;
|
package/lib/math/position.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export declare function calculateBaseAssetValue(market: Market, userPosition: Us
|
|
|
18
18
|
* @returns BaseAssetAmount : Precision QUOTE_PRECISION
|
|
19
19
|
*/
|
|
20
20
|
export declare function calculatePositionPNL(market: Market, marketPosition: UserPosition, withFunding?: boolean): BN;
|
|
21
|
+
export declare function calculateSettledPositionPNL(market: Market, marketPosition: UserPosition): BN;
|
|
21
22
|
/**
|
|
22
23
|
*
|
|
23
24
|
* @param market
|
package/lib/math/position.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateEntryPrice = exports.calculatePositionFundingPNL = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
|
|
3
|
+
exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateEntryPrice = exports.calculatePositionFundingPNL = exports.calculateSettledPositionPNL = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
|
|
4
4
|
const __1 = require("../");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const types_1 = require("../types");
|
|
7
7
|
const amm_1 = require("./amm");
|
|
8
|
+
const settlement_1 = require("../settlement");
|
|
8
9
|
/**
|
|
9
10
|
* calculateBaseAssetValue
|
|
10
11
|
* = market value of closing entire position
|
|
@@ -60,6 +61,23 @@ function calculatePositionPNL(market, marketPosition, withFunding = false) {
|
|
|
60
61
|
return pnl;
|
|
61
62
|
}
|
|
62
63
|
exports.calculatePositionPNL = calculatePositionPNL;
|
|
64
|
+
function calculateSettledPositionPNL(market, marketPosition) {
|
|
65
|
+
let pnl = calculatePositionPNL(market, marketPosition);
|
|
66
|
+
if (pnl.gt(numericConstants_1.ZERO)) {
|
|
67
|
+
try {
|
|
68
|
+
pnl = pnl
|
|
69
|
+
.mul(new __1.BN(settlement_1.SETTLEMENT_RATIOS[marketPosition.marketIndex.toNumber()]))
|
|
70
|
+
.div(settlement_1.SETTLEMENT_RATIO_PRECISION);
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
console.log(pnl.toString());
|
|
74
|
+
console.log(marketPosition.marketIndex.toNumber());
|
|
75
|
+
throw e;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return pnl;
|
|
79
|
+
}
|
|
80
|
+
exports.calculateSettledPositionPNL = calculateSettledPositionPNL;
|
|
63
81
|
/**
|
|
64
82
|
*
|
|
65
83
|
* @param market
|
package/lib/math/trade.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' |
|
|
|
8
8
|
* @param direction
|
|
9
9
|
* @param amount
|
|
10
10
|
* @param market
|
|
11
|
+
* @param inputAssetType which asset is being traded
|
|
12
|
+
* @param useSpread whether to consider spread with calculating slippage
|
|
11
13
|
* @return [pctAvgSlippage, pctMaxSlippage, entryPrice, newPrice]
|
|
12
14
|
*
|
|
13
15
|
* 'pctAvgSlippage' => the percentage change to entryPrice (average est slippage in execution) : Precision MARK_PRICE_PRECISION
|
|
@@ -18,7 +20,7 @@ export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' |
|
|
|
18
20
|
*
|
|
19
21
|
* 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
|
|
20
22
|
*/
|
|
21
|
-
export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market: Market, inputAssetType?: AssetType): [BN, BN, BN, BN];
|
|
23
|
+
export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market: Market, inputAssetType?: AssetType, useSpread?: boolean): [BN, BN, BN, BN];
|
|
22
24
|
/**
|
|
23
25
|
* Calculates acquired amounts for trade executed
|
|
24
26
|
* @param direction
|
|
@@ -27,7 +29,7 @@ export declare function calculateTradeSlippage(direction: PositionDirection, amo
|
|
|
27
29
|
* @param inputAssetType
|
|
28
30
|
* @param useSpread
|
|
29
31
|
* @return
|
|
30
|
-
* | 'acquiredBase' => positive/negative change in user's base : BN
|
|
32
|
+
* | 'acquiredBase' => positive/negative change in user's base : BN AMM_RESERVE_PRECISION
|
|
31
33
|
* | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
|
|
32
34
|
*/
|
|
33
35
|
export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market: Market, inputAssetType?: AssetType, useSpread?: boolean): [BN, BN];
|
|
@@ -37,13 +39,15 @@ export declare function calculateTradeAcquiredAmounts(direction: PositionDirecti
|
|
|
37
39
|
* @param market
|
|
38
40
|
* @param targetPrice
|
|
39
41
|
* @param pct optional default is 100% gap filling, can set smaller.
|
|
42
|
+
* @param outputAssetType which asset to trade.
|
|
43
|
+
* @param useSpread whether or not to consider the spread when calculating the trade size
|
|
40
44
|
* @returns trade direction/size in order to push price to a targetPrice,
|
|
41
45
|
*
|
|
42
46
|
* [
|
|
43
|
-
* direction => direction of trade required,
|
|
47
|
+
* direction => direction of trade required, PositionDirection
|
|
44
48
|
* tradeSize => size of trade required, TODO-PRECISION
|
|
45
|
-
* entryPrice => the entry price for the trade,
|
|
46
|
-
* targetPrice => the target price
|
|
49
|
+
* entryPrice => the entry price for the trade, MARK_PRICE_PRECISION
|
|
50
|
+
* targetPrice => the target price MARK_PRICE_PRECISION
|
|
47
51
|
* ]
|
|
48
52
|
*/
|
|
49
|
-
export declare function calculateTargetPriceTrade(market: Market, targetPrice: BN, pct?: BN, outputAssetType?: AssetType): [PositionDirection, BN, BN, BN];
|
|
53
|
+
export declare function calculateTargetPriceTrade(market: Market, targetPrice: BN, pct?: BN, outputAssetType?: AssetType, useSpread?: boolean): [PositionDirection, BN, BN, BN];
|
package/lib/math/trade.js
CHANGED
|
@@ -8,12 +8,15 @@ const numericConstants_1 = require("../constants/numericConstants");
|
|
|
8
8
|
const market_1 = require("./market");
|
|
9
9
|
const amm_1 = require("./amm");
|
|
10
10
|
const utils_1 = require("./utils");
|
|
11
|
+
const types_2 = require("../types");
|
|
11
12
|
const MAXPCT = new anchor_1.BN(1000); //percentage units are [0,1000] => [0,1]
|
|
12
13
|
/**
|
|
13
14
|
* Calculates avg/max slippage (price impact) for candidate trade
|
|
14
15
|
* @param direction
|
|
15
16
|
* @param amount
|
|
16
17
|
* @param market
|
|
18
|
+
* @param inputAssetType which asset is being traded
|
|
19
|
+
* @param useSpread whether to consider spread with calculating slippage
|
|
17
20
|
* @return [pctAvgSlippage, pctMaxSlippage, entryPrice, newPrice]
|
|
18
21
|
*
|
|
19
22
|
* 'pctAvgSlippage' => the percentage change to entryPrice (average est slippage in execution) : Precision MARK_PRICE_PRECISION
|
|
@@ -24,14 +27,38 @@ const MAXPCT = new anchor_1.BN(1000); //percentage units are [0,1000] => [0,1]
|
|
|
24
27
|
*
|
|
25
28
|
* 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
|
|
26
29
|
*/
|
|
27
|
-
function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote') {
|
|
28
|
-
|
|
30
|
+
function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote', useSpread = true) {
|
|
31
|
+
let oldPrice;
|
|
32
|
+
if (useSpread && market.amm.baseSpread > 0) {
|
|
33
|
+
if ((0, types_2.isVariant)(direction, 'long')) {
|
|
34
|
+
oldPrice = (0, market_1.calculateAskPrice)(market);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
oldPrice = (0, market_1.calculateBidPrice)(market);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
oldPrice = (0, market_1.calculateMarkPrice)(market);
|
|
42
|
+
}
|
|
29
43
|
if (amount.eq(numericConstants_1.ZERO)) {
|
|
30
44
|
return [numericConstants_1.ZERO, numericConstants_1.ZERO, oldPrice, oldPrice];
|
|
31
45
|
}
|
|
32
|
-
const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType);
|
|
46
|
+
const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType, useSpread);
|
|
33
47
|
const entryPrice = (0, amm_1.calculatePrice)(acquiredBase, acquiredQuote, market.amm.pegMultiplier).mul(new anchor_1.BN(-1));
|
|
34
|
-
|
|
48
|
+
let amm;
|
|
49
|
+
if (useSpread && market.amm.baseSpread > 0) {
|
|
50
|
+
const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.calculateSpreadReserves)(market.amm, direction);
|
|
51
|
+
amm = {
|
|
52
|
+
baseAssetReserve,
|
|
53
|
+
quoteAssetReserve,
|
|
54
|
+
sqrtK: market.amm.sqrtK,
|
|
55
|
+
pegMultiplier: market.amm.pegMultiplier,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
amm = market.amm;
|
|
60
|
+
}
|
|
61
|
+
const newPrice = (0, amm_1.calculatePrice)(amm.baseAssetReserve.sub(acquiredBase), amm.quoteAssetReserve.sub(acquiredQuote), amm.pegMultiplier);
|
|
35
62
|
if (direction == types_1.PositionDirection.SHORT) {
|
|
36
63
|
(0, assert_1.assert)(newPrice.lt(oldPrice));
|
|
37
64
|
}
|
|
@@ -59,7 +86,7 @@ exports.calculateTradeSlippage = calculateTradeSlippage;
|
|
|
59
86
|
* @param inputAssetType
|
|
60
87
|
* @param useSpread
|
|
61
88
|
* @return
|
|
62
|
-
* | 'acquiredBase' => positive/negative change in user's base : BN
|
|
89
|
+
* | 'acquiredBase' => positive/negative change in user's base : BN AMM_RESERVE_PRECISION
|
|
63
90
|
* | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
|
|
64
91
|
*/
|
|
65
92
|
function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType = 'quote', useSpread = true) {
|
|
@@ -92,35 +119,50 @@ exports.calculateTradeAcquiredAmounts = calculateTradeAcquiredAmounts;
|
|
|
92
119
|
* @param market
|
|
93
120
|
* @param targetPrice
|
|
94
121
|
* @param pct optional default is 100% gap filling, can set smaller.
|
|
122
|
+
* @param outputAssetType which asset to trade.
|
|
123
|
+
* @param useSpread whether or not to consider the spread when calculating the trade size
|
|
95
124
|
* @returns trade direction/size in order to push price to a targetPrice,
|
|
96
125
|
*
|
|
97
126
|
* [
|
|
98
|
-
* direction => direction of trade required,
|
|
127
|
+
* direction => direction of trade required, PositionDirection
|
|
99
128
|
* tradeSize => size of trade required, TODO-PRECISION
|
|
100
|
-
* entryPrice => the entry price for the trade,
|
|
101
|
-
* targetPrice => the target price
|
|
129
|
+
* entryPrice => the entry price for the trade, MARK_PRICE_PRECISION
|
|
130
|
+
* targetPrice => the target price MARK_PRICE_PRECISION
|
|
102
131
|
* ]
|
|
103
132
|
*/
|
|
104
|
-
function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAssetType = 'quote') {
|
|
133
|
+
function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAssetType = 'quote', useSpread = true) {
|
|
105
134
|
(0, assert_1.assert)(market.amm.baseAssetReserve.gt(numericConstants_1.ZERO));
|
|
106
135
|
(0, assert_1.assert)(targetPrice.gt(numericConstants_1.ZERO));
|
|
107
136
|
(0, assert_1.assert)(pct.lte(MAXPCT) && pct.gt(numericConstants_1.ZERO));
|
|
108
137
|
const markPriceBefore = (0, market_1.calculateMarkPrice)(market);
|
|
138
|
+
const bidPriceBefore = (0, market_1.calculateBidPrice)(market);
|
|
139
|
+
const askPriceBefore = (0, market_1.calculateAskPrice)(market);
|
|
140
|
+
let direction;
|
|
109
141
|
if (targetPrice.gt(markPriceBefore)) {
|
|
110
142
|
const priceGap = targetPrice.sub(markPriceBefore);
|
|
111
143
|
const priceGapScaled = priceGap.mul(pct).div(MAXPCT);
|
|
112
144
|
targetPrice = markPriceBefore.add(priceGapScaled);
|
|
145
|
+
direction = types_1.PositionDirection.LONG;
|
|
113
146
|
}
|
|
114
147
|
else {
|
|
115
148
|
const priceGap = markPriceBefore.sub(targetPrice);
|
|
116
149
|
const priceGapScaled = priceGap.mul(pct).div(MAXPCT);
|
|
117
150
|
targetPrice = markPriceBefore.sub(priceGapScaled);
|
|
151
|
+
direction = types_1.PositionDirection.SHORT;
|
|
118
152
|
}
|
|
119
|
-
let direction;
|
|
120
153
|
let tradeSize;
|
|
121
154
|
let baseSize;
|
|
122
|
-
|
|
123
|
-
|
|
155
|
+
let baseAssetReserveBefore;
|
|
156
|
+
let quoteAssetReserveBefore;
|
|
157
|
+
if (useSpread && market.amm.baseSpread > 0) {
|
|
158
|
+
const { baseAssetReserve, quoteAssetReserve } = (0, amm_1.calculateSpreadReserves)(market.amm, direction);
|
|
159
|
+
baseAssetReserveBefore = baseAssetReserve;
|
|
160
|
+
quoteAssetReserveBefore = quoteAssetReserve;
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
baseAssetReserveBefore = market.amm.baseAssetReserve;
|
|
164
|
+
quoteAssetReserveBefore = market.amm.quoteAssetReserve;
|
|
165
|
+
}
|
|
124
166
|
const peg = market.amm.pegMultiplier;
|
|
125
167
|
const invariant = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
126
168
|
const k = invariant.mul(numericConstants_1.MARK_PRICE_PRECISION);
|
|
@@ -128,7 +170,20 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
|
|
|
128
170
|
let quoteAssetReserveAfter;
|
|
129
171
|
const biasModifier = new anchor_1.BN(1);
|
|
130
172
|
let markPriceAfter;
|
|
131
|
-
if (
|
|
173
|
+
if (useSpread &&
|
|
174
|
+
targetPrice.lt(askPriceBefore) &&
|
|
175
|
+
targetPrice.gt(bidPriceBefore)) {
|
|
176
|
+
// no trade, market is at target
|
|
177
|
+
if (markPriceBefore.gt(targetPrice)) {
|
|
178
|
+
direction = types_1.PositionDirection.SHORT;
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
direction = types_1.PositionDirection.LONG;
|
|
182
|
+
}
|
|
183
|
+
tradeSize = numericConstants_1.ZERO;
|
|
184
|
+
return [direction, tradeSize, targetPrice, targetPrice];
|
|
185
|
+
}
|
|
186
|
+
else if (markPriceBefore.gt(targetPrice)) {
|
|
132
187
|
// overestimate y2
|
|
133
188
|
baseAssetReserveAfter = (0, utils_1.squareRootBN)(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).sub(biasModifier)).sub(new anchor_1.BN(1));
|
|
134
189
|
quoteAssetReserveAfter = k
|
|
@@ -38,6 +38,7 @@ class PythClient {
|
|
|
38
38
|
confidence: convertPythPrice(priceData.confidence, priceData.exponent),
|
|
39
39
|
twap: convertPythPrice(priceData.twap.value, priceData.exponent),
|
|
40
40
|
twapConfidence: convertPythPrice(priceData.twac.value, priceData.exponent),
|
|
41
|
+
hasSufficientNumberOfDataPoints: true,
|
|
41
42
|
};
|
|
42
43
|
});
|
|
43
44
|
}
|
|
@@ -39,11 +39,14 @@ class SwitchboardClient {
|
|
|
39
39
|
const price = convertSwitchboardDecimal(aggregatorAccountData.latestConfirmedRound.result);
|
|
40
40
|
const confidence = convertSwitchboardDecimal(aggregatorAccountData.latestConfirmedRound
|
|
41
41
|
.stdDeviation);
|
|
42
|
+
const hasSufficientNumberOfDataPoints = aggregatorAccountData.latestConfirmedRound.numSuccess >=
|
|
43
|
+
aggregatorAccountData.minOracleResults;
|
|
42
44
|
const slot = aggregatorAccountData.latestConfirmedRound.roundOpenSlot;
|
|
43
45
|
return {
|
|
44
46
|
price,
|
|
45
47
|
slot,
|
|
46
48
|
confidence,
|
|
49
|
+
hasSufficientNumberOfDataPoints,
|
|
47
50
|
};
|
|
48
51
|
});
|
|
49
52
|
}
|
package/lib/oracles/types.d.ts
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SETTLEMENT_RATIOS = exports.SETTLEMENT_RATIO_PRECISION = void 0;
|
|
4
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
5
|
+
exports.SETTLEMENT_RATIO_PRECISION = new anchor_1.BN(1000000);
|
|
6
|
+
exports.SETTLEMENT_RATIOS = [
|
|
7
|
+
291786, 243613, 712271, 293771, 555181, 604938, 241133, 218489, 251741,
|
|
8
|
+
883058, 51614, 531737, 956092, 106424, 727107, 477277, 217325, 127477, 248561,
|
|
9
|
+
565938, 59349,
|
|
10
|
+
];
|
package/lib/types.d.ts
CHANGED
|
@@ -275,6 +275,12 @@ export declare type OrderStateAccount = {
|
|
|
275
275
|
orderFillerRewardStructure: OrderFillerRewardStructure;
|
|
276
276
|
minOrderQuoteAssetAmount: BN;
|
|
277
277
|
};
|
|
278
|
+
export declare type SettlementStateAccount = {
|
|
279
|
+
totalSettlementValue: BN;
|
|
280
|
+
collateralAvailableToClaim: BN;
|
|
281
|
+
collateralClaimed: BN;
|
|
282
|
+
enabled: boolean;
|
|
283
|
+
};
|
|
278
284
|
export declare type MarketsAccount = {
|
|
279
285
|
markets: Market[];
|
|
280
286
|
};
|
|
@@ -337,6 +343,11 @@ export declare type UserAccount = {
|
|
|
337
343
|
totalTokenDiscount: BN;
|
|
338
344
|
totalReferralReward: BN;
|
|
339
345
|
totalRefereeDiscount: BN;
|
|
346
|
+
settledPositionValue: BN;
|
|
347
|
+
collateralClaimed: BN;
|
|
348
|
+
lastCollateralAvailableToClaim: BN;
|
|
349
|
+
forgoPositionSettlement: number;
|
|
350
|
+
hasSettledPosition: number;
|
|
340
351
|
};
|
|
341
352
|
export declare type UserOrdersAccount = {
|
|
342
353
|
orders: Order[];
|
package/package.json
CHANGED
|
@@ -24,6 +24,7 @@ export class BulkAccountLoader {
|
|
|
24
24
|
loadPromise?: Promise<void>;
|
|
25
25
|
loadPromiseResolver: () => void;
|
|
26
26
|
lastTimeLoadingPromiseCleared = Date.now();
|
|
27
|
+
mostRecentSlot = 0;
|
|
27
28
|
|
|
28
29
|
public constructor(
|
|
29
30
|
connection: Connection,
|
|
@@ -159,6 +160,10 @@ export class BulkAccountLoader {
|
|
|
159
160
|
|
|
160
161
|
const newSlot = rpcResponse.result.context.slot;
|
|
161
162
|
|
|
163
|
+
if (newSlot > this.mostRecentSlot) {
|
|
164
|
+
this.mostRecentSlot = newSlot;
|
|
165
|
+
}
|
|
166
|
+
|
|
162
167
|
for (const i in accountsToLoad) {
|
|
163
168
|
const accountToLoad = accountsToLoad[i];
|
|
164
169
|
const key = accountToLoad.publicKey.toString();
|
package/src/addresses.ts
CHANGED
|
@@ -69,3 +69,14 @@ export async function getUserOrdersAccountPublicKey(
|
|
|
69
69
|
await getUserOrdersAccountPublicKeyAndNonce(programId, userAccount)
|
|
70
70
|
)[0];
|
|
71
71
|
}
|
|
72
|
+
|
|
73
|
+
export async function getSettlementStatePublicKey(
|
|
74
|
+
programId: PublicKey
|
|
75
|
+
): Promise<PublicKey> {
|
|
76
|
+
return (
|
|
77
|
+
await anchor.web3.PublicKey.findProgramAddress(
|
|
78
|
+
[Buffer.from(anchor.utils.bytes.utf8.encode('settlement_state'))],
|
|
79
|
+
programId
|
|
80
|
+
)
|
|
81
|
+
)[0];
|
|
82
|
+
}
|
package/src/admin.ts
CHANGED
|
@@ -18,6 +18,8 @@ import {
|
|
|
18
18
|
getClearingHouseStateAccountPublicKey,
|
|
19
19
|
getClearingHouseStateAccountPublicKeyAndNonce,
|
|
20
20
|
getOrderStateAccountPublicKeyAndNonce,
|
|
21
|
+
getSettlementStatePublicKey,
|
|
22
|
+
getUserAccountPublicKey,
|
|
21
23
|
} from './addresses';
|
|
22
24
|
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
|
23
25
|
import { ClearingHouse } from './clearingHouse';
|
|
@@ -733,4 +735,85 @@ export class Admin extends ClearingHouse {
|
|
|
733
735
|
},
|
|
734
736
|
});
|
|
735
737
|
}
|
|
738
|
+
|
|
739
|
+
public async transferFromInsuranceVaultToCollateralVault(): Promise<TransactionSignature> {
|
|
740
|
+
const state = await this.getStateAccount();
|
|
741
|
+
return await this.program.rpc.transferFromInsuranceVaultToCollateralVault({
|
|
742
|
+
accounts: {
|
|
743
|
+
admin: this.wallet.publicKey,
|
|
744
|
+
state: await this.getStatePublicKey(),
|
|
745
|
+
insuranceVault: state.insuranceVault,
|
|
746
|
+
insuranceVaultAuthority: state.insuranceVaultAuthority,
|
|
747
|
+
collateralVault: state.collateralVault,
|
|
748
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
749
|
+
},
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
public async adminUpdateUserForgoSettlement(
|
|
754
|
+
authority: PublicKey
|
|
755
|
+
): Promise<TransactionSignature> {
|
|
756
|
+
const user = await getUserAccountPublicKey(
|
|
757
|
+
this.program.programId,
|
|
758
|
+
authority
|
|
759
|
+
);
|
|
760
|
+
|
|
761
|
+
return await this.program.rpc.adminUpdateUserForgoSettlement({
|
|
762
|
+
accounts: {
|
|
763
|
+
admin: this.wallet.publicKey,
|
|
764
|
+
state: await this.getStatePublicKey(),
|
|
765
|
+
user: user,
|
|
766
|
+
},
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
public async initializeSettlementState(): Promise<TransactionSignature> {
|
|
771
|
+
const settlementState = await getSettlementStatePublicKey(
|
|
772
|
+
this.program.programId
|
|
773
|
+
);
|
|
774
|
+
|
|
775
|
+
const settlementSize = await this.getTotalSettlementSize();
|
|
776
|
+
|
|
777
|
+
return await this.program.rpc.initializeSettlementState(settlementSize, {
|
|
778
|
+
accounts: {
|
|
779
|
+
admin: this.wallet.publicKey,
|
|
780
|
+
state: await this.getStatePublicKey(),
|
|
781
|
+
settlementState: settlementState,
|
|
782
|
+
rent: SYSVAR_RENT_PUBKEY,
|
|
783
|
+
systemProgram: anchor.web3.SystemProgram.programId,
|
|
784
|
+
collateralVault: (await this.getStateAccount()).collateralVault,
|
|
785
|
+
},
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
public async updateSettlementState(): Promise<TransactionSignature> {
|
|
790
|
+
const settlementState = await getSettlementStatePublicKey(
|
|
791
|
+
this.program.programId
|
|
792
|
+
);
|
|
793
|
+
|
|
794
|
+
return await this.program.rpc.updateSettlementState({
|
|
795
|
+
accounts: {
|
|
796
|
+
admin: this.wallet.publicKey,
|
|
797
|
+
state: await this.getStatePublicKey(),
|
|
798
|
+
settlementState: settlementState,
|
|
799
|
+
collateralVault: (await this.getStateAccount()).collateralVault,
|
|
800
|
+
},
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
public async updateSettlementStateEnabled(
|
|
805
|
+
enabled: boolean
|
|
806
|
+
): Promise<TransactionSignature> {
|
|
807
|
+
const settlementState = await getSettlementStatePublicKey(
|
|
808
|
+
this.program.programId
|
|
809
|
+
);
|
|
810
|
+
|
|
811
|
+
return await this.program.rpc.updateSettlementStateEnabled(enabled, {
|
|
812
|
+
accounts: {
|
|
813
|
+
admin: this.wallet.publicKey,
|
|
814
|
+
state: await this.getStatePublicKey(),
|
|
815
|
+
settlementState: settlementState,
|
|
816
|
+
},
|
|
817
|
+
});
|
|
818
|
+
}
|
|
736
819
|
}
|