@haven-fi/solauto-sdk 1.0.529 → 1.0.531

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.
@@ -1 +1 @@
1
- {"version":3,"file":"rebalanceUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/solauto/rebalanceUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EACL,WAAW,EACX,aAAa,EAEb,kBAAkB,EAClB,yBAAyB,EACzB,SAAS,EACV,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAe,cAAc,EAAgB,MAAM,iBAAiB,CAAC;AAc5E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAqI9C,MAAM,WAAW,eAAe;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,yBAAyB,GAAG,SAAS,EAC/C,GAAG,EAAE,WAAW,GAAG,SAAS,EAC5B,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,2BAA2B,CAAC,EAAE,MAAM,GACnC,eAAe,CA4EjB;AAWD,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAkG5C;AAED,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC7D,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,cAAc,EAAE,qBAAqB,EACrC,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,aAAa,GACtB,gBAAgB,GAAG,SAAS,CA2B9B;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,cAAc,CAAC,EAAE,qBAAqB,EACtC,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,cAAc,CAAC,CAsEzB"}
1
+ {"version":3,"file":"rebalanceUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/solauto/rebalanceUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EACL,WAAW,EACX,aAAa,EAEb,kBAAkB,EAClB,yBAAyB,EACzB,SAAS,EACV,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAe,cAAc,EAAgB,MAAM,iBAAiB,CAAC;AAc5E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAqI9C,MAAM,WAAW,eAAe;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,yBAAyB,GAAG,SAAS,EAC/C,GAAG,EAAE,WAAW,GAAG,SAAS,EAC5B,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,2BAA2B,CAAC,EAAE,MAAM,GACnC,eAAe,CA4EjB;AAoDD,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAkG5C;AAED,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC7D,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,cAAc,EAAE,qBAAqB,EACrC,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,aAAa,GACtB,gBAAgB,GAAG,SAAS,CA2B9B;AA4CD,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,cAAc,CAAC,EAAE,qBAAqB,EACtC,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,cAAc,CAAC,CA2EzB"}
@@ -125,6 +125,25 @@ function getRebalanceValues(state, settings, dca, currentUnixTime, supplyPrice,
125
125
  targetRateBps,
126
126
  };
127
127
  }
128
+ function postRebalanceLiqUtilizationRateBps(client, values, swapOutputAmount) {
129
+ let supplyUsd = (0, numberUtils_1.fromBaseUnit)(client.solautoPositionState.supply.amountUsed.baseAmountUsdValue, generalAccounts_1.USD_DECIMALS) +
130
+ (values.dcaTokenType === generated_1.TokenType.Supply ? values.amountUsdToDcaIn : 0);
131
+ let debtUsd = (0, numberUtils_1.fromBaseUnit)(client.solautoPositionState.debt.amountUsed.baseAmountUsdValue, generalAccounts_1.USD_DECIMALS);
132
+ const boost = values.rebalanceDirection === generated_1.RebalanceDirection.Boost;
133
+ const outputToken = (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(boost
134
+ ? client.solautoPositionState.supply.mint
135
+ : client.solautoPositionState.debt.mint);
136
+ const debtAdjustmentUsdAbs = Math.abs(values.debtAdjustmentUsd);
137
+ const swapOutputUsd = swapOutputAmount
138
+ ? (0, numberUtils_1.fromBaseUnit)(swapOutputAmount, (0, generalUtils_2.tokenInfo)(outputToken).decimals) *
139
+ ((0, priceUtils_1.safeGetPrice)(outputToken) ?? 0)
140
+ : debtAdjustmentUsdAbs;
141
+ supplyUsd = boost
142
+ ? supplyUsd + swapOutputUsd
143
+ : supplyUsd - debtAdjustmentUsdAbs;
144
+ debtUsd = boost ? debtUsd + debtAdjustmentUsdAbs : debtUsd - swapOutputUsd;
145
+ return (0, numberUtils_1.getLiqUtilzationRateBps)(supplyUsd, debtUsd, client.solautoPositionState?.liqThresholdBps ?? 0);
146
+ }
128
147
  function insufficientLiquidity(amountNeeded, liquidity, tokenDecimals, tokenPrice) {
129
148
  return amountNeeded > (0, numberUtils_1.fromBaseUnit)(liquidity, tokenDecimals) * tokenPrice;
130
149
  }
@@ -152,7 +171,7 @@ async function getFlashLoanRequirements(client, values, attemptNum) {
152
171
  let useDebtLiquidity = values.rebalanceDirection === generated_1.RebalanceDirection.Boost ||
153
172
  insufficientSupplyLiquidity;
154
173
  let signerFlashLoan = false;
155
- if ((attemptNum ?? 0) > 3 ||
174
+ if ((attemptNum ?? 0) >= 3 ||
156
175
  (insufficientSupplyLiquidity && insufficientDebtLiquidity)) {
157
176
  const { supplyBalance, debtBalance } = await client.signerBalances();
158
177
  const sufficientSignerSupplyLiquidity = !insufficientLiquidity(debtAdjustmentUsd, supplyBalance, (0, generalUtils_2.tokenInfo)(client.supplyMint).decimals, supplyPrice);
@@ -194,6 +213,31 @@ function getFlashLoanDetails(client, flRequirements, values, jupQuote) {
194
213
  mint: (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(flashLoanToken.mint),
195
214
  };
196
215
  }
216
+ async function findSufficientQuote(client, values, jupSwapInput, criteria) {
217
+ let jupQuote;
218
+ let insufficient = false;
219
+ for (let i = 0; i < 10; i++) {
220
+ (0, generalUtils_2.consoleLog)("Finding sufficient quote...");
221
+ jupQuote = await (0, jupiterUtils_1.getJupQuote)(jupSwapInput);
222
+ const outputAmount = parseInt(jupQuote.outAmount);
223
+ const postRebalanceRate = postRebalanceLiqUtilizationRateBps(client, values, BigInt(outputAmount));
224
+ insufficient = criteria.minOutputAmount
225
+ ? outputAmount < Number(criteria.minOutputAmount)
226
+ : criteria.minLiqUtilizationRateBps
227
+ ? postRebalanceRate < criteria.minLiqUtilizationRateBps
228
+ : postRebalanceRate > criteria.maxLiqUtilizationRateBps;
229
+ if (insufficient) {
230
+ (0, generalUtils_2.consoleLog)(jupQuote);
231
+ jupSwapInput.amount =
232
+ jupSwapInput.amount +
233
+ BigInt(Math.round(Number(jupSwapInput.amount) * 0.01));
234
+ }
235
+ else {
236
+ break;
237
+ }
238
+ }
239
+ return jupQuote;
240
+ }
197
241
  async function getJupSwapRebalanceDetails(client, values, flRequirements, targetLiqUtilizationRateBps, attemptNum) {
198
242
  const input = values.rebalanceDirection === generated_1.RebalanceDirection.Boost
199
243
  ? client.solautoPositionState.debt
@@ -216,6 +260,9 @@ async function getJupSwapRebalanceDetails(client, values, flRequirements, target
216
260
  const exactOut = flashLoanRepayFromDebt && !rebalanceToZero;
217
261
  // || rebalanceToZero
218
262
  const exactIn = !exactOut;
263
+ if (exactIn && rebalanceToZero) {
264
+ inputAmount = inputAmount + BigInt(Math.round(Number(inputAmount) * 0.005));
265
+ }
219
266
  const jupSwapInput = {
220
267
  inputMint: (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(input.mint),
221
268
  outputMint: (0, umi_web3js_adapters_1.toWeb3JsPublicKey)(output.mint),
@@ -225,15 +272,14 @@ async function getJupSwapRebalanceDetails(client, values, flRequirements, target
225
272
  };
226
273
  (0, generalUtils_2.consoleLog)(jupSwapInput);
227
274
  let jupQuote = undefined;
228
- if (rebalanceToZero) {
229
- do {
230
- jupSwapInput.amount =
231
- jupSwapInput.amount +
232
- BigInt(Math.round(Number(jupSwapInput.amount) * 0.01));
233
- jupQuote = await (0, jupiterUtils_1.getJupQuote)(jupSwapInput);
234
- } while (parseInt(jupQuote.outAmount) < outputAmount);
275
+ if (exactIn && (rebalanceToZero || values.repayingCloseToMaxLtv)) {
276
+ jupQuote = await findSufficientQuote(client, values, jupSwapInput, {
277
+ minOutputAmount: rebalanceToZero ? outputAmount : undefined,
278
+ maxLiqUtilizationRateBps: values.repayingCloseToMaxLtv
279
+ ? (0, numberUtils_1.maxRepayToBps)(client.solautoPositionState?.maxLtvBps ?? 0, client.solautoPositionState?.liqThresholdBps ?? 0) - 15
280
+ : undefined,
281
+ });
235
282
  }
236
- (0, generalUtils_2.consoleLog)("Quote:", jupQuote);
237
283
  const addPadding = exactOut;
238
284
  return {
239
285
  ...jupSwapInput,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haven-fi/solauto-sdk",
3
- "version": "1.0.529",
3
+ "version": "1.0.531",
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",
@@ -260,6 +260,47 @@ export function getRebalanceValues(
260
260
  };
261
261
  }
262
262
 
263
+ function postRebalanceLiqUtilizationRateBps(
264
+ client: SolautoClient,
265
+ values: RebalanceValues,
266
+ swapOutputAmount?: bigint
267
+ ) {
268
+ let supplyUsd =
269
+ fromBaseUnit(
270
+ client.solautoPositionState!.supply.amountUsed.baseAmountUsdValue,
271
+ USD_DECIMALS
272
+ ) +
273
+ (values.dcaTokenType === TokenType.Supply ? values.amountUsdToDcaIn : 0);
274
+ let debtUsd = fromBaseUnit(
275
+ client.solautoPositionState!.debt.amountUsed.baseAmountUsdValue,
276
+ USD_DECIMALS
277
+ );
278
+
279
+ const boost = values.rebalanceDirection === RebalanceDirection.Boost;
280
+
281
+ const outputToken = toWeb3JsPublicKey(
282
+ boost
283
+ ? client.solautoPositionState!.supply.mint
284
+ : client.solautoPositionState!.debt.mint
285
+ );
286
+ const debtAdjustmentUsdAbs = Math.abs(values.debtAdjustmentUsd);
287
+ const swapOutputUsd = swapOutputAmount
288
+ ? fromBaseUnit(swapOutputAmount, tokenInfo(outputToken).decimals) *
289
+ (safeGetPrice(outputToken) ?? 0)
290
+ : debtAdjustmentUsdAbs;
291
+
292
+ supplyUsd = boost
293
+ ? supplyUsd + swapOutputUsd
294
+ : supplyUsd - debtAdjustmentUsdAbs;
295
+ debtUsd = boost ? debtUsd + debtAdjustmentUsdAbs : debtUsd - swapOutputUsd;
296
+
297
+ return getLiqUtilzationRateBps(
298
+ supplyUsd,
299
+ debtUsd,
300
+ client.solautoPositionState?.liqThresholdBps ?? 0
301
+ );
302
+ }
303
+
263
304
  function insufficientLiquidity(
264
305
  amountNeeded: number,
265
306
  liquidity: bigint,
@@ -336,7 +377,7 @@ export async function getFlashLoanRequirements(
336
377
 
337
378
  let signerFlashLoan = false;
338
379
  if (
339
- (attemptNum ?? 0) > 3 ||
380
+ (attemptNum ?? 0) >= 3 ||
340
381
  (insufficientSupplyLiquidity && insufficientDebtLiquidity)
341
382
  ) {
342
383
  const { supplyBalance, debtBalance } = await client.signerBalances();
@@ -417,6 +458,48 @@ export function getFlashLoanDetails(
417
458
  };
418
459
  }
419
460
 
461
+ async function findSufficientQuote(
462
+ client: SolautoClient,
463
+ values: RebalanceValues,
464
+ jupSwapInput: JupSwapInput,
465
+ criteria: {
466
+ minOutputAmount?: bigint;
467
+ minLiqUtilizationRateBps?: number;
468
+ maxLiqUtilizationRateBps?: number;
469
+ }
470
+ ): Promise<QuoteResponse> {
471
+ let jupQuote: QuoteResponse;
472
+ let insufficient: boolean = false;
473
+
474
+ for (let i = 0; i < 10; i++) {
475
+ consoleLog("Finding sufficient quote...");
476
+ jupQuote = await getJupQuote(jupSwapInput);
477
+
478
+ const outputAmount = parseInt(jupQuote.outAmount);
479
+ const postRebalanceRate = postRebalanceLiqUtilizationRateBps(
480
+ client,
481
+ values,
482
+ BigInt(outputAmount)
483
+ );
484
+ insufficient = criteria.minOutputAmount
485
+ ? outputAmount < Number(criteria.minOutputAmount)
486
+ : criteria.minLiqUtilizationRateBps
487
+ ? postRebalanceRate < criteria.minLiqUtilizationRateBps
488
+ : postRebalanceRate > criteria.maxLiqUtilizationRateBps!;
489
+
490
+ if (insufficient) {
491
+ consoleLog(jupQuote);
492
+ jupSwapInput.amount =
493
+ jupSwapInput.amount +
494
+ BigInt(Math.round(Number(jupSwapInput.amount) * 0.01));
495
+ } else {
496
+ break;
497
+ }
498
+ }
499
+
500
+ return jupQuote!;
501
+ }
502
+
420
503
  export async function getJupSwapRebalanceDetails(
421
504
  client: SolautoClient,
422
505
  values: RebalanceValues,
@@ -462,6 +545,9 @@ export async function getJupSwapRebalanceDetails(
462
545
  // || rebalanceToZero
463
546
  const exactIn = !exactOut;
464
547
 
548
+ if (exactIn && rebalanceToZero) {
549
+ inputAmount = inputAmount + BigInt(Math.round(Number(inputAmount) * 0.005));
550
+ }
465
551
  const jupSwapInput: JupSwapInput = {
466
552
  inputMint: toWeb3JsPublicKey(input.mint),
467
553
  outputMint: toWeb3JsPublicKey(output.mint),
@@ -472,15 +558,17 @@ export async function getJupSwapRebalanceDetails(
472
558
  consoleLog(jupSwapInput);
473
559
 
474
560
  let jupQuote: QuoteResponse | undefined = undefined;
475
- if (rebalanceToZero) {
476
- do {
477
- jupSwapInput.amount =
478
- jupSwapInput.amount +
479
- BigInt(Math.round(Number(jupSwapInput.amount) * 0.01));
480
- jupQuote = await getJupQuote(jupSwapInput);
481
- } while (parseInt(jupQuote.outAmount) < outputAmount);
561
+ if (exactIn && (rebalanceToZero || values.repayingCloseToMaxLtv)) {
562
+ jupQuote = await findSufficientQuote(client, values, jupSwapInput, {
563
+ minOutputAmount: rebalanceToZero ? outputAmount : undefined,
564
+ maxLiqUtilizationRateBps: values.repayingCloseToMaxLtv
565
+ ? maxRepayToBps(
566
+ client.solautoPositionState?.maxLtvBps ?? 0,
567
+ client.solautoPositionState?.liqThresholdBps ?? 0
568
+ ) - 15
569
+ : undefined,
570
+ });
482
571
  }
483
- consoleLog("Quote:", jupQuote);
484
572
 
485
573
  const addPadding = exactOut;
486
574