@drift-labs/sdk 0.1.36-master.5 → 0.2.0-master.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 +7 -6
- package/lib/accounts/bulkAccountLoader.js +83 -93
- package/lib/accounts/bulkUserSubscription.js +13 -57
- package/lib/accounts/fetch.d.ts +4 -0
- package/lib/accounts/fetch.js +18 -0
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +34 -38
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +224 -224
- package/lib/accounts/pollingOracleSubscriber.d.ts +3 -3
- package/lib/accounts/pollingOracleSubscriber.js +37 -49
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
- package/lib/accounts/pollingTokenAccountSubscriber.js +35 -50
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +7 -13
- package/lib/accounts/pollingUserAccountSubscriber.js +71 -134
- package/lib/accounts/types.d.ts +34 -41
- package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -4
- package/lib/accounts/webSocketAccountSubscriber.js +39 -35
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +33 -28
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +153 -185
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts +5 -11
- package/lib/accounts/webSocketUserAccountSubscriber.js +22 -67
- package/lib/addresses/marketAddresses.d.ts +4 -0
- package/lib/addresses/marketAddresses.js +15 -0
- package/lib/addresses/pda.d.ts +12 -0
- package/lib/addresses/pda.js +83 -0
- package/lib/admin.d.ts +8 -12
- package/lib/admin.js +366 -490
- package/lib/clearingHouse.d.ts +84 -103
- package/lib/clearingHouse.js +779 -810
- package/lib/clearingHouseConfig.d.ts +34 -0
- package/lib/clearingHouseConfig.js +2 -0
- package/lib/clearingHouseUser.d.ts +19 -18
- package/lib/clearingHouseUser.js +157 -115
- package/lib/clearingHouseUserConfig.d.ts +14 -0
- package/lib/clearingHouseUserConfig.js +2 -0
- package/lib/config.d.ts +12 -0
- package/lib/config.js +35 -4
- package/lib/constants/banks.d.ts +16 -0
- package/lib/constants/banks.js +34 -0
- package/lib/constants/markets.d.ts +8 -3
- package/lib/constants/markets.js +13 -206
- package/lib/constants/numericConstants.d.ts +16 -0
- package/lib/constants/numericConstants.js +22 -6
- package/lib/events/eventList.d.ts +22 -0
- package/lib/events/eventList.js +77 -0
- package/lib/events/eventSubscriber.d.ts +34 -0
- package/lib/events/eventSubscriber.js +126 -0
- package/lib/events/fetchLogs.d.ts +13 -0
- package/lib/events/fetchLogs.js +39 -0
- package/lib/events/pollingLogProvider.d.ts +15 -0
- package/lib/events/pollingLogProvider.js +53 -0
- package/lib/events/sort.d.ts +2 -0
- package/lib/events/sort.js +44 -0
- package/lib/events/txEventCache.d.ts +24 -0
- package/lib/events/txEventCache.js +71 -0
- package/lib/events/types.d.ts +49 -0
- package/lib/events/types.js +20 -0
- package/lib/events/webSocketLogProvider.d.ts +12 -0
- package/lib/events/webSocketLogProvider.js +30 -0
- package/lib/examples/makeTradeExample.js +26 -27
- package/lib/factory/bigNum.d.ts +112 -0
- package/lib/factory/bigNum.js +356 -0
- package/lib/factory/oracleClient.d.ts +1 -2
- package/lib/factory/oracleClient.js +6 -2
- package/lib/idl/clearing_house.json +1739 -2287
- package/lib/index.d.ts +13 -4
- package/lib/index.js +13 -4
- package/lib/math/amm.d.ts +19 -29
- package/lib/math/amm.js +129 -179
- package/lib/math/auction.d.ts +5 -0
- package/lib/math/auction.js +39 -0
- package/lib/math/bankBalance.d.ts +9 -0
- package/lib/math/bankBalance.js +75 -0
- package/lib/math/conversion.d.ts +0 -1
- package/lib/math/conversion.js +1 -5
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +158 -175
- package/lib/math/market.d.ts +6 -6
- package/lib/math/market.js +10 -9
- package/lib/math/oracles.d.ts +3 -0
- package/lib/math/oracles.js +26 -0
- package/lib/math/orders.d.ts +5 -0
- package/lib/math/orders.js +31 -1
- package/lib/math/position.d.ts +7 -4
- package/lib/math/position.js +27 -9
- package/lib/math/repeg.d.ts +22 -0
- package/lib/math/repeg.js +128 -0
- package/lib/math/trade.d.ts +13 -8
- package/lib/math/trade.js +85 -22
- package/lib/mockUSDCFaucet.js +87 -116
- package/lib/oracles/oracleClientCache.d.ts +8 -0
- package/lib/oracles/oracleClientCache.js +19 -0
- package/lib/oracles/pythClient.d.ts +3 -5
- package/lib/oracles/pythClient.js +12 -30
- package/lib/oracles/quoteAssetOracleClient.d.ts +9 -0
- package/lib/oracles/quoteAssetOracleClient.js +21 -0
- package/lib/oracles/switchboardClient.d.ts +3 -5
- package/lib/oracles/switchboardClient.js +29 -47
- package/lib/oracles/types.d.ts +7 -1
- package/lib/orders.d.ts +6 -6
- package/lib/orders.js +10 -9
- package/lib/slot/SlotSubscriber.d.ts +12 -0
- package/lib/slot/SlotSubscriber.js +23 -0
- package/lib/tx/retryTxSender.d.ts +2 -2
- package/lib/tx/retryTxSender.js +108 -123
- package/lib/tx/types.d.ts +5 -1
- package/lib/tx/utils.d.ts +1 -1
- package/lib/tx/utils.js +11 -2
- package/lib/types.d.ts +105 -98
- package/lib/types.js +13 -1
- package/lib/userName.d.ts +4 -0
- package/lib/userName.js +20 -0
- package/lib/util/computeUnits.js +10 -21
- package/lib/util/tps.js +11 -22
- package/lib/wallet.js +7 -20
- package/package.json +10 -3
- package/src/accounts/bulkAccountLoader.ts +26 -15
- package/src/accounts/bulkUserSubscription.ts +1 -45
- package/src/accounts/fetch.ts +33 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +249 -214
- package/src/accounts/pollingOracleSubscriber.ts +16 -8
- package/src/accounts/pollingTokenAccountSubscriber.ts +11 -8
- package/src/accounts/pollingUserAccountSubscriber.ts +21 -86
- package/src/accounts/types.ts +41 -70
- package/src/accounts/webSocketAccountSubscriber.ts +33 -16
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +190 -240
- package/src/accounts/webSocketUserAccountSubscriber.ts +11 -71
- package/src/addresses/marketAddresses.ts +18 -0
- package/src/addresses/pda.ts +118 -0
- package/src/admin.ts +209 -267
- package/src/clearingHouse.ts +921 -829
- package/src/clearingHouseConfig.ts +37 -0
- package/src/clearingHouseUser.ts +280 -127
- package/src/clearingHouseUserConfig.ts +18 -0
- package/src/config.ts +54 -1
- package/src/constants/banks.ts +43 -0
- package/src/constants/markets.ts +16 -207
- package/src/constants/numericConstants.ts +33 -5
- package/src/events/eventList.ts +94 -0
- package/src/events/eventSubscriber.ts +194 -0
- package/src/events/fetchLogs.ts +80 -0
- package/src/events/pollingLogProvider.ts +79 -0
- package/src/events/sort.ts +65 -0
- package/src/events/txEventCache.ts +74 -0
- package/src/events/types.ts +98 -0
- package/src/events/webSocketLogProvider.ts +38 -0
- package/src/examples/makeTradeExample.ts +20 -11
- package/src/factory/bigNum.ts +507 -0
- package/src/factory/oracleClient.ts +7 -4
- package/src/idl/clearing_house.json +1739 -2287
- package/src/index.ts +13 -4
- package/src/math/amm.ts +229 -245
- package/src/math/auction.ts +39 -0
- package/src/math/bankBalance.ts +112 -0
- package/src/math/conversion.ts +1 -11
- package/src/math/funding.ts +12 -9
- package/src/math/market.ts +37 -30
- package/src/math/oracles.ts +36 -0
- package/src/math/orders.ts +38 -0
- package/src/math/position.ts +48 -13
- package/src/math/repeg.ts +175 -0
- package/src/math/trade.ts +114 -36
- package/src/math/utils.js +27 -0
- package/src/math/utils.js.map +1 -0
- package/src/oracles/oracleClientCache.ts +20 -0
- package/src/oracles/pythClient.ts +5 -11
- package/src/oracles/quoteAssetOracleClient.ts +25 -0
- package/src/oracles/switchboardClient.ts +16 -24
- package/src/oracles/types.ts +8 -1
- package/src/orders.ts +35 -20
- package/src/slot/SlotSubscriber.ts +32 -0
- package/src/tx/retryTxSender.ts +6 -4
- package/src/tx/types.ts +6 -1
- package/src/tx/utils.ts +22 -3
- package/src/types.ts +108 -110
- package/src/userName.ts +20 -0
- package/src/util/computeUnits.js +17 -0
- package/src/util/computeUnits.js.map +1 -0
- package/tests/bn/test.ts +255 -0
- package/tsconfig.json +12 -12
- package/lib/addresses.d.ts +0 -9
- package/lib/addresses.js +0 -87
- package/lib/constants/accounts.d.ts +0 -15
- package/lib/constants/accounts.js +0 -18
- package/lib/factory/clearingHouse.d.ts +0 -35
- package/lib/factory/clearingHouse.js +0 -81
- package/lib/factory/clearingHouseUser.d.ts +0 -19
- package/lib/factory/clearingHouseUser.js +0 -34
- package/lib/math/insuranceFund.d.ts +0 -15
- package/lib/math/insuranceFund.js +0 -33
- package/lib/tx/defaultTxSender.d.ts +0 -8
- package/lib/tx/defaultTxSender.js +0 -12
- package/src/addresses.ts +0 -71
- package/src/constants/accounts.ts +0 -26
- package/src/factory/clearingHouse.ts +0 -173
- package/src/factory/clearingHouseUser.ts +0 -73
- package/src/math/insuranceFund.ts +0 -29
- package/src/tx/defaultTxSender.ts +0 -24
package/src/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './oracles/pythClient';
|
|
|
7
7
|
export * from './oracles/switchboardClient';
|
|
8
8
|
export * from './types';
|
|
9
9
|
export * from './constants/markets';
|
|
10
|
+
export * from './accounts/fetch';
|
|
10
11
|
export * from './accounts/webSocketClearingHouseAccountSubscriber';
|
|
11
12
|
export * from './accounts/bulkAccountLoader';
|
|
12
13
|
export * from './accounts/bulkUserSubscription';
|
|
@@ -14,23 +15,28 @@ export * from './accounts/pollingClearingHouseAccountSubscriber';
|
|
|
14
15
|
export * from './accounts/pollingOracleSubscriber';
|
|
15
16
|
export * from './accounts/pollingTokenAccountSubscriber';
|
|
16
17
|
export * from './accounts/types';
|
|
17
|
-
export * from './addresses';
|
|
18
|
+
export * from './addresses/pda';
|
|
18
19
|
export * from './admin';
|
|
19
20
|
export * from './clearingHouseUser';
|
|
21
|
+
export * from './clearingHouseUserConfig';
|
|
20
22
|
export * from './clearingHouse';
|
|
21
|
-
export * from './factory/clearingHouse';
|
|
22
|
-
export * from './factory/clearingHouseUser';
|
|
23
23
|
export * from './factory/oracleClient';
|
|
24
|
+
export * from './factory/bigNum';
|
|
25
|
+
export * from './events/types';
|
|
26
|
+
export * from './events/eventSubscriber';
|
|
27
|
+
export * from './math/auction';
|
|
24
28
|
export * from './math/conversion';
|
|
25
29
|
export * from './math/funding';
|
|
26
|
-
export * from './math/insuranceFund';
|
|
27
30
|
export * from './math/market';
|
|
28
31
|
export * from './math/position';
|
|
32
|
+
export * from './math/oracles';
|
|
29
33
|
export * from './math/amm';
|
|
30
34
|
export * from './math/trade';
|
|
31
35
|
export * from './math/orders';
|
|
36
|
+
export * from './math/repeg';
|
|
32
37
|
export * from './orders';
|
|
33
38
|
export * from './orderParams';
|
|
39
|
+
export * from './slot/SlotSubscriber';
|
|
34
40
|
export * from './wallet';
|
|
35
41
|
export * from './types';
|
|
36
42
|
export * from './math/utils';
|
|
@@ -39,5 +45,8 @@ export * from './constants/numericConstants';
|
|
|
39
45
|
export * from './tx/retryTxSender';
|
|
40
46
|
export * from './util/computeUnits';
|
|
41
47
|
export * from './util/tps';
|
|
48
|
+
export * from './math/bankBalance';
|
|
49
|
+
export * from './constants/banks';
|
|
50
|
+
export * from './clearingHouseConfig';
|
|
42
51
|
|
|
43
52
|
export { BN, PublicKey };
|
package/src/math/amm.ts
CHANGED
|
@@ -4,50 +4,189 @@ import {
|
|
|
4
4
|
MARK_PRICE_PRECISION,
|
|
5
5
|
PEG_PRECISION,
|
|
6
6
|
ZERO,
|
|
7
|
-
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
8
|
-
QUOTE_PRECISION,
|
|
9
|
-
AMM_RESERVE_PRECISION,
|
|
10
7
|
BID_ASK_SPREAD_PRECISION,
|
|
11
8
|
ONE,
|
|
9
|
+
// QUOTE_PRECISION,
|
|
10
|
+
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
12
11
|
} from '../constants/numericConstants';
|
|
13
|
-
import { calculateBaseAssetValue } from './position';
|
|
14
12
|
import {
|
|
15
13
|
AMM,
|
|
16
14
|
PositionDirection,
|
|
17
15
|
SwapDirection,
|
|
18
|
-
|
|
16
|
+
MarketAccount,
|
|
19
17
|
isVariant,
|
|
20
18
|
} from '../types';
|
|
21
19
|
import { assert } from '../assert/assert';
|
|
20
|
+
import { squareRootBN } from '..';
|
|
21
|
+
|
|
22
|
+
import { OraclePriceData } from '../oracles/types';
|
|
22
23
|
import {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
calculateRepegCost,
|
|
25
|
+
calculateAdjustKCost,
|
|
26
|
+
calculateBudgetedPeg,
|
|
27
|
+
} from './repeg';
|
|
28
|
+
export function calculateNewAmm(
|
|
29
|
+
amm: AMM,
|
|
30
|
+
oraclePriceData: OraclePriceData
|
|
31
|
+
): [BN, BN, BN, BN] {
|
|
32
|
+
let pKNumer = new BN(1);
|
|
33
|
+
let pKDenom = new BN(1);
|
|
34
|
+
|
|
35
|
+
const targetPrice = oraclePriceData.price;
|
|
36
|
+
let newPeg = targetPrice
|
|
37
|
+
.mul(amm.baseAssetReserve)
|
|
38
|
+
.div(amm.quoteAssetReserve)
|
|
39
|
+
.add(MARK_PRICE_PRECISION.div(PEG_PRECISION).div(new BN(2)))
|
|
40
|
+
.div(MARK_PRICE_PRECISION.div(PEG_PRECISION));
|
|
41
|
+
let prePegCost = calculateRepegCost(amm, newPeg);
|
|
42
|
+
|
|
43
|
+
const totalFeeLB = amm.totalExchangeFee.div(new BN(2));
|
|
44
|
+
const budget = BN.max(ZERO, amm.totalFeeMinusDistributions.sub(totalFeeLB));
|
|
45
|
+
|
|
46
|
+
if (prePegCost.gt(budget)) {
|
|
47
|
+
[pKNumer, pKDenom] = [new BN(999), new BN(1000)];
|
|
48
|
+
const deficitMadeup = calculateAdjustKCost(amm, pKNumer, pKDenom);
|
|
49
|
+
assert(deficitMadeup.lte(new BN(0)));
|
|
50
|
+
prePegCost = budget.add(deficitMadeup.abs());
|
|
51
|
+
const newAmm = Object.assign({}, amm);
|
|
52
|
+
newAmm.baseAssetReserve = newAmm.baseAssetReserve.mul(pKNumer).div(pKDenom);
|
|
53
|
+
newAmm.sqrtK = newAmm.sqrtK.mul(pKNumer).div(pKDenom);
|
|
54
|
+
const invariant = newAmm.sqrtK.mul(newAmm.sqrtK);
|
|
55
|
+
newAmm.quoteAssetReserve = invariant.div(newAmm.baseAssetReserve);
|
|
56
|
+
const directionToClose = amm.netBaseAssetAmount.gt(ZERO)
|
|
57
|
+
? PositionDirection.SHORT
|
|
58
|
+
: PositionDirection.LONG;
|
|
59
|
+
|
|
60
|
+
const [newQuoteAssetReserve, _newBaseAssetReserve] =
|
|
61
|
+
calculateAmmReservesAfterSwap(
|
|
62
|
+
newAmm,
|
|
63
|
+
'base',
|
|
64
|
+
amm.netBaseAssetAmount.abs(),
|
|
65
|
+
getSwapDirection('base', directionToClose)
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
newAmm.terminalQuoteAssetReserve = newQuoteAssetReserve;
|
|
69
|
+
|
|
70
|
+
newPeg = calculateBudgetedPeg(newAmm, prePegCost, targetPrice);
|
|
71
|
+
prePegCost = calculateRepegCost(newAmm, newPeg);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return [prePegCost, pKNumer, pKDenom, newPeg];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function calculateUpdatedAMM(
|
|
78
|
+
amm: AMM,
|
|
79
|
+
oraclePriceData: OraclePriceData
|
|
80
|
+
): AMM {
|
|
81
|
+
if (amm.curveUpdateIntensity == 0) {
|
|
82
|
+
return amm;
|
|
83
|
+
}
|
|
84
|
+
const newAmm = Object.assign({}, amm);
|
|
85
|
+
const [prepegCost, pKNumer, pKDenom, newPeg] = calculateNewAmm(
|
|
86
|
+
amm,
|
|
87
|
+
oraclePriceData
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
newAmm.baseAssetReserve = newAmm.baseAssetReserve.mul(pKNumer).div(pKDenom);
|
|
91
|
+
newAmm.sqrtK = newAmm.sqrtK.mul(pKNumer).div(pKDenom);
|
|
92
|
+
const invariant = newAmm.sqrtK.mul(newAmm.sqrtK);
|
|
93
|
+
newAmm.quoteAssetReserve = invariant.div(newAmm.baseAssetReserve);
|
|
94
|
+
newAmm.pegMultiplier = newPeg;
|
|
95
|
+
|
|
96
|
+
const directionToClose = amm.netBaseAssetAmount.gt(ZERO)
|
|
97
|
+
? PositionDirection.SHORT
|
|
98
|
+
: PositionDirection.LONG;
|
|
99
|
+
|
|
100
|
+
const [newQuoteAssetReserve, _newBaseAssetReserve] =
|
|
101
|
+
calculateAmmReservesAfterSwap(
|
|
102
|
+
newAmm,
|
|
103
|
+
'base',
|
|
104
|
+
amm.netBaseAssetAmount.abs(),
|
|
105
|
+
getSwapDirection('base', directionToClose)
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
newAmm.terminalQuoteAssetReserve = newQuoteAssetReserve;
|
|
109
|
+
|
|
110
|
+
newAmm.totalFeeMinusDistributions =
|
|
111
|
+
newAmm.totalFeeMinusDistributions.sub(prepegCost);
|
|
112
|
+
|
|
113
|
+
return newAmm;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function calculateUpdatedAMMSpreadReserves(
|
|
117
|
+
amm: AMM,
|
|
118
|
+
direction: PositionDirection,
|
|
119
|
+
oraclePriceData: OraclePriceData
|
|
120
|
+
): { baseAssetReserve: BN; quoteAssetReserve: BN; sqrtK: BN; newPeg: BN } {
|
|
121
|
+
const newAmm = calculateUpdatedAMM(amm, oraclePriceData);
|
|
122
|
+
const dirReserves = calculateSpreadReserves(
|
|
123
|
+
newAmm,
|
|
124
|
+
direction,
|
|
125
|
+
oraclePriceData
|
|
126
|
+
);
|
|
127
|
+
const result = {
|
|
128
|
+
baseAssetReserve: dirReserves.baseAssetReserve,
|
|
129
|
+
quoteAssetReserve: dirReserves.quoteAssetReserve,
|
|
130
|
+
sqrtK: newAmm.sqrtK,
|
|
131
|
+
newPeg: newAmm.pegMultiplier,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function calculateBidAskPrice(
|
|
138
|
+
amm: AMM,
|
|
139
|
+
oraclePriceData: OraclePriceData
|
|
140
|
+
): [BN, BN] {
|
|
141
|
+
const newAmm = calculateUpdatedAMM(amm, oraclePriceData);
|
|
142
|
+
const askReserves = calculateSpreadReserves(
|
|
143
|
+
newAmm,
|
|
144
|
+
PositionDirection.LONG,
|
|
145
|
+
oraclePriceData
|
|
146
|
+
);
|
|
147
|
+
const bidReserves = calculateSpreadReserves(
|
|
148
|
+
newAmm,
|
|
149
|
+
PositionDirection.SHORT,
|
|
150
|
+
oraclePriceData
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
const askPrice = calculatePrice(
|
|
154
|
+
askReserves.baseAssetReserve,
|
|
155
|
+
askReserves.quoteAssetReserve,
|
|
156
|
+
newAmm.pegMultiplier
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
const bidPrice = calculatePrice(
|
|
160
|
+
bidReserves.baseAssetReserve,
|
|
161
|
+
bidReserves.quoteAssetReserve,
|
|
162
|
+
newAmm.pegMultiplier
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
return [bidPrice, askPrice];
|
|
166
|
+
}
|
|
28
167
|
|
|
29
168
|
/**
|
|
30
169
|
* Calculates a price given an arbitrary base and quote amount (they must have the same precision)
|
|
31
170
|
*
|
|
32
|
-
* @param
|
|
33
|
-
* @param
|
|
34
|
-
* @param
|
|
171
|
+
* @param baseAssetReserves
|
|
172
|
+
* @param quoteAssetReserves
|
|
173
|
+
* @param pegMultiplier
|
|
35
174
|
* @returns price : Precision MARK_PRICE_PRECISION
|
|
36
175
|
*/
|
|
37
176
|
export function calculatePrice(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
177
|
+
baseAssetReserves: BN,
|
|
178
|
+
quoteAssetReserves: BN,
|
|
179
|
+
pegMultiplier: BN
|
|
41
180
|
): BN {
|
|
42
|
-
if (
|
|
181
|
+
if (baseAssetReserves.abs().lte(ZERO)) {
|
|
43
182
|
return new BN(0);
|
|
44
183
|
}
|
|
45
184
|
|
|
46
|
-
return
|
|
185
|
+
return quoteAssetReserves
|
|
47
186
|
.mul(MARK_PRICE_PRECISION)
|
|
48
|
-
.mul(
|
|
187
|
+
.mul(pegMultiplier)
|
|
49
188
|
.div(PEG_PRECISION)
|
|
50
|
-
.div(
|
|
189
|
+
.div(baseAssetReserves);
|
|
51
190
|
}
|
|
52
191
|
|
|
53
192
|
export type AssetType = 'quote' | 'base';
|
|
@@ -100,15 +239,65 @@ export function calculateAmmReservesAfterSwap(
|
|
|
100
239
|
|
|
101
240
|
export function calculateSpread(
|
|
102
241
|
amm: AMM,
|
|
103
|
-
direction: PositionDirection
|
|
242
|
+
direction: PositionDirection,
|
|
243
|
+
oraclePriceData: OraclePriceData
|
|
104
244
|
): number {
|
|
105
|
-
let spread;
|
|
245
|
+
let spread = amm.baseSpread / 2;
|
|
106
246
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
247
|
+
if (amm.baseSpread == 0 || amm.curveUpdateIntensity == 0) {
|
|
248
|
+
return spread;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const markPrice = calculatePrice(
|
|
252
|
+
amm.baseAssetReserve,
|
|
253
|
+
amm.quoteAssetReserve,
|
|
254
|
+
amm.pegMultiplier
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
const targetPrice = oraclePriceData?.price || markPrice;
|
|
258
|
+
|
|
259
|
+
const targetMarkSpreadPct = markPrice
|
|
260
|
+
.sub(targetPrice)
|
|
261
|
+
.mul(BID_ASK_SPREAD_PRECISION)
|
|
262
|
+
.div(markPrice);
|
|
263
|
+
|
|
264
|
+
// oracle retreat
|
|
265
|
+
if (
|
|
266
|
+
(isVariant(direction, 'long') && targetMarkSpreadPct.lt(ZERO)) ||
|
|
267
|
+
(isVariant(direction, 'short') && targetMarkSpreadPct.gt(ZERO))
|
|
268
|
+
) {
|
|
269
|
+
spread = Math.max(spread, targetMarkSpreadPct.abs().toNumber());
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// inventory skew
|
|
273
|
+
const MAX_INVENTORY_SKEW = 5;
|
|
274
|
+
if (
|
|
275
|
+
(amm.netBaseAssetAmount.gt(ZERO) && isVariant(direction, 'long')) ||
|
|
276
|
+
(amm.netBaseAssetAmount.lt(ZERO) && isVariant(direction, 'short')) ||
|
|
277
|
+
amm.totalFeeMinusDistributions.eq(ZERO)
|
|
278
|
+
) {
|
|
279
|
+
const netCostBasis = amm.quoteAssetAmountLong.sub(
|
|
280
|
+
amm.quoteAssetAmountShort
|
|
281
|
+
);
|
|
282
|
+
const netBaseAssetValue = amm.quoteAssetReserve
|
|
283
|
+
.sub(amm.terminalQuoteAssetReserve)
|
|
284
|
+
.mul(amm.pegMultiplier)
|
|
285
|
+
.div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
286
|
+
|
|
287
|
+
const localBaseAssetValue = amm.netBaseAssetAmount
|
|
288
|
+
.mul(markPrice)
|
|
289
|
+
.div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
|
|
290
|
+
const netPnl = netBaseAssetValue.sub(netCostBasis);
|
|
291
|
+
const localPnl = localBaseAssetValue.sub(netCostBasis);
|
|
292
|
+
|
|
293
|
+
let effectiveLeverage = MAX_INVENTORY_SKEW;
|
|
294
|
+
if (amm.totalFeeMinusDistributions.gt(ZERO)) {
|
|
295
|
+
effectiveLeverage =
|
|
296
|
+
localPnl.sub(netPnl).toNumber() /
|
|
297
|
+
amm.totalFeeMinusDistributions.toNumber();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
spread *= Math.min(MAX_INVENTORY_SKEW, 1 + effectiveLeverage);
|
|
112
301
|
}
|
|
113
302
|
|
|
114
303
|
return spread;
|
|
@@ -116,12 +305,13 @@ export function calculateSpread(
|
|
|
116
305
|
|
|
117
306
|
export function calculateSpreadReserves(
|
|
118
307
|
amm: AMM,
|
|
119
|
-
direction: PositionDirection
|
|
308
|
+
direction: PositionDirection,
|
|
309
|
+
oraclePriceData: OraclePriceData
|
|
120
310
|
): {
|
|
121
311
|
baseAssetReserve: BN;
|
|
122
312
|
quoteAssetReserve: BN;
|
|
123
313
|
} {
|
|
124
|
-
const spread = calculateSpread(amm, direction);
|
|
314
|
+
const spread = calculateSpread(amm, direction, oraclePriceData);
|
|
125
315
|
|
|
126
316
|
if (spread === 0) {
|
|
127
317
|
return {
|
|
@@ -131,7 +321,7 @@ export function calculateSpreadReserves(
|
|
|
131
321
|
}
|
|
132
322
|
|
|
133
323
|
const quoteAsserReserveDelta = amm.quoteAssetReserve.div(
|
|
134
|
-
BID_ASK_SPREAD_PRECISION.div(new BN(spread /
|
|
324
|
+
BID_ASK_SPREAD_PRECISION.div(new BN(spread / 2))
|
|
135
325
|
);
|
|
136
326
|
|
|
137
327
|
let quoteAssetReserve;
|
|
@@ -194,133 +384,14 @@ export function getSwapDirection(
|
|
|
194
384
|
return SwapDirection.ADD;
|
|
195
385
|
}
|
|
196
386
|
|
|
197
|
-
/**
|
|
198
|
-
* Helper function calculating adjust k cost
|
|
199
|
-
* @param market
|
|
200
|
-
* @param marketIndex
|
|
201
|
-
* @param numerator
|
|
202
|
-
* @param denomenator
|
|
203
|
-
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
204
|
-
*/
|
|
205
|
-
export function calculateAdjustKCost(
|
|
206
|
-
market: Market,
|
|
207
|
-
marketIndex: BN,
|
|
208
|
-
numerator: BN,
|
|
209
|
-
denomenator: BN
|
|
210
|
-
): BN {
|
|
211
|
-
const netUserPosition = {
|
|
212
|
-
baseAssetAmount: market.baseAssetAmount,
|
|
213
|
-
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
214
|
-
marketIndex: new BN(marketIndex),
|
|
215
|
-
quoteAssetAmount: new BN(0),
|
|
216
|
-
openOrders: new BN(0),
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
const currentValue = calculateBaseAssetValue(market, netUserPosition);
|
|
220
|
-
|
|
221
|
-
const marketNewK = Object.assign({}, market);
|
|
222
|
-
marketNewK.amm = Object.assign({}, market.amm);
|
|
223
|
-
|
|
224
|
-
marketNewK.amm.baseAssetReserve = market.amm.baseAssetReserve
|
|
225
|
-
.mul(numerator)
|
|
226
|
-
.div(denomenator);
|
|
227
|
-
marketNewK.amm.quoteAssetReserve = market.amm.quoteAssetReserve
|
|
228
|
-
.mul(numerator)
|
|
229
|
-
.div(denomenator);
|
|
230
|
-
marketNewK.amm.sqrtK = market.amm.sqrtK.mul(numerator).div(denomenator);
|
|
231
|
-
|
|
232
|
-
netUserPosition.quoteAssetAmount = currentValue;
|
|
233
|
-
|
|
234
|
-
const cost = calculatePositionPNL(marketNewK, netUserPosition);
|
|
235
|
-
|
|
236
|
-
const p = PEG_PRECISION.mul(numerator).div(denomenator);
|
|
237
|
-
const x = market.amm.baseAssetReserve;
|
|
238
|
-
const y = market.amm.quoteAssetReserve;
|
|
239
|
-
const delta = market.baseAssetAmount;
|
|
240
|
-
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
241
|
-
|
|
242
|
-
const numer1 = PEG_PRECISION.sub(p).mul(y).div(PEG_PRECISION);
|
|
243
|
-
const numer20 = k
|
|
244
|
-
.mul(p)
|
|
245
|
-
.mul(p)
|
|
246
|
-
.div(PEG_PRECISION)
|
|
247
|
-
.div(PEG_PRECISION)
|
|
248
|
-
.div(x.mul(p).div(PEG_PRECISION).add(delta));
|
|
249
|
-
const numer21 = k.div(x.add(delta));
|
|
250
|
-
|
|
251
|
-
const formulaCost = numer21
|
|
252
|
-
.sub(numer20)
|
|
253
|
-
.sub(numer1)
|
|
254
|
-
.mul(market.amm.pegMultiplier)
|
|
255
|
-
.div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
256
|
-
console.log(convertToNumber(formulaCost, QUOTE_PRECISION));
|
|
257
|
-
|
|
258
|
-
// p.div(p.mul(x).add(delta)).sub()
|
|
259
|
-
|
|
260
|
-
return cost;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
265
|
-
*
|
|
266
|
-
* @param market
|
|
267
|
-
* @param marketIndex
|
|
268
|
-
* @param newPeg
|
|
269
|
-
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
270
|
-
*/
|
|
271
|
-
export function calculateRepegCost(
|
|
272
|
-
market: Market,
|
|
273
|
-
marketIndex: BN,
|
|
274
|
-
newPeg: BN
|
|
275
|
-
): BN {
|
|
276
|
-
const netUserPosition = {
|
|
277
|
-
baseAssetAmount: market.baseAssetAmount,
|
|
278
|
-
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
279
|
-
marketIndex: new BN(marketIndex),
|
|
280
|
-
quoteAssetAmount: new BN(0),
|
|
281
|
-
openOrders: new BN(0),
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
const currentValue = calculateBaseAssetValue(market, netUserPosition);
|
|
285
|
-
netUserPosition.quoteAssetAmount = currentValue;
|
|
286
|
-
const prevMarketPrice = calculateMarkPrice(market);
|
|
287
|
-
const marketNewPeg = Object.assign({}, market);
|
|
288
|
-
marketNewPeg.amm = Object.assign({}, market.amm);
|
|
289
|
-
|
|
290
|
-
// const marketNewPeg = JSON.parse(JSON.stringify(market));
|
|
291
|
-
marketNewPeg.amm.pegMultiplier = newPeg;
|
|
292
|
-
|
|
293
|
-
console.log(
|
|
294
|
-
'Price moves from',
|
|
295
|
-
convertToNumber(prevMarketPrice),
|
|
296
|
-
'to',
|
|
297
|
-
convertToNumber(calculateMarkPrice(marketNewPeg))
|
|
298
|
-
);
|
|
299
|
-
|
|
300
|
-
const cost = calculatePositionPNL(marketNewPeg, netUserPosition);
|
|
301
|
-
|
|
302
|
-
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
303
|
-
const newQuoteAssetReserve = k.div(
|
|
304
|
-
market.amm.baseAssetReserve.add(netUserPosition.baseAssetAmount)
|
|
305
|
-
);
|
|
306
|
-
const deltaQuoteAssetReserves = newQuoteAssetReserve.sub(
|
|
307
|
-
market.amm.quoteAssetReserve
|
|
308
|
-
);
|
|
309
|
-
const cost2 = deltaQuoteAssetReserves
|
|
310
|
-
.mul(market.amm.pegMultiplier.sub(newPeg))
|
|
311
|
-
.div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
312
|
-
console.log(convertToNumber(cost2, QUOTE_PRECISION));
|
|
313
|
-
return cost;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
387
|
/**
|
|
317
388
|
* Helper function calculating terminal price of amm
|
|
318
389
|
*
|
|
319
390
|
* @param market
|
|
320
391
|
* @returns cost : Precision MARK_PRICE_PRECISION
|
|
321
392
|
*/
|
|
322
|
-
export function calculateTerminalPrice(market:
|
|
323
|
-
const directionToClose = market.
|
|
393
|
+
export function calculateTerminalPrice(market: MarketAccount) {
|
|
394
|
+
const directionToClose = market.amm.netBaseAssetAmount.gt(ZERO)
|
|
324
395
|
? PositionDirection.SHORT
|
|
325
396
|
: PositionDirection.LONG;
|
|
326
397
|
|
|
@@ -328,7 +399,7 @@ export function calculateTerminalPrice(market: Market) {
|
|
|
328
399
|
calculateAmmReservesAfterSwap(
|
|
329
400
|
market.amm,
|
|
330
401
|
'base',
|
|
331
|
-
market.
|
|
402
|
+
market.amm.netBaseAssetAmount.abs(),
|
|
332
403
|
getSwapDirection('base', directionToClose)
|
|
333
404
|
);
|
|
334
405
|
|
|
@@ -345,7 +416,7 @@ export function calculateMaxBaseAssetAmountToTrade(
|
|
|
345
416
|
amm: AMM,
|
|
346
417
|
limit_price: BN,
|
|
347
418
|
direction: PositionDirection,
|
|
348
|
-
|
|
419
|
+
oraclePriceData?: OraclePriceData
|
|
349
420
|
): [BN, PositionDirection] {
|
|
350
421
|
const invariant = amm.sqrtK.mul(amm.sqrtK);
|
|
351
422
|
|
|
@@ -357,15 +428,11 @@ export function calculateMaxBaseAssetAmountToTrade(
|
|
|
357
428
|
|
|
358
429
|
const newBaseAssetReserve = squareRootBN(newBaseAssetReserveSquared);
|
|
359
430
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
).baseAssetReserve;
|
|
366
|
-
} else {
|
|
367
|
-
baseAssetReserveBefore = amm.baseAssetReserve;
|
|
368
|
-
}
|
|
431
|
+
const baseAssetReserveBefore = calculateSpreadReserves(
|
|
432
|
+
amm,
|
|
433
|
+
direction,
|
|
434
|
+
oraclePriceData
|
|
435
|
+
).baseAssetReserve;
|
|
369
436
|
|
|
370
437
|
if (newBaseAssetReserve.gt(baseAssetReserveBefore)) {
|
|
371
438
|
return [
|
|
@@ -383,89 +450,6 @@ export function calculateMaxBaseAssetAmountToTrade(
|
|
|
383
450
|
}
|
|
384
451
|
}
|
|
385
452
|
|
|
386
|
-
export function calculateBudgetedK(market: Market, cost: BN): [BN, BN] {
|
|
387
|
-
// wolframalpha.com
|
|
388
|
-
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
389
|
-
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
390
|
-
|
|
391
|
-
// todo: assumes k = x * y
|
|
392
|
-
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
393
|
-
|
|
394
|
-
// const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
395
|
-
const x = market.amm.baseAssetReserve;
|
|
396
|
-
const y = market.amm.quoteAssetReserve;
|
|
397
|
-
|
|
398
|
-
const d = market.baseAssetAmount;
|
|
399
|
-
const Q = market.amm.pegMultiplier;
|
|
400
|
-
|
|
401
|
-
const C = cost.mul(new BN(-1));
|
|
402
|
-
|
|
403
|
-
const numer1 = y.mul(d).mul(Q).div(AMM_RESERVE_PRECISION).div(PEG_PRECISION);
|
|
404
|
-
const numer2 = C.mul(x.add(d)).div(QUOTE_PRECISION);
|
|
405
|
-
const denom1 = C.mul(x)
|
|
406
|
-
.mul(x.add(d))
|
|
407
|
-
.div(AMM_RESERVE_PRECISION)
|
|
408
|
-
.div(QUOTE_PRECISION);
|
|
409
|
-
const denom2 = y
|
|
410
|
-
.mul(d)
|
|
411
|
-
.mul(d)
|
|
412
|
-
.mul(Q)
|
|
413
|
-
.div(AMM_RESERVE_PRECISION)
|
|
414
|
-
.div(AMM_RESERVE_PRECISION)
|
|
415
|
-
.div(PEG_PRECISION);
|
|
416
|
-
|
|
417
|
-
const numerator = d
|
|
418
|
-
.mul(numer1.add(numer2))
|
|
419
|
-
.div(AMM_RESERVE_PRECISION)
|
|
420
|
-
.div(AMM_RESERVE_PRECISION)
|
|
421
|
-
.div(AMM_TO_QUOTE_PRECISION_RATIO);
|
|
422
|
-
const denominator = denom1
|
|
423
|
-
.add(denom2)
|
|
424
|
-
.div(AMM_RESERVE_PRECISION)
|
|
425
|
-
.div(AMM_TO_QUOTE_PRECISION_RATIO);
|
|
426
|
-
console.log(numerator, denominator);
|
|
427
|
-
// const p = (numerator).div(denominator);
|
|
428
|
-
|
|
429
|
-
// const formulaCost = (numer21.sub(numer20).sub(numer1)).mul(market.amm.pegMultiplier).div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
|
|
430
|
-
// console.log(convertToNumber(formulaCost, QUOTE_PRECISION))
|
|
431
|
-
|
|
432
|
-
return [numerator, denominator];
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
export function calculateBudgetedPeg(market: Market, cost: BN): BN {
|
|
436
|
-
// wolframalpha.com
|
|
437
|
-
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
438
|
-
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
439
|
-
|
|
440
|
-
// todo: assumes k = x * y
|
|
441
|
-
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
442
|
-
|
|
443
|
-
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
444
|
-
const x = market.amm.baseAssetReserve;
|
|
445
|
-
const y = market.amm.quoteAssetReserve;
|
|
446
|
-
|
|
447
|
-
const d = market.baseAssetAmount;
|
|
448
|
-
const Q = market.amm.pegMultiplier;
|
|
449
|
-
|
|
450
|
-
const C = cost.mul(new BN(-1));
|
|
451
|
-
|
|
452
|
-
const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
|
|
453
|
-
const deltaPegMultiplier = C.mul(MARK_PRICE_PRECISION)
|
|
454
|
-
.div(deltaQuoteAssetReserves.div(AMM_TO_QUOTE_PRECISION_RATIO))
|
|
455
|
-
.mul(PEG_PRECISION)
|
|
456
|
-
.div(QUOTE_PRECISION);
|
|
457
|
-
console.log(
|
|
458
|
-
Q.toNumber(),
|
|
459
|
-
'change by',
|
|
460
|
-
deltaPegMultiplier.toNumber() / MARK_PRICE_PRECISION.toNumber()
|
|
461
|
-
);
|
|
462
|
-
const newPeg = Q.sub(
|
|
463
|
-
deltaPegMultiplier.mul(PEG_PRECISION).div(MARK_PRICE_PRECISION)
|
|
464
|
-
);
|
|
465
|
-
|
|
466
|
-
return newPeg;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
453
|
export function calculateQuoteAssetAmountSwapped(
|
|
470
454
|
quoteAssetReserves: BN,
|
|
471
455
|
pegMultiplier: BN,
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { isVariant, Order } from '../types';
|
|
2
|
+
import { BN, ZERO } from '../.';
|
|
3
|
+
|
|
4
|
+
export function isAuctionComplete(order: Order, slot: number): boolean {
|
|
5
|
+
return new BN(slot).sub(order.slot).gte(new BN(order.auctionDuration));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function getAuctionPrice(order: Order, slot: number): BN {
|
|
9
|
+
const slotsElapsed = new BN(slot).sub(order.slot);
|
|
10
|
+
|
|
11
|
+
const deltaDenominator = new BN(order.auctionDuration);
|
|
12
|
+
const deltaNumerator = BN.min(slotsElapsed, deltaDenominator);
|
|
13
|
+
|
|
14
|
+
if (deltaDenominator.eq(ZERO)) {
|
|
15
|
+
return order.auctionEndPrice;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let priceDelta;
|
|
19
|
+
if (isVariant(order.direction, 'long')) {
|
|
20
|
+
priceDelta = order.auctionEndPrice
|
|
21
|
+
.sub(order.auctionStartPrice)
|
|
22
|
+
.mul(deltaNumerator)
|
|
23
|
+
.div(deltaDenominator);
|
|
24
|
+
} else {
|
|
25
|
+
priceDelta = order.auctionStartPrice
|
|
26
|
+
.sub(order.auctionEndPrice)
|
|
27
|
+
.mul(deltaNumerator)
|
|
28
|
+
.div(deltaDenominator);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let price;
|
|
32
|
+
if (isVariant(order.direction, 'long')) {
|
|
33
|
+
price = order.auctionStartPrice.add(priceDelta);
|
|
34
|
+
} else {
|
|
35
|
+
price = order.auctionStartPrice.sub(priceDelta);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return price;
|
|
39
|
+
}
|