@drift-labs/sdk 0.1.27 → 0.1.29-master.1
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.js +13 -3
- package/lib/clearingHouse.d.ts +2 -0
- package/lib/clearingHouse.js +24 -0
- package/lib/constants/markets.js +12 -1
- package/lib/idl/clearing_house.json +66 -2
- package/lib/math/amm.d.ts +0 -18
- package/lib/math/amm.js +1 -88
- package/lib/math/repeg.d.ts +32 -0
- package/lib/math/repeg.js +178 -0
- package/lib/types.d.ts +3 -0
- package/lib/types.js +1 -0
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.ts +14 -4
- package/src/clearingHouse.ts +40 -0
- package/src/constants/markets.ts +12 -1
- package/src/idl/clearing_house.json +66 -2
- package/src/math/amm.ts +2 -127
- package/src/math/repeg.ts +253 -0
- package/src/types.ts +1 -0
- package/src/accounts/bulkAccountLoader.js +0 -180
- package/src/accounts/bulkAccountLoader.js.map +0 -1
- package/src/addresses.js +0 -59
- package/src/addresses.js.map +0 -1
- package/src/admin.js +0 -443
- package/src/admin.js.map +0 -1
- package/src/clearingHouse.js +0 -769
- package/src/clearingHouse.js.map +0 -1
- package/src/clearingHouseUser.js +0 -581
- package/src/clearingHouseUser.js.map +0 -1
- package/src/config.js +0 -37
- package/src/config.js.map +0 -1
- package/src/index.js +0 -56
- package/src/index.js.map +0 -1
- package/src/mockUSDCFaucet.js +0 -143
- package/src/mockUSDCFaucet.js.map +0 -1
- package/src/orderParams.js +0 -109
- package/src/orderParams.js.map +0 -1
- package/src/orders.js +0 -172
- package/src/orders.js.map +0 -1
- package/src/types.js +0 -61
- package/src/types.js.map +0 -1
- package/src/wallet.js +0 -23
- package/src/wallet.js.map +0 -1
|
@@ -13,6 +13,7 @@ exports.BulkAccountLoader = void 0;
|
|
|
13
13
|
const web3_js_1 = require("@solana/web3.js");
|
|
14
14
|
const uuid_1 = require("uuid");
|
|
15
15
|
const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
|
|
16
|
+
const oneMinute = 60 * 1000;
|
|
16
17
|
const fiveMinutes = 5 * 60 * 1000;
|
|
17
18
|
class BulkAccountLoader {
|
|
18
19
|
constructor(connection, commitment, pollingFrequency) {
|
|
@@ -82,9 +83,6 @@ class BulkAccountLoader {
|
|
|
82
83
|
this.loadPromise = new Promise((resolver) => {
|
|
83
84
|
this.loadPromiseResolver = resolver;
|
|
84
85
|
});
|
|
85
|
-
if (this.loggingEnabled) {
|
|
86
|
-
console.log('Loading accounts');
|
|
87
|
-
}
|
|
88
86
|
try {
|
|
89
87
|
const chunks = this.chunks(Array.from(this.accountsToLoad.values()), GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE);
|
|
90
88
|
yield Promise.all(chunks.map((chunk) => {
|
|
@@ -126,6 +124,10 @@ class BulkAccountLoader {
|
|
|
126
124
|
];
|
|
127
125
|
// @ts-ignore
|
|
128
126
|
const rpcResponse = yield this.connection._rpcRequest('getMultipleAccounts', args);
|
|
127
|
+
const oneMinuteSinceLastUpdate = Date.now() - this.lastUpdate > oneMinute;
|
|
128
|
+
if (this.loggingEnabled && oneMinuteSinceLastUpdate) {
|
|
129
|
+
console.log('rpcResponse', JSON.stringify(rpcResponse));
|
|
130
|
+
}
|
|
129
131
|
const newSlot = rpcResponse.result.context.slot;
|
|
130
132
|
for (const i in accountsToLoad) {
|
|
131
133
|
const accountToLoad = accountsToLoad[i];
|
|
@@ -137,6 +139,9 @@ class BulkAccountLoader {
|
|
|
137
139
|
const dataType = rpcResponse.result.value[i].data[1];
|
|
138
140
|
newBuffer = Buffer.from(raw, dataType);
|
|
139
141
|
}
|
|
142
|
+
if (this.loggingEnabled && oneMinuteSinceLastUpdate) {
|
|
143
|
+
console.log('oldRPCResponse', oldRPCResponse);
|
|
144
|
+
}
|
|
140
145
|
if (!oldRPCResponse) {
|
|
141
146
|
this.accountData.set(key, {
|
|
142
147
|
slot: newSlot,
|
|
@@ -158,6 +163,11 @@ class BulkAccountLoader {
|
|
|
158
163
|
this.handleAccountCallbacks(accountToLoad, newBuffer);
|
|
159
164
|
this.lastUpdate = Date.now();
|
|
160
165
|
}
|
|
166
|
+
else if (this.loggingEnabled) {
|
|
167
|
+
console.log('unable to update account for newest slot');
|
|
168
|
+
console.log('oldBuffer', oldBuffer);
|
|
169
|
+
console.log('newBuffer', newBuffer);
|
|
170
|
+
}
|
|
161
171
|
}
|
|
162
172
|
});
|
|
163
173
|
}
|
package/lib/clearingHouse.d.ts
CHANGED
|
@@ -121,6 +121,8 @@ export declare class ClearingHouse {
|
|
|
121
121
|
initializeUserOrdersThenPlaceOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
|
|
122
122
|
placeOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
|
|
123
123
|
getPlaceOrderIx(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionInstruction>;
|
|
124
|
+
expireOrders(userAccountPublicKey: PublicKey, userOrdersAccountPublicKey: PublicKey): Promise<TransactionSignature>;
|
|
125
|
+
getExpireOrdersIx(userAccountPublicKey: PublicKey, userOrdersAccountPublicKey: PublicKey): Promise<TransactionInstruction>;
|
|
124
126
|
cancelOrder(orderId: BN, oracle?: PublicKey): Promise<TransactionSignature>;
|
|
125
127
|
getCancelOrderIx(orderId: BN, oracle?: PublicKey): Promise<TransactionInstruction>;
|
|
126
128
|
cancelOrderByUserId(userOrderId: number, oracle?: PublicKey): Promise<TransactionSignature>;
|
package/lib/clearingHouse.js
CHANGED
|
@@ -538,6 +538,30 @@ class ClearingHouse {
|
|
|
538
538
|
});
|
|
539
539
|
});
|
|
540
540
|
}
|
|
541
|
+
expireOrders(userAccountPublicKey, userOrdersAccountPublicKey) {
|
|
542
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
543
|
+
return yield this.txSender.send((0, utils_1.wrapInTx)(yield this.getExpireOrdersIx(userAccountPublicKey, userOrdersAccountPublicKey)), [], this.opts);
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
getExpireOrdersIx(userAccountPublicKey, userOrdersAccountPublicKey) {
|
|
547
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
548
|
+
const fillerPublicKey = yield this.getUserAccountPublicKey();
|
|
549
|
+
const userAccount = yield this.program.account.user.fetch(userAccountPublicKey);
|
|
550
|
+
const orderState = this.getOrderStateAccount();
|
|
551
|
+
return yield this.program.instruction.expireOrders({
|
|
552
|
+
accounts: {
|
|
553
|
+
state: yield this.getStatePublicKey(),
|
|
554
|
+
filler: fillerPublicKey,
|
|
555
|
+
user: userAccountPublicKey,
|
|
556
|
+
authority: this.wallet.publicKey,
|
|
557
|
+
userPositions: userAccount.positions,
|
|
558
|
+
userOrders: userOrdersAccountPublicKey,
|
|
559
|
+
orderState: yield this.getOrderStatePublicKey(),
|
|
560
|
+
orderHistory: orderState.orderHistory,
|
|
561
|
+
},
|
|
562
|
+
});
|
|
563
|
+
});
|
|
564
|
+
}
|
|
541
565
|
cancelOrder(orderId, oracle) {
|
|
542
566
|
return __awaiter(this, void 0, void 0, function* () {
|
|
543
567
|
return yield this.txSender.send((0, utils_1.wrapInTx)(yield this.getCancelOrderIx(orderId, oracle)), [], this.opts);
|
package/lib/constants/markets.js
CHANGED
|
@@ -156,7 +156,7 @@ exports.Markets = [
|
|
|
156
156
|
oracleSource: __1.OracleSource.SWITCHBOARD,
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
|
-
fullName: '
|
|
159
|
+
fullName: 'ApeCoin',
|
|
160
160
|
category: ['NFT'],
|
|
161
161
|
symbol: 'APE-PERP',
|
|
162
162
|
baseAssetSymbol: 'APE',
|
|
@@ -166,6 +166,17 @@ exports.Markets = [
|
|
|
166
166
|
launchTs: 1648475932000,
|
|
167
167
|
oracleSource: __1.OracleSource.SWITCHBOARD,
|
|
168
168
|
},
|
|
169
|
+
{
|
|
170
|
+
fullName: 'DogeCoin',
|
|
171
|
+
category: ['Meme', 'NFT'],
|
|
172
|
+
symbol: 'DOGE-PERP',
|
|
173
|
+
baseAssetSymbol: 'DOGE',
|
|
174
|
+
marketIndex: new __1.BN(15),
|
|
175
|
+
devnetPublicKey: '4L6YhY8VvUgmqG5MvJkUJATtzB2rFqdrJwQCmFLv4Jzy',
|
|
176
|
+
mainnetPublicKey: 'FsSM3s38PX9K7Dn6eGzuE29S2Dsk1Sss1baytTQdCaQj',
|
|
177
|
+
launchTs: 1648607439000,
|
|
178
|
+
oracleSource: __1.OracleSource.PYTH,
|
|
179
|
+
},
|
|
169
180
|
// {
|
|
170
181
|
// symbol: 'mSOL-PERP',
|
|
171
182
|
// baseAssetSymbol: 'mSOL',
|
|
@@ -677,6 +677,52 @@
|
|
|
677
677
|
}
|
|
678
678
|
]
|
|
679
679
|
},
|
|
680
|
+
{
|
|
681
|
+
"name": "expireOrders",
|
|
682
|
+
"accounts": [
|
|
683
|
+
{
|
|
684
|
+
"name": "state",
|
|
685
|
+
"isMut": false,
|
|
686
|
+
"isSigner": false
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
"name": "orderState",
|
|
690
|
+
"isMut": false,
|
|
691
|
+
"isSigner": false
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
"name": "authority",
|
|
695
|
+
"isMut": false,
|
|
696
|
+
"isSigner": true
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
"name": "filler",
|
|
700
|
+
"isMut": true,
|
|
701
|
+
"isSigner": false
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
"name": "user",
|
|
705
|
+
"isMut": true,
|
|
706
|
+
"isSigner": false
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
"name": "userPositions",
|
|
710
|
+
"isMut": true,
|
|
711
|
+
"isSigner": false
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
"name": "userOrders",
|
|
715
|
+
"isMut": true,
|
|
716
|
+
"isSigner": false
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
"name": "orderHistory",
|
|
720
|
+
"isMut": true,
|
|
721
|
+
"isSigner": false
|
|
722
|
+
}
|
|
723
|
+
],
|
|
724
|
+
"args": []
|
|
725
|
+
},
|
|
680
726
|
{
|
|
681
727
|
"name": "fillOrder",
|
|
682
728
|
"accounts": [
|
|
@@ -1398,6 +1444,11 @@
|
|
|
1398
1444
|
"isMut": true,
|
|
1399
1445
|
"isSigner": false
|
|
1400
1446
|
},
|
|
1447
|
+
{
|
|
1448
|
+
"name": "userOrders",
|
|
1449
|
+
"isMut": true,
|
|
1450
|
+
"isSigner": false
|
|
1451
|
+
},
|
|
1401
1452
|
{
|
|
1402
1453
|
"name": "authority",
|
|
1403
1454
|
"isMut": false,
|
|
@@ -3190,8 +3241,8 @@
|
|
|
3190
3241
|
"type": "u128"
|
|
3191
3242
|
},
|
|
3192
3243
|
{
|
|
3193
|
-
"name": "
|
|
3194
|
-
"type": "
|
|
3244
|
+
"name": "netRevenueSinceLastFunding",
|
|
3245
|
+
"type": "i64"
|
|
3195
3246
|
},
|
|
3196
3247
|
{
|
|
3197
3248
|
"name": "padding2",
|
|
@@ -3800,6 +3851,9 @@
|
|
|
3800
3851
|
},
|
|
3801
3852
|
{
|
|
3802
3853
|
"name": "Fill"
|
|
3854
|
+
},
|
|
3855
|
+
{
|
|
3856
|
+
"name": "Expire"
|
|
3803
3857
|
}
|
|
3804
3858
|
]
|
|
3805
3859
|
}
|
|
@@ -4190,6 +4244,16 @@
|
|
|
4190
4244
|
"code": 6059,
|
|
4191
4245
|
"name": "InvalidOracleOffset",
|
|
4192
4246
|
"msg": "InvalidOracleOffset"
|
|
4247
|
+
},
|
|
4248
|
+
{
|
|
4249
|
+
"code": 6060,
|
|
4250
|
+
"name": "CantExpireOrders",
|
|
4251
|
+
"msg": "CantExpireOrders"
|
|
4252
|
+
},
|
|
4253
|
+
{
|
|
4254
|
+
"code": 6061,
|
|
4255
|
+
"name": "InvalidRepegPriceImpact",
|
|
4256
|
+
"msg": "AMM repeg mark price impact vs oracle too large"
|
|
4193
4257
|
}
|
|
4194
4258
|
]
|
|
4195
4259
|
}
|
package/lib/math/amm.d.ts
CHANGED
|
@@ -38,24 +38,6 @@ export declare function calculateSwapOutput(inputAssetReserve: BN, swapAmount: B
|
|
|
38
38
|
* @param positionDirection
|
|
39
39
|
*/
|
|
40
40
|
export declare function getSwapDirection(inputAssetType: AssetType, positionDirection: PositionDirection): SwapDirection;
|
|
41
|
-
/**
|
|
42
|
-
* Helper function calculating adjust k cost
|
|
43
|
-
* @param market
|
|
44
|
-
* @param marketIndex
|
|
45
|
-
* @param numerator
|
|
46
|
-
* @param denomenator
|
|
47
|
-
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
48
|
-
*/
|
|
49
|
-
export declare function calculateAdjustKCost(market: Market, marketIndex: BN, numerator: BN, denomenator: BN): BN;
|
|
50
|
-
/**
|
|
51
|
-
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
52
|
-
*
|
|
53
|
-
* @param market
|
|
54
|
-
* @param marketIndex
|
|
55
|
-
* @param newPeg
|
|
56
|
-
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
57
|
-
*/
|
|
58
|
-
export declare function calculateRepegCost(market: Market, marketIndex: BN, newPeg: BN): BN;
|
|
59
41
|
/**
|
|
60
42
|
* Helper function calculating terminal price of amm
|
|
61
43
|
*
|
package/lib/math/amm.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.
|
|
3
|
+
exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = void 0;
|
|
4
4
|
const anchor_1 = require("@project-serum/anchor");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
|
-
const position_1 = require("./position");
|
|
7
6
|
const types_1 = require("../types");
|
|
8
7
|
const assert_1 = require("../assert/assert");
|
|
9
8
|
const __1 = require("..");
|
|
@@ -88,92 +87,6 @@ function getSwapDirection(inputAssetType, positionDirection) {
|
|
|
88
87
|
return types_1.SwapDirection.ADD;
|
|
89
88
|
}
|
|
90
89
|
exports.getSwapDirection = getSwapDirection;
|
|
91
|
-
/**
|
|
92
|
-
* Helper function calculating adjust k cost
|
|
93
|
-
* @param market
|
|
94
|
-
* @param marketIndex
|
|
95
|
-
* @param numerator
|
|
96
|
-
* @param denomenator
|
|
97
|
-
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
98
|
-
*/
|
|
99
|
-
function calculateAdjustKCost(market, marketIndex, numerator, denomenator) {
|
|
100
|
-
const netUserPosition = {
|
|
101
|
-
baseAssetAmount: market.baseAssetAmount,
|
|
102
|
-
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
103
|
-
marketIndex: new anchor_1.BN(marketIndex),
|
|
104
|
-
quoteAssetAmount: new anchor_1.BN(0),
|
|
105
|
-
openOrders: new anchor_1.BN(0),
|
|
106
|
-
};
|
|
107
|
-
const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
|
|
108
|
-
const marketNewK = Object.assign({}, market);
|
|
109
|
-
marketNewK.amm = Object.assign({}, market.amm);
|
|
110
|
-
marketNewK.amm.baseAssetReserve = market.amm.baseAssetReserve
|
|
111
|
-
.mul(numerator)
|
|
112
|
-
.div(denomenator);
|
|
113
|
-
marketNewK.amm.quoteAssetReserve = market.amm.quoteAssetReserve
|
|
114
|
-
.mul(numerator)
|
|
115
|
-
.div(denomenator);
|
|
116
|
-
marketNewK.amm.sqrtK = market.amm.sqrtK.mul(numerator).div(denomenator);
|
|
117
|
-
netUserPosition.quoteAssetAmount = currentValue;
|
|
118
|
-
const cost = (0, __1.calculatePositionPNL)(marketNewK, netUserPosition);
|
|
119
|
-
const p = numericConstants_1.PEG_PRECISION.mul(numerator).div(denomenator);
|
|
120
|
-
const x = market.amm.baseAssetReserve;
|
|
121
|
-
const y = market.amm.quoteAssetReserve;
|
|
122
|
-
const delta = market.baseAssetAmount;
|
|
123
|
-
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
124
|
-
const numer1 = numericConstants_1.PEG_PRECISION.sub(p).mul(y).div(numericConstants_1.PEG_PRECISION);
|
|
125
|
-
const numer20 = k
|
|
126
|
-
.mul(p)
|
|
127
|
-
.mul(p)
|
|
128
|
-
.div(numericConstants_1.PEG_PRECISION)
|
|
129
|
-
.div(numericConstants_1.PEG_PRECISION)
|
|
130
|
-
.div(x.mul(p).div(numericConstants_1.PEG_PRECISION).add(delta));
|
|
131
|
-
const numer21 = k.div(x.add(delta));
|
|
132
|
-
const formulaCost = numer21
|
|
133
|
-
.sub(numer20)
|
|
134
|
-
.sub(numer1)
|
|
135
|
-
.mul(market.amm.pegMultiplier)
|
|
136
|
-
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
137
|
-
console.log((0, __1.convertToNumber)(formulaCost, numericConstants_1.QUOTE_PRECISION));
|
|
138
|
-
// p.div(p.mul(x).add(delta)).sub()
|
|
139
|
-
return cost;
|
|
140
|
-
}
|
|
141
|
-
exports.calculateAdjustKCost = calculateAdjustKCost;
|
|
142
|
-
/**
|
|
143
|
-
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
144
|
-
*
|
|
145
|
-
* @param market
|
|
146
|
-
* @param marketIndex
|
|
147
|
-
* @param newPeg
|
|
148
|
-
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
149
|
-
*/
|
|
150
|
-
function calculateRepegCost(market, marketIndex, newPeg) {
|
|
151
|
-
const netUserPosition = {
|
|
152
|
-
baseAssetAmount: market.baseAssetAmount,
|
|
153
|
-
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
154
|
-
marketIndex: new anchor_1.BN(marketIndex),
|
|
155
|
-
quoteAssetAmount: new anchor_1.BN(0),
|
|
156
|
-
openOrders: new anchor_1.BN(0),
|
|
157
|
-
};
|
|
158
|
-
const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
|
|
159
|
-
netUserPosition.quoteAssetAmount = currentValue;
|
|
160
|
-
const prevMarketPrice = (0, __1.calculateMarkPrice)(market);
|
|
161
|
-
const marketNewPeg = Object.assign({}, market);
|
|
162
|
-
marketNewPeg.amm = Object.assign({}, market.amm);
|
|
163
|
-
// const marketNewPeg = JSON.parse(JSON.stringify(market));
|
|
164
|
-
marketNewPeg.amm.pegMultiplier = newPeg;
|
|
165
|
-
console.log('Price moves from', (0, __1.convertToNumber)(prevMarketPrice), 'to', (0, __1.convertToNumber)((0, __1.calculateMarkPrice)(marketNewPeg)));
|
|
166
|
-
const cost = (0, __1.calculatePositionPNL)(marketNewPeg, netUserPosition);
|
|
167
|
-
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
168
|
-
const newQuoteAssetReserve = k.div(market.amm.baseAssetReserve.add(netUserPosition.baseAssetAmount));
|
|
169
|
-
const deltaQuoteAssetReserves = newQuoteAssetReserve.sub(market.amm.quoteAssetReserve);
|
|
170
|
-
const cost2 = deltaQuoteAssetReserves
|
|
171
|
-
.mul(market.amm.pegMultiplier.sub(newPeg))
|
|
172
|
-
.div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
173
|
-
console.log((0, __1.convertToNumber)(cost2, numericConstants_1.QUOTE_PRECISION));
|
|
174
|
-
return cost;
|
|
175
|
-
}
|
|
176
|
-
exports.calculateRepegCost = calculateRepegCost;
|
|
177
90
|
/**
|
|
178
91
|
* Helper function calculating terminal price of amm
|
|
179
92
|
*
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { BN } from '@project-serum/anchor';
|
|
3
|
+
import { Market } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Helper function calculating adjust k cost
|
|
6
|
+
* @param market
|
|
7
|
+
* @param marketIndex
|
|
8
|
+
* @param numerator
|
|
9
|
+
* @param denomenator
|
|
10
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
11
|
+
*/
|
|
12
|
+
export declare function calculateAdjustKCost(market: Market, marketIndex: BN, numerator: BN, denomenator: BN): BN;
|
|
13
|
+
/**
|
|
14
|
+
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
15
|
+
*
|
|
16
|
+
* @param market
|
|
17
|
+
* @param marketIndex
|
|
18
|
+
* @param newPeg
|
|
19
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
20
|
+
*/
|
|
21
|
+
export declare function calculateRepegCost(market: Market, marketIndex: BN, newPeg: BN): BN;
|
|
22
|
+
/**
|
|
23
|
+
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
24
|
+
*
|
|
25
|
+
* @param market
|
|
26
|
+
* @param marketIndex
|
|
27
|
+
* @param newPeg
|
|
28
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
29
|
+
*/
|
|
30
|
+
export declare function calculateReserveRebalanceCost(market: Market, marketIndex: BN): BN;
|
|
31
|
+
export declare function calculateBudgetedK(market: Market, cost: BN): [BN, BN];
|
|
32
|
+
export declare function calculateBudgetedPeg(market: Market, cost: BN): BN;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateReserveRebalanceCost = exports.calculateRepegCost = exports.calculateAdjustKCost = void 0;
|
|
4
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
5
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
|
+
const position_1 = require("./position");
|
|
7
|
+
const amm_1 = require("./amm");
|
|
8
|
+
const __1 = require("..");
|
|
9
|
+
/**
|
|
10
|
+
* Helper function calculating adjust k cost
|
|
11
|
+
* @param market
|
|
12
|
+
* @param marketIndex
|
|
13
|
+
* @param numerator
|
|
14
|
+
* @param denomenator
|
|
15
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
16
|
+
*/
|
|
17
|
+
function calculateAdjustKCost(market, marketIndex, numerator, denomenator) {
|
|
18
|
+
const netUserPosition = {
|
|
19
|
+
baseAssetAmount: market.baseAssetAmount,
|
|
20
|
+
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
21
|
+
marketIndex: new anchor_1.BN(marketIndex),
|
|
22
|
+
quoteAssetAmount: numericConstants_1.ZERO,
|
|
23
|
+
openOrders: numericConstants_1.ZERO,
|
|
24
|
+
};
|
|
25
|
+
const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
|
|
26
|
+
const marketNewK = Object.assign({}, market);
|
|
27
|
+
marketNewK.amm = Object.assign({}, market.amm);
|
|
28
|
+
marketNewK.amm.baseAssetReserve = market.amm.baseAssetReserve
|
|
29
|
+
.mul(numerator)
|
|
30
|
+
.div(denomenator);
|
|
31
|
+
marketNewK.amm.quoteAssetReserve = market.amm.quoteAssetReserve
|
|
32
|
+
.mul(numerator)
|
|
33
|
+
.div(denomenator);
|
|
34
|
+
marketNewK.amm.sqrtK = market.amm.sqrtK.mul(numerator).div(denomenator);
|
|
35
|
+
netUserPosition.quoteAssetAmount = currentValue;
|
|
36
|
+
const cost = (0, __1.calculatePositionPNL)(marketNewK, netUserPosition);
|
|
37
|
+
return cost;
|
|
38
|
+
}
|
|
39
|
+
exports.calculateAdjustKCost = calculateAdjustKCost;
|
|
40
|
+
/**
|
|
41
|
+
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
42
|
+
*
|
|
43
|
+
* @param market
|
|
44
|
+
* @param marketIndex
|
|
45
|
+
* @param newPeg
|
|
46
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
47
|
+
*/
|
|
48
|
+
function calculateRepegCost(market, marketIndex, newPeg) {
|
|
49
|
+
const netUserPosition = {
|
|
50
|
+
baseAssetAmount: market.baseAssetAmount,
|
|
51
|
+
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
52
|
+
marketIndex: new anchor_1.BN(marketIndex),
|
|
53
|
+
quoteAssetAmount: new anchor_1.BN(0),
|
|
54
|
+
openOrders: numericConstants_1.ZERO,
|
|
55
|
+
};
|
|
56
|
+
const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
|
|
57
|
+
netUserPosition.quoteAssetAmount = currentValue;
|
|
58
|
+
const prevMarketPrice = (0, __1.calculateMarkPrice)(market);
|
|
59
|
+
const marketNewPeg = Object.assign({}, market);
|
|
60
|
+
marketNewPeg.amm = Object.assign({}, market.amm);
|
|
61
|
+
// const marketNewPeg = JSON.parse(JSON.stringify(market));
|
|
62
|
+
marketNewPeg.amm.pegMultiplier = newPeg;
|
|
63
|
+
console.log('Price moves from', (0, __1.convertToNumber)(prevMarketPrice), 'to', (0, __1.convertToNumber)((0, __1.calculateMarkPrice)(marketNewPeg)));
|
|
64
|
+
const cost = (0, __1.calculatePositionPNL)(marketNewPeg, netUserPosition);
|
|
65
|
+
return cost;
|
|
66
|
+
}
|
|
67
|
+
exports.calculateRepegCost = calculateRepegCost;
|
|
68
|
+
/**
|
|
69
|
+
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
70
|
+
*
|
|
71
|
+
* @param market
|
|
72
|
+
* @param marketIndex
|
|
73
|
+
* @param newPeg
|
|
74
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
75
|
+
*/
|
|
76
|
+
function calculateReserveRebalanceCost(market, marketIndex) {
|
|
77
|
+
const netUserPosition = {
|
|
78
|
+
baseAssetAmount: market.baseAssetAmount,
|
|
79
|
+
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
80
|
+
marketIndex: new anchor_1.BN(marketIndex),
|
|
81
|
+
quoteAssetAmount: new anchor_1.BN(0),
|
|
82
|
+
openOrders: numericConstants_1.ZERO,
|
|
83
|
+
};
|
|
84
|
+
const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
|
|
85
|
+
netUserPosition.quoteAssetAmount = currentValue;
|
|
86
|
+
const prevMarketPrice = (0, __1.calculateMarkPrice)(market);
|
|
87
|
+
const marketNewPeg = Object.assign({}, market);
|
|
88
|
+
marketNewPeg.amm = Object.assign({}, market.amm);
|
|
89
|
+
// const marketNewPeg = JSON.parse(JSON.stringify(market));
|
|
90
|
+
const newPeg = (0, amm_1.calculateTerminalPrice)(market)
|
|
91
|
+
.mul(numericConstants_1.PEG_PRECISION)
|
|
92
|
+
.div(numericConstants_1.MARK_PRICE_PRECISION);
|
|
93
|
+
// const newPeg = prevMarketPrice.mul(PEG_PRECISION).div(MARK_PRICE_PRECISION);
|
|
94
|
+
const newBaseReserve = market.amm.baseAssetReserve.add(market.baseAssetAmount);
|
|
95
|
+
const newQuoteReserve = market.amm.sqrtK
|
|
96
|
+
.mul(market.amm.sqrtK)
|
|
97
|
+
.div(newBaseReserve);
|
|
98
|
+
console.log('current reserves on close, quote:', (0, __1.convertToNumber)(newQuoteReserve, numericConstants_1.AMM_RESERVE_PRECISION), 'base:', (0, __1.convertToNumber)(newBaseReserve, numericConstants_1.AMM_RESERVE_PRECISION));
|
|
99
|
+
let newSqrtK;
|
|
100
|
+
if (newPeg.lt(market.amm.pegMultiplier)) {
|
|
101
|
+
newSqrtK = newBaseReserve;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
newSqrtK = newQuoteReserve;
|
|
105
|
+
}
|
|
106
|
+
marketNewPeg.amm.baseAssetReserve = newSqrtK.sub(market.baseAssetAmount); // newSqrtK.sub(market.baseAssetAmount);
|
|
107
|
+
marketNewPeg.amm.quoteAssetReserve = newSqrtK
|
|
108
|
+
.mul(newSqrtK)
|
|
109
|
+
.div(marketNewPeg.amm.baseAssetReserve);
|
|
110
|
+
marketNewPeg.amm.sqrtK = newSqrtK;
|
|
111
|
+
marketNewPeg.amm.pegMultiplier = newPeg;
|
|
112
|
+
console.log('Price moves from', (0, __1.convertToNumber)(prevMarketPrice), 'to', (0, __1.convertToNumber)((0, __1.calculateMarkPrice)(marketNewPeg)));
|
|
113
|
+
const cost = (0, __1.calculatePositionPNL)(marketNewPeg, netUserPosition);
|
|
114
|
+
return cost;
|
|
115
|
+
}
|
|
116
|
+
exports.calculateReserveRebalanceCost = calculateReserveRebalanceCost;
|
|
117
|
+
function calculateBudgetedK(market, cost) {
|
|
118
|
+
// wolframalpha.com
|
|
119
|
+
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
120
|
+
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
121
|
+
// todo: assumes k = x * y
|
|
122
|
+
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
123
|
+
// const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
124
|
+
const x = market.amm.baseAssetReserve;
|
|
125
|
+
const y = market.amm.quoteAssetReserve;
|
|
126
|
+
const d = market.baseAssetAmount;
|
|
127
|
+
const Q = market.amm.pegMultiplier;
|
|
128
|
+
const C = cost.mul(new anchor_1.BN(-1));
|
|
129
|
+
const numer1 = y.mul(d).mul(Q).div(numericConstants_1.AMM_RESERVE_PRECISION).div(numericConstants_1.PEG_PRECISION);
|
|
130
|
+
const numer2 = C.mul(x.add(d)).div(numericConstants_1.QUOTE_PRECISION);
|
|
131
|
+
const denom1 = C.mul(x)
|
|
132
|
+
.mul(x.add(d))
|
|
133
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
134
|
+
.div(numericConstants_1.QUOTE_PRECISION);
|
|
135
|
+
const denom2 = y
|
|
136
|
+
.mul(d)
|
|
137
|
+
.mul(d)
|
|
138
|
+
.mul(Q)
|
|
139
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
140
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
141
|
+
.div(numericConstants_1.PEG_PRECISION);
|
|
142
|
+
const numerator = d
|
|
143
|
+
.mul(numer1.add(numer2))
|
|
144
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
145
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
146
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
|
|
147
|
+
const denominator = denom1
|
|
148
|
+
.add(denom2)
|
|
149
|
+
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
150
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
|
|
151
|
+
console.log(numerator, denominator);
|
|
152
|
+
// const p = (numerator).div(denominator);
|
|
153
|
+
// const formulaCost = (numer21.sub(numer20).sub(numer1)).mul(market.amm.pegMultiplier).div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
|
|
154
|
+
// console.log(convertToNumber(formulaCost, QUOTE_PRECISION))
|
|
155
|
+
return [numerator, denominator];
|
|
156
|
+
}
|
|
157
|
+
exports.calculateBudgetedK = calculateBudgetedK;
|
|
158
|
+
function calculateBudgetedPeg(market, cost) {
|
|
159
|
+
// wolframalpha.com
|
|
160
|
+
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
161
|
+
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
162
|
+
// todo: assumes k = x * y
|
|
163
|
+
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
164
|
+
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
165
|
+
const x = market.amm.baseAssetReserve;
|
|
166
|
+
const y = market.amm.quoteAssetReserve;
|
|
167
|
+
const d = market.baseAssetAmount;
|
|
168
|
+
const Q = market.amm.pegMultiplier;
|
|
169
|
+
const C = cost.mul(new anchor_1.BN(-1));
|
|
170
|
+
const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
|
|
171
|
+
const deltaPegMultiplier = C.mul(numericConstants_1.MARK_PRICE_PRECISION).div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO));
|
|
172
|
+
// .mul(PEG_PRECISION)
|
|
173
|
+
// .div(QUOTE_PRECISION);
|
|
174
|
+
console.log(Q.toNumber(), 'change by', deltaPegMultiplier.toNumber() / numericConstants_1.MARK_PRICE_PRECISION.toNumber());
|
|
175
|
+
const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.MARK_PRICE_PRECISION));
|
|
176
|
+
return newPeg;
|
|
177
|
+
}
|
|
178
|
+
exports.calculateBudgetedPeg = calculateBudgetedPeg;
|
package/lib/types.d.ts
CHANGED
package/lib/types.js
CHANGED
package/package.json
CHANGED
|
@@ -9,6 +9,7 @@ type AccountToLoad = {
|
|
|
9
9
|
|
|
10
10
|
const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
|
|
11
11
|
|
|
12
|
+
const oneMinute = 60 * 1000;
|
|
12
13
|
const fiveMinutes = 5 * 60 * 1000;
|
|
13
14
|
|
|
14
15
|
export class BulkAccountLoader {
|
|
@@ -104,10 +105,6 @@ export class BulkAccountLoader {
|
|
|
104
105
|
this.loadPromiseResolver = resolver;
|
|
105
106
|
});
|
|
106
107
|
|
|
107
|
-
if (this.loggingEnabled) {
|
|
108
|
-
console.log('Loading accounts');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
108
|
try {
|
|
112
109
|
const chunks = this.chunks(
|
|
113
110
|
Array.from(this.accountsToLoad.values()),
|
|
@@ -163,6 +160,11 @@ export class BulkAccountLoader {
|
|
|
163
160
|
args
|
|
164
161
|
);
|
|
165
162
|
|
|
163
|
+
const oneMinuteSinceLastUpdate = Date.now() - this.lastUpdate > oneMinute;
|
|
164
|
+
if (this.loggingEnabled && oneMinuteSinceLastUpdate) {
|
|
165
|
+
console.log('rpcResponse', JSON.stringify(rpcResponse));
|
|
166
|
+
}
|
|
167
|
+
|
|
166
168
|
const newSlot = rpcResponse.result.context.slot;
|
|
167
169
|
|
|
168
170
|
for (const i in accountsToLoad) {
|
|
@@ -177,6 +179,10 @@ export class BulkAccountLoader {
|
|
|
177
179
|
newBuffer = Buffer.from(raw, dataType);
|
|
178
180
|
}
|
|
179
181
|
|
|
182
|
+
if (this.loggingEnabled && oneMinuteSinceLastUpdate) {
|
|
183
|
+
console.log('oldRPCResponse', oldRPCResponse);
|
|
184
|
+
}
|
|
185
|
+
|
|
180
186
|
if (!oldRPCResponse) {
|
|
181
187
|
this.accountData.set(key, {
|
|
182
188
|
slot: newSlot,
|
|
@@ -199,6 +205,10 @@ export class BulkAccountLoader {
|
|
|
199
205
|
});
|
|
200
206
|
this.handleAccountCallbacks(accountToLoad, newBuffer);
|
|
201
207
|
this.lastUpdate = Date.now();
|
|
208
|
+
} else if (this.loggingEnabled) {
|
|
209
|
+
console.log('unable to update account for newest slot');
|
|
210
|
+
console.log('oldBuffer', oldBuffer);
|
|
211
|
+
console.log('newBuffer', newBuffer);
|
|
202
212
|
}
|
|
203
213
|
}
|
|
204
214
|
}
|