@drift-labs/sdk 2.14.0-beta.0 → 2.15.0-beta.0
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 +0 -1
- package/lib/accounts/bulkAccountLoader.js +3 -3
- package/lib/accounts/fetch.js +2 -2
- package/lib/accounts/pollingDriftClientAccountSubscriber.js +7 -7
- package/lib/accounts/pollingTokenAccountSubscriber.js +2 -2
- package/lib/accounts/pollingUserAccountSubscriber.js +2 -2
- package/lib/accounts/pollingUserStatsAccountSubscriber.js +2 -2
- package/lib/accounts/types.d.ts +0 -1
- package/lib/accounts/webSocketAccountSubscriber.js +1 -1
- package/lib/accounts/webSocketDriftClientAccountSubscriber.js +3 -3
- package/lib/addresses/marketAddresses.js +1 -1
- package/lib/addresses/pda.js +1 -5
- package/lib/adminClient.js +57 -61
- package/lib/constants/numericConstants.d.ts +1 -0
- package/lib/constants/numericConstants.js +3 -2
- package/lib/constants/perpMarkets.js +10 -0
- package/lib/dlob/DLOB.js +68 -68
- package/lib/dlob/DLOBNode.js +7 -7
- package/lib/dlob/NodeList.js +2 -2
- package/lib/driftClient.js +81 -85
- package/lib/events/eventSubscriber.js +2 -2
- package/lib/events/pollingLogProvider.js +1 -1
- package/lib/examples/loadDlob.js +2 -2
- package/lib/examples/makeTradeExample.js +9 -9
- package/lib/factory/bigNum.js +9 -9
- package/lib/factory/oracleClient.js +2 -2
- package/lib/idl/drift.json +1 -1
- package/lib/index.js +1 -5
- package/lib/math/amm.js +23 -23
- package/lib/math/auction.js +6 -6
- package/lib/math/exchangeStatus.js +2 -2
- package/lib/math/funding.js +2 -2
- package/lib/math/margin.js +5 -5
- package/lib/math/market.js +13 -13
- package/lib/math/oracles.js +1 -1
- package/lib/math/orders.js +23 -23
- package/lib/math/position.js +5 -5
- package/lib/math/repeg.js +1 -1
- package/lib/math/spotBalance.js +8 -8
- package/lib/math/spotPosition.js +3 -3
- package/lib/math/trade.js +42 -42
- package/lib/oracles/oracleClientCache.js +1 -1
- package/lib/oracles/pythClient.js +1 -1
- package/lib/tokenFaucet.js +1 -5
- package/lib/tx/retryTxSender.js +1 -1
- package/lib/user.js +52 -52
- package/lib/userMap/userMap.js +1 -1
- package/lib/userMap/userStatsMap.js +3 -3
- package/lib/userStats.js +2 -2
- package/package.json +1 -1
- package/src/assert/assert.js +9 -0
- package/src/constants/numericConstants.ts +1 -0
- package/src/constants/perpMarkets.ts +10 -0
- package/src/dlob/DLOB.ts +1 -1
- package/src/idl/drift.json +1 -1
- package/src/token/index.js +38 -0
- package/src/tx/types.js +2 -0
- package/src/tx/utils.js +17 -0
- package/src/user.ts +2 -1
- package/src/util/computeUnits.js +27 -0
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/promiseTimeout.js +14 -0
- package/src/util/tps.js +27 -0
|
@@ -20,7 +20,7 @@ class EventSubscriber {
|
|
|
20
20
|
this.txEventCache = new txEventCache_1.TxEventCache(this.options.maxTx);
|
|
21
21
|
this.eventListMap = new Map();
|
|
22
22
|
for (const eventType of this.options.eventTypes) {
|
|
23
|
-
this.eventListMap.set(eventType, new eventList_1.EventList(eventType, this.options.maxEventsPerType,
|
|
23
|
+
this.eventListMap.set(eventType, new eventList_1.EventList(eventType, this.options.maxEventsPerType, sort_1.getSortFn(this.options.orderBy, this.options.orderDir, eventType), this.options.orderDir));
|
|
24
24
|
}
|
|
25
25
|
this.eventEmitter = new events_1.EventEmitter();
|
|
26
26
|
if (this.options.logProviderConfig.type === 'websocket') {
|
|
@@ -80,7 +80,7 @@ class EventSubscriber {
|
|
|
80
80
|
let beforeTx = undefined;
|
|
81
81
|
const untilTx = this.options.untilTx;
|
|
82
82
|
while (txFetched < this.options.maxTx) {
|
|
83
|
-
const response = await
|
|
83
|
+
const response = await fetchLogs_1.fetchLogs(this.connection, this.program.programId, this.options.commitment === 'finalized' ? 'finalized' : 'confirmed', beforeTx, untilTx);
|
|
84
84
|
if (response === undefined) {
|
|
85
85
|
break;
|
|
86
86
|
}
|
|
@@ -20,7 +20,7 @@ class PollingLogProvider {
|
|
|
20
20
|
}
|
|
21
21
|
this.mutex = 1;
|
|
22
22
|
try {
|
|
23
|
-
const response = await
|
|
23
|
+
const response = await fetchLogs_1.fetchLogs(this.connection, this.programId, this.finality, undefined, this.mostRecentSeenTx,
|
|
24
24
|
// If skipping history, only fetch one log back, not the maximum amount available
|
|
25
25
|
skipHistory && this.firstFetch ? 1 : undefined);
|
|
26
26
|
if (response === undefined) {
|
package/lib/examples/loadDlob.js
CHANGED
|
@@ -7,7 +7,7 @@ const __2 = require("..");
|
|
|
7
7
|
const env = 'mainnet-beta';
|
|
8
8
|
const main = async () => {
|
|
9
9
|
// Initialize Drift SDK
|
|
10
|
-
const sdkConfig =
|
|
10
|
+
const sdkConfig = __2.initialize({ env });
|
|
11
11
|
// Set up the Wallet and Provider
|
|
12
12
|
const privateKey = process.env.BOT_PRIVATE_KEY; // stored as an array string
|
|
13
13
|
const keypair = web3_js_1.Keypair.fromSecretKey(Uint8Array.from(JSON.parse(privateKey)));
|
|
@@ -24,7 +24,7 @@ const main = async () => {
|
|
|
24
24
|
connection,
|
|
25
25
|
wallet: provider.wallet,
|
|
26
26
|
programID: driftPublicKey,
|
|
27
|
-
...
|
|
27
|
+
...__2.getMarketsAndOraclesForSubscription(env),
|
|
28
28
|
accountSubscription: {
|
|
29
29
|
type: 'polling',
|
|
30
30
|
accountLoader: bulkAccountLoader,
|
|
@@ -14,7 +14,7 @@ exports.getTokenAddress = getTokenAddress;
|
|
|
14
14
|
const env = 'devnet';
|
|
15
15
|
const main = async () => {
|
|
16
16
|
// Initialize Drift SDK
|
|
17
|
-
const sdkConfig =
|
|
17
|
+
const sdkConfig = __2.initialize({ env });
|
|
18
18
|
// Set up the Wallet and Provider
|
|
19
19
|
const privateKey = process.env.BOT_PRIVATE_KEY; // stored as an array string
|
|
20
20
|
const keypair = web3_js_1.Keypair.fromSecretKey(Uint8Array.from(JSON.parse(privateKey)));
|
|
@@ -28,7 +28,7 @@ const main = async () => {
|
|
|
28
28
|
const lamportsBalance = await connection.getBalance(wallet.publicKey);
|
|
29
29
|
console.log('SOL balance:', lamportsBalance / 10 ** 9);
|
|
30
30
|
// Misc. other things to set up
|
|
31
|
-
const usdcTokenAddress = await
|
|
31
|
+
const usdcTokenAddress = await exports.getTokenAddress(sdkConfig.USDC_MINT_ADDRESS, wallet.publicKey.toString());
|
|
32
32
|
// Set up the Drift Clearing House
|
|
33
33
|
const driftPublicKey = new web3_js_1.PublicKey(sdkConfig.DRIFT_PROGRAM_ID);
|
|
34
34
|
const bulkAccountLoader = new __2.BulkAccountLoader(connection, 'confirmed', 1000);
|
|
@@ -36,7 +36,7 @@ const main = async () => {
|
|
|
36
36
|
connection,
|
|
37
37
|
wallet: provider.wallet,
|
|
38
38
|
programID: driftPublicKey,
|
|
39
|
-
...
|
|
39
|
+
...__2.getMarketsAndOraclesForSubscription(env),
|
|
40
40
|
accountSubscription: {
|
|
41
41
|
type: 'polling',
|
|
42
42
|
accountLoader: bulkAccountLoader,
|
|
@@ -57,21 +57,21 @@ const main = async () => {
|
|
|
57
57
|
if (!userAccountExists) {
|
|
58
58
|
//// Create a Clearing House account by Depositing some USDC ($10,000 in this case)
|
|
59
59
|
const depositAmount = new anchor_1.BN(10000).mul(__2.QUOTE_PRECISION);
|
|
60
|
-
await driftClient.initializeUserAccountAndDepositCollateral(depositAmount, await
|
|
60
|
+
await driftClient.initializeUserAccountAndDepositCollateral(depositAmount, await exports.getTokenAddress(usdcTokenAddress.toString(), wallet.publicKey.toString()), spotMarkets_1.SpotMarkets['devnet'][0].marketIndex);
|
|
61
61
|
}
|
|
62
62
|
await user.subscribe();
|
|
63
63
|
// Get current price
|
|
64
64
|
const solMarketInfo = sdkConfig.PERP_MARKETS.find((market) => market.baseAssetSymbol === 'SOL');
|
|
65
65
|
const marketIndex = solMarketInfo.marketIndex;
|
|
66
|
-
const [bid, ask] =
|
|
67
|
-
const formattedBidPrice =
|
|
68
|
-
const formattedAskPrice =
|
|
66
|
+
const [bid, ask] = __1.calculateBidAskPrice(driftClient.getPerpMarketAccount(marketIndex).amm, driftClient.getOracleDataForPerpMarket(marketIndex));
|
|
67
|
+
const formattedBidPrice = __2.convertToNumber(bid, __2.PRICE_PRECISION);
|
|
68
|
+
const formattedAskPrice = __2.convertToNumber(ask, __2.PRICE_PRECISION);
|
|
69
69
|
console.log(`Current amm bid and ask price are $${formattedBidPrice} and $${formattedAskPrice}`);
|
|
70
70
|
// Estimate the slippage for a $5000 LONG trade
|
|
71
71
|
const solMarketAccount = driftClient.getPerpMarketAccount(solMarketInfo.marketIndex);
|
|
72
|
-
const slippage =
|
|
72
|
+
const slippage = __2.convertToNumber(__2.calculateTradeSlippage(__2.PositionDirection.LONG, new anchor_1.BN(1).mul(__1.BASE_PRECISION), solMarketAccount, 'base', driftClient.getOracleDataForPerpMarket(solMarketInfo.marketIndex))[0], __2.PRICE_PRECISION);
|
|
73
73
|
console.log(`Slippage for a 1 SOL-PERP would be $${slippage}`);
|
|
74
|
-
await driftClient.placePerpOrder(
|
|
74
|
+
await driftClient.placePerpOrder(__1.getMarketOrderParams({
|
|
75
75
|
baseAssetAmount: new anchor_1.BN(1).mul(__1.BASE_PRECISION),
|
|
76
76
|
direction: __2.PositionDirection.LONG,
|
|
77
77
|
marketIndex: solMarketAccount.marketIndex,
|
package/lib/factory/bigNum.js
CHANGED
|
@@ -18,11 +18,11 @@ class BigNum {
|
|
|
18
18
|
return anchor_1.BN.isBN(bn) ? BigNum.from(bn) : bn;
|
|
19
19
|
}
|
|
20
20
|
add(bn) {
|
|
21
|
-
|
|
21
|
+
assert_1.assert(bn.precision.eq(this.precision), 'Adding unequal precisions');
|
|
22
22
|
return BigNum.from(this.val.add(bn.val), this.precision);
|
|
23
23
|
}
|
|
24
24
|
sub(bn) {
|
|
25
|
-
|
|
25
|
+
assert_1.assert(bn.precision.eq(this.precision), 'Subtracting unequal precisions');
|
|
26
26
|
return BigNum.from(this.val.sub(bn.val), this.precision);
|
|
27
27
|
}
|
|
28
28
|
mul(bn) {
|
|
@@ -82,35 +82,35 @@ class BigNum {
|
|
|
82
82
|
gt(bn, ignorePrecision) {
|
|
83
83
|
const comparisonVal = this.bigNumFromParam(bn);
|
|
84
84
|
if (!ignorePrecision && !comparisonVal.eq(numericConstants_1.ZERO)) {
|
|
85
|
-
|
|
85
|
+
assert_1.assert(comparisonVal.precision.eq(this.precision), 'Trying to compare numbers with different precision. Yo can opt to ignore precision using the ignorePrecision parameter');
|
|
86
86
|
}
|
|
87
87
|
return this.val.gt(comparisonVal.val);
|
|
88
88
|
}
|
|
89
89
|
lt(bn, ignorePrecision) {
|
|
90
90
|
const comparisonVal = this.bigNumFromParam(bn);
|
|
91
91
|
if (!ignorePrecision && !comparisonVal.val.eq(numericConstants_1.ZERO)) {
|
|
92
|
-
|
|
92
|
+
assert_1.assert(comparisonVal.precision.eq(this.precision), 'Trying to compare numbers with different precision. Yo can opt to ignore precision using the ignorePrecision parameter');
|
|
93
93
|
}
|
|
94
94
|
return this.val.lt(comparisonVal.val);
|
|
95
95
|
}
|
|
96
96
|
gte(bn, ignorePrecision) {
|
|
97
97
|
const comparisonVal = this.bigNumFromParam(bn);
|
|
98
98
|
if (!ignorePrecision && !comparisonVal.val.eq(numericConstants_1.ZERO)) {
|
|
99
|
-
|
|
99
|
+
assert_1.assert(comparisonVal.precision.eq(this.precision), 'Trying to compare numbers with different precision. Yo can opt to ignore precision using the ignorePrecision parameter');
|
|
100
100
|
}
|
|
101
101
|
return this.val.gte(comparisonVal.val);
|
|
102
102
|
}
|
|
103
103
|
lte(bn, ignorePrecision) {
|
|
104
104
|
const comparisonVal = this.bigNumFromParam(bn);
|
|
105
105
|
if (!ignorePrecision && !comparisonVal.val.eq(numericConstants_1.ZERO)) {
|
|
106
|
-
|
|
106
|
+
assert_1.assert(comparisonVal.precision.eq(this.precision), 'Trying to compare numbers with different precision. Yo can opt to ignore precision using the ignorePrecision parameter');
|
|
107
107
|
}
|
|
108
108
|
return this.val.lte(comparisonVal.val);
|
|
109
109
|
}
|
|
110
110
|
eq(bn, ignorePrecision) {
|
|
111
111
|
const comparisonVal = this.bigNumFromParam(bn);
|
|
112
112
|
if (!ignorePrecision && !comparisonVal.val.eq(numericConstants_1.ZERO)) {
|
|
113
|
-
|
|
113
|
+
assert_1.assert(comparisonVal.precision.eq(this.precision), 'Trying to compare numbers with different precision. Yo can opt to ignore precision using the ignorePrecision parameter');
|
|
114
114
|
}
|
|
115
115
|
return this.val.eq(comparisonVal.val);
|
|
116
116
|
}
|
|
@@ -140,7 +140,7 @@ class BigNum {
|
|
|
140
140
|
* @returns
|
|
141
141
|
*/
|
|
142
142
|
print() {
|
|
143
|
-
|
|
143
|
+
assert_1.assert(this.precision.gte(numericConstants_1.ZERO), 'Tried to print a BN with precision lower than zero');
|
|
144
144
|
const isNeg = this.isNeg();
|
|
145
145
|
const plainString = this.abs().toString();
|
|
146
146
|
const precisionNum = this.precision.toNumber();
|
|
@@ -409,7 +409,7 @@ class BigNum {
|
|
|
409
409
|
* @returns
|
|
410
410
|
*/
|
|
411
411
|
static from(val = numericConstants_1.ZERO, precision) {
|
|
412
|
-
|
|
412
|
+
assert_1.assert(new anchor_1.BN(precision).lt(new anchor_1.BN(100)), 'Tried to create a bignum with precision higher than 10^100');
|
|
413
413
|
return new BigNum(val, precision);
|
|
414
414
|
}
|
|
415
415
|
/**
|
|
@@ -6,13 +6,13 @@ const pythClient_1 = require("../oracles/pythClient");
|
|
|
6
6
|
// import { SwitchboardClient } from '../oracles/switchboardClient';
|
|
7
7
|
const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
|
|
8
8
|
function getOracleClient(oracleSource, connection) {
|
|
9
|
-
if (
|
|
9
|
+
if (types_1.isVariant(oracleSource, 'pyth')) {
|
|
10
10
|
return new pythClient_1.PythClient(connection);
|
|
11
11
|
}
|
|
12
12
|
// if (isVariant(oracleSource, 'switchboard')) {
|
|
13
13
|
// return new SwitchboardClient(connection);
|
|
14
14
|
// }
|
|
15
|
-
if (
|
|
15
|
+
if (types_1.isVariant(oracleSource, 'quoteAsset')) {
|
|
16
16
|
return new quoteAssetOracleClient_1.QuoteAssetOracleClient();
|
|
17
17
|
}
|
|
18
18
|
throw new Error(`Unknown oracle source ${oracleSource}`);
|
package/lib/idl/drift.json
CHANGED
package/lib/index.js
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
9
5
|
}) : (function(o, m, k, k2) {
|
|
10
6
|
if (k2 === undefined) k2 = k;
|
|
11
7
|
o[k2] = m[k];
|
package/lib/math/amm.js
CHANGED
|
@@ -20,7 +20,7 @@ function calculateOptimalPegAndBudget(amm, oraclePriceData) {
|
|
|
20
20
|
const reservePriceBefore = calculatePrice(amm.baseAssetReserve, amm.quoteAssetReserve, amm.pegMultiplier);
|
|
21
21
|
const targetPrice = oraclePriceData.price;
|
|
22
22
|
const newPeg = calculatePegFromTargetPrice(targetPrice, amm.baseAssetReserve, amm.quoteAssetReserve);
|
|
23
|
-
const prePegCost =
|
|
23
|
+
const prePegCost = repeg_1.calculateRepegCost(amm, newPeg);
|
|
24
24
|
const totalFeeLB = amm.totalExchangeFee.div(new anchor_1.BN(2));
|
|
25
25
|
const budget = anchor_1.BN.max(numericConstants_1.ZERO, amm.totalFeeMinusDistributions.sub(totalFeeLB));
|
|
26
26
|
let checkLowerBound = true;
|
|
@@ -42,7 +42,7 @@ function calculateOptimalPegAndBudget(amm, oraclePriceData) {
|
|
|
42
42
|
newTargetPrice = reservePriceBefore.sub(markAdj);
|
|
43
43
|
}
|
|
44
44
|
newOptimalPeg = calculatePegFromTargetPrice(newTargetPrice, amm.baseAssetReserve, amm.quoteAssetReserve);
|
|
45
|
-
newBudget =
|
|
45
|
+
newBudget = repeg_1.calculateRepegCost(amm, newOptimalPeg);
|
|
46
46
|
checkLowerBound = false;
|
|
47
47
|
return [newTargetPrice, newOptimalPeg, newBudget, false];
|
|
48
48
|
}
|
|
@@ -57,12 +57,12 @@ function calculateNewAmm(amm, oraclePriceData) {
|
|
|
57
57
|
let pKNumer = new anchor_1.BN(1);
|
|
58
58
|
let pKDenom = new anchor_1.BN(1);
|
|
59
59
|
const [targetPrice, _newPeg, budget, _checkLowerBound] = calculateOptimalPegAndBudget(amm, oraclePriceData);
|
|
60
|
-
let prePegCost =
|
|
60
|
+
let prePegCost = repeg_1.calculateRepegCost(amm, _newPeg);
|
|
61
61
|
let newPeg = _newPeg;
|
|
62
62
|
if (prePegCost.gte(budget) && prePegCost.gt(numericConstants_1.ZERO)) {
|
|
63
63
|
[pKNumer, pKDenom] = [new anchor_1.BN(999), new anchor_1.BN(1000)];
|
|
64
|
-
const deficitMadeup =
|
|
65
|
-
|
|
64
|
+
const deficitMadeup = repeg_1.calculateAdjustKCost(amm, pKNumer, pKDenom);
|
|
65
|
+
assert_1.assert(deficitMadeup.lte(new anchor_1.BN(0)));
|
|
66
66
|
prePegCost = budget.add(deficitMadeup.abs());
|
|
67
67
|
const newAmm = Object.assign({}, amm);
|
|
68
68
|
newAmm.baseAssetReserve = newAmm.baseAssetReserve.mul(pKNumer).div(pKDenom);
|
|
@@ -74,8 +74,8 @@ function calculateNewAmm(amm, oraclePriceData) {
|
|
|
74
74
|
: types_1.PositionDirection.LONG;
|
|
75
75
|
const [newQuoteAssetReserve, _newBaseAssetReserve] = calculateAmmReservesAfterSwap(newAmm, 'base', amm.baseAssetAmountWithAmm.abs(), getSwapDirection('base', directionToClose));
|
|
76
76
|
newAmm.terminalQuoteAssetReserve = newQuoteAssetReserve;
|
|
77
|
-
newPeg =
|
|
78
|
-
prePegCost =
|
|
77
|
+
newPeg = repeg_1.calculateBudgetedPeg(newAmm, prePegCost, targetPrice);
|
|
78
|
+
prePegCost = repeg_1.calculateRepegCost(newAmm, newPeg);
|
|
79
79
|
}
|
|
80
80
|
return [prePegCost, pKNumer, pKDenom, newPeg];
|
|
81
81
|
}
|
|
@@ -106,7 +106,7 @@ exports.calculateUpdatedAMM = calculateUpdatedAMM;
|
|
|
106
106
|
function calculateUpdatedAMMSpreadReserves(amm, direction, oraclePriceData) {
|
|
107
107
|
const newAmm = calculateUpdatedAMM(amm, oraclePriceData);
|
|
108
108
|
const [shortReserves, longReserves] = calculateSpreadReserves(newAmm, oraclePriceData);
|
|
109
|
-
const dirReserves =
|
|
109
|
+
const dirReserves = types_1.isVariant(direction, 'long')
|
|
110
110
|
? longReserves
|
|
111
111
|
: shortReserves;
|
|
112
112
|
const result = {
|
|
@@ -161,7 +161,7 @@ exports.calculatePrice = calculatePrice;
|
|
|
161
161
|
* @returns quoteAssetReserve and baseAssetReserve after swap. : Precision AMM_RESERVE_PRECISION
|
|
162
162
|
*/
|
|
163
163
|
function calculateAmmReservesAfterSwap(amm, inputAssetType, swapAmount, swapDirection) {
|
|
164
|
-
|
|
164
|
+
assert_1.assert(swapAmount.gte(numericConstants_1.ZERO), 'swapAmount must be greater than 0');
|
|
165
165
|
let newQuoteAssetReserve;
|
|
166
166
|
let newBaseAssetReserve;
|
|
167
167
|
if (inputAssetType === 'quote') {
|
|
@@ -256,16 +256,16 @@ function calculateVolSpreadBN(lastOracleConfPct, reservePrice, markStd, oracleSt
|
|
|
256
256
|
const volSpread = anchor_1.BN.max(lastOracleConfPct, marketAvgStdPct.div(new anchor_1.BN(2)));
|
|
257
257
|
const clampMin = numericConstants_1.PERCENTAGE_PRECISION.div(new anchor_1.BN(100));
|
|
258
258
|
const clampMax = numericConstants_1.PERCENTAGE_PRECISION.mul(new anchor_1.BN(16)).div(new anchor_1.BN(10));
|
|
259
|
-
const longVolSpreadFactor =
|
|
260
|
-
const shortVolSpreadFactor =
|
|
259
|
+
const longVolSpreadFactor = __1.clampBN(longIntensity.mul(numericConstants_1.PERCENTAGE_PRECISION).div(anchor_1.BN.max(numericConstants_1.ONE, volume24H)), clampMin, clampMax);
|
|
260
|
+
const shortVolSpreadFactor = __1.clampBN(shortIntensity.mul(numericConstants_1.PERCENTAGE_PRECISION).div(anchor_1.BN.max(numericConstants_1.ONE, volume24H)), clampMin, clampMax);
|
|
261
261
|
const longVolSpread = anchor_1.BN.max(lastOracleConfPct, volSpread.mul(longVolSpreadFactor).div(numericConstants_1.PERCENTAGE_PRECISION));
|
|
262
262
|
const shortVolSpread = anchor_1.BN.max(lastOracleConfPct, volSpread.mul(shortVolSpreadFactor).div(numericConstants_1.PERCENTAGE_PRECISION));
|
|
263
263
|
return [longVolSpread, shortVolSpread];
|
|
264
264
|
}
|
|
265
265
|
exports.calculateVolSpreadBN = calculateVolSpreadBN;
|
|
266
266
|
function calculateSpreadBN(baseSpread, lastOracleReservePriceSpreadPct, lastOracleConfPct, maxSpread, quoteAssetReserve, terminalQuoteAssetReserve, pegMultiplier, baseAssetAmountWithAmm, reservePrice, totalFeeMinusDistributions, netRevenueSinceLastFunding, baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve, markStd, oracleStd, longIntensity, shortIntensity, volume24H, returnTerms = false) {
|
|
267
|
-
|
|
268
|
-
|
|
267
|
+
assert_1.assert(Number.isInteger(baseSpread));
|
|
268
|
+
assert_1.assert(Number.isInteger(maxSpread));
|
|
269
269
|
const spreadTerms = {
|
|
270
270
|
longVolSpread: 0,
|
|
271
271
|
shortVolSpread: 0,
|
|
@@ -395,7 +395,7 @@ function calculateSpread(amm, oraclePriceData, now) {
|
|
|
395
395
|
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
|
|
396
396
|
.div(reservePrice);
|
|
397
397
|
now = now || new anchor_1.BN(new Date().getTime() / 1000); //todo
|
|
398
|
-
const liveOracleStd =
|
|
398
|
+
const liveOracleStd = oracles_1.calculateLiveOracleStd(amm, oraclePriceData, now);
|
|
399
399
|
const spreads = calculateSpreadBN(amm.baseSpread, targetMarkSpreadPct, confIntervalPct, amm.maxSpread, amm.quoteAssetReserve, amm.terminalQuoteAssetReserve, amm.pegMultiplier, amm.baseAssetAmountWithAmm, reservePrice, amm.totalFeeMinusDistributions, amm.netRevenueSinceLastFunding, amm.baseAssetReserve, amm.minBaseAssetReserve, amm.maxBaseAssetReserve, amm.markStd, liveOracleStd, amm.longIntensityVolume, amm.shortIntensityVolume, amm.volume24H);
|
|
400
400
|
const longSpread = spreads[0];
|
|
401
401
|
const shortSpread = spreads[1];
|
|
@@ -412,7 +412,7 @@ function calculateSpreadReserves(amm, oraclePriceData, now) {
|
|
|
412
412
|
}
|
|
413
413
|
const quoteAssetReserveDelta = amm.quoteAssetReserve.div(numericConstants_1.BID_ASK_SPREAD_PRECISION.div(new anchor_1.BN(spread / 2)));
|
|
414
414
|
let quoteAssetReserve;
|
|
415
|
-
if (
|
|
415
|
+
if (types_1.isVariant(direction, 'long')) {
|
|
416
416
|
quoteAssetReserve = amm.quoteAssetReserve.add(quoteAssetReserveDelta);
|
|
417
417
|
}
|
|
418
418
|
else {
|
|
@@ -458,10 +458,10 @@ exports.calculateSwapOutput = calculateSwapOutput;
|
|
|
458
458
|
* @param positionDirection
|
|
459
459
|
*/
|
|
460
460
|
function getSwapDirection(inputAssetType, positionDirection) {
|
|
461
|
-
if (
|
|
461
|
+
if (types_1.isVariant(positionDirection, 'long') && inputAssetType === 'base') {
|
|
462
462
|
return types_1.SwapDirection.REMOVE;
|
|
463
463
|
}
|
|
464
|
-
if (
|
|
464
|
+
if (types_1.isVariant(positionDirection, 'short') && inputAssetType === 'quote') {
|
|
465
465
|
return types_1.SwapDirection.REMOVE;
|
|
466
466
|
}
|
|
467
467
|
return types_1.SwapDirection.ADD;
|
|
@@ -493,9 +493,9 @@ function calculateMaxBaseAssetAmountToTrade(amm, limit_price, direction, oracleP
|
|
|
493
493
|
.mul(amm.pegMultiplier)
|
|
494
494
|
.div(limit_price)
|
|
495
495
|
.div(numericConstants_1.PEG_PRECISION);
|
|
496
|
-
const newBaseAssetReserve =
|
|
496
|
+
const newBaseAssetReserve = __1.squareRootBN(newBaseAssetReserveSquared);
|
|
497
497
|
const [shortSpreadReserves, longSpreadReserves] = calculateSpreadReserves(amm, oraclePriceData, now);
|
|
498
|
-
const baseAssetReserveBefore =
|
|
498
|
+
const baseAssetReserveBefore = types_1.isVariant(direction, 'long')
|
|
499
499
|
? longSpreadReserves.baseAssetReserve
|
|
500
500
|
: shortSpreadReserves.baseAssetReserve;
|
|
501
501
|
if (newBaseAssetReserve.gt(baseAssetReserveBefore)) {
|
|
@@ -517,13 +517,13 @@ function calculateMaxBaseAssetAmountToTrade(amm, limit_price, direction, oracleP
|
|
|
517
517
|
}
|
|
518
518
|
exports.calculateMaxBaseAssetAmountToTrade = calculateMaxBaseAssetAmountToTrade;
|
|
519
519
|
function calculateQuoteAssetAmountSwapped(quoteAssetReserves, pegMultiplier, swapDirection) {
|
|
520
|
-
if (
|
|
520
|
+
if (types_1.isVariant(swapDirection, 'remove')) {
|
|
521
521
|
quoteAssetReserves = quoteAssetReserves.add(numericConstants_1.ONE);
|
|
522
522
|
}
|
|
523
523
|
let quoteAssetAmount = quoteAssetReserves
|
|
524
524
|
.mul(pegMultiplier)
|
|
525
525
|
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
526
|
-
if (
|
|
526
|
+
if (types_1.isVariant(swapDirection, 'remove')) {
|
|
527
527
|
quoteAssetAmount = quoteAssetAmount.add(numericConstants_1.ONE);
|
|
528
528
|
}
|
|
529
529
|
return quoteAssetAmount;
|
|
@@ -532,12 +532,12 @@ exports.calculateQuoteAssetAmountSwapped = calculateQuoteAssetAmountSwapped;
|
|
|
532
532
|
function calculateMaxBaseAssetAmountFillable(amm, orderDirection) {
|
|
533
533
|
const maxFillSize = amm.baseAssetReserve.div(new anchor_1.BN(amm.maxFillReserveFraction));
|
|
534
534
|
let maxBaseAssetAmountOnSide;
|
|
535
|
-
if (
|
|
535
|
+
if (types_1.isVariant(orderDirection, 'long')) {
|
|
536
536
|
maxBaseAssetAmountOnSide = anchor_1.BN.max(numericConstants_1.ZERO, amm.baseAssetReserve.sub(amm.minBaseAssetReserve));
|
|
537
537
|
}
|
|
538
538
|
else {
|
|
539
539
|
maxBaseAssetAmountOnSide = anchor_1.BN.max(numericConstants_1.ZERO, amm.maxBaseAssetReserve.sub(amm.baseAssetReserve));
|
|
540
540
|
}
|
|
541
|
-
return
|
|
541
|
+
return __1.standardizeBaseAssetAmount(anchor_1.BN.min(maxFillSize, maxBaseAssetAmountOnSide), amm.orderStepSize);
|
|
542
542
|
}
|
|
543
543
|
exports.calculateMaxBaseAssetAmountFillable = calculateMaxBaseAssetAmountFillable;
|
package/lib/math/auction.js
CHANGED
|
@@ -11,10 +11,10 @@ function isAuctionComplete(order, slot) {
|
|
|
11
11
|
}
|
|
12
12
|
exports.isAuctionComplete = isAuctionComplete;
|
|
13
13
|
function getAuctionPrice(order, slot, oraclePrice) {
|
|
14
|
-
if (
|
|
14
|
+
if (types_1.isOneOfVariant(order.orderType, ['market', 'triggerMarket'])) {
|
|
15
15
|
return getAuctionPriceForFixedAuction(order, slot);
|
|
16
16
|
}
|
|
17
|
-
else if (
|
|
17
|
+
else if (types_1.isVariant(order.orderType, 'oracle')) {
|
|
18
18
|
return getAuctionPriceForOracleOffsetAuction(order, slot, oraclePrice);
|
|
19
19
|
}
|
|
20
20
|
else {
|
|
@@ -30,7 +30,7 @@ function getAuctionPriceForFixedAuction(order, slot) {
|
|
|
30
30
|
return order.auctionEndPrice;
|
|
31
31
|
}
|
|
32
32
|
let priceDelta;
|
|
33
|
-
if (
|
|
33
|
+
if (types_1.isVariant(order.direction, 'long')) {
|
|
34
34
|
priceDelta = order.auctionEndPrice
|
|
35
35
|
.sub(order.auctionStartPrice)
|
|
36
36
|
.mul(deltaNumerator)
|
|
@@ -43,7 +43,7 @@ function getAuctionPriceForFixedAuction(order, slot) {
|
|
|
43
43
|
.div(deltaDenominator);
|
|
44
44
|
}
|
|
45
45
|
let price;
|
|
46
|
-
if (
|
|
46
|
+
if (types_1.isVariant(order.direction, 'long')) {
|
|
47
47
|
price = order.auctionStartPrice.add(priceDelta);
|
|
48
48
|
}
|
|
49
49
|
else {
|
|
@@ -60,7 +60,7 @@ function getAuctionPriceForOracleOffsetAuction(order, slot, oraclePrice) {
|
|
|
60
60
|
return order.auctionEndPrice.add(order.auctionEndPrice);
|
|
61
61
|
}
|
|
62
62
|
let priceOffsetDelta;
|
|
63
|
-
if (
|
|
63
|
+
if (types_1.isVariant(order.direction, 'long')) {
|
|
64
64
|
priceOffsetDelta = order.auctionEndPrice
|
|
65
65
|
.sub(order.auctionStartPrice)
|
|
66
66
|
.mul(deltaNumerator)
|
|
@@ -73,7 +73,7 @@ function getAuctionPriceForOracleOffsetAuction(order, slot, oraclePrice) {
|
|
|
73
73
|
.div(deltaDenominator);
|
|
74
74
|
}
|
|
75
75
|
let priceOffset;
|
|
76
|
-
if (
|
|
76
|
+
if (types_1.isVariant(order.direction, 'long')) {
|
|
77
77
|
priceOffset = order.auctionStartPrice.add(priceOffsetDelta);
|
|
78
78
|
}
|
|
79
79
|
else {
|
|
@@ -9,12 +9,12 @@ exports.exchangePaused = exchangePaused;
|
|
|
9
9
|
function fillPaused(state, market) {
|
|
10
10
|
return ((state.exchangeStatus & types_1.ExchangeStatus.FILL_PAUSED) ===
|
|
11
11
|
types_1.ExchangeStatus.FILL_PAUSED ||
|
|
12
|
-
|
|
12
|
+
types_1.isOneOfVariant(market.status, ['paused', 'fillPaused']));
|
|
13
13
|
}
|
|
14
14
|
exports.fillPaused = fillPaused;
|
|
15
15
|
function ammPaused(state, market) {
|
|
16
16
|
return ((state.exchangeStatus & types_1.ExchangeStatus.AMM_PAUSED) ===
|
|
17
17
|
types_1.ExchangeStatus.AMM_PAUSED ||
|
|
18
|
-
|
|
18
|
+
types_1.isOneOfVariant(market.status, ['paused', 'ammPaused']));
|
|
19
19
|
}
|
|
20
20
|
exports.ammPaused = ammPaused;
|
package/lib/math/funding.js
CHANGED
|
@@ -20,7 +20,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
20
20
|
const secondsInHour = new anchor_1.BN(3600);
|
|
21
21
|
const hoursInDay = new anchor_1.BN(24);
|
|
22
22
|
const ONE = new anchor_1.BN(1);
|
|
23
|
-
if (
|
|
23
|
+
if (types_1.isVariant(market.status, 'uninitialized')) {
|
|
24
24
|
return [numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO];
|
|
25
25
|
}
|
|
26
26
|
const payFreq = new anchor_1.BN(market.amm.fundingPeriod);
|
|
@@ -32,7 +32,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
32
32
|
const lastMarkPriceTwapTs = market.amm.lastMarkPriceTwapTs;
|
|
33
33
|
const timeSinceLastMarkChange = now.sub(lastMarkPriceTwapTs);
|
|
34
34
|
const markTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, anchor_1.BN.max(numericConstants_1.ZERO, secondsInHour.sub(timeSinceLastMarkChange)));
|
|
35
|
-
const [bid, ask] =
|
|
35
|
+
const [bid, ask] = amm_1.calculateBidAskPrice(market.amm, oraclePriceData);
|
|
36
36
|
const baseAssetPriceWithMantissa = bid.add(ask).div(new anchor_1.BN(2));
|
|
37
37
|
const markTwapWithMantissa = markTwapTimeSinceLastUpdate
|
|
38
38
|
.mul(lastMarkTwapWithMantissa)
|
package/lib/math/margin.js
CHANGED
|
@@ -11,12 +11,12 @@ imfFactor, liabilityWeight, precision) {
|
|
|
11
11
|
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
12
12
|
return liabilityWeight;
|
|
13
13
|
}
|
|
14
|
-
const sizeSqrt =
|
|
14
|
+
const sizeSqrt = utils_1.squareRootBN(size.abs().mul(new anchor_1.BN(10)).add(new anchor_1.BN(1))); //1e9 -> 1e10 -> 1e5
|
|
15
15
|
const denom0 = anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor));
|
|
16
|
-
|
|
16
|
+
assert_1.assert(denom0.gt(numericConstants_1.ZERO));
|
|
17
17
|
const liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor))));
|
|
18
18
|
const denom = new anchor_1.BN(100000).mul(numericConstants_1.SPOT_MARKET_IMF_PRECISION).div(precision);
|
|
19
|
-
|
|
19
|
+
assert_1.assert(denom.gt(numericConstants_1.ZERO));
|
|
20
20
|
const sizePremiumLiabilityWeight = liabilityWeightNumerator.add(sizeSqrt // 1e5
|
|
21
21
|
.mul(imfFactor)
|
|
22
22
|
.div(denom) // 1e5
|
|
@@ -30,7 +30,7 @@ imfFactor, assetWeight) {
|
|
|
30
30
|
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
31
31
|
return assetWeight;
|
|
32
32
|
}
|
|
33
|
-
const sizeSqrt =
|
|
33
|
+
const sizeSqrt = utils_1.squareRootBN(size.abs().mul(new anchor_1.BN(10)).add(new anchor_1.BN(1))); //1e9 -> 1e10 -> 1e5
|
|
34
34
|
const imfNumerator = numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(new anchor_1.BN(10)));
|
|
35
35
|
const sizeDiscountAssetWeight = imfNumerator
|
|
36
36
|
.mul(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
|
|
@@ -60,7 +60,7 @@ function calculateOraclePriceForPerpMargin(perpPosition, market, oraclePriceData
|
|
|
60
60
|
exports.calculateOraclePriceForPerpMargin = calculateOraclePriceForPerpMargin;
|
|
61
61
|
function calculateBaseAssetValueWithOracle(market, perpPosition, oraclePriceData, includeOpenOrders = false) {
|
|
62
62
|
let price = oraclePriceData.price;
|
|
63
|
-
if (
|
|
63
|
+
if (types_1.isVariant(market.status, 'settlement')) {
|
|
64
64
|
price = market.expiryPrice;
|
|
65
65
|
}
|
|
66
66
|
const baseAssetAmount = includeOpenOrders
|
package/lib/math/market.js
CHANGED
|
@@ -14,8 +14,8 @@ const spotBalance_1 = require("./spotBalance");
|
|
|
14
14
|
* @return markPrice : Precision PRICE_PRECISION
|
|
15
15
|
*/
|
|
16
16
|
function calculateReservePrice(market, oraclePriceData) {
|
|
17
|
-
const newAmm =
|
|
18
|
-
return
|
|
17
|
+
const newAmm = amm_1.calculateUpdatedAMM(market.amm, oraclePriceData);
|
|
18
|
+
return amm_1.calculatePrice(newAmm.baseAssetReserve, newAmm.quoteAssetReserve, newAmm.pegMultiplier);
|
|
19
19
|
}
|
|
20
20
|
exports.calculateReservePrice = calculateReservePrice;
|
|
21
21
|
/**
|
|
@@ -25,8 +25,8 @@ exports.calculateReservePrice = calculateReservePrice;
|
|
|
25
25
|
* @return bidPrice : Precision PRICE_PRECISION
|
|
26
26
|
*/
|
|
27
27
|
function calculateBidPrice(market, oraclePriceData) {
|
|
28
|
-
const { baseAssetReserve, quoteAssetReserve, newPeg } =
|
|
29
|
-
return
|
|
28
|
+
const { baseAssetReserve, quoteAssetReserve, newPeg } = amm_1.calculateUpdatedAMMSpreadReserves(market.amm, types_1.PositionDirection.SHORT, oraclePriceData);
|
|
29
|
+
return amm_1.calculatePrice(baseAssetReserve, quoteAssetReserve, newPeg);
|
|
30
30
|
}
|
|
31
31
|
exports.calculateBidPrice = calculateBidPrice;
|
|
32
32
|
/**
|
|
@@ -36,12 +36,12 @@ exports.calculateBidPrice = calculateBidPrice;
|
|
|
36
36
|
* @return askPrice : Precision PRICE_PRECISION
|
|
37
37
|
*/
|
|
38
38
|
function calculateAskPrice(market, oraclePriceData) {
|
|
39
|
-
const { baseAssetReserve, quoteAssetReserve, newPeg } =
|
|
40
|
-
return
|
|
39
|
+
const { baseAssetReserve, quoteAssetReserve, newPeg } = amm_1.calculateUpdatedAMMSpreadReserves(market.amm, types_1.PositionDirection.LONG, oraclePriceData);
|
|
40
|
+
return amm_1.calculatePrice(baseAssetReserve, quoteAssetReserve, newPeg);
|
|
41
41
|
}
|
|
42
42
|
exports.calculateAskPrice = calculateAskPrice;
|
|
43
43
|
function calculateNewMarketAfterTrade(baseAssetAmount, direction, market) {
|
|
44
|
-
const [newQuoteAssetReserve, newBaseAssetReserve] =
|
|
44
|
+
const [newQuoteAssetReserve, newBaseAssetReserve] = amm_1.calculateAmmReservesAfterSwap(market.amm, 'base', baseAssetAmount.abs(), amm_1.getSwapDirection('base', direction));
|
|
45
45
|
const newAmm = Object.assign({}, market.amm);
|
|
46
46
|
const newMarket = Object.assign({}, market);
|
|
47
47
|
newMarket.amm = newAmm;
|
|
@@ -63,10 +63,10 @@ function calculateMarketMarginRatio(market, size, marginCategory) {
|
|
|
63
63
|
let marginRatio;
|
|
64
64
|
switch (marginCategory) {
|
|
65
65
|
case 'Initial':
|
|
66
|
-
marginRatio =
|
|
66
|
+
marginRatio = margin_1.calculateSizePremiumLiabilityWeight(size, new anchor_1.BN(market.imfFactor), new anchor_1.BN(market.marginRatioInitial), numericConstants_1.MARGIN_PRECISION).toNumber();
|
|
67
67
|
break;
|
|
68
68
|
case 'Maintenance':
|
|
69
|
-
marginRatio =
|
|
69
|
+
marginRatio = margin_1.calculateSizePremiumLiabilityWeight(size, new anchor_1.BN(market.imfFactor), new anchor_1.BN(market.marginRatioMaintenance), numericConstants_1.MARGIN_PRECISION).toNumber();
|
|
70
70
|
break;
|
|
71
71
|
}
|
|
72
72
|
return marginRatio;
|
|
@@ -85,7 +85,7 @@ function calculateUnrealizedAssetWeight(market, quoteSpotMarket, unrealizedPnl,
|
|
|
85
85
|
.div(netUnsettledPnl);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
assetWeight =
|
|
88
|
+
assetWeight = margin_1.calculateSizeDiscountAssetWeight(unrealizedPnl, new anchor_1.BN(market.unrealizedPnlImfFactor), assetWeight);
|
|
89
89
|
break;
|
|
90
90
|
case 'Maintenance':
|
|
91
91
|
assetWeight = new anchor_1.BN(market.unrealizedPnlMaintenanceAssetWeight);
|
|
@@ -95,7 +95,7 @@ function calculateUnrealizedAssetWeight(market, quoteSpotMarket, unrealizedPnl,
|
|
|
95
95
|
}
|
|
96
96
|
exports.calculateUnrealizedAssetWeight = calculateUnrealizedAssetWeight;
|
|
97
97
|
function calculateMarketAvailablePNL(perpMarket, spotMarket) {
|
|
98
|
-
return
|
|
98
|
+
return spotBalance_1.getTokenAmount(perpMarket.pnlPool.scaledBalance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
|
|
99
99
|
}
|
|
100
100
|
exports.calculateMarketAvailablePNL = calculateMarketAvailablePNL;
|
|
101
101
|
function calculateNetUserPnl(perpMarket, oraclePriceData) {
|
|
@@ -110,13 +110,13 @@ function calculateNetUserPnl(perpMarket, oraclePriceData) {
|
|
|
110
110
|
exports.calculateNetUserPnl = calculateNetUserPnl;
|
|
111
111
|
function calculateNetUserPnlImbalance(perpMarket, spotMarket, oraclePriceData) {
|
|
112
112
|
const netUserPnl = calculateNetUserPnl(perpMarket, oraclePriceData);
|
|
113
|
-
const pnlPool =
|
|
113
|
+
const pnlPool = spotBalance_1.getTokenAmount(perpMarket.pnlPool.scaledBalance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
|
|
114
114
|
const imbalance = netUserPnl.sub(pnlPool);
|
|
115
115
|
return imbalance;
|
|
116
116
|
}
|
|
117
117
|
exports.calculateNetUserPnlImbalance = calculateNetUserPnlImbalance;
|
|
118
118
|
function calculateAvailablePerpLiquidity(market, oraclePriceData, dlob, slot) {
|
|
119
|
-
let [bids, asks] =
|
|
119
|
+
let [bids, asks] = amm_1.calculateMarketOpenBidAsk(market.amm.baseAssetReserve, market.amm.minBaseAssetReserve, market.amm.maxBaseAssetReserve, market.amm.orderStepSize);
|
|
120
120
|
asks = asks.abs();
|
|
121
121
|
const bidPrice = calculateBidPrice(market, oraclePriceData);
|
|
122
122
|
const askPrice = calculateAskPrice(market, oraclePriceData);
|
package/lib/math/oracles.js
CHANGED
|
@@ -9,7 +9,7 @@ function oraclePriceBands(market, oraclePriceData) {
|
|
|
9
9
|
const offset = oraclePriceData.price
|
|
10
10
|
.mul(new index_1.BN(maxPercentDiff))
|
|
11
11
|
.div(numericConstants_1.MARGIN_PRECISION);
|
|
12
|
-
|
|
12
|
+
assert_1.assert(offset.gt(numericConstants_1.ZERO));
|
|
13
13
|
return [oraclePriceData.price.sub(offset), oraclePriceData.price.add(offset)];
|
|
14
14
|
}
|
|
15
15
|
exports.oraclePriceBands = oraclePriceBands;
|