@drift-labs/sdk 0.1.36-master.7 → 0.2.0-master.10
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 +6 -6
- package/lib/accounts/bulkAccountLoader.js +81 -95
- 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 +12 -18
- package/lib/admin.js +398 -558
- package/lib/clearingHouse.d.ts +83 -109
- package/lib/clearingHouse.js +832 -893
- package/lib/clearingHouseConfig.d.ts +34 -0
- package/lib/clearingHouseConfig.js +2 -0
- package/lib/clearingHouseUser.d.ts +19 -22
- package/lib/clearingHouseUser.js +155 -141
- 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 +41 -0
- package/lib/constants/markets.d.ts +8 -3
- package/lib/constants/markets.js +13 -206
- package/lib/constants/numericConstants.d.ts +17 -0
- package/lib/constants/numericConstants.js +23 -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 +118 -0
- package/lib/factory/bigNum.js +364 -0
- package/lib/factory/oracleClient.d.ts +1 -2
- package/lib/factory/oracleClient.js +6 -2
- package/lib/idl/clearing_house.json +2258 -2774
- package/lib/index.d.ts +14 -5
- package/lib/index.js +18 -5
- package/lib/math/amm.d.ts +24 -29
- package/lib/math/amm.js +209 -176
- package/lib/math/auction.d.ts +5 -0
- package/lib/math/auction.js +42 -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/orders.d.ts +6 -1
- package/lib/math/orders.js +38 -1
- package/lib/math/position.d.ts +7 -5
- package/lib/math/position.js +29 -27
- package/lib/math/repeg.d.ts +22 -0
- package/lib/math/repeg.js +128 -0
- package/lib/math/trade.d.ts +5 -4
- package/lib/math/trade.js +29 -24
- 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 -31
- 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 -50
- package/lib/oracles/types.d.ts +6 -1
- package/lib/orderParams.d.ts +14 -5
- package/lib/orderParams.js +8 -96
- package/lib/orders.d.ts +6 -7
- package/lib/orders.js +11 -89
- package/lib/slot/SlotSubscriber.d.ts +19 -0
- package/lib/slot/SlotSubscriber.js +26 -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 +180 -110
- package/lib/types.js +54 -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 +11 -4
- package/src/accounts/bulkAccountLoader.js +197 -0
- package/src/accounts/bulkAccountLoader.ts +21 -15
- package/src/accounts/bulkUserSubscription.js +33 -0
- package/src/accounts/bulkUserSubscription.ts +1 -45
- package/src/accounts/fetch.js +29 -0
- package/src/accounts/fetch.ts +33 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +311 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +249 -214
- package/src/accounts/pollingOracleSubscriber.js +93 -0
- package/src/accounts/pollingOracleSubscriber.ts +16 -8
- package/src/accounts/pollingTokenAccountSubscriber.js +90 -0
- package/src/accounts/pollingTokenAccountSubscriber.ts +11 -8
- package/src/accounts/pollingUserAccountSubscriber.js +132 -0
- package/src/accounts/pollingUserAccountSubscriber.ts +21 -86
- package/src/accounts/types.js +10 -0
- package/src/accounts/types.ts +41 -70
- package/src/accounts/utils.js +7 -0
- package/src/accounts/webSocketAccountSubscriber.js +93 -0
- package/src/accounts/webSocketAccountSubscriber.ts +33 -16
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +233 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +190 -240
- package/src/accounts/webSocketUserAccountSubscriber.js +62 -0
- package/src/accounts/webSocketUserAccountSubscriber.ts +11 -71
- package/src/addresses/marketAddresses.js +26 -0
- package/src/addresses/marketAddresses.ts +18 -0
- package/{lib/addresses.js → src/addresses/pda.js} +45 -34
- package/src/addresses/pda.ts +118 -0
- package/src/admin.ts +247 -336
- package/src/assert/assert.js +9 -0
- package/src/clearingHouse.ts +1023 -1026
- package/src/clearingHouseConfig.ts +37 -0
- package/src/clearingHouseUser.ts +275 -185
- package/src/clearingHouseUserConfig.ts +18 -0
- package/src/config.ts +54 -1
- package/src/constants/banks.ts +50 -0
- package/src/constants/markets.ts +16 -207
- package/src/constants/numericConstants.ts +34 -5
- package/src/events/eventList.js +77 -0
- package/src/events/eventList.ts +94 -0
- package/src/events/eventSubscriber.js +139 -0
- package/src/events/eventSubscriber.ts +194 -0
- package/src/events/fetchLogs.js +50 -0
- package/src/events/fetchLogs.ts +80 -0
- package/src/events/pollingLogProvider.js +64 -0
- package/src/events/pollingLogProvider.ts +79 -0
- package/src/events/sort.js +44 -0
- package/src/events/sort.ts +65 -0
- package/src/events/txEventCache.js +71 -0
- package/src/events/txEventCache.ts +74 -0
- package/src/events/types.js +20 -0
- package/src/events/types.ts +98 -0
- package/src/events/webSocketLogProvider.js +41 -0
- package/src/events/webSocketLogProvider.ts +38 -0
- package/src/examples/makeTradeExample.js +80 -0
- package/src/examples/makeTradeExample.ts +20 -11
- package/src/factory/bigNum.js +364 -0
- package/src/factory/bigNum.ts +524 -0
- package/src/factory/oracleClient.js +20 -0
- package/src/factory/oracleClient.ts +7 -4
- package/src/idl/clearing_house.json +2258 -2774
- package/src/index.js +69 -0
- package/src/index.ts +14 -5
- package/src/math/amm.js +369 -0
- package/src/math/amm.ts +382 -243
- package/src/math/auction.js +42 -0
- package/src/math/auction.ts +43 -0
- package/src/math/bankBalance.js +75 -0
- package/src/math/bankBalance.ts +112 -0
- package/src/math/conversion.js +11 -0
- package/src/math/conversion.ts +1 -11
- package/src/math/funding.js +248 -0
- package/src/math/funding.ts +12 -9
- package/src/math/market.js +57 -0
- package/src/math/market.ts +37 -30
- package/src/math/oracles.js +26 -0
- package/src/math/orders.js +110 -0
- package/src/math/orders.ts +43 -1
- package/src/math/position.js +140 -0
- package/src/math/position.ts +52 -35
- package/src/math/repeg.js +128 -0
- package/src/math/repeg.ts +176 -0
- package/src/math/state.js +15 -0
- package/src/math/trade.js +253 -0
- package/src/math/trade.ts +55 -47
- package/src/math/utils.js +26 -0
- package/src/math/utils.js.map +1 -0
- package/src/mockUSDCFaucet.js +171 -0
- package/src/oracles/oracleClientCache.js +19 -0
- package/src/oracles/oracleClientCache.ts +20 -0
- package/src/oracles/pythClient.js +46 -0
- package/src/oracles/pythClient.ts +4 -11
- package/src/oracles/quoteAssetOracleClient.js +32 -0
- package/src/oracles/quoteAssetOracleClient.ts +25 -0
- package/src/oracles/switchboardClient.js +69 -0
- package/src/oracles/switchboardClient.ts +11 -24
- package/src/oracles/types.js +2 -0
- package/src/oracles/types.ts +7 -1
- package/src/orderParams.js +20 -0
- package/src/orderParams.ts +20 -141
- package/src/orders.js +134 -0
- package/src/orders.ts +25 -134
- package/src/slot/SlotSubscriber.js +39 -0
- package/src/slot/SlotSubscriber.ts +42 -0
- package/src/token/index.js +38 -0
- package/src/tx/retryTxSender.js +188 -0
- package/src/tx/retryTxSender.ts +6 -4
- package/src/tx/types.js +2 -0
- package/src/tx/types.ts +6 -1
- package/src/tx/utils.js +17 -0
- package/src/tx/utils.ts +22 -3
- package/src/types.js +114 -0
- package/src/types.ts +176 -124
- package/src/userName.js +20 -0
- package/src/userName.ts +20 -0
- package/src/util/promiseTimeout.js +14 -0
- package/src/util/tps.js +27 -0
- package/src/wallet.js +35 -0
- package/tests/bn/test.ts +255 -0
- package/tsconfig.json +12 -12
- package/lib/addresses.d.ts +0 -10
- 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/settlement.d.ts +0 -4
- package/lib/settlement.js +0 -10
- package/lib/tx/defaultTxSender.d.ts +0 -8
- package/lib/tx/defaultTxSender.js +0 -12
- package/src/addresses.ts +0 -82
- 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/settlement.ts +0 -9
- package/src/tx/defaultTxSender.ts +0 -24
package/src/math/amm.ts
CHANGED
|
@@ -4,50 +4,257 @@ 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
|
+
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
10
|
+
QUOTE_PRECISION,
|
|
11
|
+
MARGIN_PRECISION,
|
|
12
|
+
PRICE_DIV_PEG,
|
|
12
13
|
} from '../constants/numericConstants';
|
|
13
|
-
import { calculateBaseAssetValue } from './position';
|
|
14
14
|
import {
|
|
15
15
|
AMM,
|
|
16
16
|
PositionDirection,
|
|
17
17
|
SwapDirection,
|
|
18
|
-
|
|
18
|
+
MarketAccount,
|
|
19
19
|
isVariant,
|
|
20
20
|
} from '../types';
|
|
21
21
|
import { assert } from '../assert/assert';
|
|
22
|
+
import { squareRootBN } from '..';
|
|
23
|
+
|
|
24
|
+
import { OraclePriceData } from '../oracles/types';
|
|
22
25
|
import {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
calculateRepegCost,
|
|
27
|
+
calculateAdjustKCost,
|
|
28
|
+
calculateBudgetedPeg,
|
|
29
|
+
} from './repeg';
|
|
30
|
+
|
|
31
|
+
export function calculatePegFromTargetPrice(
|
|
32
|
+
targetPrice: BN,
|
|
33
|
+
baseAssetReserve: BN,
|
|
34
|
+
quoteAssetReserve: BN
|
|
35
|
+
): BN {
|
|
36
|
+
return targetPrice
|
|
37
|
+
.mul(baseAssetReserve)
|
|
38
|
+
.div(quoteAssetReserve)
|
|
39
|
+
.add(PRICE_DIV_PEG.div(new BN(2)))
|
|
40
|
+
.div(PRICE_DIV_PEG);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function calculateOptimalPegAndBudget(
|
|
44
|
+
amm: AMM,
|
|
45
|
+
oraclePriceData: OraclePriceData
|
|
46
|
+
): [BN, BN, BN, boolean] {
|
|
47
|
+
const markPriceBefore = calculatePrice(
|
|
48
|
+
amm.baseAssetReserve,
|
|
49
|
+
amm.quoteAssetReserve,
|
|
50
|
+
amm.pegMultiplier
|
|
51
|
+
);
|
|
52
|
+
const targetPrice = oraclePriceData.price;
|
|
53
|
+
const newPeg = calculatePegFromTargetPrice(
|
|
54
|
+
targetPrice,
|
|
55
|
+
amm.baseAssetReserve,
|
|
56
|
+
amm.quoteAssetReserve
|
|
57
|
+
);
|
|
58
|
+
const prePegCost = calculateRepegCost(amm, newPeg);
|
|
59
|
+
|
|
60
|
+
const totalFeeLB = amm.totalExchangeFee.div(new BN(2));
|
|
61
|
+
const budget = BN.max(ZERO, amm.totalFeeMinusDistributions.sub(totalFeeLB));
|
|
62
|
+
if (budget.lt(prePegCost)) {
|
|
63
|
+
const maxPriceSpread = new BN(amm.maxSpread)
|
|
64
|
+
.mul(targetPrice)
|
|
65
|
+
.div(BID_ASK_SPREAD_PRECISION);
|
|
66
|
+
|
|
67
|
+
let newTargetPrice: BN;
|
|
68
|
+
let newOptimalPeg: BN;
|
|
69
|
+
let newBudget: BN;
|
|
70
|
+
const targetPriceGap = markPriceBefore.sub(targetPrice);
|
|
71
|
+
|
|
72
|
+
if (targetPriceGap.abs().gt(maxPriceSpread)) {
|
|
73
|
+
const markAdj = targetPriceGap.abs().sub(maxPriceSpread);
|
|
74
|
+
|
|
75
|
+
if (targetPriceGap.lt(new BN(0))) {
|
|
76
|
+
newTargetPrice = markPriceBefore.add(markAdj);
|
|
77
|
+
} else {
|
|
78
|
+
newTargetPrice = markPriceBefore.sub(markAdj);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
newOptimalPeg = calculatePegFromTargetPrice(
|
|
82
|
+
newTargetPrice,
|
|
83
|
+
amm.baseAssetReserve,
|
|
84
|
+
amm.quoteAssetReserve
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
newBudget = calculateRepegCost(amm, newOptimalPeg);
|
|
88
|
+
return [newTargetPrice, newOptimalPeg, newBudget, false];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return [targetPrice, newPeg, budget, true];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function calculateNewAmm(
|
|
96
|
+
amm: AMM,
|
|
97
|
+
oraclePriceData: OraclePriceData
|
|
98
|
+
): [BN, BN, BN, BN] {
|
|
99
|
+
let pKNumer = new BN(1);
|
|
100
|
+
let pKDenom = new BN(1);
|
|
101
|
+
|
|
102
|
+
const [targetPrice, _newPeg, budget, checkLowerBound] =
|
|
103
|
+
calculateOptimalPegAndBudget(amm, oraclePriceData);
|
|
104
|
+
let prePegCost = calculateRepegCost(amm, _newPeg);
|
|
105
|
+
let newPeg = _newPeg;
|
|
106
|
+
|
|
107
|
+
if (prePegCost.gt(budget) && checkLowerBound) {
|
|
108
|
+
[pKNumer, pKDenom] = [new BN(999), new BN(1000)];
|
|
109
|
+
const deficitMadeup = calculateAdjustKCost(amm, pKNumer, pKDenom);
|
|
110
|
+
assert(deficitMadeup.lte(new BN(0)));
|
|
111
|
+
prePegCost = budget.add(deficitMadeup.abs());
|
|
112
|
+
const newAmm = Object.assign({}, amm);
|
|
113
|
+
newAmm.baseAssetReserve = newAmm.baseAssetReserve.mul(pKNumer).div(pKDenom);
|
|
114
|
+
newAmm.sqrtK = newAmm.sqrtK.mul(pKNumer).div(pKDenom);
|
|
115
|
+
const invariant = newAmm.sqrtK.mul(newAmm.sqrtK);
|
|
116
|
+
newAmm.quoteAssetReserve = invariant.div(newAmm.baseAssetReserve);
|
|
117
|
+
const directionToClose = amm.netBaseAssetAmount.gt(ZERO)
|
|
118
|
+
? PositionDirection.SHORT
|
|
119
|
+
: PositionDirection.LONG;
|
|
120
|
+
|
|
121
|
+
const [newQuoteAssetReserve, _newBaseAssetReserve] =
|
|
122
|
+
calculateAmmReservesAfterSwap(
|
|
123
|
+
newAmm,
|
|
124
|
+
'base',
|
|
125
|
+
amm.netBaseAssetAmount.abs(),
|
|
126
|
+
getSwapDirection('base', directionToClose)
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
newAmm.terminalQuoteAssetReserve = newQuoteAssetReserve;
|
|
130
|
+
|
|
131
|
+
newPeg = calculateBudgetedPeg(newAmm, prePegCost, targetPrice);
|
|
132
|
+
prePegCost = calculateRepegCost(newAmm, newPeg);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return [prePegCost, pKNumer, pKDenom, newPeg];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function calculateUpdatedAMM(
|
|
139
|
+
amm: AMM,
|
|
140
|
+
oraclePriceData: OraclePriceData
|
|
141
|
+
): AMM {
|
|
142
|
+
if (amm.curveUpdateIntensity == 0) {
|
|
143
|
+
return amm;
|
|
144
|
+
}
|
|
145
|
+
const newAmm = Object.assign({}, amm);
|
|
146
|
+
const [prepegCost, pKNumer, pKDenom, newPeg] = calculateNewAmm(
|
|
147
|
+
amm,
|
|
148
|
+
oraclePriceData
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
newAmm.baseAssetReserve = newAmm.baseAssetReserve.mul(pKNumer).div(pKDenom);
|
|
152
|
+
newAmm.sqrtK = newAmm.sqrtK.mul(pKNumer).div(pKDenom);
|
|
153
|
+
const invariant = newAmm.sqrtK.mul(newAmm.sqrtK);
|
|
154
|
+
newAmm.quoteAssetReserve = invariant.div(newAmm.baseAssetReserve);
|
|
155
|
+
newAmm.pegMultiplier = newPeg;
|
|
156
|
+
|
|
157
|
+
const directionToClose = amm.netBaseAssetAmount.gt(ZERO)
|
|
158
|
+
? PositionDirection.SHORT
|
|
159
|
+
: PositionDirection.LONG;
|
|
160
|
+
|
|
161
|
+
const [newQuoteAssetReserve, _newBaseAssetReserve] =
|
|
162
|
+
calculateAmmReservesAfterSwap(
|
|
163
|
+
newAmm,
|
|
164
|
+
'base',
|
|
165
|
+
amm.netBaseAssetAmount.abs(),
|
|
166
|
+
getSwapDirection('base', directionToClose)
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
newAmm.terminalQuoteAssetReserve = newQuoteAssetReserve;
|
|
170
|
+
|
|
171
|
+
newAmm.totalFeeMinusDistributions =
|
|
172
|
+
newAmm.totalFeeMinusDistributions.sub(prepegCost);
|
|
173
|
+
|
|
174
|
+
return newAmm;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function calculateUpdatedAMMSpreadReserves(
|
|
178
|
+
amm: AMM,
|
|
179
|
+
direction: PositionDirection,
|
|
180
|
+
oraclePriceData: OraclePriceData
|
|
181
|
+
): { baseAssetReserve: BN; quoteAssetReserve: BN; sqrtK: BN; newPeg: BN } {
|
|
182
|
+
const newAmm = calculateUpdatedAMM(amm, oraclePriceData);
|
|
183
|
+
const dirReserves = calculateSpreadReserves(
|
|
184
|
+
newAmm,
|
|
185
|
+
direction,
|
|
186
|
+
oraclePriceData
|
|
187
|
+
);
|
|
188
|
+
const result = {
|
|
189
|
+
baseAssetReserve: dirReserves.baseAssetReserve,
|
|
190
|
+
quoteAssetReserve: dirReserves.quoteAssetReserve,
|
|
191
|
+
sqrtK: newAmm.sqrtK,
|
|
192
|
+
newPeg: newAmm.pegMultiplier,
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function calculateBidAskPrice(
|
|
199
|
+
amm: AMM,
|
|
200
|
+
oraclePriceData: OraclePriceData,
|
|
201
|
+
withUpdate = true
|
|
202
|
+
): [BN, BN] {
|
|
203
|
+
let newAmm: AMM;
|
|
204
|
+
if (withUpdate) {
|
|
205
|
+
newAmm = calculateUpdatedAMM(amm, oraclePriceData);
|
|
206
|
+
} else {
|
|
207
|
+
newAmm = amm;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const askReserves = calculateSpreadReserves(
|
|
211
|
+
newAmm,
|
|
212
|
+
PositionDirection.LONG,
|
|
213
|
+
oraclePriceData
|
|
214
|
+
);
|
|
215
|
+
const bidReserves = calculateSpreadReserves(
|
|
216
|
+
newAmm,
|
|
217
|
+
PositionDirection.SHORT,
|
|
218
|
+
oraclePriceData
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
const askPrice = calculatePrice(
|
|
222
|
+
askReserves.baseAssetReserve,
|
|
223
|
+
askReserves.quoteAssetReserve,
|
|
224
|
+
newAmm.pegMultiplier
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
const bidPrice = calculatePrice(
|
|
228
|
+
bidReserves.baseAssetReserve,
|
|
229
|
+
bidReserves.quoteAssetReserve,
|
|
230
|
+
newAmm.pegMultiplier
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
return [bidPrice, askPrice];
|
|
234
|
+
}
|
|
28
235
|
|
|
29
236
|
/**
|
|
30
237
|
* Calculates a price given an arbitrary base and quote amount (they must have the same precision)
|
|
31
238
|
*
|
|
32
|
-
* @param
|
|
33
|
-
* @param
|
|
34
|
-
* @param
|
|
239
|
+
* @param baseAssetReserves
|
|
240
|
+
* @param quoteAssetReserves
|
|
241
|
+
* @param pegMultiplier
|
|
35
242
|
* @returns price : Precision MARK_PRICE_PRECISION
|
|
36
243
|
*/
|
|
37
244
|
export function calculatePrice(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
245
|
+
baseAssetReserves: BN,
|
|
246
|
+
quoteAssetReserves: BN,
|
|
247
|
+
pegMultiplier: BN
|
|
41
248
|
): BN {
|
|
42
|
-
if (
|
|
249
|
+
if (baseAssetReserves.abs().lte(ZERO)) {
|
|
43
250
|
return new BN(0);
|
|
44
251
|
}
|
|
45
252
|
|
|
46
|
-
return
|
|
253
|
+
return quoteAssetReserves
|
|
47
254
|
.mul(MARK_PRICE_PRECISION)
|
|
48
|
-
.mul(
|
|
255
|
+
.mul(pegMultiplier)
|
|
49
256
|
.div(PEG_PRECISION)
|
|
50
|
-
.div(
|
|
257
|
+
.div(baseAssetReserves);
|
|
51
258
|
}
|
|
52
259
|
|
|
53
260
|
export type AssetType = 'quote' | 'base';
|
|
@@ -98,17 +305,154 @@ export function calculateAmmReservesAfterSwap(
|
|
|
98
305
|
return [newQuoteAssetReserve, newBaseAssetReserve];
|
|
99
306
|
}
|
|
100
307
|
|
|
308
|
+
export function calculateEffectiveLeverage(
|
|
309
|
+
baseSpread: number,
|
|
310
|
+
quoteAssetReserve: BN,
|
|
311
|
+
terminalQuoteAssetReserve: BN,
|
|
312
|
+
pegMultiplier: BN,
|
|
313
|
+
netBaseAssetAmount: BN,
|
|
314
|
+
markPrice: BN,
|
|
315
|
+
totalFeeMinusDistributions: BN
|
|
316
|
+
): number {
|
|
317
|
+
// inventory skew
|
|
318
|
+
const netBaseAssetValue = quoteAssetReserve
|
|
319
|
+
.sub(terminalQuoteAssetReserve)
|
|
320
|
+
.mul(pegMultiplier)
|
|
321
|
+
.div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
322
|
+
|
|
323
|
+
const localBaseAssetValue = netBaseAssetAmount
|
|
324
|
+
.mul(markPrice)
|
|
325
|
+
.div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
|
|
326
|
+
|
|
327
|
+
const effectiveLeverage =
|
|
328
|
+
localBaseAssetValue.sub(netBaseAssetValue).toNumber() /
|
|
329
|
+
(Math.max(0, totalFeeMinusDistributions.toNumber()) + 1) +
|
|
330
|
+
1 / QUOTE_PRECISION.toNumber();
|
|
331
|
+
|
|
332
|
+
return effectiveLeverage;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export function calculateMaxSpread(marginRatioInitial: number): number {
|
|
336
|
+
const maxTargetSpread: number = new BN(marginRatioInitial)
|
|
337
|
+
.mul(BID_ASK_SPREAD_PRECISION.div(MARGIN_PRECISION))
|
|
338
|
+
.toNumber();
|
|
339
|
+
|
|
340
|
+
return maxTargetSpread;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export function calculateSpreadBN(
|
|
344
|
+
baseSpread: number,
|
|
345
|
+
lastOracleMarkSpreadPct: BN,
|
|
346
|
+
lastOracleConfPct: BN,
|
|
347
|
+
maxSpread: number,
|
|
348
|
+
quoteAssetReserve: BN,
|
|
349
|
+
terminalQuoteAssetReserve: BN,
|
|
350
|
+
pegMultiplier: BN,
|
|
351
|
+
netBaseAssetAmount: BN,
|
|
352
|
+
markPrice: BN,
|
|
353
|
+
totalFeeMinusDistributions: BN
|
|
354
|
+
): [number, number] {
|
|
355
|
+
let longSpread = baseSpread / 2;
|
|
356
|
+
let shortSpread = baseSpread / 2;
|
|
357
|
+
|
|
358
|
+
if (lastOracleMarkSpreadPct.gt(ZERO)) {
|
|
359
|
+
shortSpread = Math.max(
|
|
360
|
+
shortSpread,
|
|
361
|
+
lastOracleMarkSpreadPct.abs().toNumber() + lastOracleConfPct.toNumber()
|
|
362
|
+
);
|
|
363
|
+
} else if (lastOracleMarkSpreadPct.lt(ZERO)) {
|
|
364
|
+
longSpread = Math.max(
|
|
365
|
+
longSpread,
|
|
366
|
+
lastOracleMarkSpreadPct.abs().toNumber() + lastOracleConfPct.toNumber()
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const maxTargetSpread: number = maxSpread;
|
|
371
|
+
|
|
372
|
+
const MAX_INVENTORY_SKEW = 5;
|
|
373
|
+
|
|
374
|
+
const effectiveLeverage = calculateEffectiveLeverage(
|
|
375
|
+
baseSpread,
|
|
376
|
+
quoteAssetReserve,
|
|
377
|
+
terminalQuoteAssetReserve,
|
|
378
|
+
pegMultiplier,
|
|
379
|
+
netBaseAssetAmount,
|
|
380
|
+
markPrice,
|
|
381
|
+
totalFeeMinusDistributions
|
|
382
|
+
);
|
|
383
|
+
|
|
384
|
+
if (totalFeeMinusDistributions.gt(ZERO)) {
|
|
385
|
+
const spreadScale = Math.min(MAX_INVENTORY_SKEW, 1 + effectiveLeverage);
|
|
386
|
+
if (netBaseAssetAmount.gt(ZERO)) {
|
|
387
|
+
longSpread *= spreadScale;
|
|
388
|
+
} else {
|
|
389
|
+
shortSpread *= spreadScale;
|
|
390
|
+
}
|
|
391
|
+
} else {
|
|
392
|
+
longSpread *= MAX_INVENTORY_SKEW;
|
|
393
|
+
shortSpread *= MAX_INVENTORY_SKEW;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const totalSpread = longSpread + shortSpread;
|
|
397
|
+
if (totalSpread > maxTargetSpread) {
|
|
398
|
+
if (longSpread > shortSpread) {
|
|
399
|
+
longSpread = Math.min(longSpread, maxTargetSpread);
|
|
400
|
+
shortSpread = maxTargetSpread - longSpread;
|
|
401
|
+
} else {
|
|
402
|
+
shortSpread = Math.min(shortSpread, maxTargetSpread);
|
|
403
|
+
longSpread = maxTargetSpread - shortSpread;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
return [longSpread, shortSpread];
|
|
408
|
+
}
|
|
409
|
+
|
|
101
410
|
export function calculateSpread(
|
|
102
411
|
amm: AMM,
|
|
103
|
-
direction: PositionDirection
|
|
412
|
+
direction: PositionDirection,
|
|
413
|
+
oraclePriceData: OraclePriceData
|
|
104
414
|
): number {
|
|
105
|
-
|
|
415
|
+
if (amm.baseSpread == 0 || amm.curveUpdateIntensity == 0) {
|
|
416
|
+
return amm.baseSpread / 2;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const markPrice = calculatePrice(
|
|
420
|
+
amm.baseAssetReserve,
|
|
421
|
+
amm.quoteAssetReserve,
|
|
422
|
+
amm.pegMultiplier
|
|
423
|
+
);
|
|
424
|
+
|
|
425
|
+
const targetPrice = oraclePriceData?.price || markPrice;
|
|
426
|
+
const confInterval = oraclePriceData.confidence || ZERO;
|
|
427
|
+
|
|
428
|
+
const targetMarkSpreadPct = markPrice
|
|
429
|
+
.sub(targetPrice)
|
|
430
|
+
.mul(BID_ASK_SPREAD_PRECISION)
|
|
431
|
+
.div(markPrice);
|
|
432
|
+
|
|
433
|
+
const confIntervalPct = confInterval
|
|
434
|
+
.mul(BID_ASK_SPREAD_PRECISION)
|
|
435
|
+
.div(markPrice);
|
|
436
|
+
|
|
437
|
+
const [longSpread, shortSpread] = calculateSpreadBN(
|
|
438
|
+
amm.baseSpread,
|
|
439
|
+
targetMarkSpreadPct,
|
|
440
|
+
confIntervalPct,
|
|
441
|
+
amm.maxSpread,
|
|
442
|
+
amm.quoteAssetReserve,
|
|
443
|
+
amm.terminalQuoteAssetReserve,
|
|
444
|
+
amm.pegMultiplier,
|
|
445
|
+
amm.netBaseAssetAmount,
|
|
446
|
+
markPrice,
|
|
447
|
+
amm.totalFeeMinusDistributions
|
|
448
|
+
);
|
|
449
|
+
|
|
450
|
+
let spread: number;
|
|
106
451
|
|
|
107
|
-
// future logic
|
|
108
452
|
if (isVariant(direction, 'long')) {
|
|
109
|
-
spread =
|
|
453
|
+
spread = longSpread;
|
|
110
454
|
} else {
|
|
111
|
-
spread =
|
|
455
|
+
spread = shortSpread;
|
|
112
456
|
}
|
|
113
457
|
|
|
114
458
|
return spread;
|
|
@@ -116,12 +460,13 @@ export function calculateSpread(
|
|
|
116
460
|
|
|
117
461
|
export function calculateSpreadReserves(
|
|
118
462
|
amm: AMM,
|
|
119
|
-
direction: PositionDirection
|
|
463
|
+
direction: PositionDirection,
|
|
464
|
+
oraclePriceData: OraclePriceData
|
|
120
465
|
): {
|
|
121
466
|
baseAssetReserve: BN;
|
|
122
467
|
quoteAssetReserve: BN;
|
|
123
468
|
} {
|
|
124
|
-
const spread = calculateSpread(amm, direction);
|
|
469
|
+
const spread = calculateSpread(amm, direction, oraclePriceData);
|
|
125
470
|
|
|
126
471
|
if (spread === 0) {
|
|
127
472
|
return {
|
|
@@ -131,7 +476,7 @@ export function calculateSpreadReserves(
|
|
|
131
476
|
}
|
|
132
477
|
|
|
133
478
|
const quoteAsserReserveDelta = amm.quoteAssetReserve.div(
|
|
134
|
-
BID_ASK_SPREAD_PRECISION.div(new BN(spread /
|
|
479
|
+
BID_ASK_SPREAD_PRECISION.div(new BN(spread / 2))
|
|
135
480
|
);
|
|
136
481
|
|
|
137
482
|
let quoteAssetReserve;
|
|
@@ -194,133 +539,14 @@ export function getSwapDirection(
|
|
|
194
539
|
return SwapDirection.ADD;
|
|
195
540
|
}
|
|
196
541
|
|
|
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
542
|
/**
|
|
317
543
|
* Helper function calculating terminal price of amm
|
|
318
544
|
*
|
|
319
545
|
* @param market
|
|
320
546
|
* @returns cost : Precision MARK_PRICE_PRECISION
|
|
321
547
|
*/
|
|
322
|
-
export function calculateTerminalPrice(market:
|
|
323
|
-
const directionToClose = market.
|
|
548
|
+
export function calculateTerminalPrice(market: MarketAccount) {
|
|
549
|
+
const directionToClose = market.amm.netBaseAssetAmount.gt(ZERO)
|
|
324
550
|
? PositionDirection.SHORT
|
|
325
551
|
: PositionDirection.LONG;
|
|
326
552
|
|
|
@@ -328,7 +554,7 @@ export function calculateTerminalPrice(market: Market) {
|
|
|
328
554
|
calculateAmmReservesAfterSwap(
|
|
329
555
|
market.amm,
|
|
330
556
|
'base',
|
|
331
|
-
market.
|
|
557
|
+
market.amm.netBaseAssetAmount.abs(),
|
|
332
558
|
getSwapDirection('base', directionToClose)
|
|
333
559
|
);
|
|
334
560
|
|
|
@@ -345,7 +571,7 @@ export function calculateMaxBaseAssetAmountToTrade(
|
|
|
345
571
|
amm: AMM,
|
|
346
572
|
limit_price: BN,
|
|
347
573
|
direction: PositionDirection,
|
|
348
|
-
|
|
574
|
+
oraclePriceData?: OraclePriceData
|
|
349
575
|
): [BN, PositionDirection] {
|
|
350
576
|
const invariant = amm.sqrtK.mul(amm.sqrtK);
|
|
351
577
|
|
|
@@ -357,15 +583,11 @@ export function calculateMaxBaseAssetAmountToTrade(
|
|
|
357
583
|
|
|
358
584
|
const newBaseAssetReserve = squareRootBN(newBaseAssetReserveSquared);
|
|
359
585
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
).baseAssetReserve;
|
|
366
|
-
} else {
|
|
367
|
-
baseAssetReserveBefore = amm.baseAssetReserve;
|
|
368
|
-
}
|
|
586
|
+
const baseAssetReserveBefore = calculateSpreadReserves(
|
|
587
|
+
amm,
|
|
588
|
+
direction,
|
|
589
|
+
oraclePriceData
|
|
590
|
+
).baseAssetReserve;
|
|
369
591
|
|
|
370
592
|
if (newBaseAssetReserve.gt(baseAssetReserveBefore)) {
|
|
371
593
|
return [
|
|
@@ -383,89 +605,6 @@ export function calculateMaxBaseAssetAmountToTrade(
|
|
|
383
605
|
}
|
|
384
606
|
}
|
|
385
607
|
|
|
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
608
|
export function calculateQuoteAssetAmountSwapped(
|
|
470
609
|
quoteAssetReserves: BN,
|
|
471
610
|
pegMultiplier: BN,
|