@drift-labs/sdk 2.86.0-beta.0 → 2.86.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,56 @@
1
+ import { BN } from '@coral-xyz/anchor';
2
+ import { SpotMarketAccount, PerpMarketAccount } from '..';
3
+ import {
4
+ QUOTE_PRECISION,
5
+ ZERO,
6
+ FUEL_WINDOW,
7
+ } from '../constants/numericConstants';
8
+
9
+ export function calculateSpotFuelBonus(
10
+ spotMarket: SpotMarketAccount,
11
+ signedTokenValue: BN,
12
+ fuelBonusNumerator: BN
13
+ ): BN {
14
+ let result: BN;
15
+
16
+ if (signedTokenValue.abs().lt(new BN(1))) {
17
+ result = ZERO;
18
+ } else if (signedTokenValue.gt(new BN(0))) {
19
+ result = signedTokenValue
20
+ .abs()
21
+ .mul(fuelBonusNumerator)
22
+ .mul(new BN(spotMarket.fuelBoostDeposits))
23
+ .div(FUEL_WINDOW)
24
+ .div(QUOTE_PRECISION.div(new BN(10)));
25
+ } else {
26
+ result = signedTokenValue
27
+ .abs()
28
+ .mul(fuelBonusNumerator)
29
+ .mul(new BN(spotMarket.fuelBoostBorrows))
30
+ .div(FUEL_WINDOW)
31
+ .div(QUOTE_PRECISION.div(new BN(10)));
32
+ }
33
+
34
+ return result;
35
+ }
36
+
37
+ export function calculatePerpFuelBonus(
38
+ perpMarket: PerpMarketAccount,
39
+ baseAssetValue: BN,
40
+ fuelBonusNumerator: BN
41
+ ): BN {
42
+ let result: BN;
43
+
44
+ if (baseAssetValue.abs().lte(QUOTE_PRECISION)) {
45
+ result = new BN(0);
46
+ } else {
47
+ result = baseAssetValue
48
+ .abs()
49
+ .mul(fuelBonusNumerator)
50
+ .mul(new BN(perpMarket.fuelBoostPosition))
51
+ .div(FUEL_WINDOW)
52
+ .div(QUOTE_PRECISION.div(new BN(10)));
53
+ }
54
+
55
+ return result;
56
+ }
package/src/types.ts CHANGED
@@ -636,6 +636,10 @@ export type PerpMarketAccount = {
636
636
  quoteSpotMarketIndex: number;
637
637
  feeAdjustment: number;
638
638
  pausedOperations: number;
639
+
640
+ fuelBoostPosition: number;
641
+ fuelBoostMaker: number;
642
+ fuelBoostTaker: number;
639
643
  };
640
644
 
641
645
  export type HistoricalOracleData = {
@@ -734,6 +738,11 @@ export type SpotMarketAccount = {
734
738
 
735
739
  maxTokenBorrowsFraction: number;
736
740
  minBorrowRate: number;
741
+
742
+ fuelBoostDeposits: number;
743
+ fuelBoostBorrows: number;
744
+ fuelBoostMaker: number;
745
+ fuelBoostTaker: number;
737
746
  };
738
747
 
739
748
  export type PoolBalance = {
@@ -876,6 +885,14 @@ export type UserStatsAccount = {
876
885
  isReferrer: boolean;
877
886
  authority: PublicKey;
878
887
  ifStakedQuoteAssetAmount: BN;
888
+
889
+ fuelDeposits: number;
890
+ fuelBorrows: number;
891
+ fuelPositions: number;
892
+ fuelTaker: number;
893
+ fuelMaker: number;
894
+
895
+ ifStakedGovTokenAmount: BN;
879
896
  };
880
897
 
881
898
  export type UserAccount = {
@@ -905,6 +922,8 @@ export type UserAccount = {
905
922
  hasOpenOrder: boolean;
906
923
  openAuctions: number;
907
924
  hasOpenAuction: boolean;
925
+
926
+ lastFuelBonusUpdateTs: BN;
908
927
  };
909
928
 
910
929
  export type SpotPosition = {
package/src/user.ts CHANGED
@@ -35,6 +35,7 @@ import {
35
35
  TEN_THOUSAND,
36
36
  TWO,
37
37
  ZERO,
38
+ FUEL_START_TS,
38
39
  } from './constants/numericConstants';
39
40
  import {
40
41
  DataAndSlot,
@@ -88,6 +89,8 @@ import { calculateLiveOracleTwap } from './math/oracles';
88
89
  import { getPerpMarketTierNumber, getSpotMarketTierNumber } from './math/tiers';
89
90
  import { StrictOraclePrice } from './oracles/strictOraclePrice';
90
91
 
92
+ import { calculateSpotFuelBonus, calculatePerpFuelBonus } from './math/fuel';
93
+
91
94
  export class User {
92
95
  driftClient: DriftClient;
93
96
  userAccountPublicKey: PublicKey;
@@ -873,6 +876,123 @@ export class User {
873
876
  }, ZERO);
874
877
  }
875
878
 
879
+ public getFuelBonus(
880
+ now: BN,
881
+ includeSettled = true,
882
+ includeUnsettled = true
883
+ ): {
884
+ depositFuel;
885
+ borrowFuel;
886
+ positionFuel;
887
+ takerFuel;
888
+ makerFuel;
889
+ } {
890
+ const userAccount: UserAccount = this.getUserAccount();
891
+
892
+ const result = {
893
+ takerFuel: ZERO,
894
+ makerFuel: ZERO,
895
+ depositFuel: ZERO,
896
+ borrowFuel: ZERO,
897
+ positionFuel: ZERO,
898
+ };
899
+
900
+ if (includeSettled) {
901
+ const userStats: UserStatsAccount = this.driftClient
902
+ .getUserStats()
903
+ .getAccount();
904
+ result.takerFuel = result.takerFuel.add(new BN(userStats.fuelTaker));
905
+ result.makerFuel = result.makerFuel.add(new BN(userStats.fuelMaker));
906
+ result.depositFuel = result.depositFuel.add(
907
+ new BN(userStats.fuelDeposits)
908
+ );
909
+ result.borrowFuel = result.borrowFuel.add(new BN(userStats.fuelBorrows));
910
+ result.positionFuel = result.positionFuel.add(
911
+ new BN(userStats.fuelPositions)
912
+ );
913
+ }
914
+
915
+ if (includeUnsettled) {
916
+ const fuelBonusNumerator = BN.max(
917
+ now.sub(BN.max(userAccount.lastFuelBonusUpdateTs, FUEL_START_TS)),
918
+ ZERO
919
+ );
920
+
921
+ if (fuelBonusNumerator.gt(ZERO)) {
922
+ for (const spotPosition of this.getActiveSpotPositions()) {
923
+ const spotMarketAccount: SpotMarketAccount =
924
+ this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
925
+
926
+ const tokenAmount = this.getTokenAmount(spotPosition.marketIndex);
927
+ const oraclePriceData = this.getOracleDataForSpotMarket(
928
+ spotPosition.marketIndex
929
+ );
930
+
931
+ const twap5min = calculateLiveOracleTwap(
932
+ spotMarketAccount.historicalOracleData,
933
+ oraclePriceData,
934
+ now,
935
+ FIVE_MINUTE // 5MIN
936
+ );
937
+ const strictOraclePrice = new StrictOraclePrice(
938
+ oraclePriceData.price,
939
+ twap5min
940
+ );
941
+
942
+ const signedTokenValue = getStrictTokenValue(
943
+ tokenAmount,
944
+ spotMarketAccount.decimals,
945
+ strictOraclePrice
946
+ );
947
+
948
+ if (signedTokenValue.gt(ZERO)) {
949
+ result.depositFuel = result.depositFuel.add(
950
+ calculateSpotFuelBonus(
951
+ spotMarketAccount,
952
+ signedTokenValue,
953
+ fuelBonusNumerator
954
+ )
955
+ );
956
+ } else {
957
+ result.borrowFuel = result.borrowFuel.add(
958
+ calculateSpotFuelBonus(
959
+ spotMarketAccount,
960
+ signedTokenValue,
961
+ fuelBonusNumerator
962
+ )
963
+ );
964
+ }
965
+ }
966
+
967
+ for (const perpPosition of this.getActivePerpPositions()) {
968
+ const oraclePriceData = this.getOracleDataForPerpMarket(
969
+ perpPosition.marketIndex
970
+ );
971
+
972
+ const perpMarketAccount = this.driftClient.getPerpMarketAccount(
973
+ perpPosition.marketIndex
974
+ );
975
+
976
+ const baseAssetValue = this.getPerpPositionValue(
977
+ perpPosition.marketIndex,
978
+ oraclePriceData,
979
+ false
980
+ );
981
+
982
+ result.positionFuel = result.positionFuel.add(
983
+ calculatePerpFuelBonus(
984
+ perpMarketAccount,
985
+ baseAssetValue,
986
+ fuelBonusNumerator
987
+ )
988
+ );
989
+ }
990
+ }
991
+ }
992
+
993
+ return result;
994
+ }
995
+
876
996
  public getSpotMarketAssetAndLiabilityValue(
877
997
  marketIndex?: number,
878
998
  marginCategory?: MarginCategory,