@drift-labs/sdk 2.86.0-beta.18 → 2.86.0-beta.19

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/VERSION CHANGED
@@ -1 +1 @@
1
- 2.86.0-beta.18
1
+ 2.86.0-beta.19
@@ -179,8 +179,8 @@ export declare class AdminClient extends DriftClient {
179
179
  getUpdatePrelaunchOracleParamsIx(perpMarketIndex: number, price?: BN, maxPrice?: BN): Promise<TransactionInstruction>;
180
180
  deletePrelaunchOracle(perpMarketIndex: number): Promise<TransactionSignature>;
181
181
  getDeletePrelaunchOracleIx(perpMarketIndex: number, price?: BN, maxPrice?: BN): Promise<TransactionInstruction>;
182
- updateSpotMarketFuel(spotMarketIndex: number, fuelBoostDeposits?: number, fuelBoostBorrows?: number, fuelBoostTaker?: number, fuelBoostMaker?: number): Promise<TransactionSignature>;
183
- getUpdateSpotMarketFuelIx(spotMarketIndex: number, fuelBoostDeposits?: number, fuelBoostBorrows?: number, fuelBoostTaker?: number, fuelBoostMaker?: number): Promise<TransactionInstruction>;
182
+ updateSpotMarketFuel(spotMarketIndex: number, fuelBoostDeposits?: number, fuelBoostBorrows?: number, fuelBoostTaker?: number, fuelBoostMaker?: number, fuelBoostInsurance?: number): Promise<TransactionSignature>;
183
+ getUpdateSpotMarketFuelIx(spotMarketIndex: number, fuelBoostDeposits?: number, fuelBoostBorrows?: number, fuelBoostTaker?: number, fuelBoostMaker?: number, fuelBoostInsurance?: number): Promise<TransactionInstruction>;
184
184
  updatePerpMarketFuel(perpMarketIndex: number, fuelBoostTaker?: number, fuelBoostMaker?: number, fuelBoostPosition?: number): Promise<TransactionSignature>;
185
185
  getUpdatePerpMarketFuelIx(perpMarketIndex: number, fuelBoostTaker?: number, fuelBoostMaker?: number, fuelBoostPosition?: number): Promise<TransactionInstruction>;
186
186
  initializePythPullOracle(feedId: string): Promise<TransactionSignature>;
@@ -1631,15 +1631,15 @@ class AdminClient extends driftClient_1.DriftClient {
1631
1631
  },
1632
1632
  });
1633
1633
  }
1634
- async updateSpotMarketFuel(spotMarketIndex, fuelBoostDeposits, fuelBoostBorrows, fuelBoostTaker, fuelBoostMaker) {
1635
- const updateSpotMarketFuelIx = await this.getUpdateSpotMarketFuelIx(spotMarketIndex, fuelBoostDeposits || null, fuelBoostBorrows || null, fuelBoostTaker || null, fuelBoostMaker || null);
1634
+ async updateSpotMarketFuel(spotMarketIndex, fuelBoostDeposits, fuelBoostBorrows, fuelBoostTaker, fuelBoostMaker, fuelBoostInsurance) {
1635
+ const updateSpotMarketFuelIx = await this.getUpdateSpotMarketFuelIx(spotMarketIndex, fuelBoostDeposits || null, fuelBoostBorrows || null, fuelBoostTaker || null, fuelBoostMaker || null, fuelBoostInsurance || null);
1636
1636
  const tx = await this.buildTransaction(updateSpotMarketFuelIx);
1637
1637
  const { txSig } = await this.sendTransaction(tx, [], this.opts);
1638
1638
  return txSig;
1639
1639
  }
1640
- async getUpdateSpotMarketFuelIx(spotMarketIndex, fuelBoostDeposits, fuelBoostBorrows, fuelBoostTaker, fuelBoostMaker) {
1640
+ async getUpdateSpotMarketFuelIx(spotMarketIndex, fuelBoostDeposits, fuelBoostBorrows, fuelBoostTaker, fuelBoostMaker, fuelBoostInsurance) {
1641
1641
  const spotMarketPublicKey = await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, spotMarketIndex);
1642
- return await this.program.instruction.updateSpotMarketFuel(fuelBoostDeposits || null, fuelBoostBorrows || null, fuelBoostTaker || null, fuelBoostMaker || null, {
1642
+ return await this.program.instruction.updateSpotMarketFuel(fuelBoostDeposits || null, fuelBoostBorrows || null, fuelBoostTaker || null, fuelBoostMaker || null, fuelBoostInsurance || null, {
1643
1643
  accounts: {
1644
1644
  admin: this.isSubscribed
1645
1645
  ? this.getStateAccount().admin
@@ -26,6 +26,7 @@ export declare class BankrunContextWrapper {
26
26
  getLatestBlockhash(): Promise<Blockhash>;
27
27
  printTxLogs(signature: string): void;
28
28
  moveTimeForward(increment: number): Promise<void>;
29
+ setTimestamp(unix_timestamp: number): Promise<void>;
29
30
  }
30
31
  export declare class BankrunConnection {
31
32
  private readonly _banksClient;
@@ -53,6 +53,12 @@ class BankrunContextWrapper {
53
53
  const newClock = new solana_bankrun_1.Clock(currentClock.slot, currentClock.epochStartTimestamp, currentClock.epoch, currentClock.leaderScheduleEpoch, newUnixTimestamp);
54
54
  await this.context.setClock(newClock);
55
55
  }
56
+ async setTimestamp(unix_timestamp) {
57
+ const currentClock = await this.context.banksClient.getClock();
58
+ const newUnixTimestamp = BigInt(unix_timestamp);
59
+ const newClock = new solana_bankrun_1.Clock(currentClock.slot, currentClock.epochStartTimestamp, currentClock.epoch, currentClock.leaderScheduleEpoch, newUnixTimestamp);
60
+ await this.context.setClock(newClock);
61
+ }
56
62
  }
57
63
  exports.BankrunContextWrapper = BankrunContextWrapper;
58
64
  class BankrunConnection {
@@ -57,6 +57,7 @@ export declare const FIVE_MINUTE: BN;
57
57
  export declare const ONE_HOUR: BN;
58
58
  export declare const ONE_YEAR: BN;
59
59
  export declare const QUOTE_SPOT_MARKET_INDEX = 0;
60
+ export declare const GOV_SPOT_MARKET_INDEX = 15;
60
61
  export declare const LAMPORTS_PRECISION: BN;
61
62
  export declare const LAMPORTS_EXP: BN;
62
63
  export declare const OPEN_ORDER_MARGIN_REQUIREMENT: BN;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.PRICE_DIV_PEG = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION_EXP = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_RATE_BUFFER_PRECISION = exports.FUNDING_RATE_PRECISION = exports.PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.SPOT_MARKET_IMF_PRECISION = exports.SPOT_MARKET_IMF_PRECISION_EXP = exports.SPOT_MARKET_BALANCE_PRECISION = exports.SPOT_MARKET_BALANCE_PRECISION_EXP = exports.SPOT_MARKET_WEIGHT_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION_EXP = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION_EXP = exports.SPOT_MARKET_RATE_PRECISION = exports.SPOT_MARKET_RATE_PRECISION_EXP = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.PRICE_PRECISION_EXP = exports.FUNDING_RATE_BUFFER_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.CONCENTRATION_PRECISION = exports.PERCENTAGE_PRECISION = exports.PERCENTAGE_PRECISION_EXP = exports.MAX_LEVERAGE_ORDER_SIZE = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.NINE = exports.EIGHT = exports.SEVEN = exports.SIX = exports.FIVE = exports.FOUR = exports.THREE = exports.TWO = exports.ONE = exports.ZERO = void 0;
4
- exports.FUEL_START_TS = exports.FUEL_WINDOW = exports.DUST_POSITION_SIZE = exports.SLOT_TIME_ESTIMATE_MS = exports.IDLE_TIME_SLOTS = exports.ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.ONE_HOUR = exports.FIVE_MINUTE = exports.FUNDING_RATE_OFFSET_DENOMINATOR = exports.LIQUIDATION_PCT_PRECISION = exports.BID_ASK_SPREAD_PRECISION = void 0;
4
+ exports.FUEL_START_TS = exports.FUEL_WINDOW = exports.DUST_POSITION_SIZE = exports.SLOT_TIME_ESTIMATE_MS = exports.IDLE_TIME_SLOTS = exports.ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.GOV_SPOT_MARKET_INDEX = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.ONE_HOUR = exports.FIVE_MINUTE = exports.FUNDING_RATE_OFFSET_DENOMINATOR = exports.LIQUIDATION_PCT_PRECISION = exports.BID_ASK_SPREAD_PRECISION = void 0;
5
5
  const web3_js_1 = require("@solana/web3.js");
6
6
  const __1 = require("../");
7
7
  exports.ZERO = new __1.BN(0);
@@ -61,6 +61,7 @@ exports.FIVE_MINUTE = new __1.BN(60 * 5);
61
61
  exports.ONE_HOUR = new __1.BN(60 * 60);
62
62
  exports.ONE_YEAR = new __1.BN(31536000);
63
63
  exports.QUOTE_SPOT_MARKET_INDEX = 0;
64
+ exports.GOV_SPOT_MARKET_INDEX = 15;
64
65
  exports.LAMPORTS_PRECISION = new __1.BN(web3_js_1.LAMPORTS_PER_SOL);
65
66
  exports.LAMPORTS_EXP = new __1.BN(Math.log10(web3_js_1.LAMPORTS_PER_SOL));
66
67
  exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.QUOTE_PRECISION.div(new __1.BN(100));
@@ -70,4 +71,4 @@ exports.IDLE_TIME_SLOTS = 9000;
70
71
  exports.SLOT_TIME_ESTIMATE_MS = 400;
71
72
  exports.DUST_POSITION_SIZE = exports.QUOTE_PRECISION.divn(100); // Dust position is any position smaller than 1c
72
73
  exports.FUEL_WINDOW = new __1.BN(60 * 60 * 24 * 28); // 28 days
73
- exports.FUEL_START_TS = new __1.BN(1715745600); // unix timestamp
74
+ exports.FUEL_START_TS = new __1.BN(1722384000); // unix timestamp
@@ -5198,6 +5198,12 @@
5198
5198
  "type": {
5199
5199
  "option": "u8"
5200
5200
  }
5201
+ },
5202
+ {
5203
+ "name": "fuelBoostInsurance",
5204
+ "type": {
5205
+ "option": "u8"
5206
+ }
5201
5207
  }
5202
5208
  ]
5203
5209
  },
@@ -6554,12 +6560,20 @@
6554
6560
  ],
6555
6561
  "type": "u8"
6556
6562
  },
6563
+ {
6564
+ "name": "fuelBoostInsurance",
6565
+ "docs": [
6566
+ "fuel multiplier for spot insurance stake",
6567
+ "precision: 10"
6568
+ ],
6569
+ "type": "u8"
6570
+ },
6557
6571
  {
6558
6572
  "name": "padding",
6559
6573
  "type": {
6560
6574
  "array": [
6561
6575
  "u8",
6562
- 43
6576
+ 42
6563
6577
  ]
6564
6578
  }
6565
6579
  }
@@ -6918,14 +6932,14 @@
6918
6932
  },
6919
6933
  {
6920
6934
  "name": "lastFuelBonusUpdateTs",
6921
- "type": "i64"
6935
+ "type": "u32"
6922
6936
  },
6923
6937
  {
6924
6938
  "name": "padding",
6925
6939
  "type": {
6926
6940
  "array": [
6927
6941
  "u8",
6928
- 8
6942
+ 12
6929
6943
  ]
6930
6944
  }
6931
6945
  }
@@ -7051,21 +7065,28 @@
7051
7065
  "type": {
7052
7066
  "array": [
7053
7067
  "u8",
7054
- 6
7068
+ 2
7055
7069
  ]
7056
7070
  }
7057
7071
  },
7072
+ {
7073
+ "name": "fuelInsurance",
7074
+ "docs": [
7075
+ "accumulated fuel for token amounts of insurance"
7076
+ ],
7077
+ "type": "u32"
7078
+ },
7058
7079
  {
7059
7080
  "name": "fuelDeposits",
7060
7081
  "docs": [
7061
- "sub account id for spot deposit, borrow fuel tracking"
7082
+ "accumulated fuel for notional of deposits"
7062
7083
  ],
7063
7084
  "type": "u32"
7064
7085
  },
7065
7086
  {
7066
7087
  "name": "fuelBorrows",
7067
7088
  "docs": [
7068
- "accumulate fuel bonus for epoch"
7089
+ "accumulate fuel bonus for notional of borrows"
7069
7090
  ],
7070
7091
  "type": "u32"
7071
7092
  },
@@ -7079,14 +7100,14 @@
7079
7100
  {
7080
7101
  "name": "fuelTaker",
7081
7102
  "docs": [
7082
- "accumulate fuel bonus for epoch"
7103
+ "accumulate fuel bonus for taker volume"
7083
7104
  ],
7084
7105
  "type": "u32"
7085
7106
  },
7086
7107
  {
7087
7108
  "name": "fuelMaker",
7088
7109
  "docs": [
7089
- "accumulate fuel bonus for epoch"
7110
+ "accumulate fuel bonus for maker volume"
7090
7111
  ],
7091
7112
  "type": "u32"
7092
7113
  },
@@ -7097,12 +7118,19 @@
7097
7118
  ],
7098
7119
  "type": "u64"
7099
7120
  },
7121
+ {
7122
+ "name": "lastFuelIfBonusUpdateTs",
7123
+ "docs": [
7124
+ "last unix ts user stats data was used to update if fuel (u32 to save space)"
7125
+ ],
7126
+ "type": "u32"
7127
+ },
7100
7128
  {
7101
7129
  "name": "padding",
7102
7130
  "type": {
7103
7131
  "array": [
7104
7132
  "u8",
7105
- 16
7133
+ 12
7106
7134
  ]
7107
7135
  }
7108
7136
  }
@@ -1,5 +1,6 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { BN } from '@coral-xyz/anchor';
3
3
  import { SpotMarketAccount, PerpMarketAccount } from '..';
4
+ export declare function calculateInsuranceFuelBonus(spotMarket: SpotMarketAccount, tokenStakeAmount: BN, fuelBonusNumerator: BN): BN;
4
5
  export declare function calculateSpotFuelBonus(spotMarket: SpotMarketAccount, signedTokenValue: BN, fuelBonusNumerator: BN): BN;
5
6
  export declare function calculatePerpFuelBonus(perpMarket: PerpMarketAccount, baseAssetValue: BN, fuelBonusNumerator: BN): BN;
package/lib/math/fuel.js CHANGED
@@ -1,11 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculatePerpFuelBonus = exports.calculateSpotFuelBonus = void 0;
3
+ exports.calculatePerpFuelBonus = exports.calculateSpotFuelBonus = exports.calculateInsuranceFuelBonus = void 0;
4
4
  const anchor_1 = require("@coral-xyz/anchor");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
+ function calculateInsuranceFuelBonus(spotMarket, tokenStakeAmount, fuelBonusNumerator) {
7
+ const result = tokenStakeAmount
8
+ .abs()
9
+ .mul(fuelBonusNumerator)
10
+ .mul(new anchor_1.BN(spotMarket.fuelBoostInsurance))
11
+ .div(numericConstants_1.FUEL_WINDOW)
12
+ .div(numericConstants_1.QUOTE_PRECISION.div(new anchor_1.BN(10)));
13
+ return result;
14
+ }
15
+ exports.calculateInsuranceFuelBonus = calculateInsuranceFuelBonus;
6
16
  function calculateSpotFuelBonus(spotMarket, signedTokenValue, fuelBonusNumerator) {
7
17
  let result;
8
- if (signedTokenValue.abs().lt(new anchor_1.BN(1))) {
18
+ if (signedTokenValue.abs().lte(numericConstants_1.QUOTE_PRECISION)) {
9
19
  result = numericConstants_1.ZERO;
10
20
  }
11
21
  else if (signedTokenValue.gt(new anchor_1.BN(0))) {
package/lib/types.d.ts CHANGED
@@ -731,9 +731,9 @@ export type PerpMarketAccount = {
731
731
  quoteSpotMarketIndex: number;
732
732
  feeAdjustment: number;
733
733
  pausedOperations: number;
734
- fuelBoostPosition: number;
735
- fuelBoostMaker: number;
736
734
  fuelBoostTaker: number;
735
+ fuelBoostMaker: number;
736
+ fuelBoostPosition: number;
737
737
  };
738
738
  export type HistoricalOracleData = {
739
739
  lastOraclePrice: BN;
@@ -817,8 +817,9 @@ export type SpotMarketAccount = {
817
817
  minBorrowRate: number;
818
818
  fuelBoostDeposits: number;
819
819
  fuelBoostBorrows: number;
820
- fuelBoostMaker: number;
821
820
  fuelBoostTaker: number;
821
+ fuelBoostMaker: number;
822
+ fuelBoostInsurance: number;
822
823
  };
823
824
  export type PoolBalance = {
824
825
  scaledBalance: BN;
@@ -946,6 +947,8 @@ export type UserStatsAccount = {
946
947
  isReferrer: boolean;
947
948
  authority: PublicKey;
948
949
  ifStakedQuoteAssetAmount: BN;
950
+ lastFuelBonusUpdateTs: number;
951
+ fuelInsurance: number;
949
952
  fuelDeposits: number;
950
953
  fuelBorrows: number;
951
954
  fuelPositions: number;
@@ -980,7 +983,7 @@ export type UserAccount = {
980
983
  hasOpenOrder: boolean;
981
984
  openAuctions: number;
982
985
  hasOpenAuction: boolean;
983
- lastFuelBonusUpdateTs: BN;
986
+ lastFuelBonusUpdateTs: number;
984
987
  };
985
988
  export type SpotPosition = {
986
989
  marketIndex: number;
package/lib/user.js CHANGED
@@ -543,6 +543,7 @@ class User {
543
543
  getFuelBonus(now, includeSettled = true, includeUnsettled = true) {
544
544
  const userAccount = this.getUserAccount();
545
545
  const result = {
546
+ insuranceFuel: numericConstants_1.ZERO,
546
547
  takerFuel: numericConstants_1.ZERO,
547
548
  makerFuel: numericConstants_1.ZERO,
548
549
  depositFuel: numericConstants_1.ZERO,
@@ -560,7 +561,7 @@ class User {
560
561
  result.positionFuel = result.positionFuel.add(new _1.BN(userStats.fuelPositions));
561
562
  }
562
563
  if (includeUnsettled) {
563
- const fuelBonusNumerator = _1.BN.max(now.sub(_1.BN.max(userAccount.lastFuelBonusUpdateTs, numericConstants_1.FUEL_START_TS)), numericConstants_1.ZERO);
564
+ const fuelBonusNumerator = _1.BN.max(now.sub(_1.BN.max(new _1.BN(userAccount.lastFuelBonusUpdateTs), numericConstants_1.FUEL_START_TS)), numericConstants_1.ZERO);
564
565
  if (fuelBonusNumerator.gt(numericConstants_1.ZERO)) {
565
566
  for (const spotPosition of this.getActiveSpotPositions()) {
566
567
  const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
@@ -584,6 +585,15 @@ class User {
584
585
  result.positionFuel = result.positionFuel.add((0, fuel_1.calculatePerpFuelBonus)(perpMarketAccount, baseAssetValue, fuelBonusNumerator));
585
586
  }
586
587
  }
588
+ const userStats = this.driftClient
589
+ .getUserStats()
590
+ .getAccount();
591
+ // todo: get real time ifStakedGovTokenAmount using ifStakeAccount
592
+ if (userStats.ifStakedGovTokenAmount.gt(numericConstants_1.ZERO)) {
593
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(numericConstants_1.GOV_SPOT_MARKET_INDEX);
594
+ const fuelBonusNumeratorUserStats = now.sub(new _1.BN(userStats.lastFuelBonusUpdateTs));
595
+ result.insuranceFuel = result.insuranceFuel.add((0, fuel_1.calculateInsuranceFuelBonus)(spotMarketAccount, userStats.ifStakedGovTokenAmount, fuelBonusNumeratorUserStats));
596
+ }
587
597
  }
588
598
  return result;
589
599
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.86.0-beta.18",
3
+ "version": "2.86.0-beta.19",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -3538,14 +3538,16 @@ export class AdminClient extends DriftClient {
3538
3538
  fuelBoostDeposits?: number,
3539
3539
  fuelBoostBorrows?: number,
3540
3540
  fuelBoostTaker?: number,
3541
- fuelBoostMaker?: number
3541
+ fuelBoostMaker?: number,
3542
+ fuelBoostInsurance?: number
3542
3543
  ): Promise<TransactionSignature> {
3543
3544
  const updateSpotMarketFuelIx = await this.getUpdateSpotMarketFuelIx(
3544
3545
  spotMarketIndex,
3545
3546
  fuelBoostDeposits || null,
3546
3547
  fuelBoostBorrows || null,
3547
3548
  fuelBoostTaker || null,
3548
- fuelBoostMaker || null
3549
+ fuelBoostMaker || null,
3550
+ fuelBoostInsurance || null
3549
3551
  );
3550
3552
 
3551
3553
  const tx = await this.buildTransaction(updateSpotMarketFuelIx);
@@ -3559,7 +3561,8 @@ export class AdminClient extends DriftClient {
3559
3561
  fuelBoostDeposits?: number,
3560
3562
  fuelBoostBorrows?: number,
3561
3563
  fuelBoostTaker?: number,
3562
- fuelBoostMaker?: number
3564
+ fuelBoostMaker?: number,
3565
+ fuelBoostInsurance?: number
3563
3566
  ): Promise<TransactionInstruction> {
3564
3567
  const spotMarketPublicKey = await getSpotMarketPublicKey(
3565
3568
  this.program.programId,
@@ -3571,6 +3574,7 @@ export class AdminClient extends DriftClient {
3571
3574
  fuelBoostBorrows || null,
3572
3575
  fuelBoostTaker || null,
3573
3576
  fuelBoostMaker || null,
3577
+ fuelBoostInsurance || null,
3574
3578
  {
3575
3579
  accounts: {
3576
3580
  admin: this.isSubscribed
@@ -118,6 +118,19 @@ export class BankrunContextWrapper {
118
118
  );
119
119
  await this.context.setClock(newClock);
120
120
  }
121
+
122
+ async setTimestamp(unix_timestamp: number): Promise<void> {
123
+ const currentClock = await this.context.banksClient.getClock();
124
+ const newUnixTimestamp = BigInt(unix_timestamp);
125
+ const newClock = new Clock(
126
+ currentClock.slot,
127
+ currentClock.epochStartTimestamp,
128
+ currentClock.epoch,
129
+ currentClock.leaderScheduleEpoch,
130
+ newUnixTimestamp
131
+ );
132
+ await this.context.setClock(newClock);
133
+ }
121
134
  }
122
135
 
123
136
  export class BankrunConnection {
@@ -90,6 +90,7 @@ export const ONE_HOUR = new BN(60 * 60);
90
90
  export const ONE_YEAR = new BN(31536000);
91
91
 
92
92
  export const QUOTE_SPOT_MARKET_INDEX = 0;
93
+ export const GOV_SPOT_MARKET_INDEX = 15;
93
94
 
94
95
  export const LAMPORTS_PRECISION = new BN(LAMPORTS_PER_SOL);
95
96
  export const LAMPORTS_EXP = new BN(Math.log10(LAMPORTS_PER_SOL));
@@ -107,4 +108,4 @@ export const SLOT_TIME_ESTIMATE_MS = 400;
107
108
  export const DUST_POSITION_SIZE = QUOTE_PRECISION.divn(100); // Dust position is any position smaller than 1c
108
109
 
109
110
  export const FUEL_WINDOW = new BN(60 * 60 * 24 * 28); // 28 days
110
- export const FUEL_START_TS = new BN(1715745600); // unix timestamp
111
+ export const FUEL_START_TS = new BN(1722384000); // unix timestamp
@@ -5198,6 +5198,12 @@
5198
5198
  "type": {
5199
5199
  "option": "u8"
5200
5200
  }
5201
+ },
5202
+ {
5203
+ "name": "fuelBoostInsurance",
5204
+ "type": {
5205
+ "option": "u8"
5206
+ }
5201
5207
  }
5202
5208
  ]
5203
5209
  },
@@ -6554,12 +6560,20 @@
6554
6560
  ],
6555
6561
  "type": "u8"
6556
6562
  },
6563
+ {
6564
+ "name": "fuelBoostInsurance",
6565
+ "docs": [
6566
+ "fuel multiplier for spot insurance stake",
6567
+ "precision: 10"
6568
+ ],
6569
+ "type": "u8"
6570
+ },
6557
6571
  {
6558
6572
  "name": "padding",
6559
6573
  "type": {
6560
6574
  "array": [
6561
6575
  "u8",
6562
- 43
6576
+ 42
6563
6577
  ]
6564
6578
  }
6565
6579
  }
@@ -6918,14 +6932,14 @@
6918
6932
  },
6919
6933
  {
6920
6934
  "name": "lastFuelBonusUpdateTs",
6921
- "type": "i64"
6935
+ "type": "u32"
6922
6936
  },
6923
6937
  {
6924
6938
  "name": "padding",
6925
6939
  "type": {
6926
6940
  "array": [
6927
6941
  "u8",
6928
- 8
6942
+ 12
6929
6943
  ]
6930
6944
  }
6931
6945
  }
@@ -7051,21 +7065,28 @@
7051
7065
  "type": {
7052
7066
  "array": [
7053
7067
  "u8",
7054
- 6
7068
+ 2
7055
7069
  ]
7056
7070
  }
7057
7071
  },
7072
+ {
7073
+ "name": "fuelInsurance",
7074
+ "docs": [
7075
+ "accumulated fuel for token amounts of insurance"
7076
+ ],
7077
+ "type": "u32"
7078
+ },
7058
7079
  {
7059
7080
  "name": "fuelDeposits",
7060
7081
  "docs": [
7061
- "sub account id for spot deposit, borrow fuel tracking"
7082
+ "accumulated fuel for notional of deposits"
7062
7083
  ],
7063
7084
  "type": "u32"
7064
7085
  },
7065
7086
  {
7066
7087
  "name": "fuelBorrows",
7067
7088
  "docs": [
7068
- "accumulate fuel bonus for epoch"
7089
+ "accumulate fuel bonus for notional of borrows"
7069
7090
  ],
7070
7091
  "type": "u32"
7071
7092
  },
@@ -7079,14 +7100,14 @@
7079
7100
  {
7080
7101
  "name": "fuelTaker",
7081
7102
  "docs": [
7082
- "accumulate fuel bonus for epoch"
7103
+ "accumulate fuel bonus for taker volume"
7083
7104
  ],
7084
7105
  "type": "u32"
7085
7106
  },
7086
7107
  {
7087
7108
  "name": "fuelMaker",
7088
7109
  "docs": [
7089
- "accumulate fuel bonus for epoch"
7110
+ "accumulate fuel bonus for maker volume"
7090
7111
  ],
7091
7112
  "type": "u32"
7092
7113
  },
@@ -7097,12 +7118,19 @@
7097
7118
  ],
7098
7119
  "type": "u64"
7099
7120
  },
7121
+ {
7122
+ "name": "lastFuelIfBonusUpdateTs",
7123
+ "docs": [
7124
+ "last unix ts user stats data was used to update if fuel (u32 to save space)"
7125
+ ],
7126
+ "type": "u32"
7127
+ },
7100
7128
  {
7101
7129
  "name": "padding",
7102
7130
  "type": {
7103
7131
  "array": [
7104
7132
  "u8",
7105
- 16
7133
+ 12
7106
7134
  ]
7107
7135
  }
7108
7136
  }
package/src/math/fuel.ts CHANGED
@@ -6,6 +6,20 @@ import {
6
6
  FUEL_WINDOW,
7
7
  } from '../constants/numericConstants';
8
8
 
9
+ export function calculateInsuranceFuelBonus(
10
+ spotMarket: SpotMarketAccount,
11
+ tokenStakeAmount: BN,
12
+ fuelBonusNumerator: BN
13
+ ): BN {
14
+ const result = tokenStakeAmount
15
+ .abs()
16
+ .mul(fuelBonusNumerator)
17
+ .mul(new BN(spotMarket.fuelBoostInsurance))
18
+ .div(FUEL_WINDOW)
19
+ .div(QUOTE_PRECISION.div(new BN(10)));
20
+ return result;
21
+ }
22
+
9
23
  export function calculateSpotFuelBonus(
10
24
  spotMarket: SpotMarketAccount,
11
25
  signedTokenValue: BN,
@@ -13,7 +27,7 @@ export function calculateSpotFuelBonus(
13
27
  ): BN {
14
28
  let result: BN;
15
29
 
16
- if (signedTokenValue.abs().lt(new BN(1))) {
30
+ if (signedTokenValue.abs().lte(QUOTE_PRECISION)) {
17
31
  result = ZERO;
18
32
  } else if (signedTokenValue.gt(new BN(0))) {
19
33
  result = signedTokenValue
package/src/types.ts CHANGED
@@ -637,9 +637,9 @@ export type PerpMarketAccount = {
637
637
  feeAdjustment: number;
638
638
  pausedOperations: number;
639
639
 
640
- fuelBoostPosition: number;
641
- fuelBoostMaker: number;
642
640
  fuelBoostTaker: number;
641
+ fuelBoostMaker: number;
642
+ fuelBoostPosition: number;
643
643
  };
644
644
 
645
645
  export type HistoricalOracleData = {
@@ -741,8 +741,9 @@ export type SpotMarketAccount = {
741
741
 
742
742
  fuelBoostDeposits: number;
743
743
  fuelBoostBorrows: number;
744
- fuelBoostMaker: number;
745
744
  fuelBoostTaker: number;
745
+ fuelBoostMaker: number;
746
+ fuelBoostInsurance: number;
746
747
  };
747
748
 
748
749
  export type PoolBalance = {
@@ -886,6 +887,9 @@ export type UserStatsAccount = {
886
887
  authority: PublicKey;
887
888
  ifStakedQuoteAssetAmount: BN;
888
889
 
890
+ lastFuelBonusUpdateTs: number; // u32 onchain
891
+
892
+ fuelInsurance: number;
889
893
  fuelDeposits: number;
890
894
  fuelBorrows: number;
891
895
  fuelPositions: number;
@@ -922,8 +926,7 @@ export type UserAccount = {
922
926
  hasOpenOrder: boolean;
923
927
  openAuctions: number;
924
928
  hasOpenAuction: boolean;
925
-
926
- lastFuelBonusUpdateTs: BN;
929
+ lastFuelBonusUpdateTs: number;
927
930
  };
928
931
 
929
932
  export type SpotPosition = {
package/src/user.ts CHANGED
@@ -31,6 +31,7 @@ import {
31
31
  QUOTE_PRECISION_EXP,
32
32
  QUOTE_SPOT_MARKET_INDEX,
33
33
  SPOT_MARKET_WEIGHT_PRECISION,
34
+ GOV_SPOT_MARKET_INDEX,
34
35
  TEN,
35
36
  TEN_THOUSAND,
36
37
  TWO,
@@ -89,7 +90,11 @@ import { calculateLiveOracleTwap } from './math/oracles';
89
90
  import { getPerpMarketTierNumber, getSpotMarketTierNumber } from './math/tiers';
90
91
  import { StrictOraclePrice } from './oracles/strictOraclePrice';
91
92
 
92
- import { calculateSpotFuelBonus, calculatePerpFuelBonus } from './math/fuel';
93
+ import {
94
+ calculateSpotFuelBonus,
95
+ calculatePerpFuelBonus,
96
+ calculateInsuranceFuelBonus,
97
+ } from './math/fuel';
93
98
 
94
99
  export class User {
95
100
  driftClient: DriftClient;
@@ -890,6 +895,7 @@ export class User {
890
895
  const userAccount: UserAccount = this.getUserAccount();
891
896
 
892
897
  const result = {
898
+ insuranceFuel: ZERO,
893
899
  takerFuel: ZERO,
894
900
  makerFuel: ZERO,
895
901
  depositFuel: ZERO,
@@ -914,7 +920,9 @@ export class User {
914
920
 
915
921
  if (includeUnsettled) {
916
922
  const fuelBonusNumerator = BN.max(
917
- now.sub(BN.max(userAccount.lastFuelBonusUpdateTs, FUEL_START_TS)),
923
+ now.sub(
924
+ BN.max(new BN(userAccount.lastFuelBonusUpdateTs), FUEL_START_TS)
925
+ ),
918
926
  ZERO
919
927
  );
920
928
 
@@ -988,6 +996,28 @@ export class User {
988
996
  );
989
997
  }
990
998
  }
999
+
1000
+ const userStats: UserStatsAccount = this.driftClient
1001
+ .getUserStats()
1002
+ .getAccount();
1003
+
1004
+ // todo: get real time ifStakedGovTokenAmount using ifStakeAccount
1005
+ if (userStats.ifStakedGovTokenAmount.gt(ZERO)) {
1006
+ const spotMarketAccount: SpotMarketAccount =
1007
+ this.driftClient.getSpotMarketAccount(GOV_SPOT_MARKET_INDEX);
1008
+
1009
+ const fuelBonusNumeratorUserStats = now.sub(
1010
+ new BN(userStats.lastFuelBonusUpdateTs)
1011
+ );
1012
+
1013
+ result.insuranceFuel = result.insuranceFuel.add(
1014
+ calculateInsuranceFuelBonus(
1015
+ spotMarketAccount,
1016
+ userStats.ifStakedGovTokenAmount,
1017
+ fuelBonusNumeratorUserStats
1018
+ )
1019
+ );
1020
+ }
991
1021
  }
992
1022
 
993
1023
  return result;
@@ -187,6 +187,9 @@ export const mockPerpMarkets: Array<PerpMarketAccount> = [
187
187
  quoteSpotMarketIndex: 0,
188
188
  feeAdjustment: 0,
189
189
  pausedOperations: 0,
190
+ fuelBoostPosition: 0,
191
+ fuelBoostMaker: 0,
192
+ fuelBoostTaker: 0,
190
193
  },
191
194
  {
192
195
  status: MarketStatus.INITIALIZED,
@@ -226,6 +229,9 @@ export const mockPerpMarkets: Array<PerpMarketAccount> = [
226
229
  quoteSpotMarketIndex: 0,
227
230
  feeAdjustment: 0,
228
231
  pausedOperations: 0,
232
+ fuelBoostPosition: 0,
233
+ fuelBoostMaker: 0,
234
+ fuelBoostTaker: 0,
229
235
  },
230
236
  {
231
237
  status: MarketStatus.INITIALIZED,
@@ -265,6 +271,9 @@ export const mockPerpMarkets: Array<PerpMarketAccount> = [
265
271
  quoteSpotMarketIndex: 0,
266
272
  feeAdjustment: 0,
267
273
  pausedOperations: 0,
274
+ fuelBoostPosition: 0,
275
+ fuelBoostMaker: 0,
276
+ fuelBoostTaker: 0,
268
277
  },
269
278
  ];
270
279
 
@@ -351,6 +360,13 @@ export const mockSpotMarkets: Array<SpotMarketAccount> = [
351
360
  },
352
361
  pausedOperations: 0,
353
362
  ifPausedOperations: 0,
363
+ maxTokenBorrowsFraction: 0,
364
+ minBorrowRate: 0,
365
+ fuelBoostDeposits: 0,
366
+ fuelBoostBorrows: 0,
367
+ fuelBoostTaker: 0,
368
+ fuelBoostMaker: 0,
369
+ fuelBoostInsurance: 0,
354
370
  },
355
371
  {
356
372
  status: MarketStatus.ACTIVE,
@@ -434,6 +450,13 @@ export const mockSpotMarkets: Array<SpotMarketAccount> = [
434
450
  },
435
451
  pausedOperations: 0,
436
452
  ifPausedOperations: 0,
453
+ maxTokenBorrowsFraction: 0,
454
+ minBorrowRate: 0,
455
+ fuelBoostDeposits: 0,
456
+ fuelBoostBorrows: 0,
457
+ fuelBoostTaker: 0,
458
+ fuelBoostMaker: 0,
459
+ fuelBoostInsurance: 0,
437
460
  },
438
461
  {
439
462
  status: MarketStatus.ACTIVE,
@@ -517,6 +540,13 @@ export const mockSpotMarkets: Array<SpotMarketAccount> = [
517
540
  },
518
541
  pausedOperations: 0,
519
542
  ifPausedOperations: 0,
543
+ maxTokenBorrowsFraction: 0,
544
+ minBorrowRate: 0,
545
+ fuelBoostDeposits: 0,
546
+ fuelBoostBorrows: 0,
547
+ fuelBoostTaker: 0,
548
+ fuelBoostMaker: 0,
549
+ fuelBoostInsurance: 0,
520
550
  },
521
551
  ];
522
552
 
@@ -85,4 +85,5 @@ export const mockUserAccount: UserAccount = {
85
85
  hasOpenOrder: false,
86
86
  openAuctions: 0,
87
87
  hasOpenAuction: false,
88
+ lastFuelBonusUpdateTs: 0,
88
89
  };
@@ -35,6 +35,8 @@ async function makeMockUser(
35
35
  const mockUser: User = await umap.mustGet('1');
36
36
  mockUser._isSubscribed = true;
37
37
  mockUser.driftClient._isSubscribed = true;
38
+ mockUser.driftClient.accountSubscriber.isSubscribed = true;
39
+
38
40
  const oraclePriceMap = {};
39
41
  // console.log(perpOraclePriceList, myMockPerpMarkets.length);
40
42
  // console.log(spotOraclePriceList, myMockSpotMarkets.length);