@haven-fi/solauto-sdk 1.0.628 → 1.0.630

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 (72) hide show
  1. package/README.md +35 -6
  2. package/dist/constants/marginfiAccounts.d.ts.map +1 -1
  3. package/dist/constants/solautoConstants.d.ts +2 -1
  4. package/dist/constants/solautoConstants.d.ts.map +1 -1
  5. package/dist/generated/instructions/marginfiRebalance.d.ts +5 -3
  6. package/dist/generated/instructions/marginfiRebalance.d.ts.map +1 -1
  7. package/dist/generated/instructions/marginfiRebalance.js +2 -1
  8. package/dist/generated/instructions/marginfiRefreshData.d.ts +7 -2
  9. package/dist/generated/instructions/marginfiRefreshData.d.ts.map +1 -1
  10. package/dist/generated/instructions/marginfiRefreshData.js +8 -4
  11. package/dist/generated/types/index.d.ts +1 -0
  12. package/dist/generated/types/index.d.ts.map +1 -1
  13. package/dist/generated/types/index.js +1 -0
  14. package/dist/generated/types/priceType.d.ts +15 -0
  15. package/dist/generated/types/priceType.d.ts.map +1 -0
  16. package/dist/generated/types/priceType.js +22 -0
  17. package/dist/services/rebalance/rebalanceSwapManager.d.ts.map +1 -1
  18. package/dist/services/rebalance/rebalanceSwapManager.js +8 -8
  19. package/dist/services/rebalance/rebalanceTxBuilder.d.ts +2 -0
  20. package/dist/services/rebalance/rebalanceTxBuilder.d.ts.map +1 -1
  21. package/dist/services/rebalance/rebalanceTxBuilder.js +21 -10
  22. package/dist/services/rebalance/rebalanceValues.d.ts +2 -2
  23. package/dist/services/rebalance/rebalanceValues.d.ts.map +1 -1
  24. package/dist/services/rebalance/rebalanceValues.js +17 -17
  25. package/dist/services/solauto/solautoClient.d.ts +2 -2
  26. package/dist/services/solauto/solautoClient.d.ts.map +1 -1
  27. package/dist/services/solauto/solautoClient.js +27 -28
  28. package/dist/services/solauto/solautoMarginfiClient.d.ts +2 -2
  29. package/dist/services/solauto/solautoMarginfiClient.d.ts.map +1 -1
  30. package/dist/services/solauto/solautoMarginfiClient.js +12 -10
  31. package/dist/services/transactions/transactionUtils.d.ts.map +1 -1
  32. package/dist/services/transactions/transactionUtils.js +10 -9
  33. package/dist/solautoPosition/marginfiSolautoPositionEx.d.ts +3 -3
  34. package/dist/solautoPosition/marginfiSolautoPositionEx.d.ts.map +1 -1
  35. package/dist/solautoPosition/marginfiSolautoPositionEx.js +9 -9
  36. package/dist/solautoPosition/solautoPositionEx.d.ts +44 -33
  37. package/dist/solautoPosition/solautoPositionEx.d.ts.map +1 -1
  38. package/dist/solautoPosition/solautoPositionEx.js +109 -90
  39. package/dist/types/solauto.d.ts +2 -1
  40. package/dist/types/solauto.d.ts.map +1 -1
  41. package/dist/utils/instructionUtils.js +2 -2
  42. package/dist/utils/marginfiUtils.d.ts +2 -2
  43. package/dist/utils/marginfiUtils.d.ts.map +1 -1
  44. package/dist/utils/marginfiUtils.js +5 -5
  45. package/dist/utils/priceUtils.d.ts +11 -5
  46. package/dist/utils/priceUtils.d.ts.map +1 -1
  47. package/dist/utils/priceUtils.js +45 -21
  48. package/local/logPositions.ts +12 -12
  49. package/local/shared.ts +1 -1
  50. package/local/txSandbox.ts +27 -32
  51. package/local/updateMarginfiLUT.ts +13 -6
  52. package/package.json +2 -1
  53. package/src/constants/marginfiAccounts.ts +0 -1
  54. package/src/constants/solautoConstants.ts +1 -1
  55. package/src/generated/instructions/marginfiRebalance.ts +9 -3
  56. package/src/generated/instructions/marginfiRefreshData.ts +27 -7
  57. package/src/generated/types/index.ts +1 -0
  58. package/src/generated/types/priceType.ts +22 -0
  59. package/src/services/rebalance/rebalanceSwapManager.ts +8 -12
  60. package/src/services/rebalance/rebalanceTxBuilder.ts +41 -11
  61. package/src/services/rebalance/rebalanceValues.ts +22 -16
  62. package/src/services/solauto/solautoClient.ts +30 -30
  63. package/src/services/solauto/solautoMarginfiClient.ts +13 -10
  64. package/src/services/transactions/transactionUtils.ts +11 -9
  65. package/src/solautoPosition/marginfiSolautoPositionEx.ts +11 -10
  66. package/src/solautoPosition/solautoPositionEx.ts +141 -117
  67. package/src/types/solauto.ts +2 -0
  68. package/src/utils/instructionUtils.ts +2 -2
  69. package/src/utils/marginfiUtils.ts +12 -8
  70. package/src/utils/priceUtils.ts +66 -22
  71. package/tests/transactions/shared.ts +2 -5
  72. package/tests/unit/rebalanceCalculations.ts +9 -12
package/local/shared.ts CHANGED
@@ -56,7 +56,7 @@ export async function createAndSendV0Tx(
56
56
  lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
57
57
  });
58
58
  if (confirmation.value.err) {
59
- throw new Error(confirmation.value.err.toString());
59
+ throw confirmation.value.err;
60
60
  }
61
61
  console.log(txid);
62
62
  }
@@ -3,21 +3,22 @@ import { createSignerFromKeypair } from "@metaplex-foundation/umi";
3
3
  import { fromWeb3JsKeypair } from "@metaplex-foundation/umi-web3js-adapters";
4
4
  import {
5
5
  consoleLog,
6
+ fetchTokenPrices,
6
7
  getClient,
7
8
  getSolanaRpcConnection,
8
9
  LendingPlatform,
9
10
  LOCAL_IRONFORGE_API_URL,
10
11
  PriorityFeeSetting,
11
- RebalanceTxBuilder,
12
+ rebalance,
12
13
  SOLAUTO_PROD_PROGRAM,
13
14
  SOLAUTO_TEST_PROGRAM,
14
- TransactionItem,
15
15
  TransactionsManager,
16
16
  } from "../src";
17
17
  import { getSecretKey } from "./shared";
18
+ import { NATIVE_MINT } from "@solana/spl-token";
18
19
 
19
20
  const payForTransaction = false;
20
- const testProgram = false;
21
+ const testProgram = true;
21
22
 
22
23
  export async function main() {
23
24
  const [, umi] = getSolanaRpcConnection(
@@ -30,40 +31,34 @@ export async function main() {
30
31
  fromWeb3JsKeypair(Keypair.fromSecretKey(getSecretKey("solauto-manager")))
31
32
  );
32
33
 
33
- const client = getClient(LendingPlatform.Marginfi, {
34
- signer,
35
- showLogs: true,
36
- rpcUrl: LOCAL_IRONFORGE_API_URL,
37
- programId: testProgram ? SOLAUTO_TEST_PROGRAM : SOLAUTO_PROD_PROGRAM,
38
- });
34
+ await fetchTokenPrices([NATIVE_MINT]);
39
35
 
40
- await client.initialize({
41
- positionId: 1,
42
- authority: new PublicKey("7ZN1w3ZE51FTXxdDjPPNpdZHuXWRvDK2h6osTHNXfsuL"),
43
- });
36
+ // const client = getClient(LendingPlatform.Marginfi, {
37
+ // signer,
38
+ // showLogs: true,
39
+ // rpcUrl: LOCAL_IRONFORGE_API_URL,
40
+ // programId: testProgram ? SOLAUTO_TEST_PROGRAM : SOLAUTO_PROD_PROGRAM,
41
+ // });
44
42
 
45
- const transactionItems: TransactionItem[] = [];
43
+ // await client.initialize({
44
+ // positionId: 3,
45
+ // authority: new PublicKey("5UqsR2PGzbP8pGPbXEeXx86Gjz2N2UFBAuFZUSVydAEe"),
46
+ // });
46
47
 
47
- transactionItems.push(
48
- new TransactionItem(
49
- async (attemptNum) =>
50
- await new RebalanceTxBuilder(client).buildRebalanceTx(attemptNum),
51
- "rebalance"
52
- )
53
- );
48
+ // const transactionItems = [rebalance(client)];
54
49
 
55
- const txManager = new TransactionsManager(
56
- client,
57
- undefined,
58
- payForTransaction ? "normal" : "only-simulate",
59
- PriorityFeeSetting.Min,
60
- true,
61
- undefined,
62
- { totalRetries: 5 }
63
- );
64
- const statuses = await txManager.clientSend(transactionItems);
50
+ // const txManager = new TransactionsManager(
51
+ // client,
52
+ // undefined,
53
+ // payForTransaction ? "normal" : "only-simulate",
54
+ // PriorityFeeSetting.Min,
55
+ // true,
56
+ // undefined,
57
+ // { totalRetries: 5 }
58
+ // );
59
+ // const statuses = await txManager.clientSend(transactionItems);
65
60
 
66
- consoleLog(statuses);
61
+ // consoleLog(statuses);
67
62
  }
68
63
 
69
64
  main();
@@ -17,19 +17,26 @@ import {
17
17
  LOCAL_IRONFORGE_API_URL,
18
18
  getMarginfiAccounts,
19
19
  getAllBankRelatedAccounts,
20
+ umiWithMarginfiProgram,
21
+ ProgramEnv,
20
22
  } from "../src";
21
23
  import { createAndSendV0Tx, getSecretKey, updateLookupTable } from "./shared";
22
24
 
23
- const mfiAccounts = getMarginfiAccounts("Prod");
25
+ const programEnv: ProgramEnv = "Prod";
26
+ const mfiAccounts = getMarginfiAccounts(programEnv);
24
27
 
25
28
  const LOOKUP_TABLE_ADDRESS = mfiAccounts.lookupTable;
26
29
  let [, umi] = getSolanaRpcConnection(LOCAL_IRONFORGE_API_URL);
27
- umi = umi.use(
28
- signerIdentity(
29
- createSignerFromKeypair(umi, umi.eddsa.generateKeypair()),
30
- true
31
- )
30
+ umi = umiWithMarginfiProgram(
31
+ umi.use(
32
+ signerIdentity(
33
+ createSignerFromKeypair(umi, umi.eddsa.generateKeypair()),
34
+ true
35
+ )
36
+ ),
37
+ programEnv
32
38
  );
39
+
33
40
  const solautoManagerKeypair = Keypair.fromSecretKey(
34
41
  getSecretKey("solauto-manager")
35
42
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haven-fi/solauto-sdk",
3
- "version": "1.0.628",
3
+ "version": "1.0.630",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "description": "Typescript SDK for the Solauto program on the Solana blockchain",
@@ -23,6 +23,7 @@
23
23
  "@switchboard-xyz/common": "=3.0.12",
24
24
  "@switchboard-xyz/on-demand": "=1.2.51",
25
25
  "axios": "^1.7.8",
26
+ "borsh": "^2.0.0",
26
27
  "bs58": "^5.0.0",
27
28
  "cross-fetch": "^4.0.0",
28
29
  "dotenv": "^16.4.7",
@@ -2,7 +2,6 @@ import { PublicKey } from "@solana/web3.js";
2
2
  import { NATIVE_MINT } from "@solana/spl-token";
3
3
  import * as tokens from "./tokenConstants";
4
4
  import { MarginfiAssetAccounts } from "../types/accounts";
5
- import { SWITCHBOARD_PRICE_FEED_IDS } from "./switchboardConstants";
6
5
  import { ProgramEnv } from "../types";
7
6
 
8
7
  const MARGINFI_PROD_PROGRAM = new PublicKey(
@@ -28,7 +28,7 @@ export const MIN_USD_SUPPORTED_POSITION = 1000;
28
28
 
29
29
  export const REFERRER_PERCENTAGE = 0.15;
30
30
 
31
- export const PRICES: { [key: string]: { price: number; time: number } } = {};
31
+ export const PRICES: { [key: string]: { realtimePrice: number; emaPrice: number; time: number } } = {};
32
32
 
33
33
  export const JITO_TIP_ACCOUNTS = [
34
34
  "96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5",
@@ -31,10 +31,13 @@ import {
31
31
  getAccountMetasAndSigners,
32
32
  } from '../shared';
33
33
  import {
34
+ PriceType,
35
+ PriceTypeArgs,
34
36
  SolautoRebalanceType,
35
37
  SolautoRebalanceTypeArgs,
36
38
  SwapType,
37
39
  SwapTypeArgs,
40
+ getPriceTypeSerializer,
38
41
  getSolautoRebalanceTypeSerializer,
39
42
  getSwapTypeSerializer,
40
43
  } from '../types';
@@ -72,17 +75,19 @@ export type MarginfiRebalanceInstructionAccounts = {
72
75
  export type MarginfiRebalanceInstructionData = {
73
76
  discriminator: number;
74
77
  rebalanceType: SolautoRebalanceType;
75
- targetLiqUtilizationRateBps: Option<number>;
76
78
  swapInAmountBaseUnit: Option<bigint>;
79
+ targetLiqUtilizationRateBps: Option<number>;
77
80
  flashLoanFeeBps: Option<number>;
81
+ priceType: Option<PriceType>;
78
82
  swapType: Option<SwapType>;
79
83
  };
80
84
 
81
85
  export type MarginfiRebalanceInstructionDataArgs = {
82
86
  rebalanceType: SolautoRebalanceTypeArgs;
83
- targetLiqUtilizationRateBps: OptionOrNullable<number>;
84
87
  swapInAmountBaseUnit: OptionOrNullable<number | bigint>;
88
+ targetLiqUtilizationRateBps: OptionOrNullable<number>;
85
89
  flashLoanFeeBps: OptionOrNullable<number>;
90
+ priceType: OptionOrNullable<PriceTypeArgs>;
86
91
  swapType: OptionOrNullable<SwapTypeArgs>;
87
92
  };
88
93
 
@@ -99,9 +104,10 @@ export function getMarginfiRebalanceInstructionDataSerializer(): Serializer<
99
104
  [
100
105
  ['discriminator', u8()],
101
106
  ['rebalanceType', getSolautoRebalanceTypeSerializer()],
102
- ['targetLiqUtilizationRateBps', option(u16())],
103
107
  ['swapInAmountBaseUnit', option(u64())],
108
+ ['targetLiqUtilizationRateBps', option(u16())],
104
109
  ['flashLoanFeeBps', option(u16())],
110
+ ['priceType', option(getPriceTypeSerializer())],
105
111
  ['swapType', option(getSwapTypeSerializer())],
106
112
  ],
107
113
  { description: 'MarginfiRebalanceInstructionData' }
@@ -25,6 +25,7 @@ import {
25
25
  ResolvedAccountsWithIndices,
26
26
  getAccountMetasAndSigners,
27
27
  } from '../shared';
28
+ import { PriceType, PriceTypeArgs, getPriceTypeSerializer } from '../types';
28
29
 
29
30
  // Accounts.
30
31
  export type MarginfiRefreshDataInstructionAccounts = {
@@ -40,9 +41,14 @@ export type MarginfiRefreshDataInstructionAccounts = {
40
41
  };
41
42
 
42
43
  // Data.
43
- export type MarginfiRefreshDataInstructionData = { discriminator: number };
44
+ export type MarginfiRefreshDataInstructionData = {
45
+ discriminator: number;
46
+ priceType: PriceType;
47
+ };
44
48
 
45
- export type MarginfiRefreshDataInstructionDataArgs = {};
49
+ export type MarginfiRefreshDataInstructionDataArgs = {
50
+ priceType: PriceTypeArgs;
51
+ };
46
52
 
47
53
  export function getMarginfiRefreshDataInstructionDataSerializer(): Serializer<
48
54
  MarginfiRefreshDataInstructionDataArgs,
@@ -53,9 +59,13 @@ export function getMarginfiRefreshDataInstructionDataSerializer(): Serializer<
53
59
  any,
54
60
  MarginfiRefreshDataInstructionData
55
61
  >(
56
- struct<MarginfiRefreshDataInstructionData>([['discriminator', u8()]], {
57
- description: 'MarginfiRefreshDataInstructionData',
58
- }),
62
+ struct<MarginfiRefreshDataInstructionData>(
63
+ [
64
+ ['discriminator', u8()],
65
+ ['priceType', getPriceTypeSerializer()],
66
+ ],
67
+ { description: 'MarginfiRefreshDataInstructionData' }
68
+ ),
59
69
  (value) => ({ ...value, discriminator: 7 })
60
70
  ) as Serializer<
61
71
  MarginfiRefreshDataInstructionDataArgs,
@@ -63,10 +73,15 @@ export function getMarginfiRefreshDataInstructionDataSerializer(): Serializer<
63
73
  >;
64
74
  }
65
75
 
76
+ // Args.
77
+ export type MarginfiRefreshDataInstructionArgs =
78
+ MarginfiRefreshDataInstructionDataArgs;
79
+
66
80
  // Instruction.
67
81
  export function marginfiRefreshData(
68
82
  context: Pick<Context, 'programs'>,
69
- input: MarginfiRefreshDataInstructionAccounts
83
+ input: MarginfiRefreshDataInstructionAccounts &
84
+ MarginfiRefreshDataInstructionArgs
70
85
  ): TransactionBuilder {
71
86
  // Program ID.
72
87
  const programId = context.programs.getPublicKey(
@@ -123,6 +138,9 @@ export function marginfiRefreshData(
123
138
  },
124
139
  } satisfies ResolvedAccountsWithIndices;
125
140
 
141
+ // Arguments.
142
+ const resolvedArgs: MarginfiRefreshDataInstructionArgs = { ...input };
143
+
126
144
  // Accounts in order.
127
145
  const orderedAccounts: ResolvedAccount[] = Object.values(
128
146
  resolvedAccounts
@@ -136,7 +154,9 @@ export function marginfiRefreshData(
136
154
  );
137
155
 
138
156
  // Data.
139
- const data = getMarginfiRefreshDataInstructionDataSerializer().serialize({});
157
+ const data = getMarginfiRefreshDataInstructionDataSerializer().serialize(
158
+ resolvedArgs as MarginfiRefreshDataInstructionDataArgs
159
+ );
140
160
 
141
161
  // Bytes Created On Chain.
142
162
  const bytesCreatedOnChain = 0;
@@ -16,6 +16,7 @@ export * from './positionData';
16
16
  export * from './positionState';
17
17
  export * from './positionTokenState';
18
18
  export * from './positionType';
19
+ export * from './priceType';
19
20
  export * from './rebalanceData';
20
21
  export * from './rebalanceDirection';
21
22
  export * from './rebalanceInstructionData';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * This code was AUTOGENERATED using the kinobi library.
3
+ * Please DO NOT EDIT THIS FILE, instead use visitors
4
+ * to add features, then rerun kinobi to update it.
5
+ *
6
+ * @see https://github.com/metaplex-foundation/kinobi
7
+ */
8
+
9
+ import { Serializer, scalarEnum } from '@metaplex-foundation/umi/serializers';
10
+
11
+ export enum PriceType {
12
+ Realtime,
13
+ Ema,
14
+ }
15
+
16
+ export type PriceTypeArgs = PriceType;
17
+
18
+ export function getPriceTypeSerializer(): Serializer<PriceTypeArgs, PriceType> {
19
+ return scalarEnum<PriceType>(PriceType, {
20
+ description: 'PriceType',
21
+ }) as Serializer<PriceTypeArgs, PriceType>;
22
+ }
@@ -9,7 +9,6 @@ import {
9
9
  consoleLog,
10
10
  fromBaseUnit,
11
11
  getLiqUtilzationRateBps,
12
- maxRepayToBps,
13
12
  safeGetPrice,
14
13
  toBaseUnit,
15
14
  tokenInfo,
@@ -46,8 +45,8 @@ export class RebalanceSwapManager {
46
45
 
47
46
  const outputToken = toWeb3JsPublicKey(
48
47
  this.isBoost()
49
- ? this.client.pos.state().supply.mint
50
- : this.client.pos.state().debt.mint
48
+ ? this.client.pos.state.supply.mint
49
+ : this.client.pos.state.debt.mint
51
50
  );
52
51
  const swapOutputUsd = swapOutputAmount
53
52
  ? fromBaseUnit(swapOutputAmount, tokenInfo(outputToken).decimals) *
@@ -64,7 +63,7 @@ export class RebalanceSwapManager {
64
63
  return getLiqUtilzationRateBps(
65
64
  supplyUsd,
66
65
  debtUsd,
67
- this.client.pos.state().liqThresholdBps ?? 0
66
+ this.client.pos.state.liqThresholdBps ?? 0
68
67
  );
69
68
  }
70
69
 
@@ -106,11 +105,11 @@ export class RebalanceSwapManager {
106
105
 
107
106
  private swapDetails() {
108
107
  const input = this.isBoost()
109
- ? this.client.pos.state().debt
110
- : this.client.pos.state().supply;
108
+ ? this.client.pos.state.debt
109
+ : this.client.pos.state.supply;
111
110
  const output = this.isBoost()
112
- ? this.client.pos.state().supply
113
- : this.client.pos.state().debt;
111
+ ? this.client.pos.state.supply
112
+ : this.client.pos.state.debt;
114
113
 
115
114
  let inputAmount = toBaseUnit(
116
115
  this.usdToSwap() / safeGetPrice(input.mint)!,
@@ -185,10 +184,7 @@ export class RebalanceSwapManager {
185
184
  this.swapQuote = await this.findSufficientQuote(swapInput, {
186
185
  minOutputAmount: rebalanceToZero ? outputAmount : undefined,
187
186
  maxLiqUtilizationRateBps: this.values.repayingCloseToMaxLtv
188
- ? maxRepayToBps(
189
- this.client.pos.state().maxLtvBps ?? 0,
190
- this.client.pos.state().liqThresholdBps ?? 0
191
- ) - 15
187
+ ? this.client.pos.maxRepayToBps - 15
192
188
  : undefined,
193
189
  });
194
190
  }
@@ -10,6 +10,7 @@ import {
10
10
  import {
11
11
  consoleLog,
12
12
  fromBaseUnit,
13
+ getLiqUtilzationRateBps,
13
14
  getMaxLiqUtilizationRateBps,
14
15
  getTokenAccount,
15
16
  hasFirstRebalance,
@@ -19,6 +20,7 @@ import {
19
20
  } from "../../utils";
20
21
  import {
21
22
  PositionTokenState,
23
+ PriceType,
22
24
  RebalanceDirection,
23
25
  RebalanceStep,
24
26
  SolautoRebalanceType,
@@ -35,6 +37,7 @@ export class RebalanceTxBuilder {
35
37
  private rebalanceType!: SolautoRebalanceType;
36
38
  private swapManager!: RebalanceSwapManager;
37
39
  private flRequirements?: FlashLoanRequirements;
40
+ private priceType!: PriceType;
38
41
 
39
42
  constructor(
40
43
  private client: SolautoClient,
@@ -49,14 +52,15 @@ export class RebalanceTxBuilder {
49
52
  );
50
53
  }
51
54
 
52
- private getRebalanceValues(flFee?: number) {
55
+ private getRebalanceValues(priceType: PriceType, flFee?: number) {
53
56
  return getRebalanceValues(
54
57
  this.client.pos,
58
+ priceType,
55
59
  this.targetLiqUtilizationRateBps,
56
60
  SolautoFeesBps.create(
57
61
  this.client.isReferred(),
58
62
  this.targetLiqUtilizationRateBps,
59
- this.client.pos.netWorthUsd()
63
+ this.client.pos.netWorthUsd
60
64
  ),
61
65
  flFee ?? 0
62
66
  );
@@ -84,12 +88,12 @@ export class RebalanceTxBuilder {
84
88
  const insufficientSupplyLiquidity = insufficientLiquidity(
85
89
  debtAdjustmentUsd,
86
90
  supplyLiquidityAvailable,
87
- this.client.pos.supplyMint()
91
+ this.client.pos.supplyMint
88
92
  );
89
93
  const insufficientDebtLiquidity = insufficientLiquidity(
90
94
  debtAdjustmentUsd,
91
95
  debtLiquidityAvailable,
92
- this.client.pos.debtMint()
96
+ this.client.pos.debtMint
93
97
  );
94
98
 
95
99
  let useDebtLiquidity =
@@ -107,8 +111,8 @@ export class RebalanceTxBuilder {
107
111
  attemptNum: number
108
112
  ): Promise<FlashLoanRequirements | undefined> {
109
113
  const maxLtvRateBps = getMaxLiqUtilizationRateBps(
110
- this.client.pos.state().maxLtvBps,
111
- this.client.pos.state().liqThresholdBps,
114
+ this.client.pos.state.maxLtvBps,
115
+ this.client.pos.state.liqThresholdBps,
112
116
  0.02
113
117
  );
114
118
 
@@ -156,9 +160,9 @@ export class RebalanceTxBuilder {
156
160
 
157
161
  let flashLoanToken: PositionTokenState | undefined = undefined;
158
162
  if (boosting || useDebtLiquidity) {
159
- flashLoanToken = this.client.pos.state().debt;
163
+ flashLoanToken = this.client.pos.state.debt;
160
164
  } else {
161
- flashLoanToken = this.client.pos.state().supply;
165
+ flashLoanToken = this.client.pos.state.supply;
162
166
  }
163
167
 
164
168
  return {
@@ -199,8 +203,33 @@ export class RebalanceTxBuilder {
199
203
  }
200
204
  }
201
205
 
206
+ private realtimeUsdToEmaUsd(realtimeAmountUsd: number, mint: PublicKey) {
207
+ return (
208
+ (realtimeAmountUsd / safeGetPrice(mint, PriceType.Realtime)!) *
209
+ safeGetPrice(mint, PriceType.Ema)!
210
+ );
211
+ }
212
+
202
213
  private async setRebalanceDetails(attemptNum: number) {
203
- this.values = this.getRebalanceValues();
214
+ this.priceType = PriceType.Realtime;
215
+ this.values = this.getRebalanceValues(this.priceType);
216
+
217
+ const postRebalanceEmaUtilRateBps = getLiqUtilzationRateBps(
218
+ this.realtimeUsdToEmaUsd(
219
+ this.values.endResult.supplyUsd,
220
+ this.client.pos.supplyMint
221
+ ),
222
+ this.realtimeUsdToEmaUsd(
223
+ this.values.endResult.debtUsd,
224
+ this.client.pos.debtMint
225
+ ),
226
+ this.client.pos.state.liqThresholdBps
227
+ );
228
+ if (postRebalanceEmaUtilRateBps > this.client.pos.maxBoostToBps) {
229
+ this.priceType = PriceType.Ema;
230
+ this.values = this.getRebalanceValues(this.priceType);
231
+ }
232
+
204
233
  this.flRequirements = await this.flashLoanRequirements(attemptNum);
205
234
 
206
235
  if (this.flRequirements?.flFeeBps) {
@@ -223,7 +252,7 @@ export class RebalanceTxBuilder {
223
252
  this.client.selfManaged ||
224
253
  this.client.contextUpdates.supplyAdjustment > BigInt(0) ||
225
254
  this.client.contextUpdates.debtAdjustment > BigInt(0) ||
226
- !this.client.pos.exists()
255
+ !this.client.pos.exists
227
256
  ) {
228
257
  return false;
229
258
  }
@@ -254,7 +283,7 @@ export class RebalanceTxBuilder {
254
283
  let tx = transactionBuilder();
255
284
 
256
285
  if (await this.refreshBeforeRebalance()) {
257
- tx = tx.add(this.client.refreshIx());
286
+ tx = tx.add(this.client.refreshIx(this.priceType));
258
287
  }
259
288
 
260
289
  const rebalanceDetails: RebalanceDetails = {
@@ -263,6 +292,7 @@ export class RebalanceTxBuilder {
263
292
  flashLoan: flashLoanDetails,
264
293
  swapQuote,
265
294
  targetLiqUtilizationRateBps: this.targetLiqUtilizationRateBps,
295
+ priceType: this.priceType,
266
296
  };
267
297
  consoleLog("Rebalance details:", rebalanceDetails);
268
298
 
@@ -1,4 +1,5 @@
1
1
  import {
2
+ PriceType,
2
3
  RebalanceDirection,
3
4
  TokenBalanceChange,
4
5
  TokenBalanceChangeType,
@@ -117,6 +118,7 @@ function getTokenBalanceChange(): TokenBalanceChange | undefined {
117
118
 
118
119
  function getTargetLiqUtilizationRateBps(
119
120
  solautoPosition: SolautoPositionEx,
121
+ priceType: PriceType,
120
122
  targetLiqUtilizationRateBps: number | undefined,
121
123
  tokenBalanceChange: TokenBalanceChange | undefined
122
124
  ): number {
@@ -124,12 +126,16 @@ function getTargetLiqUtilizationRateBps(
124
126
  return targetLiqUtilizationRateBps;
125
127
  }
126
128
 
127
- const currentRate = solautoPosition.state().liqUtilizationRateBps;
128
-
129
- if (currentRate <= solautoPosition.boostFromBps()) {
130
- return solautoPosition.settings()!.boostToBps;
131
- } else if (currentRate >= solautoPosition.repayFromBps()) {
132
- return solautoPosition.settings()!.repayToBps;
129
+ if (
130
+ solautoPosition.liqUtilizationRateBps(PriceType.Realtime) >=
131
+ solautoPosition.repayFromBps
132
+ ) {
133
+ return solautoPosition.settings!.repayToBps;
134
+ } else if (
135
+ solautoPosition.liqUtilizationRateBps(priceType) <=
136
+ solautoPosition.boostFromBps
137
+ ) {
138
+ return solautoPosition.settings!.boostToBps;
133
139
  }
134
140
  // TODO: DCA, limit orders, take profit, stop loss, etc.
135
141
  // else if (tokenBalanceChange !== null) {
@@ -141,10 +147,11 @@ function getTargetLiqUtilizationRateBps(
141
147
 
142
148
  function getAdjustedPositionValues(
143
149
  solautoPosition: SolautoPositionEx,
150
+ priceType: PriceType,
144
151
  tokenBalanceChange: TokenBalanceChange | undefined
145
152
  ): PositionValues {
146
- let supplyUsd = solautoPosition.supplyUsd();
147
- const debtUsd = solautoPosition.debtUsd();
153
+ let supplyUsd = solautoPosition.supplyUsd(priceType);
154
+ const debtUsd = solautoPosition.debtUsd(priceType);
148
155
 
149
156
  if (tokenBalanceChange) {
150
157
  const tb = tokenBalanceChange;
@@ -172,7 +179,7 @@ function getRebalanceDirection(
172
179
  solautoPosition: SolautoPositionEx,
173
180
  targetLtvBps: number
174
181
  ): RebalanceDirection {
175
- return solautoPosition.state().liqUtilizationRateBps < targetLtvBps
182
+ return solautoPosition.state.liqUtilizationRateBps < targetLtvBps
176
183
  ? RebalanceDirection.Boost
177
184
  : RebalanceDirection.Repay;
178
185
  }
@@ -185,6 +192,7 @@ export interface RebalanceValues extends DebtAdjustment {
185
192
 
186
193
  export function getRebalanceValues(
187
194
  solautoPosition: SolautoPositionEx,
195
+ priceType: PriceType,
188
196
  targetLiqUtilizationRateBps?: number,
189
197
  solautoFeeBps?: SolautoFeesBps,
190
198
  flFeeBps?: number
@@ -193,6 +201,7 @@ export function getRebalanceValues(
193
201
 
194
202
  const targetRate = getTargetLiqUtilizationRateBps(
195
203
  solautoPosition,
204
+ priceType,
196
205
  targetLiqUtilizationRateBps,
197
206
  tokenBalanceChange
198
207
  );
@@ -201,6 +210,7 @@ export function getRebalanceValues(
201
210
 
202
211
  const position = getAdjustedPositionValues(
203
212
  solautoPosition,
213
+ priceType,
204
214
  tokenBalanceChange
205
215
  );
206
216
 
@@ -208,12 +218,12 @@ export function getRebalanceValues(
208
218
  solauto: solautoFeeBps
209
219
  ? solautoFeeBps.getSolautoFeesBps(rebalanceDirection).total
210
220
  : 0,
211
- lpBorrow: solautoPosition.state().debt.borrowFeeBps,
221
+ lpBorrow: solautoPosition.state.debt.borrowFeeBps,
212
222
  flashLoan: flFeeBps ?? 0,
213
223
  };
214
224
 
215
225
  const debtAdjustment = getDebtAdjustment(
216
- solautoPosition.state().liqThresholdBps,
226
+ solautoPosition.state.liqThresholdBps,
217
227
  position,
218
228
  targetRate,
219
229
  fees
@@ -221,11 +231,7 @@ export function getRebalanceValues(
221
231
 
222
232
  const repayingCloseToMaxLtv =
223
233
  rebalanceDirection === RebalanceDirection.Repay &&
224
- targetRate >=
225
- maxRepayToBps(
226
- solautoPosition.state().maxLtvBps,
227
- solautoPosition.state().liqThresholdBps
228
- );
234
+ targetRate >= solautoPosition.maxRepayToBps;
229
235
 
230
236
  return {
231
237
  ...debtAdjustment,