@drift-labs/sdk 0.1.29-master.0 → 0.1.30-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 +1 -0
- package/lib/accounts/bulkAccountLoader.js +33 -13
- package/lib/clearingHouse.d.ts +4 -1
- package/lib/clearingHouse.js +49 -0
- package/lib/constants/markets.js +11 -0
- package/lib/idl/clearing_house.json +63 -2
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/amm.d.ts +0 -20
- package/lib/math/amm.js +1 -151
- package/lib/math/repeg.d.ts +32 -0
- package/lib/math/repeg.js +178 -0
- package/lib/oracles/pythClient.js +1 -1
- package/lib/orderParams.d.ts +1 -1
- package/lib/orderParams.js +2 -2
- package/lib/tx/retryTxSender.d.ts +5 -2
- package/lib/tx/retryTxSender.js +14 -1
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.ts +40 -15
- package/src/clearingHouse.ts +71 -0
- package/src/constants/markets.ts +11 -0
- package/src/idl/clearing_house.json +63 -2
- package/src/index.ts +1 -0
- package/src/math/amm.ts +1 -212
- package/src/math/repeg.ts +253 -0
- package/src/oracles/pythClient.ts +1 -1
- package/src/orderParams.ts +3 -2
- package/src/tx/retryTxSender.ts +19 -1
- package/src/accounts/bulkUserSubscription.js +0 -56
- package/src/accounts/bulkUserSubscription.js.map +0 -1
- package/src/accounts/pollingUserAccountSubscriber.js +0 -139
- package/src/accounts/pollingUserAccountSubscriber.js.map +0 -1
- package/src/accounts/types.js +0 -11
- package/src/accounts/types.js.map +0 -1
- package/src/accounts/webSocketUserAccountSubscriber.js +0 -78
- package/src/accounts/webSocketUserAccountSubscriber.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/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/factory/clearingHouse.js +0 -65
- package/src/factory/clearingHouse.js.map +0 -1
- package/src/factory/clearingHouseUser.js +0 -35
- package/src/factory/clearingHouseUser.js.map +0 -1
- package/src/factory/oracleClient.js +0 -17
- package/src/factory/oracleClient.js.map +0 -1
- package/src/index.js +0 -56
- package/src/index.js.map +0 -1
- package/src/math/amm.js +0 -285
- package/src/math/amm.js.map +0 -1
- package/src/mockUSDCFaucet.js +0 -143
- package/src/mockUSDCFaucet.js.map +0 -1
- package/src/oracles/pythClient.js +0 -39
- package/src/oracles/pythClient.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/tx/retryTxSender.js +0 -137
- package/src/tx/retryTxSender.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
|
@@ -29,11 +29,14 @@ class BulkAccountLoader {
|
|
|
29
29
|
addAccount(publicKey, callback) {
|
|
30
30
|
const existingSize = this.accountsToLoad.size;
|
|
31
31
|
const callbackId = (0, uuid_1.v4)();
|
|
32
|
+
this.log(`Adding account ${publicKey.toString()} callback id ${callbackId}`);
|
|
32
33
|
const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
|
|
33
34
|
if (existingAccountToLoad) {
|
|
35
|
+
this.log(`account already exists`);
|
|
34
36
|
existingAccountToLoad.callbacks.set(callbackId, callback);
|
|
35
37
|
}
|
|
36
38
|
else {
|
|
39
|
+
this.log(`account doesn't already exist. creating new callback map`);
|
|
37
40
|
const callbacks = new Map();
|
|
38
41
|
callbacks.set(callbackId, callback);
|
|
39
42
|
const newAccountToLoad = {
|
|
@@ -50,6 +53,7 @@ class BulkAccountLoader {
|
|
|
50
53
|
return callbackId;
|
|
51
54
|
}
|
|
52
55
|
removeAccount(publicKey, callbackId) {
|
|
56
|
+
this.log(`Removing account ${publicKey.toString()} callback id ${callbackId}`);
|
|
53
57
|
const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
|
|
54
58
|
if (existingAccountToLoad) {
|
|
55
59
|
existingAccountToLoad.callbacks.delete(callbackId);
|
|
@@ -78,13 +82,16 @@ class BulkAccountLoader {
|
|
|
78
82
|
load() {
|
|
79
83
|
return __awaiter(this, void 0, void 0, function* () {
|
|
80
84
|
if (this.loadPromise) {
|
|
85
|
+
this.log(`Load promise exists. Returning early`);
|
|
81
86
|
return this.loadPromise;
|
|
82
87
|
}
|
|
83
88
|
this.loadPromise = new Promise((resolver) => {
|
|
84
89
|
this.loadPromiseResolver = resolver;
|
|
85
90
|
});
|
|
91
|
+
this.log(`Loading`);
|
|
86
92
|
try {
|
|
87
93
|
const chunks = this.chunks(Array.from(this.accountsToLoad.values()), GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE);
|
|
94
|
+
this.log(`${chunks.length} chunks`);
|
|
88
95
|
yield Promise.all(chunks.map((chunk) => {
|
|
89
96
|
return this.loadChunk(chunk);
|
|
90
97
|
}));
|
|
@@ -95,15 +102,15 @@ class BulkAccountLoader {
|
|
|
95
102
|
for (const [_, callback] of this.errorCallbacks) {
|
|
96
103
|
callback(e);
|
|
97
104
|
}
|
|
105
|
+
this.log('finished error callbacks');
|
|
98
106
|
}
|
|
99
107
|
finally {
|
|
108
|
+
this.log(`resetting load promise`);
|
|
100
109
|
this.loadPromiseResolver();
|
|
101
110
|
this.loadPromise = undefined;
|
|
102
111
|
const now = Date.now();
|
|
103
112
|
if (now - this.lastUpdate > fiveMinutes) {
|
|
104
|
-
|
|
105
|
-
console.log("Haven't seen updated account in five minutes. Bulk account loader creating new Connection Object");
|
|
106
|
-
}
|
|
113
|
+
this.log("Haven't seen updated account in five minutes. Bulk account loader creating new Connection Object");
|
|
107
114
|
this.connection = new web3_js_1.Connection(
|
|
108
115
|
// @ts-ignore
|
|
109
116
|
this.connection._rpcEndpoint, this.connection.commitment);
|
|
@@ -114,6 +121,7 @@ class BulkAccountLoader {
|
|
|
114
121
|
loadChunk(accountsToLoad) {
|
|
115
122
|
return __awaiter(this, void 0, void 0, function* () {
|
|
116
123
|
if (accountsToLoad.length === 0) {
|
|
124
|
+
this.log(`no accounts in chunk`);
|
|
117
125
|
return;
|
|
118
126
|
}
|
|
119
127
|
const args = [
|
|
@@ -125,8 +133,8 @@ class BulkAccountLoader {
|
|
|
125
133
|
// @ts-ignore
|
|
126
134
|
const rpcResponse = yield this.connection._rpcRequest('getMultipleAccounts', args);
|
|
127
135
|
const oneMinuteSinceLastUpdate = Date.now() - this.lastUpdate > oneMinute;
|
|
128
|
-
if (
|
|
129
|
-
|
|
136
|
+
if (oneMinuteSinceLastUpdate) {
|
|
137
|
+
this.log('rpcResponse ' + JSON.stringify(rpcResponse));
|
|
130
138
|
}
|
|
131
139
|
const newSlot = rpcResponse.result.context.slot;
|
|
132
140
|
for (const i in accountsToLoad) {
|
|
@@ -139,10 +147,11 @@ class BulkAccountLoader {
|
|
|
139
147
|
const dataType = rpcResponse.result.value[i].data[1];
|
|
140
148
|
newBuffer = Buffer.from(raw, dataType);
|
|
141
149
|
}
|
|
142
|
-
if (
|
|
143
|
-
|
|
150
|
+
if (oneMinuteSinceLastUpdate) {
|
|
151
|
+
this.log('oldRPCResponse' + oldRPCResponse);
|
|
144
152
|
}
|
|
145
153
|
if (!oldRPCResponse) {
|
|
154
|
+
this.log('No old rpc response, updating account data');
|
|
146
155
|
this.accountData.set(key, {
|
|
147
156
|
slot: newSlot,
|
|
148
157
|
buffer: newBuffer,
|
|
@@ -152,10 +161,12 @@ class BulkAccountLoader {
|
|
|
152
161
|
continue;
|
|
153
162
|
}
|
|
154
163
|
if (newSlot <= oldRPCResponse.slot) {
|
|
164
|
+
this.log(`new slot ${newSlot} old slot ${oldRPCResponse.slot}`);
|
|
155
165
|
continue;
|
|
156
166
|
}
|
|
157
167
|
const oldBuffer = oldRPCResponse.buffer;
|
|
158
168
|
if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
|
|
169
|
+
this.log('new buffer, updating account data');
|
|
159
170
|
this.accountData.set(key, {
|
|
160
171
|
slot: newSlot,
|
|
161
172
|
buffer: newBuffer,
|
|
@@ -163,13 +174,21 @@ class BulkAccountLoader {
|
|
|
163
174
|
this.handleAccountCallbacks(accountToLoad, newBuffer);
|
|
164
175
|
this.lastUpdate = Date.now();
|
|
165
176
|
}
|
|
177
|
+
else {
|
|
178
|
+
this.log('unable to update account for newest slot');
|
|
179
|
+
this.log('oldBuffer ' + oldBuffer);
|
|
180
|
+
this.log('newBuffer ' + newBuffer);
|
|
181
|
+
this.log('buffers equal ' + newBuffer.equals(oldBuffer));
|
|
182
|
+
}
|
|
166
183
|
}
|
|
167
184
|
});
|
|
168
185
|
}
|
|
169
186
|
handleAccountCallbacks(accountToLoad, buffer) {
|
|
187
|
+
this.log('handling account callbacks');
|
|
170
188
|
for (const [_, callback] of accountToLoad.callbacks) {
|
|
171
189
|
callback(buffer);
|
|
172
190
|
}
|
|
191
|
+
this.log('finished account callbacks');
|
|
173
192
|
}
|
|
174
193
|
getAccountData(publicKey) {
|
|
175
194
|
const accountData = this.accountData.get(publicKey.toString());
|
|
@@ -179,18 +198,19 @@ class BulkAccountLoader {
|
|
|
179
198
|
if (this.intervalId) {
|
|
180
199
|
return;
|
|
181
200
|
}
|
|
182
|
-
|
|
183
|
-
console.log(`startPolling`);
|
|
184
|
-
}
|
|
201
|
+
this.log('startPolling');
|
|
185
202
|
this.intervalId = setInterval(this.load.bind(this), this.pollingFrequency);
|
|
186
203
|
}
|
|
187
204
|
stopPolling() {
|
|
188
205
|
if (this.intervalId) {
|
|
189
206
|
clearInterval(this.intervalId);
|
|
190
207
|
this.intervalId = undefined;
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
208
|
+
this.log('stopPolling');
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
log(msg) {
|
|
212
|
+
if (this.loggingEnabled) {
|
|
213
|
+
console.log(msg);
|
|
194
214
|
}
|
|
195
215
|
}
|
|
196
216
|
}
|
package/lib/clearingHouse.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="bn.js" />
|
|
3
3
|
import { BN, Program, Provider } from '@project-serum/anchor';
|
|
4
|
-
import { MarketsAccount, StateAccount, DepositHistoryAccount, FundingPaymentHistoryAccount, FundingRateHistoryAccount, IWallet, LiquidationHistoryAccount, PositionDirection, TradeHistoryAccount, UserAccount, Market, OrderHistoryAccount, OrderStateAccount, OrderParams, Order, ExtendedCurveHistoryAccount } from './types';
|
|
4
|
+
import { MarketsAccount, StateAccount, DepositHistoryAccount, FundingPaymentHistoryAccount, FundingRateHistoryAccount, IWallet, LiquidationHistoryAccount, PositionDirection, TradeHistoryAccount, UserAccount, Market, OrderHistoryAccount, OrderStateAccount, OrderParams, Order, ExtendedCurveHistoryAccount, UserPositionsAccount } from './types';
|
|
5
5
|
import { Connection, PublicKey, TransactionSignature, Keypair, ConfirmOptions, TransactionInstruction } from '@solana/web3.js';
|
|
6
6
|
import { MockUSDCFaucet } from './mockUSDCFaucet';
|
|
7
7
|
import { EventEmitter } from 'events';
|
|
@@ -127,6 +127,8 @@ export declare class ClearingHouse {
|
|
|
127
127
|
getCancelOrderIx(orderId: BN, oracle?: PublicKey): Promise<TransactionInstruction>;
|
|
128
128
|
cancelOrderByUserId(userOrderId: number, oracle?: PublicKey): Promise<TransactionSignature>;
|
|
129
129
|
getCancelOrderByUserIdIx(userOrderId: number, oracle?: PublicKey): Promise<TransactionInstruction>;
|
|
130
|
+
cancelAllOrders(oracles?: PublicKey[]): Promise<TransactionSignature>;
|
|
131
|
+
getCancelAllOrdersIx(oracles: PublicKey[]): Promise<TransactionInstruction>;
|
|
130
132
|
fillOrder(userAccountPublicKey: PublicKey, userOrdersAccountPublicKey: PublicKey, order: Order): Promise<TransactionSignature>;
|
|
131
133
|
getFillOrderIx(userAccountPublicKey: PublicKey, userOrdersAccountPublicKey: PublicKey, order: Order): Promise<TransactionInstruction>;
|
|
132
134
|
initializeUserOrdersThenPlaceAndFillOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
|
|
@@ -141,6 +143,7 @@ export declare class ClearingHouse {
|
|
|
141
143
|
*/
|
|
142
144
|
closePosition(marketIndex: BN, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
|
|
143
145
|
getClosePositionIx(marketIndex: BN, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionInstruction>;
|
|
146
|
+
closeAllPositions(userPositionsAccount: UserPositionsAccount, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
|
|
144
147
|
liquidate(liquidateeUserAccountPublicKey: PublicKey): Promise<TransactionSignature>;
|
|
145
148
|
getLiquidateIx(liquidateeUserAccountPublicKey: PublicKey): Promise<TransactionInstruction>;
|
|
146
149
|
updateFundingRate(oracle: PublicKey, marketIndex: BN): Promise<TransactionSignature>;
|
package/lib/clearingHouse.js
CHANGED
|
@@ -634,6 +634,42 @@ class ClearingHouse {
|
|
|
634
634
|
});
|
|
635
635
|
});
|
|
636
636
|
}
|
|
637
|
+
cancelAllOrders(oracles) {
|
|
638
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
639
|
+
return yield this.txSender.send((0, utils_1.wrapInTx)(yield this.getCancelAllOrdersIx(oracles)), [], this.opts);
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
getCancelAllOrdersIx(oracles) {
|
|
643
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
644
|
+
const userAccountPublicKey = yield this.getUserAccountPublicKey();
|
|
645
|
+
const userAccount = yield this.getUserAccount();
|
|
646
|
+
const state = this.getStateAccount();
|
|
647
|
+
const orderState = this.getOrderStateAccount();
|
|
648
|
+
const remainingAccounts = [];
|
|
649
|
+
for (const oracle of oracles) {
|
|
650
|
+
remainingAccounts.push({
|
|
651
|
+
pubkey: oracle,
|
|
652
|
+
isWritable: false,
|
|
653
|
+
isSigner: false,
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
return yield this.program.instruction.cancelAllOrders({
|
|
657
|
+
accounts: {
|
|
658
|
+
state: yield this.getStatePublicKey(),
|
|
659
|
+
user: userAccountPublicKey,
|
|
660
|
+
authority: this.wallet.publicKey,
|
|
661
|
+
markets: state.markets,
|
|
662
|
+
userOrders: yield this.getUserOrdersAccountPublicKey(),
|
|
663
|
+
userPositions: userAccount.positions,
|
|
664
|
+
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
665
|
+
fundingRateHistory: state.fundingRateHistory,
|
|
666
|
+
orderState: yield this.getOrderStatePublicKey(),
|
|
667
|
+
orderHistory: orderState.orderHistory,
|
|
668
|
+
},
|
|
669
|
+
remainingAccounts,
|
|
670
|
+
});
|
|
671
|
+
});
|
|
672
|
+
}
|
|
637
673
|
fillOrder(userAccountPublicKey, userOrdersAccountPublicKey, order) {
|
|
638
674
|
return __awaiter(this, void 0, void 0, function* () {
|
|
639
675
|
return yield this.txSender.send((0, utils_1.wrapInTx)(yield this.getFillOrderIx(userAccountPublicKey, userOrdersAccountPublicKey, order)), [], this.opts);
|
|
@@ -801,6 +837,19 @@ class ClearingHouse {
|
|
|
801
837
|
});
|
|
802
838
|
});
|
|
803
839
|
}
|
|
840
|
+
closeAllPositions(userPositionsAccount, discountToken, referrer) {
|
|
841
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
842
|
+
const ixs = [];
|
|
843
|
+
for (const userPosition of userPositionsAccount.positions) {
|
|
844
|
+
if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
ixs.push(yield this.getClosePositionIx(userPosition.marketIndex, discountToken, referrer));
|
|
848
|
+
}
|
|
849
|
+
const tx = new web3_js_1.Transaction().add(...ixs);
|
|
850
|
+
return this.txSender.send(tx, [], this.opts);
|
|
851
|
+
});
|
|
852
|
+
}
|
|
804
853
|
liquidate(liquidateeUserAccountPublicKey) {
|
|
805
854
|
return __awaiter(this, void 0, void 0, function* () {
|
|
806
855
|
return this.txSender.send((0, utils_1.wrapInTx)(yield this.getLiquidateIx(liquidateeUserAccountPublicKey)), [], this.opts);
|
package/lib/constants/markets.js
CHANGED
|
@@ -177,6 +177,17 @@ exports.Markets = [
|
|
|
177
177
|
launchTs: 1648607439000,
|
|
178
178
|
oracleSource: __1.OracleSource.PYTH,
|
|
179
179
|
},
|
|
180
|
+
{
|
|
181
|
+
fullName: 'Near',
|
|
182
|
+
category: ['L1', 'Infra'],
|
|
183
|
+
symbol: 'NEAR-PERP',
|
|
184
|
+
baseAssetSymbol: 'NEAR',
|
|
185
|
+
marketIndex: new __1.BN(16),
|
|
186
|
+
devnetPublicKey: '3gnSbT7bhoTdGkFVZc1dW1PvjreWzpUNUD5ppXwv1N59',
|
|
187
|
+
mainnetPublicKey: 'ECSFWQ1bnnpqPVvoy9237t2wddZAaHisW88mYxuEHKWf',
|
|
188
|
+
launchTs: 1649105516000,
|
|
189
|
+
oracleSource: __1.OracleSource.PYTH,
|
|
190
|
+
},
|
|
180
191
|
// {
|
|
181
192
|
// symbol: 'mSOL-PERP',
|
|
182
193
|
// baseAssetSymbol: 'mSOL',
|
|
@@ -677,6 +677,57 @@
|
|
|
677
677
|
}
|
|
678
678
|
]
|
|
679
679
|
},
|
|
680
|
+
{
|
|
681
|
+
"name": "cancelAllOrders",
|
|
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": "user",
|
|
695
|
+
"isMut": false,
|
|
696
|
+
"isSigner": false
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
"name": "authority",
|
|
700
|
+
"isMut": false,
|
|
701
|
+
"isSigner": true
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
"name": "markets",
|
|
705
|
+
"isMut": false,
|
|
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": "fundingPaymentHistory",
|
|
720
|
+
"isMut": true,
|
|
721
|
+
"isSigner": false
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
"name": "orderHistory",
|
|
725
|
+
"isMut": true,
|
|
726
|
+
"isSigner": false
|
|
727
|
+
}
|
|
728
|
+
],
|
|
729
|
+
"args": []
|
|
730
|
+
},
|
|
680
731
|
{
|
|
681
732
|
"name": "expireOrders",
|
|
682
733
|
"accounts": [
|
|
@@ -1444,6 +1495,11 @@
|
|
|
1444
1495
|
"isMut": true,
|
|
1445
1496
|
"isSigner": false
|
|
1446
1497
|
},
|
|
1498
|
+
{
|
|
1499
|
+
"name": "userOrders",
|
|
1500
|
+
"isMut": true,
|
|
1501
|
+
"isSigner": false
|
|
1502
|
+
},
|
|
1447
1503
|
{
|
|
1448
1504
|
"name": "authority",
|
|
1449
1505
|
"isMut": false,
|
|
@@ -3236,8 +3292,8 @@
|
|
|
3236
3292
|
"type": "u128"
|
|
3237
3293
|
},
|
|
3238
3294
|
{
|
|
3239
|
-
"name": "
|
|
3240
|
-
"type": "
|
|
3295
|
+
"name": "netRevenueSinceLastFunding",
|
|
3296
|
+
"type": "i64"
|
|
3241
3297
|
},
|
|
3242
3298
|
{
|
|
3243
3299
|
"name": "padding2",
|
|
@@ -4244,6 +4300,11 @@
|
|
|
4244
4300
|
"code": 6060,
|
|
4245
4301
|
"name": "CantExpireOrders",
|
|
4246
4302
|
"msg": "CantExpireOrders"
|
|
4303
|
+
},
|
|
4304
|
+
{
|
|
4305
|
+
"code": 6061,
|
|
4306
|
+
"name": "InvalidRepegPriceImpact",
|
|
4307
|
+
"msg": "AMM repeg mark price impact vs oracle too large"
|
|
4247
4308
|
}
|
|
4248
4309
|
]
|
|
4249
4310
|
}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -47,6 +47,7 @@ __exportStar(require("./math/position"), exports);
|
|
|
47
47
|
__exportStar(require("./math/amm"), exports);
|
|
48
48
|
__exportStar(require("./math/trade"), exports);
|
|
49
49
|
__exportStar(require("./math/orders"), exports);
|
|
50
|
+
__exportStar(require("./math/repeg"), exports);
|
|
50
51
|
__exportStar(require("./orders"), exports);
|
|
51
52
|
__exportStar(require("./orderParams"), exports);
|
|
52
53
|
__exportStar(require("./wallet"), exports);
|
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
|
*
|
|
@@ -64,5 +46,3 @@ export declare function calculateRepegCost(market: Market, marketIndex: BN, newP
|
|
|
64
46
|
*/
|
|
65
47
|
export declare function calculateTerminalPrice(market: Market): BN;
|
|
66
48
|
export declare function calculateMaxBaseAssetAmountToTrade(amm: AMM, limit_price: BN): [BN, PositionDirection];
|
|
67
|
-
export declare function calculateBudgetedK(market: Market, cost: BN): [BN, BN];
|
|
68
|
-
export declare function calculateBudgetedPeg(market: Market, cost: BN): BN;
|
package/lib/math/amm.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
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
|
*
|
|
@@ -219,66 +132,3 @@ function calculateMaxBaseAssetAmountToTrade(amm, limit_price) {
|
|
|
219
132
|
}
|
|
220
133
|
}
|
|
221
134
|
exports.calculateMaxBaseAssetAmountToTrade = calculateMaxBaseAssetAmountToTrade;
|
|
222
|
-
function calculateBudgetedK(market, cost) {
|
|
223
|
-
// wolframalpha.com
|
|
224
|
-
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
225
|
-
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
226
|
-
// todo: assumes k = x * y
|
|
227
|
-
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
228
|
-
// const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
229
|
-
const x = market.amm.baseAssetReserve;
|
|
230
|
-
const y = market.amm.quoteAssetReserve;
|
|
231
|
-
const d = market.baseAssetAmount;
|
|
232
|
-
const Q = market.amm.pegMultiplier;
|
|
233
|
-
const C = cost.mul(new anchor_1.BN(-1));
|
|
234
|
-
const numer1 = y.mul(d).mul(Q).div(numericConstants_1.AMM_RESERVE_PRECISION).div(numericConstants_1.PEG_PRECISION);
|
|
235
|
-
const numer2 = C.mul(x.add(d)).div(numericConstants_1.QUOTE_PRECISION);
|
|
236
|
-
const denom1 = C.mul(x)
|
|
237
|
-
.mul(x.add(d))
|
|
238
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
239
|
-
.div(numericConstants_1.QUOTE_PRECISION);
|
|
240
|
-
const denom2 = y
|
|
241
|
-
.mul(d)
|
|
242
|
-
.mul(d)
|
|
243
|
-
.mul(Q)
|
|
244
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
245
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
246
|
-
.div(numericConstants_1.PEG_PRECISION);
|
|
247
|
-
const numerator = d
|
|
248
|
-
.mul(numer1.add(numer2))
|
|
249
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
250
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
251
|
-
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
|
|
252
|
-
const denominator = denom1
|
|
253
|
-
.add(denom2)
|
|
254
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
255
|
-
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
|
|
256
|
-
console.log(numerator, denominator);
|
|
257
|
-
// const p = (numerator).div(denominator);
|
|
258
|
-
// const formulaCost = (numer21.sub(numer20).sub(numer1)).mul(market.amm.pegMultiplier).div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
|
|
259
|
-
// console.log(convertToNumber(formulaCost, QUOTE_PRECISION))
|
|
260
|
-
return [numerator, denominator];
|
|
261
|
-
}
|
|
262
|
-
exports.calculateBudgetedK = calculateBudgetedK;
|
|
263
|
-
function calculateBudgetedPeg(market, cost) {
|
|
264
|
-
// wolframalpha.com
|
|
265
|
-
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
266
|
-
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
267
|
-
// todo: assumes k = x * y
|
|
268
|
-
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
269
|
-
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
270
|
-
const x = market.amm.baseAssetReserve;
|
|
271
|
-
const y = market.amm.quoteAssetReserve;
|
|
272
|
-
const d = market.baseAssetAmount;
|
|
273
|
-
const Q = market.amm.pegMultiplier;
|
|
274
|
-
const C = cost.mul(new anchor_1.BN(-1));
|
|
275
|
-
const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
|
|
276
|
-
const deltaPegMultiplier = C.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
277
|
-
.div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO))
|
|
278
|
-
.mul(numericConstants_1.PEG_PRECISION)
|
|
279
|
-
.div(numericConstants_1.QUOTE_PRECISION);
|
|
280
|
-
console.log(Q.toNumber(), 'change by', deltaPegMultiplier.toNumber() / numericConstants_1.MARK_PRICE_PRECISION.toNumber());
|
|
281
|
-
const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.MARK_PRICE_PRECISION));
|
|
282
|
-
return newPeg;
|
|
283
|
-
}
|
|
284
|
-
exports.calculateBudgetedPeg = calculateBudgetedPeg;
|
|
@@ -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;
|