@drift-labs/sdk 2.54.0-beta.1 → 2.54.0-beta.11

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.
Files changed (44) hide show
  1. package/VERSION +1 -1
  2. package/lib/accounts/pollingInsuranceFundStakeAccountSubscriber.js +0 -1
  3. package/lib/constants/perpMarkets.js +20 -0
  4. package/lib/driftClient.d.ts +8 -2
  5. package/lib/driftClient.js +95 -20
  6. package/lib/events/webSocketLogProvider.js +3 -0
  7. package/lib/idl/drift.json +7 -1
  8. package/lib/jupiter/jupiterClient.d.ts +6 -0
  9. package/lib/jupiter/jupiterClient.js +2 -2
  10. package/lib/math/funding.js +24 -1
  11. package/lib/math/oracles.js +2 -2
  12. package/lib/math/superStake.d.ts +51 -0
  13. package/lib/math/superStake.js +10 -2
  14. package/lib/priorityFee/averageOverSlotsStrategy.d.ts +0 -5
  15. package/lib/priorityFee/averageOverSlotsStrategy.js +1 -13
  16. package/lib/priorityFee/maxOverSlotsStrategy.d.ts +0 -5
  17. package/lib/priorityFee/maxOverSlotsStrategy.js +1 -13
  18. package/lib/priorityFee/priorityFeeSubscriber.d.ts +5 -4
  19. package/lib/priorityFee/priorityFeeSubscriber.js +15 -21
  20. package/lib/tx/baseTxSender.js +2 -2
  21. package/lib/tx/retryTxSender.js +4 -21
  22. package/lib/tx/utils.d.ts +5 -1
  23. package/lib/tx/utils.js +20 -1
  24. package/lib/userMap/userMap.js +4 -0
  25. package/package.json +1 -1
  26. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -1
  27. package/src/constants/perpMarkets.ts +20 -0
  28. package/src/driftClient.ts +197 -39
  29. package/src/events/webSocketLogProvider.ts +11 -2
  30. package/src/idl/drift.json +7 -1
  31. package/src/jupiter/jupiterClient.ts +8 -2
  32. package/src/math/funding.ts +28 -1
  33. package/src/math/oracles.ts +2 -2
  34. package/src/math/superStake.ts +60 -1
  35. package/src/priorityFee/averageOverSlotsStrategy.ts +1 -16
  36. package/src/priorityFee/maxOverSlotsStrategy.ts +1 -16
  37. package/src/priorityFee/priorityFeeSubscriber.ts +22 -26
  38. package/src/tx/baseTxSender.ts +3 -2
  39. package/src/tx/retryTxSender.ts +5 -23
  40. package/src/tx/utils.ts +32 -0
  41. package/src/userMap/userMap.ts +3 -0
  42. package/tests/amm/test.ts +275 -2
  43. package/tests/dlob/test.ts +2 -2
  44. package/tests/tx/priorityFeeStrategy.ts +2 -2
@@ -333,6 +333,63 @@ export async function fetchJitoSolMetrics() {
333
333
  return data;
334
334
  }
335
335
 
336
+ export type MSOL_METRICS_ENDPOINT_RESPONSE = {
337
+ total_active_balance: number;
338
+ available_reserve_balance: number;
339
+ emergency_cooling_down: number;
340
+ tvl_sol: number;
341
+ msol_directed_stake_sol: number;
342
+ msol_directed_stake_msol: number;
343
+ mnde_total_supply: number;
344
+ mnde_circulating_supply: number;
345
+ validators_count: number;
346
+ stake_accounts: number;
347
+ staking_sol_cap: number;
348
+ m_sol_price: number;
349
+ avg_staking_apy: number;
350
+ msol_price_apy_14d: number;
351
+ msol_price_apy_30d: number;
352
+ msol_price_apy_90d: number;
353
+ msol_price_apy_365d: number;
354
+ reserve_pda: number;
355
+ treasury_m_sol_amount: number;
356
+ m_sol_mint_supply: number;
357
+ m_sol_supply_state: number;
358
+ liq_pool_sol: number;
359
+ liq_pool_m_sol: number;
360
+ liq_pool_value: number;
361
+ liq_pool_token_supply: number;
362
+ liq_pool_token_price: number;
363
+ liq_pool_target: number;
364
+ liq_pool_min_fee: number;
365
+ liq_pool_max_fee: number;
366
+ liq_pool_current_fee: number;
367
+ liq_pool_treasury_cut: number;
368
+ liq_pool_cap: number;
369
+ total_cooling_down: number;
370
+ last_stake_delta_epoch: number;
371
+ circulating_ticket_count: number;
372
+ circulating_ticket_balance: number;
373
+ reward_fee_bp: number;
374
+ lido_staking: number;
375
+ lido_st_sol_price: number;
376
+ lido_stsol_price_apy_14d: number;
377
+ lido_stsol_price_apy_30d: number;
378
+ lido_stsol_price_apy_90d: number;
379
+ lido_stsol_price_apy_365d: number;
380
+ stake_delta: number;
381
+ bot_balance: number;
382
+ treasury_farm_claim_mnde_balance: number;
383
+ last_3_epochs_avg_duration_hs: number;
384
+ mnde_votes_validators: number;
385
+ };
386
+
387
+ export const fetchMSolMetrics = async () => {
388
+ const res = await fetch('https://api2.marinade.finance/metrics_json');
389
+ const data: MSOL_METRICS_ENDPOINT_RESPONSE = await res.json();
390
+ return data;
391
+ };
392
+
336
393
  const getJitoSolHistoricalPriceMap = async (timestamps: number[]) => {
337
394
  try {
338
395
  const data = await fetchJitoSolMetrics();
@@ -382,7 +439,9 @@ export async function calculateSolEarned({
382
439
  const now = Date.now() / 1000;
383
440
  const timestamps: number[] = [
384
441
  now,
385
- ...depositRecords.map((r) => r.ts.toNumber()),
442
+ ...depositRecords
443
+ .filter((r) => r.marketIndex === marketIndex)
444
+ .map((r) => r.ts.toNumber()),
386
445
  ];
387
446
 
388
447
  let lstRatios = new Map<number, number>();
@@ -1,30 +1,15 @@
1
1
  import { PriorityFeeStrategy } from './types';
2
2
 
3
3
  export class AverageOverSlotsStrategy implements PriorityFeeStrategy {
4
- private lookbackSlots: number;
5
-
6
- /**
7
- * @param lookbackSlots The number of slots to look back from the max slot in the sample
8
- */
9
- constructor(lookbackSlots = 10) {
10
- this.lookbackSlots = lookbackSlots;
11
- }
12
-
13
4
  calculate(samples: { slot: number; prioritizationFee: number }[]): number {
14
5
  if (samples.length === 0) {
15
6
  return 0;
16
7
  }
17
- const stopSlot = samples[0].slot - this.lookbackSlots;
18
8
  let runningSumFees = 0;
19
- let countFees = 0;
20
9
 
21
10
  for (let i = 0; i < samples.length; i++) {
22
- if (samples[i].slot <= stopSlot) {
23
- return runningSumFees / countFees;
24
- }
25
11
  runningSumFees += samples[i].prioritizationFee;
26
- countFees++;
27
12
  }
28
- return runningSumFees / countFees;
13
+ return runningSumFees / samples.length;
29
14
  }
30
15
  }
@@ -1,30 +1,15 @@
1
1
  import { PriorityFeeStrategy } from './types';
2
2
 
3
3
  export class MaxOverSlotsStrategy implements PriorityFeeStrategy {
4
- private lookbackSlots: number;
5
-
6
- /**
7
- * @param lookbackSlots The number of slots to look back from the max slot in the sample
8
- */
9
- constructor(lookbackSlots = 10) {
10
- this.lookbackSlots = lookbackSlots;
11
- }
12
-
13
4
  calculate(samples: { slot: number; prioritizationFee: number }[]): number {
14
5
  if (samples.length === 0) {
15
6
  return 0;
16
7
  }
17
8
  // Assuming samples are sorted in descending order of slot.
18
- const stopSlot = samples[0].slot - this.lookbackSlots;
19
9
  let currMaxFee = samples[0].prioritizationFee;
20
10
 
21
11
  for (let i = 0; i < samples.length; i++) {
22
- if (samples[i].slot <= stopSlot) {
23
- return currMaxFee;
24
- }
25
- if (samples[i].prioritizationFee > currMaxFee) {
26
- currMaxFee = samples[i].prioritizationFee;
27
- }
12
+ currMaxFee = Math.max(samples[i].prioritizationFee, currMaxFee);
28
13
  }
29
14
  return currMaxFee;
30
15
  }
@@ -10,16 +10,20 @@ export class PriorityFeeSubscriber {
10
10
  customStrategy?: PriorityFeeStrategy;
11
11
  averageStrategy = new AverageOverSlotsStrategy();
12
12
  maxStrategy = new MaxOverSlotsStrategy();
13
+ lookbackDistance: number;
13
14
 
14
15
  intervalId?: ReturnType<typeof setTimeout>;
15
16
 
16
17
  latestPriorityFee = 0;
17
- lastStrategyResult = 0;
18
18
  lastCustomStrategyResult = 0;
19
19
  lastAvgStrategyResult = 0;
20
20
  lastMaxStrategyResult = 0;
21
21
  lastSlotSeen = 0;
22
22
 
23
+ /**
24
+ * @param props
25
+ * customStrategy : strategy to return the priority fee to use based on recent samples. defaults to AVERAGE.
26
+ */
23
27
  public constructor({
24
28
  connection,
25
29
  frequencyMs,
@@ -36,28 +40,12 @@ export class PriorityFeeSubscriber {
36
40
  this.connection = connection;
37
41
  this.frequencyMs = frequencyMs;
38
42
  this.addresses = addresses;
39
- if (slotsToCheck) {
40
- this.averageStrategy = new AverageOverSlotsStrategy(slotsToCheck);
41
- this.maxStrategy = new MaxOverSlotsStrategy(slotsToCheck);
42
- }
43
- if (customStrategy) {
43
+ if (!customStrategy) {
44
+ this.customStrategy = new AverageOverSlotsStrategy();
45
+ } else {
44
46
  this.customStrategy = customStrategy;
45
47
  }
46
- }
47
-
48
- public get avgPriorityFee(): number {
49
- return Math.floor(this.lastAvgStrategyResult);
50
- }
51
-
52
- public get maxPriorityFee(): number {
53
- return Math.floor(this.lastMaxStrategyResult);
54
- }
55
-
56
- public get customPriorityFee(): number {
57
- if (!this.customStrategy) {
58
- console.error('Custom strategy not set');
59
- }
60
- return Math.floor(this.lastCustomStrategyResult);
48
+ this.lookbackDistance = slotsToCheck;
61
49
  }
62
50
 
63
51
  public async subscribe(): Promise<void> {
@@ -75,21 +63,29 @@ export class PriorityFeeSubscriber {
75
63
  [this.addresses]
76
64
  );
77
65
 
78
- // getRecentPrioritizationFees returns results unsorted
79
66
  const results: { slot: number; prioritizationFee: number }[] =
80
67
  rpcJSONResponse?.result;
68
+
81
69
  if (!results.length) return;
82
- const descResults = results.sort((a, b) => b.slot - a.slot);
83
70
 
71
+ // # Sort and filter results based on the slot lookback setting
72
+ const descResults = results.sort((a, b) => b.slot - a.slot);
84
73
  const mostRecentResult = descResults[0];
74
+ const cutoffSlot = mostRecentResult.slot - this.lookbackDistance;
75
+
76
+ const resultsToUse = descResults.filter(
77
+ (result) => result.slot >= cutoffSlot
78
+ );
79
+
80
+ // # Handle results
85
81
  this.latestPriorityFee = mostRecentResult.prioritizationFee;
86
82
  this.lastSlotSeen = mostRecentResult.slot;
87
83
 
88
- this.lastAvgStrategyResult = this.averageStrategy.calculate(descResults);
89
- this.lastMaxStrategyResult = this.maxStrategy.calculate(descResults);
84
+ this.lastAvgStrategyResult = this.averageStrategy.calculate(resultsToUse);
85
+ this.lastMaxStrategyResult = this.maxStrategy.calculate(resultsToUse);
90
86
  if (this.customStrategy) {
91
87
  this.lastCustomStrategyResult =
92
- this.customStrategy.calculate(descResults);
88
+ this.customStrategy.calculate(resultsToUse);
93
89
  }
94
90
  }
95
91
 
@@ -247,9 +247,11 @@ export abstract class BaseTxSender implements TxSender {
247
247
  commitment: Commitment = 'finalized'
248
248
  ): Promise<RpcResponseAndContext<SignatureResult> | undefined> {
249
249
  let totalTime = 0;
250
- let backoffTime = 250;
250
+ let backoffTime = 400; // approx block time
251
251
 
252
252
  while (totalTime < this.timeout) {
253
+ await new Promise((resolve) => setTimeout(resolve, backoffTime));
254
+
253
255
  const response = await this.connection.getSignatureStatus(signature);
254
256
  const result = response && response.value?.[0];
255
257
 
@@ -257,7 +259,6 @@ export abstract class BaseTxSender implements TxSender {
257
259
  return { context: result.context, value: { err: null } };
258
260
  }
259
261
 
260
- await new Promise((resolve) => setTimeout(resolve, backoffTime));
261
262
  totalTime += backoffTime;
262
263
  backoffTime = Math.min(backoffTime * 2, 5000);
263
264
  }
@@ -1,9 +1,5 @@
1
1
  import { ConfirmationStrategy, TxSigAndSlot } from './types';
2
- import {
3
- ConfirmOptions,
4
- TransactionSignature,
5
- Connection,
6
- } from '@solana/web3.js';
2
+ import { ConfirmOptions, Connection } from '@solana/web3.js';
7
3
  import { AnchorProvider } from '@coral-xyz/anchor';
8
4
  import { IWallet } from '../types';
9
5
  import { BaseTxSender } from './baseTxSender';
@@ -70,14 +66,8 @@ export class RetryTxSender extends BaseTxSender {
70
66
  ): Promise<TxSigAndSlot> {
71
67
  const startTime = this.getTimestamp();
72
68
 
73
- let txid: TransactionSignature;
74
- try {
75
- txid = await this.connection.sendRawTransaction(rawTransaction, opts);
76
- this.sendToAdditionalConnections(rawTransaction, opts);
77
- } catch (e) {
78
- console.error(e);
79
- throw e;
80
- }
69
+ const txid = await this.connection.sendRawTransaction(rawTransaction, opts);
70
+ this.sendToAdditionalConnections(rawTransaction, opts);
81
71
 
82
72
  let done = false;
83
73
  const resolveReference: ResolveReference = {
@@ -105,16 +95,8 @@ export class RetryTxSender extends BaseTxSender {
105
95
  }
106
96
  })();
107
97
 
108
- let slot: number;
109
- try {
110
- const result = await this.confirmTransaction(txid, opts.commitment);
111
- slot = result.context.slot;
112
- } catch (e) {
113
- console.error(e);
114
- throw e;
115
- } finally {
116
- stopWaiting();
117
- }
98
+ const result = await this.confirmTransaction(txid, opts.commitment);
99
+ const slot = result.context.slot;
118
100
 
119
101
  return { txSig: txid, slot };
120
102
  }
package/src/tx/utils.ts CHANGED
@@ -1,7 +1,9 @@
1
+ import { Wallet } from '@coral-xyz/anchor';
1
2
  import {
2
3
  Transaction,
3
4
  TransactionInstruction,
4
5
  ComputeBudgetProgram,
6
+ VersionedTransaction,
5
7
  } from '@solana/web3.js';
6
8
 
7
9
  const COMPUTE_UNITS_DEFAULT = 200_000;
@@ -30,3 +32,33 @@ export function wrapInTx(
30
32
 
31
33
  return tx.add(instruction);
32
34
  }
35
+
36
+ /* Helper function for signing multiple transactions where some may be undefined and mapping the output */
37
+ export async function getSignedTransactionMap(
38
+ wallet: Wallet,
39
+ txsToSign: (Transaction | VersionedTransaction | undefined)[],
40
+ keys: string[]
41
+ ): Promise<{ [key: string]: Transaction | VersionedTransaction | undefined }> {
42
+ const signedTxMap: {
43
+ [key: string]: Transaction | VersionedTransaction | undefined;
44
+ } = {};
45
+
46
+ const keysWithTx = [];
47
+ txsToSign.forEach((tx, index) => {
48
+ if (tx == undefined) {
49
+ signedTxMap[keys[index]] = undefined;
50
+ } else {
51
+ keysWithTx.push(keys[index]);
52
+ }
53
+ });
54
+
55
+ const signedTxs = await wallet.signAllTransactions(
56
+ txsToSign.filter((tx) => tx !== undefined)
57
+ );
58
+
59
+ signedTxs.forEach((signedTx, index) => {
60
+ signedTxMap[keysWithTx[index]] = signedTx;
61
+ });
62
+
63
+ return signedTxMap;
64
+ }
@@ -337,6 +337,9 @@ export class UserMap implements UserMapInterface {
337
337
  const userAccount = this.decode('User', buffer);
338
338
  await this.addPubkey(new PublicKey(key), userAccount);
339
339
  this.userMap.get(key).accountSubscriber.updateData(userAccount, slot);
340
+ } else {
341
+ const userAccount = this.decode('User', buffer);
342
+ this.userMap.get(key).accountSubscriber.updateData(userAccount, slot);
340
343
  }
341
344
  // give event loop a chance to breathe
342
345
  await new Promise((resolve) => setTimeout(resolve, 0));
package/tests/amm/test.ts CHANGED
@@ -28,6 +28,9 @@ import {
28
28
  squareRootBN,
29
29
  calculateReferencePriceOffset,
30
30
  calculateInventoryLiquidityRatio,
31
+ ContractTier,
32
+ isOracleValid,
33
+ OracleGuardRails,
31
34
  } from '../../src';
32
35
  import { mockPerpMarkets } from '../dlob/helpers';
33
36
 
@@ -875,11 +878,12 @@ describe('AMM Tests', () => {
875
878
  const mockMarket1 = myMockPerpMarkets[0];
876
879
  const mockAmm = mockMarket1.amm;
877
880
  const now = new BN(new Date().getTime() / 1000); //todo
881
+ const slot = 999999999;
878
882
 
879
883
  const oraclePriceData = {
880
884
  price: new BN(13.553 * PRICE_PRECISION.toNumber()),
881
- slot: new BN(68 + 1),
882
- confidence: new BN(1),
885
+ slot: new BN(slot),
886
+ confidence: new BN(1000),
883
887
  hasSufficientNumberOfDataPoints: true,
884
888
  };
885
889
  mockAmm.oracleStd = new BN(0.18 * PRICE_PRECISION.toNumber());
@@ -901,6 +905,127 @@ describe('AMM Tests', () => {
901
905
  const liveOracleStd = calculateLiveOracleStd(mockAmm, oraclePriceData, now);
902
906
  console.log('liveOracleStd:', liveOracleStd.toNumber());
903
907
  assert(liveOracleStd.eq(new BN(192962)));
908
+
909
+ const oracleGuardRails: OracleGuardRails = {
910
+ priceDivergence: {
911
+ markOraclePercentDivergence: PERCENTAGE_PRECISION.divn(10),
912
+ oracleTwap5MinPercentDivergence: PERCENTAGE_PRECISION.divn(10),
913
+ },
914
+ validity: {
915
+ slotsBeforeStaleForAmm: new BN(10),
916
+ slotsBeforeStaleForMargin: new BN(60),
917
+ confidenceIntervalMaxSize: new BN(20000),
918
+ tooVolatileRatio: new BN(5),
919
+ },
920
+ };
921
+
922
+ // good oracle
923
+ assert(isOracleValid(mockAmm, oraclePriceData, oracleGuardRails, slot + 5));
924
+
925
+ // conf too high
926
+ assert(
927
+ !isOracleValid(
928
+ mockAmm,
929
+ {
930
+ price: new BN(13.553 * PRICE_PRECISION.toNumber()),
931
+ slot: new BN(slot),
932
+ confidence: new BN(13.553 * PRICE_PRECISION.toNumber() * 0.021),
933
+ hasSufficientNumberOfDataPoints: true,
934
+ },
935
+ oracleGuardRails,
936
+ slot
937
+ )
938
+ );
939
+
940
+ // not hasSufficientNumberOfDataPoints
941
+ assert(
942
+ !isOracleValid(
943
+ mockAmm,
944
+ {
945
+ price: new BN(13.553 * PRICE_PRECISION.toNumber()),
946
+ slot: new BN(slot),
947
+ confidence: new BN(1),
948
+ hasSufficientNumberOfDataPoints: false,
949
+ },
950
+ oracleGuardRails,
951
+ slot
952
+ )
953
+ );
954
+
955
+ // negative oracle price
956
+ assert(
957
+ !isOracleValid(
958
+ mockAmm,
959
+ {
960
+ price: new BN(-1 * PRICE_PRECISION.toNumber()),
961
+ slot: new BN(slot),
962
+ confidence: new BN(1),
963
+ hasSufficientNumberOfDataPoints: true,
964
+ },
965
+ oracleGuardRails,
966
+ slot
967
+ )
968
+ );
969
+
970
+ // too delayed for amm
971
+ assert(
972
+ !isOracleValid(
973
+ mockAmm,
974
+ {
975
+ price: new BN(13.553 * PRICE_PRECISION.toNumber()),
976
+ slot: new BN(slot),
977
+ confidence: new BN(1),
978
+ hasSufficientNumberOfDataPoints: true,
979
+ },
980
+ oracleGuardRails,
981
+ slot + 100
982
+ )
983
+ );
984
+
985
+ // im passing stale slot (should not call oracle invalid)
986
+ assert(
987
+ isOracleValid(
988
+ mockAmm,
989
+ {
990
+ price: new BN(13.553 * PRICE_PRECISION.toNumber()),
991
+ slot: new BN(slot + 100),
992
+ confidence: new BN(1),
993
+ hasSufficientNumberOfDataPoints: true,
994
+ },
995
+ oracleGuardRails,
996
+ slot
997
+ )
998
+ );
999
+
1000
+ // too volatile (more than 5x higher)
1001
+ assert(
1002
+ !isOracleValid(
1003
+ mockAmm,
1004
+ {
1005
+ price: new BN(113.553 * PRICE_PRECISION.toNumber()),
1006
+ slot: new BN(slot + 5),
1007
+ confidence: new BN(1),
1008
+ hasSufficientNumberOfDataPoints: true,
1009
+ },
1010
+ oracleGuardRails,
1011
+ slot
1012
+ )
1013
+ );
1014
+
1015
+ // too volatile (more than 1/5 lower)
1016
+ assert(
1017
+ !isOracleValid(
1018
+ mockAmm,
1019
+ {
1020
+ price: new BN(0.553 * PRICE_PRECISION.toNumber()),
1021
+ slot: new BN(slot + 5),
1022
+ confidence: new BN(1),
1023
+ hasSufficientNumberOfDataPoints: true,
1024
+ },
1025
+ oracleGuardRails,
1026
+ slot
1027
+ )
1028
+ );
904
1029
  });
905
1030
 
906
1031
  it('predicted funding rate mock1', async () => {
@@ -1065,6 +1190,154 @@ describe('AMM Tests', () => {
1065
1190
  assert(est2.eq(new BN('-719')));
1066
1191
  });
1067
1192
 
1193
+ it('predicted funding rate mock clamp', async () => {
1194
+ const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
1195
+ const mockMarket1 = myMockPerpMarkets[0];
1196
+
1197
+ // make it like OP
1198
+ const now = new BN(1688881915);
1199
+
1200
+ mockMarket1.amm.fundingPeriod = new BN(3600);
1201
+ mockMarket1.amm.lastFundingRateTs = new BN(1688864415);
1202
+
1203
+ const currentMarkPrice = new BN(1.2242 * PRICE_PRECISION.toNumber()); // trading at a premium
1204
+ const oraclePriceData: OraclePriceData = {
1205
+ price: new BN(1.924 * PRICE_PRECISION.toNumber()),
1206
+ slot: new BN(0),
1207
+ confidence: new BN(1),
1208
+ hasSufficientNumberOfDataPoints: true,
1209
+ };
1210
+ mockMarket1.amm.historicalOracleData.lastOraclePrice = new BN(
1211
+ 1.9535 * PRICE_PRECISION.toNumber()
1212
+ );
1213
+
1214
+ // mockMarket1.amm.pegMultiplier = new BN(1.897573 * 1e3);
1215
+
1216
+ mockMarket1.amm.lastMarkPriceTwap = new BN(
1217
+ 1.218363 * PRICE_PRECISION.toNumber()
1218
+ );
1219
+ mockMarket1.amm.lastBidPriceTwap = new BN(
1220
+ 1.218363 * PRICE_PRECISION.toNumber()
1221
+ );
1222
+ mockMarket1.amm.lastAskPriceTwap = new BN(
1223
+ 1.218364 * PRICE_PRECISION.toNumber()
1224
+ );
1225
+ mockMarket1.amm.lastMarkPriceTwapTs = new BN(1688878815);
1226
+
1227
+ mockMarket1.amm.historicalOracleData.lastOraclePriceTwap = new BN(
1228
+ 1.820964 * PRICE_PRECISION.toNumber()
1229
+ );
1230
+ mockMarket1.amm.historicalOracleData.lastOraclePriceTwapTs = new BN(
1231
+ 1688879991
1232
+ );
1233
+ mockMarket1.contractTier = ContractTier.A;
1234
+
1235
+ const [
1236
+ _markTwapLive,
1237
+ _oracleTwapLive,
1238
+ _lowerboundEst,
1239
+ _cappedAltEst,
1240
+ _interpEst,
1241
+ ] = await calculateAllEstimatedFundingRate(
1242
+ mockMarket1,
1243
+ oraclePriceData,
1244
+ currentMarkPrice,
1245
+ now
1246
+ );
1247
+
1248
+ // console.log(_markTwapLive.toString());
1249
+ // console.log(_oracleTwapLive.toString());
1250
+ // console.log(_lowerboundEst.toString());
1251
+ // console.log(_cappedAltEst.toString());
1252
+ // console.log(_interpEst.toString());
1253
+ // console.log('-----');
1254
+
1255
+ let [markTwapLive, oracleTwapLive, est1, est2] =
1256
+ await calculateLongShortFundingRateAndLiveTwaps(
1257
+ mockMarket1,
1258
+ oraclePriceData,
1259
+ currentMarkPrice,
1260
+ now
1261
+ );
1262
+
1263
+ console.log(
1264
+ 'markTwapLive:',
1265
+ mockMarket1.amm.lastMarkPriceTwap.toString(),
1266
+ '->',
1267
+ markTwapLive.toString()
1268
+ );
1269
+ console.log(
1270
+ 'oracTwapLive:',
1271
+ mockMarket1.amm.historicalOracleData.lastOraclePriceTwap.toString(),
1272
+ '->',
1273
+ oracleTwapLive.toString()
1274
+ );
1275
+ console.log('pred funding:', est1.toString(), est2.toString());
1276
+
1277
+ assert(markTwapLive.eq(new BN('1680634')));
1278
+ assert(oracleTwapLive.eq(new BN('1876031')));
1279
+ assert(est1.eq(est2));
1280
+ assert(est2.eq(new BN('-126261')));
1281
+
1282
+ mockMarket1.contractTier = ContractTier.C;
1283
+
1284
+ [markTwapLive, oracleTwapLive, est1, est2] =
1285
+ await calculateLongShortFundingRateAndLiveTwaps(
1286
+ mockMarket1,
1287
+ oraclePriceData,
1288
+ currentMarkPrice,
1289
+ now
1290
+ );
1291
+
1292
+ console.log(
1293
+ 'markTwapLive:',
1294
+ mockMarket1.amm.lastMarkPriceTwap.toString(),
1295
+ '->',
1296
+ markTwapLive.toString()
1297
+ );
1298
+ console.log(
1299
+ 'oracTwapLive:',
1300
+ mockMarket1.amm.historicalOracleData.lastOraclePriceTwap.toString(),
1301
+ '->',
1302
+ oracleTwapLive.toString()
1303
+ );
1304
+ console.log('pred funding:', est1.toString(), est2.toString());
1305
+
1306
+ assert(markTwapLive.eq(new BN('1680634')));
1307
+ assert(oracleTwapLive.eq(new BN('1876031')));
1308
+ assert(est1.eq(est2));
1309
+ assert(est2.eq(new BN('-208332')));
1310
+
1311
+ mockMarket1.contractTier = ContractTier.SPECULATIVE;
1312
+
1313
+ [markTwapLive, oracleTwapLive, est1, est2] =
1314
+ await calculateLongShortFundingRateAndLiveTwaps(
1315
+ mockMarket1,
1316
+ oraclePriceData,
1317
+ currentMarkPrice,
1318
+ now
1319
+ );
1320
+
1321
+ console.log(
1322
+ 'markTwapLive:',
1323
+ mockMarket1.amm.lastMarkPriceTwap.toString(),
1324
+ '->',
1325
+ markTwapLive.toString()
1326
+ );
1327
+ console.log(
1328
+ 'oracTwapLive:',
1329
+ mockMarket1.amm.historicalOracleData.lastOraclePriceTwap.toString(),
1330
+ '->',
1331
+ oracleTwapLive.toString()
1332
+ );
1333
+ console.log('pred funding:', est1.toString(), est2.toString());
1334
+
1335
+ assert(markTwapLive.eq(new BN('1680634')));
1336
+ assert(oracleTwapLive.eq(new BN('1876031')));
1337
+ assert(est1.eq(est2));
1338
+ assert(est2.eq(new BN('-416666')));
1339
+ });
1340
+
1068
1341
  it('orderbook L2 gen (no topOfBookQuoteAmounts, 10 numOrders, low liquidity)', async () => {
1069
1342
  const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
1070
1343
 
@@ -76,7 +76,7 @@ function insertOrderToDLOB(
76
76
  auctionEndPrice,
77
77
  maxTs,
78
78
  },
79
- userAccount,
79
+ userAccount.toString(),
80
80
  slot.toNumber()
81
81
  );
82
82
  }
@@ -127,7 +127,7 @@ function insertTriggerOrderToDLOB(
127
127
  auctionEndPrice,
128
128
  maxTs,
129
129
  },
130
- userAccount,
130
+ userAccount.toString(),
131
131
  slot.toNumber()
132
132
  );
133
133
  }
@@ -66,7 +66,7 @@ describe('PriorityFeeStrategy', () => {
66
66
  });
67
67
 
68
68
  it('MaxOverSlotsStrategy should calculate the max prioritization fee over slots', () => {
69
- const maxOverSlotsStrategy = new MaxOverSlotsStrategy(5);
69
+ const maxOverSlotsStrategy = new MaxOverSlotsStrategy();
70
70
  const samples = [
71
71
  { slot: 6, prioritizationFee: 432 },
72
72
  { slot: 3, prioritizationFee: 543 },
@@ -80,7 +80,7 @@ describe('PriorityFeeStrategy', () => {
80
80
  });
81
81
 
82
82
  it('AverageOverSlotsStrategy should calculate the average prioritization fee over slots', () => {
83
- const averageOverSlotsStrategy = new AverageOverSlotsStrategy(5);
83
+ const averageOverSlotsStrategy = new AverageOverSlotsStrategy();
84
84
  const samples = [
85
85
  { slot: 6, prioritizationFee: 432 },
86
86
  { slot: 3, prioritizationFee: 543 },