@drift-labs/sdk 0.2.0-master.25 → 0.2.0-master.26
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/pollingClearingHouseAccountSubscriber.d.ts +13 -13
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +27 -27
- package/lib/accounts/types.d.ts +8 -9
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +14 -14
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +35 -34
- package/lib/addresses/pda.d.ts +7 -6
- package/lib/addresses/pda.js +31 -27
- package/lib/admin.d.ts +9 -6
- package/lib/admin.js +83 -42
- package/lib/clearingHouse.d.ts +69 -42
- package/lib/clearingHouse.js +753 -277
- package/lib/clearingHouseConfig.d.ts +2 -2
- package/lib/clearingHouseUser.d.ts +16 -16
- package/lib/clearingHouseUser.js +139 -119
- package/lib/config.d.ts +7 -7
- package/lib/config.js +20 -20
- package/lib/constants/numericConstants.d.ts +12 -12
- package/lib/constants/numericConstants.js +13 -13
- package/lib/constants/{markets.d.ts → perpMarkets.d.ts} +5 -5
- package/{src/constants/markets.js → lib/constants/perpMarkets.js} +4 -4
- package/lib/constants/{banks.d.ts → spotMarkets.d.ts} +6 -6
- package/lib/constants/{banks.js → spotMarkets.js} +16 -16
- package/lib/events/types.d.ts +2 -1
- package/lib/events/types.js +1 -0
- package/lib/examples/makeTradeExample.js +7 -7
- package/lib/idl/clearing_house.json +1008 -279
- package/lib/index.d.ts +5 -3
- package/lib/index.js +5 -3
- package/lib/math/amm.d.ts +2 -2
- package/lib/math/amm.js +1 -1
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +2 -1
- package/lib/math/margin.d.ts +4 -4
- package/lib/math/margin.js +18 -11
- package/lib/math/market.d.ts +10 -9
- package/lib/math/market.js +29 -6
- package/lib/math/oracles.d.ts +2 -1
- package/lib/math/oracles.js +11 -1
- package/lib/math/orders.d.ts +5 -5
- package/lib/math/position.d.ts +13 -13
- package/lib/math/position.js +19 -19
- package/lib/math/spotBalance.d.ts +19 -0
- package/lib/math/spotBalance.js +176 -0
- package/lib/math/spotMarket.d.ts +4 -0
- package/lib/math/spotMarket.js +8 -0
- package/lib/math/spotPosition.d.ts +2 -0
- package/lib/math/spotPosition.js +8 -0
- package/lib/math/state.js +2 -2
- package/lib/math/trade.d.ts +4 -4
- package/lib/orderParams.d.ts +4 -4
- package/lib/orderParams.js +12 -4
- package/lib/serum/serumSubscriber.d.ts +23 -0
- package/lib/serum/serumSubscriber.js +41 -0
- package/lib/serum/types.d.ts +11 -0
- package/lib/serum/types.js +2 -0
- package/lib/tx/retryTxSender.d.ts +1 -1
- package/lib/tx/retryTxSender.js +4 -2
- package/lib/tx/types.d.ts +1 -1
- package/lib/types.d.ts +123 -33
- package/lib/types.js +31 -9
- package/my-script/.env +7 -0
- package/my-script/getUserStats.ts +106 -0
- package/my-script/multiConnections.ts +119 -0
- package/my-script/test-regex.ts +11 -0
- package/my-script/utils.ts +52 -0
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.js +249 -0
- package/src/accounts/bulkUserStatsSubscription.js +75 -0
- package/src/accounts/bulkUserSubscription.js +75 -0
- package/src/accounts/fetch.js +92 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +465 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +38 -38
- package/src/accounts/pollingOracleSubscriber.js +156 -0
- package/src/accounts/pollingTokenAccountSubscriber.js +141 -0
- package/src/accounts/pollingUserAccountSubscriber.js +208 -0
- package/src/accounts/pollingUserStatsAccountSubscriber.js +208 -0
- package/src/accounts/types.js +28 -0
- package/src/accounts/types.ts +11 -9
- package/src/accounts/utils.js +7 -0
- package/src/accounts/webSocketAccountSubscriber.js +138 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +433 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +59 -52
- package/src/accounts/webSocketUserAccountSubscriber.js +113 -0
- package/src/accounts/webSocketUserStatsAccountSubsriber.js +113 -0
- package/src/addresses/pda.js +186 -0
- package/src/addresses/pda.ts +49 -44
- package/src/admin.js +1284 -0
- package/src/admin.ts +140 -47
- package/src/assert/assert.js +1 -1
- package/src/clearingHouse.js +3433 -0
- package/src/clearingHouse.ts +1083 -378
- package/src/clearingHouseConfig.js +2 -0
- package/src/clearingHouseConfig.ts +2 -2
- package/src/clearingHouseUser.js +874 -0
- package/src/clearingHouseUser.ts +232 -168
- package/src/clearingHouseUserConfig.js +2 -0
- package/src/clearingHouseUserStats.js +115 -0
- package/src/clearingHouseUserStatsConfig.js +2 -0
- package/src/config.js +80 -0
- package/src/config.ts +29 -29
- package/src/constants/numericConstants.js +18 -11
- package/src/constants/numericConstants.ts +17 -15
- package/{lib/constants/markets.js → src/constants/perpMarkets.js} +11 -11
- package/src/constants/{markets.ts → perpMarkets.ts} +5 -5
- package/src/constants/spotMarkets.js +51 -0
- package/src/constants/{banks.ts → spotMarkets.ts} +19 -19
- package/src/events/eventList.js +66 -23
- package/src/events/eventSubscriber.js +202 -0
- package/src/events/fetchLogs.js +117 -0
- package/src/events/pollingLogProvider.js +113 -0
- package/src/events/sort.js +41 -0
- package/src/events/txEventCache.js +22 -19
- package/src/events/types.js +25 -0
- package/src/events/types.ts +3 -0
- package/src/events/webSocketLogProvider.js +76 -0
- package/src/examples/makeTradeExample.ts +10 -8
- package/src/factory/bigNum.js +183 -180
- package/src/factory/oracleClient.js +9 -9
- package/src/idl/clearing_house.json +1008 -279
- package/src/index.js +75 -0
- package/src/index.ts +5 -3
- package/src/math/amm.js +422 -0
- package/src/math/amm.ts +6 -3
- package/src/math/auction.js +10 -10
- package/src/math/conversion.js +4 -3
- package/src/math/funding.js +223 -175
- package/src/math/funding.ts +7 -7
- package/src/math/insurance.js +27 -0
- package/src/math/margin.js +77 -0
- package/src/math/margin.ts +34 -23
- package/src/math/market.js +105 -0
- package/src/math/market.ts +71 -19
- package/src/math/oracles.js +40 -10
- package/src/math/oracles.ts +18 -1
- package/src/math/orders.js +153 -0
- package/src/math/orders.ts +5 -5
- package/src/math/position.js +172 -0
- package/src/math/position.ts +31 -31
- package/src/math/repeg.js +40 -40
- package/src/math/spotBalance.js +176 -0
- package/src/math/spotBalance.ts +290 -0
- package/src/math/spotMarket.js +8 -0
- package/src/math/spotMarket.ts +9 -0
- package/src/math/spotPosition.js +8 -0
- package/src/math/spotPosition.ts +6 -0
- package/src/math/state.ts +2 -2
- package/src/math/trade.js +81 -74
- package/src/math/trade.ts +4 -4
- package/src/math/utils.js +8 -7
- package/src/oracles/oracleClientCache.js +10 -9
- package/src/oracles/pythClient.js +52 -17
- package/src/oracles/quoteAssetOracleClient.js +44 -13
- package/src/oracles/switchboardClient.js +69 -37
- package/src/oracles/types.js +1 -1
- package/src/orderParams.js +14 -6
- package/src/orderParams.ts +16 -8
- package/src/serum/serumSubscriber.js +102 -0
- package/src/serum/serumSubscriber.ts +80 -0
- package/src/serum/types.js +2 -0
- package/src/serum/types.ts +13 -0
- package/src/slot/SlotSubscriber.js +67 -20
- package/src/token/index.js +4 -4
- package/src/tokenFaucet.js +288 -154
- package/src/tx/retryTxSender.js +280 -0
- package/src/tx/retryTxSender.ts +5 -2
- package/src/tx/types.js +1 -1
- package/src/tx/types.ts +2 -1
- package/src/tx/utils.js +7 -6
- package/src/types.js +216 -0
- package/src/types.ts +110 -33
- package/src/userName.js +5 -5
- package/src/util/computeUnits.js +46 -11
- package/src/util/promiseTimeout.js +5 -5
- package/src/util/tps.js +46 -12
- package/src/wallet.js +55 -18
- package/lib/math/bankBalance.d.ts +0 -15
- package/lib/math/bankBalance.js +0 -150
- package/src/addresses/marketAddresses.js +0 -26
- package/src/constants/banks.js +0 -42
- package/src/examples/makeTradeExample.js +0 -80
- package/src/math/bankBalance.ts +0 -258
- package/src/math/state.js +0 -15
- package/src/math/utils.js.map +0 -1
- package/src/util/getTokenAddress.js +0 -9
package/src/math/funding.js
CHANGED
|
@@ -8,11 +8,39 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (_) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
exports.__esModule = true;
|
|
12
39
|
exports.calculateFundingPool = exports.calculateLongShortFundingRateAndLiveTwaps = exports.calculateLongShortFundingRate = exports.calculateEstimatedFundingRate = exports.calculateAllEstimatedFundingRate = void 0;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
40
|
+
var anchor_1 = require("@project-serum/anchor");
|
|
41
|
+
var numericConstants_1 = require("../constants/numericConstants");
|
|
42
|
+
var types_1 = require("../types");
|
|
43
|
+
var market_1 = require("./market");
|
|
16
44
|
/**
|
|
17
45
|
*
|
|
18
46
|
* @param market
|
|
@@ -20,146 +48,139 @@ const market_1 = require("./market");
|
|
|
20
48
|
* @param periodAdjustment
|
|
21
49
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
22
50
|
*/
|
|
23
|
-
function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
.
|
|
47
|
-
.
|
|
48
|
-
.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
.
|
|
51
|
+
function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment) {
|
|
52
|
+
if (periodAdjustment === void 0) { periodAdjustment = new anchor_1.BN(1); }
|
|
53
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
54
|
+
var secondsInHour, hoursInDay, ONE, payFreq, now, timeSinceLastUpdate, lastMarkTwapWithMantissa, lastMarkPriceTwapTs, timeSinceLastMarkChange, markTwapTimeSinceLastUpdate, baseAssetPriceWithMantissa, markTwapWithMantissa, lastOracleTwapWithMantissa, lastOraclePriceTwapTs, oracleInvalidDuration, timeSinceLastOracleTwapUpdate, oracleTwapTimeSinceLastUpdate, oracleTwapWithMantissa, oraclePrice, oracleLiveVsTwap, shrunkLastOracleTwapwithMantissa, twapSpread, twapSpreadPct, lowerboundEst, interpEst, interpRateQuote, feePoolSize, cappedAltEst, largerSide, smallerSide, feePoolTopOff;
|
|
55
|
+
return __generator(this, function (_a) {
|
|
56
|
+
secondsInHour = new anchor_1.BN(3600);
|
|
57
|
+
hoursInDay = new anchor_1.BN(24);
|
|
58
|
+
ONE = new anchor_1.BN(1);
|
|
59
|
+
if ((0, types_1.isVariant)(market.status, 'uninitialized')) {
|
|
60
|
+
return [2 /*return*/, [numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO]];
|
|
61
|
+
}
|
|
62
|
+
payFreq = new anchor_1.BN(market.amm.fundingPeriod);
|
|
63
|
+
now = new anchor_1.BN((Date.now() / 1000).toFixed(0));
|
|
64
|
+
timeSinceLastUpdate = now.sub(market.amm.lastFundingRateTs);
|
|
65
|
+
lastMarkTwapWithMantissa = market.amm.lastMarkPriceTwap;
|
|
66
|
+
lastMarkPriceTwapTs = market.amm.lastMarkPriceTwapTs;
|
|
67
|
+
timeSinceLastMarkChange = now.sub(lastMarkPriceTwapTs);
|
|
68
|
+
markTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, anchor_1.BN.max(numericConstants_1.ZERO, secondsInHour.sub(timeSinceLastMarkChange)));
|
|
69
|
+
baseAssetPriceWithMantissa = (0, market_1.calculateMarkPrice)(market, oraclePriceData);
|
|
70
|
+
markTwapWithMantissa = markTwapTimeSinceLastUpdate
|
|
71
|
+
.mul(lastMarkTwapWithMantissa)
|
|
72
|
+
.add(timeSinceLastMarkChange.mul(baseAssetPriceWithMantissa))
|
|
73
|
+
.div(timeSinceLastMarkChange.add(markTwapTimeSinceLastUpdate));
|
|
74
|
+
lastOracleTwapWithMantissa = market.amm.lastOraclePriceTwap;
|
|
75
|
+
lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
|
|
76
|
+
oracleInvalidDuration = anchor_1.BN.max(numericConstants_1.ZERO, lastMarkPriceTwapTs.sub(lastOraclePriceTwapTs));
|
|
77
|
+
timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
|
|
78
|
+
oracleTwapTimeSinceLastUpdate = anchor_1.BN.max(ONE, anchor_1.BN.min(secondsInHour, anchor_1.BN.max(ONE, secondsInHour.sub(timeSinceLastOracleTwapUpdate))));
|
|
79
|
+
oracleTwapWithMantissa = lastOracleTwapWithMantissa;
|
|
80
|
+
// if passing live oracle data, improve predicted calc estimate
|
|
81
|
+
if (oraclePriceData) {
|
|
82
|
+
oraclePrice = oraclePriceData.price;
|
|
83
|
+
oracleLiveVsTwap = oraclePrice
|
|
84
|
+
.sub(lastOracleTwapWithMantissa)
|
|
85
|
+
.abs()
|
|
86
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
87
|
+
.mul(new anchor_1.BN(100))
|
|
88
|
+
.div(lastOracleTwapWithMantissa);
|
|
89
|
+
// verify pyth live input is within 10% of last twap for live update
|
|
90
|
+
if (oracleLiveVsTwap.lte(numericConstants_1.MARK_PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
|
|
91
|
+
oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
|
|
92
|
+
.mul(lastOracleTwapWithMantissa)
|
|
93
|
+
.add(timeSinceLastMarkChange.mul(oraclePrice))
|
|
94
|
+
.div(timeSinceLastMarkChange.add(oracleTwapTimeSinceLastUpdate));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
shrunkLastOracleTwapwithMantissa = oracleTwapTimeSinceLastUpdate
|
|
98
|
+
.mul(lastOracleTwapWithMantissa)
|
|
99
|
+
.add(oracleInvalidDuration.mul(lastMarkTwapWithMantissa))
|
|
100
|
+
.div(oracleTwapTimeSinceLastUpdate.add(oracleInvalidDuration));
|
|
101
|
+
twapSpread = lastMarkTwapWithMantissa.sub(shrunkLastOracleTwapwithMantissa);
|
|
102
|
+
twapSpreadPct = twapSpread
|
|
63
103
|
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
64
104
|
.mul(new anchor_1.BN(100))
|
|
65
|
-
.div(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
105
|
+
.div(shrunkLastOracleTwapwithMantissa);
|
|
106
|
+
lowerboundEst = twapSpreadPct
|
|
107
|
+
.mul(payFreq)
|
|
108
|
+
.mul(anchor_1.BN.min(secondsInHour, timeSinceLastUpdate))
|
|
109
|
+
.mul(periodAdjustment)
|
|
110
|
+
.div(secondsInHour)
|
|
111
|
+
.div(secondsInHour)
|
|
112
|
+
.div(hoursInDay);
|
|
113
|
+
interpEst = twapSpreadPct.mul(periodAdjustment).div(hoursInDay);
|
|
114
|
+
interpRateQuote = twapSpreadPct
|
|
115
|
+
.mul(periodAdjustment)
|
|
116
|
+
.div(hoursInDay)
|
|
117
|
+
.div(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION));
|
|
118
|
+
feePoolSize = calculateFundingPool(market);
|
|
119
|
+
if (interpRateQuote.lt(new anchor_1.BN(0))) {
|
|
120
|
+
feePoolSize = feePoolSize.mul(new anchor_1.BN(-1));
|
|
72
121
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
122
|
+
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
|
|
123
|
+
largerSide = market.baseAssetAmountLong.abs();
|
|
124
|
+
smallerSide = market.baseAssetAmountShort.abs();
|
|
125
|
+
if (twapSpread.gt(new anchor_1.BN(0))) {
|
|
126
|
+
return [2 /*return*/, [
|
|
127
|
+
markTwapWithMantissa,
|
|
128
|
+
oracleTwapWithMantissa,
|
|
129
|
+
lowerboundEst,
|
|
130
|
+
interpEst,
|
|
131
|
+
interpEst,
|
|
132
|
+
]];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
|
|
136
|
+
largerSide = market.baseAssetAmountShort.abs();
|
|
137
|
+
smallerSide = market.baseAssetAmountLong.abs();
|
|
138
|
+
if (twapSpread.lt(new anchor_1.BN(0))) {
|
|
139
|
+
return [2 /*return*/, [
|
|
140
|
+
markTwapWithMantissa,
|
|
141
|
+
oracleTwapWithMantissa,
|
|
142
|
+
lowerboundEst,
|
|
143
|
+
interpEst,
|
|
144
|
+
interpEst,
|
|
145
|
+
]];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
return [2 /*return*/, [
|
|
150
|
+
markTwapWithMantissa,
|
|
151
|
+
oracleTwapWithMantissa,
|
|
152
|
+
lowerboundEst,
|
|
153
|
+
interpEst,
|
|
154
|
+
interpEst,
|
|
155
|
+
]];
|
|
156
|
+
}
|
|
157
|
+
if (largerSide.gt(numericConstants_1.ZERO)) {
|
|
158
|
+
// funding smaller flow
|
|
159
|
+
cappedAltEst = smallerSide.mul(twapSpread).div(hoursInDay);
|
|
160
|
+
feePoolTopOff = feePoolSize
|
|
161
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION))
|
|
162
|
+
.mul(numericConstants_1.AMM_RESERVE_PRECISION);
|
|
163
|
+
cappedAltEst = cappedAltEst.add(feePoolTopOff).div(largerSide);
|
|
164
|
+
cappedAltEst = cappedAltEst
|
|
165
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
166
|
+
.mul(new anchor_1.BN(100))
|
|
167
|
+
.div(oracleTwapWithMantissa)
|
|
168
|
+
.mul(periodAdjustment);
|
|
169
|
+
if (cappedAltEst.abs().gte(interpEst.abs())) {
|
|
170
|
+
cappedAltEst = interpEst;
|
|
171
|
+
}
|
|
113
172
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (twapSpread.lt(new anchor_1.BN(0))) {
|
|
119
|
-
return [
|
|
173
|
+
else {
|
|
174
|
+
cappedAltEst = interpEst;
|
|
175
|
+
}
|
|
176
|
+
return [2 /*return*/, [
|
|
120
177
|
markTwapWithMantissa,
|
|
121
178
|
oracleTwapWithMantissa,
|
|
122
179
|
lowerboundEst,
|
|
180
|
+
cappedAltEst,
|
|
123
181
|
interpEst,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
return [
|
|
130
|
-
markTwapWithMantissa,
|
|
131
|
-
oracleTwapWithMantissa,
|
|
132
|
-
lowerboundEst,
|
|
133
|
-
interpEst,
|
|
134
|
-
interpEst,
|
|
135
|
-
];
|
|
136
|
-
}
|
|
137
|
-
if (largerSide.gt(numericConstants_1.ZERO)) {
|
|
138
|
-
// funding smaller flow
|
|
139
|
-
cappedAltEst = smallerSide.mul(twapSpread).div(hoursInDay);
|
|
140
|
-
const feePoolTopOff = feePoolSize
|
|
141
|
-
.mul(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION))
|
|
142
|
-
.mul(numericConstants_1.AMM_RESERVE_PRECISION);
|
|
143
|
-
cappedAltEst = cappedAltEst.add(feePoolTopOff).div(largerSide);
|
|
144
|
-
cappedAltEst = cappedAltEst
|
|
145
|
-
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
146
|
-
.mul(new anchor_1.BN(100))
|
|
147
|
-
.div(oracleTwapWithMantissa)
|
|
148
|
-
.mul(periodAdjustment);
|
|
149
|
-
if (cappedAltEst.abs().gte(interpEst.abs())) {
|
|
150
|
-
cappedAltEst = interpEst;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
cappedAltEst = interpEst;
|
|
155
|
-
}
|
|
156
|
-
return [
|
|
157
|
-
markTwapWithMantissa,
|
|
158
|
-
oracleTwapWithMantissa,
|
|
159
|
-
lowerboundEst,
|
|
160
|
-
cappedAltEst,
|
|
161
|
-
interpEst,
|
|
162
|
-
];
|
|
182
|
+
]];
|
|
183
|
+
});
|
|
163
184
|
});
|
|
164
185
|
}
|
|
165
186
|
exports.calculateAllEstimatedFundingRate = calculateAllEstimatedFundingRate;
|
|
@@ -171,19 +192,28 @@ exports.calculateAllEstimatedFundingRate = calculateAllEstimatedFundingRate;
|
|
|
171
192
|
* @param estimationMethod
|
|
172
193
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
173
194
|
*/
|
|
174
|
-
function calculateEstimatedFundingRate(market, oraclePriceData, periodAdjustment
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
195
|
+
function calculateEstimatedFundingRate(market, oraclePriceData, periodAdjustment, estimationMethod) {
|
|
196
|
+
if (periodAdjustment === void 0) { periodAdjustment = new anchor_1.BN(1); }
|
|
197
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
198
|
+
var _a, _1, _2, lowerboundEst, cappedAltEst, interpEst;
|
|
199
|
+
return __generator(this, function (_b) {
|
|
200
|
+
switch (_b.label) {
|
|
201
|
+
case 0: return [4 /*yield*/, calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment)];
|
|
202
|
+
case 1:
|
|
203
|
+
_a = _b.sent(), _1 = _a[0], _2 = _a[1], lowerboundEst = _a[2], cappedAltEst = _a[3], interpEst = _a[4];
|
|
204
|
+
if (estimationMethod == 'lowerbound') {
|
|
205
|
+
//assuming remaining funding period has no gap
|
|
206
|
+
return [2 /*return*/, lowerboundEst];
|
|
207
|
+
}
|
|
208
|
+
else if (estimationMethod == 'capped') {
|
|
209
|
+
return [2 /*return*/, cappedAltEst];
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
return [2 /*return*/, interpEst];
|
|
213
|
+
}
|
|
214
|
+
return [2 /*return*/];
|
|
215
|
+
}
|
|
216
|
+
});
|
|
187
217
|
});
|
|
188
218
|
}
|
|
189
219
|
exports.calculateEstimatedFundingRate = calculateEstimatedFundingRate;
|
|
@@ -194,18 +224,27 @@ exports.calculateEstimatedFundingRate = calculateEstimatedFundingRate;
|
|
|
194
224
|
* @param periodAdjustment
|
|
195
225
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
196
226
|
*/
|
|
197
|
-
function calculateLongShortFundingRate(market, oraclePriceData, periodAdjustment
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
227
|
+
function calculateLongShortFundingRate(market, oraclePriceData, periodAdjustment) {
|
|
228
|
+
if (periodAdjustment === void 0) { periodAdjustment = new anchor_1.BN(1); }
|
|
229
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
230
|
+
var _a, _1, _2, _, cappedAltEst, interpEst;
|
|
231
|
+
return __generator(this, function (_b) {
|
|
232
|
+
switch (_b.label) {
|
|
233
|
+
case 0: return [4 /*yield*/, calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment)];
|
|
234
|
+
case 1:
|
|
235
|
+
_a = _b.sent(), _1 = _a[0], _2 = _a[1], _ = _a[2], cappedAltEst = _a[3], interpEst = _a[4];
|
|
236
|
+
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort)) {
|
|
237
|
+
return [2 /*return*/, [cappedAltEst, interpEst]];
|
|
238
|
+
}
|
|
239
|
+
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort)) {
|
|
240
|
+
return [2 /*return*/, [interpEst, cappedAltEst]];
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
return [2 /*return*/, [interpEst, interpEst]];
|
|
244
|
+
}
|
|
245
|
+
return [2 /*return*/];
|
|
246
|
+
}
|
|
247
|
+
});
|
|
209
248
|
});
|
|
210
249
|
}
|
|
211
250
|
exports.calculateLongShortFundingRate = calculateLongShortFundingRate;
|
|
@@ -216,18 +255,27 @@ exports.calculateLongShortFundingRate = calculateLongShortFundingRate;
|
|
|
216
255
|
* @param periodAdjustment
|
|
217
256
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
218
257
|
*/
|
|
219
|
-
function calculateLongShortFundingRateAndLiveTwaps(market, oraclePriceData, periodAdjustment
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
258
|
+
function calculateLongShortFundingRateAndLiveTwaps(market, oraclePriceData, periodAdjustment) {
|
|
259
|
+
if (periodAdjustment === void 0) { periodAdjustment = new anchor_1.BN(1); }
|
|
260
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
261
|
+
var _a, markTwapLive, oracleTwapLive, _2, cappedAltEst, interpEst;
|
|
262
|
+
return __generator(this, function (_b) {
|
|
263
|
+
switch (_b.label) {
|
|
264
|
+
case 0: return [4 /*yield*/, calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment)];
|
|
265
|
+
case 1:
|
|
266
|
+
_a = _b.sent(), markTwapLive = _a[0], oracleTwapLive = _a[1], _2 = _a[2], cappedAltEst = _a[3], interpEst = _a[4];
|
|
267
|
+
if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
|
|
268
|
+
return [2 /*return*/, [markTwapLive, oracleTwapLive, cappedAltEst, interpEst]];
|
|
269
|
+
}
|
|
270
|
+
else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
|
|
271
|
+
return [2 /*return*/, [markTwapLive, oracleTwapLive, interpEst, cappedAltEst]];
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
return [2 /*return*/, [markTwapLive, oracleTwapLive, interpEst, interpEst]];
|
|
275
|
+
}
|
|
276
|
+
return [2 /*return*/];
|
|
277
|
+
}
|
|
278
|
+
});
|
|
231
279
|
});
|
|
232
280
|
}
|
|
233
281
|
exports.calculateLongShortFundingRateAndLiveTwaps = calculateLongShortFundingRateAndLiveTwaps;
|
|
@@ -238,8 +286,8 @@ exports.calculateLongShortFundingRateAndLiveTwaps = calculateLongShortFundingRat
|
|
|
238
286
|
*/
|
|
239
287
|
function calculateFundingPool(market) {
|
|
240
288
|
// todo
|
|
241
|
-
|
|
242
|
-
|
|
289
|
+
var totalFeeLB = market.amm.totalExchangeFee.div(new anchor_1.BN(2));
|
|
290
|
+
var feePool = anchor_1.BN.max(numericConstants_1.ZERO, market.amm.totalFeeMinusDistributions
|
|
243
291
|
.sub(totalFeeLB)
|
|
244
292
|
.mul(new anchor_1.BN(1))
|
|
245
293
|
.div(new anchor_1.BN(3)));
|
package/src/math/funding.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
QUOTE_PRECISION,
|
|
6
6
|
ZERO,
|
|
7
7
|
} from '../constants/numericConstants';
|
|
8
|
-
import {
|
|
8
|
+
import { PerpMarketAccount, isVariant } from '../types';
|
|
9
9
|
import { calculateMarkPrice } from './market';
|
|
10
10
|
import { OraclePriceData } from '../oracles/types';
|
|
11
11
|
|
|
@@ -17,7 +17,7 @@ import { OraclePriceData } from '../oracles/types';
|
|
|
17
17
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
18
18
|
*/
|
|
19
19
|
export async function calculateAllEstimatedFundingRate(
|
|
20
|
-
market:
|
|
20
|
+
market: PerpMarketAccount,
|
|
21
21
|
oraclePriceData?: OraclePriceData,
|
|
22
22
|
periodAdjustment: BN = new BN(1)
|
|
23
23
|
): Promise<[BN, BN, BN, BN, BN]> {
|
|
@@ -29,7 +29,7 @@ export async function calculateAllEstimatedFundingRate(
|
|
|
29
29
|
const hoursInDay = new BN(24);
|
|
30
30
|
const ONE = new BN(1);
|
|
31
31
|
|
|
32
|
-
if (
|
|
32
|
+
if (isVariant(market.status, 'uninitialized')) {
|
|
33
33
|
return [ZERO, ZERO, ZERO, ZERO, ZERO];
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -208,7 +208,7 @@ export async function calculateAllEstimatedFundingRate(
|
|
|
208
208
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
209
209
|
*/
|
|
210
210
|
export async function calculateEstimatedFundingRate(
|
|
211
|
-
market:
|
|
211
|
+
market: PerpMarketAccount,
|
|
212
212
|
oraclePriceData?: OraclePriceData,
|
|
213
213
|
periodAdjustment: BN = new BN(1),
|
|
214
214
|
estimationMethod?: 'interpolated' | 'lowerbound' | 'capped'
|
|
@@ -238,7 +238,7 @@ export async function calculateEstimatedFundingRate(
|
|
|
238
238
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
239
239
|
*/
|
|
240
240
|
export async function calculateLongShortFundingRate(
|
|
241
|
-
market:
|
|
241
|
+
market: PerpMarketAccount,
|
|
242
242
|
oraclePriceData?: OraclePriceData,
|
|
243
243
|
periodAdjustment: BN = new BN(1)
|
|
244
244
|
): Promise<[BN, BN]> {
|
|
@@ -266,7 +266,7 @@ export async function calculateLongShortFundingRate(
|
|
|
266
266
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
267
267
|
*/
|
|
268
268
|
export async function calculateLongShortFundingRateAndLiveTwaps(
|
|
269
|
-
market:
|
|
269
|
+
market: PerpMarketAccount,
|
|
270
270
|
oraclePriceData?: OraclePriceData,
|
|
271
271
|
periodAdjustment: BN = new BN(1)
|
|
272
272
|
): Promise<[BN, BN, BN, BN]> {
|
|
@@ -291,7 +291,7 @@ export async function calculateLongShortFundingRateAndLiveTwaps(
|
|
|
291
291
|
* @param market
|
|
292
292
|
* @returns Estimated fee pool size
|
|
293
293
|
*/
|
|
294
|
-
export function calculateFundingPool(market:
|
|
294
|
+
export function calculateFundingPool(market: PerpMarketAccount): BN {
|
|
295
295
|
// todo
|
|
296
296
|
const totalFeeLB = market.amm.totalExchangeFee.div(new BN(2));
|
|
297
297
|
const feePool = BN.max(
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
exports.unstakeSharesToAmount = exports.stakeAmountToShares = void 0;
|
|
4
|
+
var numericConstants_1 = require("../constants/numericConstants");
|
|
5
|
+
var index_1 = require("../index");
|
|
6
|
+
function stakeAmountToShares(amount, totalIfShares, insuranceFundVaultBalance) {
|
|
7
|
+
var nShares;
|
|
8
|
+
if (insuranceFundVaultBalance.gt(numericConstants_1.ZERO)) {
|
|
9
|
+
nShares = amount.mul(totalIfShares).div(insuranceFundVaultBalance);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
nShares = amount;
|
|
13
|
+
}
|
|
14
|
+
return nShares;
|
|
15
|
+
}
|
|
16
|
+
exports.stakeAmountToShares = stakeAmountToShares;
|
|
17
|
+
function unstakeSharesToAmount(nShares, totalIfShares, insuranceFundVaultBalance) {
|
|
18
|
+
var amount;
|
|
19
|
+
if (totalIfShares.gt(numericConstants_1.ZERO)) {
|
|
20
|
+
amount = index_1.BN.max(numericConstants_1.ZERO, nShares.mul(insuranceFundVaultBalance).div(totalIfShares).sub(numericConstants_1.ONE));
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
amount = numericConstants_1.ZERO;
|
|
24
|
+
}
|
|
25
|
+
return amount;
|
|
26
|
+
}
|
|
27
|
+
exports.unstakeSharesToAmount = unstakeSharesToAmount;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithOracle = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
|
|
4
|
+
var utils_1 = require("./utils");
|
|
5
|
+
var numericConstants_1 = require("../constants/numericConstants");
|
|
6
|
+
var anchor_1 = require("@project-serum/anchor");
|
|
7
|
+
var assert_1 = require("../assert/assert");
|
|
8
|
+
function calculateSizePremiumLiabilityWeight(size, // AMM_RESERVE_PRECISION
|
|
9
|
+
imfFactor, liabilityWeight, precision) {
|
|
10
|
+
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
11
|
+
return liabilityWeight;
|
|
12
|
+
}
|
|
13
|
+
var sizeSqrt = (0, utils_1.squareRootBN)(size.div(new anchor_1.BN(1000)).add(new anchor_1.BN(1))); //1e13 -> 1e10 -> 1e5
|
|
14
|
+
var denom0 = anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor));
|
|
15
|
+
(0, assert_1.assert)(denom0.gt(numericConstants_1.ZERO));
|
|
16
|
+
var liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor))));
|
|
17
|
+
var denom = new anchor_1.BN(100000).mul(numericConstants_1.SPOT_MARKET_IMF_PRECISION).div(precision);
|
|
18
|
+
(0, assert_1.assert)(denom.gt(numericConstants_1.ZERO));
|
|
19
|
+
var sizePremiumLiabilityWeight = liabilityWeightNumerator.add(sizeSqrt // 1e5
|
|
20
|
+
.mul(imfFactor)
|
|
21
|
+
.div(denom) // 1e5
|
|
22
|
+
);
|
|
23
|
+
var maxLiabilityWeight = anchor_1.BN.max(liabilityWeight, sizePremiumLiabilityWeight);
|
|
24
|
+
return maxLiabilityWeight;
|
|
25
|
+
}
|
|
26
|
+
exports.calculateSizePremiumLiabilityWeight = calculateSizePremiumLiabilityWeight;
|
|
27
|
+
function calculateSizeDiscountAssetWeight(size, // AMM_RESERVE_PRECISION
|
|
28
|
+
imfFactor, assetWeight) {
|
|
29
|
+
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
30
|
+
return assetWeight;
|
|
31
|
+
}
|
|
32
|
+
var sizeSqrt = (0, utils_1.squareRootBN)(size.div(new anchor_1.BN(1000)).add(new anchor_1.BN(1))); //1e13 -> 1e10 -> 1e5
|
|
33
|
+
var imfNumerator = numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(new anchor_1.BN(10)));
|
|
34
|
+
var sizeDiscountAssetWeight = imfNumerator
|
|
35
|
+
.mul(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
|
|
36
|
+
.div(numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(sizeSqrt // 1e5
|
|
37
|
+
.mul(imfFactor)
|
|
38
|
+
.div(new anchor_1.BN(100000)) // 1e5
|
|
39
|
+
));
|
|
40
|
+
var minAssetWeight = anchor_1.BN.min(assetWeight, sizeDiscountAssetWeight);
|
|
41
|
+
return minAssetWeight;
|
|
42
|
+
}
|
|
43
|
+
exports.calculateSizeDiscountAssetWeight = calculateSizeDiscountAssetWeight;
|
|
44
|
+
function calculateOraclePriceForPerpMargin(perpPosition, market, oraclePriceData) {
|
|
45
|
+
var oraclePriceOffset = anchor_1.BN.min(new anchor_1.BN(market.amm.maxSpread)
|
|
46
|
+
.mul(oraclePriceData.price)
|
|
47
|
+
.div(numericConstants_1.BID_ASK_SPREAD_PRECISION), oraclePriceData.confidence.add(new anchor_1.BN(market.amm.baseSpread)
|
|
48
|
+
.mul(oraclePriceData.price)
|
|
49
|
+
.div(numericConstants_1.BID_ASK_SPREAD_PRECISION)));
|
|
50
|
+
var marginPrice;
|
|
51
|
+
if (perpPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
52
|
+
marginPrice = oraclePriceData.price.sub(oraclePriceOffset);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
marginPrice = oraclePriceData.price.add(oraclePriceOffset);
|
|
56
|
+
}
|
|
57
|
+
return marginPrice;
|
|
58
|
+
}
|
|
59
|
+
exports.calculateOraclePriceForPerpMargin = calculateOraclePriceForPerpMargin;
|
|
60
|
+
function calculateBaseAssetValueWithOracle(market, perpPosition, oraclePriceData) {
|
|
61
|
+
return perpPosition.baseAssetAmount
|
|
62
|
+
.abs()
|
|
63
|
+
.mul(oraclePriceData.price)
|
|
64
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
|
|
65
|
+
}
|
|
66
|
+
exports.calculateBaseAssetValueWithOracle = calculateBaseAssetValueWithOracle;
|
|
67
|
+
function calculateWorstCaseBaseAssetAmount(perpPosition) {
|
|
68
|
+
var allBids = perpPosition.baseAssetAmount.add(perpPosition.openBids);
|
|
69
|
+
var allAsks = perpPosition.baseAssetAmount.add(perpPosition.openAsks);
|
|
70
|
+
if (allBids.abs().gt(allAsks.abs())) {
|
|
71
|
+
return allBids;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
return allAsks;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
|