@haven-fi/solauto-sdk 1.0.68 → 1.0.70

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":"transactionUtils.d.ts","sourceRoot":"","sources":["../../src/transactions/transactionUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,kBAAkB,EAClB,GAAG,EAGJ,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAGL,OAAO,IAAI,eAAe,EAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAGL,aAAa,EASd,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAuMzD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,kBAAkB,EACtB,sBAAsB,EAAE,MAAM,EAAE,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CA8G7B;AAkLD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,kBAAkB,GACrB,OAAO,CAAC,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC,CA4BnD;AAED,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,aAAa,EACrB,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CACN;IACE,EAAE,EAAE,kBAAkB,CAAC;IACvB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC,GACD,SAAS,CACZ,CA0HA;AAED,wBAAsB,gCAAgC,CACpD,GAAG,EAAE,GAAG,EACR,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,eAAe,GAC5B,OAAO,CAAC,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAC,CAAC,CA8BzC"}
1
+ {"version":3,"file":"transactionUtils.d.ts","sourceRoot":"","sources":["../../src/transactions/transactionUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kBAAkB,EAClB,GAAG,EAGJ,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAGL,OAAO,IAAI,eAAe,EAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEL,aAAa,EASd,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAuMzD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,kBAAkB,EACtB,sBAAsB,EAAE,MAAM,EAAE,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CA8G7B;AAkLD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,EAAE,EAAE,kBAAkB,GACrB,OAAO,CAAC,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC,CA4BnD;AAED,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,aAAa,EACrB,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CACN;IACE,EAAE,EAAE,kBAAkB,CAAC;IACvB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC,GACD,SAAS,CACZ,CA2HA;AAED,wBAAsB,gCAAgC,CACpD,GAAG,EAAE,GAAG,EACR,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,eAAe,GAC5B,OAAO,CAAC,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAC,CAAC,CA8BzC"}
@@ -329,7 +329,7 @@ async function buildSolautoRebalanceTransaction(client, targetLiqUtilizationRate
329
329
  client.log("Not eligible for a rebalance");
330
330
  return undefined;
331
331
  }
332
- const values = (0, rebalanceUtils_1.getRebalanceValues)(client.solautoPositionState, client.solautoPositionSettings(), client.solautoPositionActiveDca(), client.solautoPositionData?.feeType ?? generated_1.FeeType.Small, (0, generalUtils_1.currentUnixSeconds)(), constants_1.PRICES[client.supplyMint.toString()].price, constants_1.PRICES[client.debtMint.toString()].price, targetLiqUtilizationRateBps);
332
+ const values = (0, rebalanceUtils_1.getRebalanceValues)(client.solautoPositionState, client.solautoPositionSettings(), client.solautoPositionActiveDca(), client.solautoPositionData.feeType, (0, generalUtils_1.currentUnixSeconds)(), constants_1.PRICES[client.supplyMint.toString()].price, constants_1.PRICES[client.debtMint.toString()].price, targetLiqUtilizationRateBps);
333
333
  client.log("Rebalance values: ", values);
334
334
  const swapDetails = (0, rebalanceUtils_1.getJupSwapRebalanceDetails)(client, values, targetLiqUtilizationRateBps, attemptNum);
335
335
  const { jupQuote, lookupTableAddresses, setupInstructions, tokenLedgerIx, swapIx, } = await (0, jupiterUtils_1.getJupSwapTransaction)(client.signer, swapDetails, attemptNum);
@@ -366,7 +366,7 @@ async function buildSolautoRebalanceTransaction(client, targetLiqUtilizationRate
366
366
  ]);
367
367
  }
368
368
  if (client.solautoPositionState.liqUtilizationRateBps >
369
- (0, numberUtils_1.getMaxLiqUtilizationRateBps)(client.solautoPositionState.maxLtvBps, client.solautoPositionState.liqThresholdBps)) {
369
+ (0, numberUtils_1.getMaxLiqUtilizationRateBps)(client.solautoPositionState.maxLtvBps, client.solautoPositionState.liqThresholdBps, 0.01)) {
370
370
  tx = tx.prepend(client.refresh());
371
371
  }
372
372
  return {
@@ -1,3 +1,4 @@
1
+ import { FeeType } from "../generated";
1
2
  export declare function getLiqUtilzationRateBps(supplyUsd: number, debtUsd: number, liqThresholdBps: number): number;
2
3
  export declare function toBaseUnit(value: number, decimals: number): bigint;
3
4
  export declare function fromBaseUnit(value: bigint, decimals: number): number;
@@ -6,7 +7,13 @@ export declare function toBps(value: number): number;
6
7
  export declare function bytesToI80F48(bytes: number[]): number;
7
8
  export declare function uint8ArrayToBigInt(uint8Array: Uint8Array): bigint;
8
9
  export declare function getDebtAdjustmentUsd(liqThresholdBps: number, supplyUsd: number, debtUsd: number, targetLiqUtilizationRateBps: number, adjustmentFeeBps?: number): number;
9
- export declare function getMaxLiqUtilizationRateBps(maxLtvBps: number, liqThresholdBps: number): number;
10
+ export declare function getSolautoFeesBps(isReferred: boolean, feeType: FeeType, positionNetWorthUsd: number): {
11
+ solauto: number;
12
+ referrer: number;
13
+ total: number;
14
+ };
15
+ export declare function getMaxLiqUtilizationRateBps(maxLtvBps: number, liqThresholdBps: number, offsetFromMaxLtv: number): number;
16
+ export declare function maxBoostToBps(maxLtvBps: number, liqThresholdBps: number): number;
10
17
  export declare function maxRepayFromBps(maxLtvBps: number, liqThresholdBps: number): number;
11
18
  export declare function maxRepayToBps(maxLtvBps: number, liqThresholdBps: number): number;
12
19
  //# sourceMappingURL=numberUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"numberUtils.d.ts","sourceRoot":"","sources":["../../src/utils/numberUtils.ts"],"names":[],"mappings":"AAEA,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,CAM3G;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhE;AAEH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAqBrD;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAajE;AAED,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,2BAA2B,EAAE,MAAM,EACnC,gBAAgB,CAAC,EAAE,MAAM,UAQ1B;AAED,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,GACtB,MAAM,CAER;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,UAKzE;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,UAKvE"}
1
+ {"version":3,"file":"numberUtils.d.ts","sourceRoot":"","sources":["../../src/utils/numberUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,GACtB,MAAM,CAMR;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAqBrD;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAejE;AAED,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,2BAA2B,EAAE,MAAM,EACnC,gBAAgB,CAAC,EAAE,MAAM,UAW1B;AAED,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE,OAAO,EAChB,mBAAmB,EAAE,MAAM,GAC1B;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf,CA8BA;AAED,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,gBAAgB,EAAE,MAAM,GACvB,MAAM,CAER;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,UAEvE;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,UAKzE;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,UAKvE"}
@@ -8,10 +8,13 @@ exports.toBps = toBps;
8
8
  exports.bytesToI80F48 = bytesToI80F48;
9
9
  exports.uint8ArrayToBigInt = uint8ArrayToBigInt;
10
10
  exports.getDebtAdjustmentUsd = getDebtAdjustmentUsd;
11
+ exports.getSolautoFeesBps = getSolautoFeesBps;
11
12
  exports.getMaxLiqUtilizationRateBps = getMaxLiqUtilizationRateBps;
13
+ exports.maxBoostToBps = maxBoostToBps;
12
14
  exports.maxRepayFromBps = maxRepayFromBps;
13
15
  exports.maxRepayToBps = maxRepayToBps;
14
16
  const constants_1 = require("../constants");
17
+ const generated_1 = require("../generated");
15
18
  function getLiqUtilzationRateBps(supplyUsd, debtUsd, liqThresholdBps) {
16
19
  if (supplyUsd === 0) {
17
20
  return 0;
@@ -32,7 +35,7 @@ function toBps(value) {
32
35
  }
33
36
  function bytesToI80F48(bytes) {
34
37
  if (bytes.length !== 16) {
35
- throw new Error('Byte array must be exactly 16 bytes.');
38
+ throw new Error("Byte array must be exactly 16 bytes.");
36
39
  }
37
40
  const reversedBytes = bytes.slice().reverse();
38
41
  let integerPart = BigInt(0);
@@ -44,31 +47,65 @@ function bytesToI80F48(bytes) {
44
47
  fractionalPart = (fractionalPart << 8n) | BigInt(reversedBytes[i]);
45
48
  }
46
49
  const fullValue = integerPart * BigInt(2 ** 48) + fractionalPart;
47
- return Number(fullValue) / (2 ** 48);
50
+ return Number(fullValue) / 2 ** 48;
48
51
  }
49
52
  function uint8ArrayToBigInt(uint8Array) {
50
53
  if (uint8Array.length !== 8) {
51
- throw new Error('Uint8Array must be exactly 8 bytes long to convert to u64.');
54
+ throw new Error("Uint8Array must be exactly 8 bytes long to convert to u64.");
52
55
  }
53
56
  const buffer = uint8Array.buffer;
54
57
  const dataView = new DataView(buffer);
55
58
  const low = dataView.getUint32(0, true);
56
59
  const high = dataView.getUint32(4, true);
57
- return BigInt(high) << 32n | BigInt(low);
60
+ return (BigInt(high) << 32n) | BigInt(low);
58
61
  }
59
62
  function getDebtAdjustmentUsd(liqThresholdBps, supplyUsd, debtUsd, targetLiqUtilizationRateBps, adjustmentFeeBps) {
60
63
  const adjustmentFee = adjustmentFeeBps && adjustmentFeeBps > 0 ? fromBps(adjustmentFeeBps) : 0;
61
64
  const liqThreshold = fromBps(liqThresholdBps);
62
65
  const targetLiqUtilizationRate = fromBps(targetLiqUtilizationRateBps);
63
- const debtAdjustmentUsd = (targetLiqUtilizationRate * supplyUsd * liqThreshold - debtUsd) / (1 - targetLiqUtilizationRate * (1 - adjustmentFee) * liqThreshold);
66
+ const debtAdjustmentUsd = (targetLiqUtilizationRate * supplyUsd * liqThreshold - debtUsd) /
67
+ (1 - targetLiqUtilizationRate * (1 - adjustmentFee) * liqThreshold);
64
68
  return debtAdjustmentUsd;
65
69
  }
66
- function getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps) {
67
- return toBps((fromBps(maxLtvBps) - 0.015) / fromBps(liqThresholdBps)) - 1; // -1 to account for any rounding issues
70
+ function getSolautoFeesBps(isReferred, feeType, positionNetWorthUsd) {
71
+ const minSize = 10000; // Minimum position size
72
+ const maxSize = 1000000; // Maximum position size
73
+ const maxFeeBps = 500; // Fee in basis points for minSize (5%)
74
+ const minFeeBps = 100; // Fee in basis points for maxSize (1%)
75
+ let feeBps = 0;
76
+ if (feeType === generated_1.FeeType.Small) {
77
+ feeBps = 100;
78
+ }
79
+ else if (positionNetWorthUsd <= minSize) {
80
+ feeBps = maxFeeBps;
81
+ }
82
+ else if (positionNetWorthUsd >= maxSize) {
83
+ feeBps = minFeeBps;
84
+ }
85
+ else {
86
+ const t = (Math.log(positionNetWorthUsd) - Math.log(minSize)) /
87
+ (Math.log(maxSize) - Math.log(minSize));
88
+ feeBps = Math.round(minFeeBps + (maxFeeBps - minFeeBps) * (1 - t));
89
+ }
90
+ let referrer = 0;
91
+ if (isReferred) {
92
+ referrer = Math.floor(feeBps / 4);
93
+ }
94
+ return {
95
+ solauto: feeBps - referrer,
96
+ referrer,
97
+ total: feeBps,
98
+ };
99
+ }
100
+ function getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps, offsetFromMaxLtv) {
101
+ return toBps((fromBps(maxLtvBps) - offsetFromMaxLtv) / fromBps(liqThresholdBps)) - 1; // -1 to account for any rounding issues
102
+ }
103
+ function maxBoostToBps(maxLtvBps, liqThresholdBps) {
104
+ return getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps, 0.015);
68
105
  }
69
106
  function maxRepayFromBps(maxLtvBps, liqThresholdBps) {
70
- return Math.min(9000, getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps - 1000));
107
+ return Math.min(9000, getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps - 1000, 0.005));
71
108
  }
72
109
  function maxRepayToBps(maxLtvBps, liqThresholdBps) {
73
- return Math.min(maxRepayFromBps(maxLtvBps, liqThresholdBps) - constants_1.MAX_REPAY_GAP_BPS, getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps));
110
+ return Math.min(maxRepayFromBps(maxLtvBps, liqThresholdBps) - constants_1.MAX_REPAY_GAP_BPS, getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps, 0.005));
74
111
  }
@@ -1,17 +1,12 @@
1
1
  import { PublicKey } from "@solana/web3.js";
2
2
  import { Umi } from "@metaplex-foundation/umi";
3
- import { AutomationSettings, DCASettings, DCASettingsInpArgs, FeeType, PositionState, SolautoSettingsParameters, SolautoSettingsParametersInpArgs } from "../../generated";
3
+ import { AutomationSettings, DCASettings, DCASettingsInpArgs, PositionState, SolautoSettingsParameters, SolautoSettingsParametersInpArgs } from "../../generated";
4
4
  import { RebalanceAction, SolautoPositionDetails } from "../../types/solauto";
5
5
  export declare function nextAutomationPeriodTimestamp(automation: AutomationSettings): number;
6
6
  export declare function eligibleForNextAutomationPeriod(automation: AutomationSettings, currentUnixTime: number): boolean;
7
7
  export declare function getUpdatedValueFromAutomation(currValue: number, targetValue: number, automation: AutomationSettings, currentUnixTimestamp: number): number;
8
8
  export declare function getAdjustedSettingsFromAutomation(settings: SolautoSettingsParameters, currentUnixTime: number): SolautoSettingsParameters;
9
- export declare function getSolautoFeesBps(isReferred: boolean, feeType: FeeType): {
10
- solauto: number;
11
- referrer: number;
12
- total: number;
13
- };
14
- export declare function eligibleForRebalance(positionState: PositionState, positionSettings: SolautoSettingsParameters, positionDca: DCASettings | undefined, currentUnixSecs: number): RebalanceAction | undefined;
9
+ export declare function eligibleForRebalance(positionState: PositionState, positionSettings: SolautoSettingsParameters, positionDca: DCASettings | undefined, currentUnixTime: number): RebalanceAction | undefined;
15
10
  export declare function eligibleForRefresh(positionState: PositionState, positionSettings: SolautoSettingsParameters, currentUnixTime: number): boolean;
16
11
  export declare function getSolautoManagedPositions(umi: Umi, authority?: PublicKey): Promise<SolautoPositionDetails[]>;
17
12
  export declare function getAllReferralStates(umi: Umi): Promise<PublicKey[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/solauto/generalUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/solauto/generalUtils.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,6 @@ exports.nextAutomationPeriodTimestamp = nextAutomationPeriodTimestamp;
5
5
  exports.eligibleForNextAutomationPeriod = eligibleForNextAutomationPeriod;
6
6
  exports.getUpdatedValueFromAutomation = getUpdatedValueFromAutomation;
7
7
  exports.getAdjustedSettingsFromAutomation = getAdjustedSettingsFromAutomation;
8
- exports.getSolautoFeesBps = getSolautoFeesBps;
9
8
  exports.eligibleForRebalance = eligibleForRebalance;
10
9
  exports.eligibleForRefresh = eligibleForRefresh;
11
10
  exports.getSolautoManagedPositions = getSolautoManagedPositions;
@@ -55,30 +54,18 @@ function getAdjustedSettingsFromAutomation(settings, currentUnixTime) {
55
54
  boostToBps,
56
55
  };
57
56
  }
58
- function getSolautoFeesBps(isReferred, feeType) {
59
- const fees = feeType === generated_1.FeeType.Small ? 100 : 500;
60
- let referrer = 0;
61
- if (isReferred) {
62
- referrer = fees / 4;
63
- }
64
- return {
65
- solauto: fees - referrer,
66
- referrer,
67
- total: fees,
68
- };
69
- }
70
- function eligibleForRebalance(positionState, positionSettings, positionDca, currentUnixSecs) {
57
+ function eligibleForRebalance(positionState, positionSettings, positionDca, currentUnixTime) {
71
58
  if (positionDca &&
72
59
  positionDca.automation.targetPeriods > 0 &&
73
- eligibleForNextAutomationPeriod(positionDca.automation, currentUnixSecs)) {
60
+ eligibleForNextAutomationPeriod(positionDca.automation, currentUnixTime)) {
74
61
  return "dca";
75
62
  }
76
63
  if (positionState.supply.amountUsed.baseUnit === BigInt(0)) {
77
64
  return undefined;
78
65
  }
79
- const boostToBps = eligibleForRefresh(positionState, positionSettings, currentUnixSecs) &&
66
+ const boostToBps = eligibleForRefresh(positionState, positionSettings, currentUnixTime) &&
80
67
  positionSettings.automation.targetPeriods > 0
81
- ? getUpdatedValueFromAutomation(positionSettings.boostToBps, positionSettings.targetBoostToBps, positionSettings.automation, currentUnixSecs)
68
+ ? getUpdatedValueFromAutomation(positionSettings.boostToBps, positionSettings.targetBoostToBps, positionSettings.automation, currentUnixTime)
82
69
  : positionSettings.boostToBps;
83
70
  const repayFrom = positionSettings.repayToBps + positionSettings.repayGap;
84
71
  const boostFrom = boostToBps - positionSettings.boostGap;
@@ -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,OAAO,EACP,aAAa,EAEb,yBAAyB,EAC1B,MAAM,iBAAiB,CAAC;AAQzB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAiJjD,MAAM,WAAW,eAAe;IAC9B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,yBAAyB,GAAG,SAAS,EAC/C,GAAG,EAAE,WAAW,GAAG,SAAS,EAC5B,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,2BAA2B,CAAC,EAAE,MAAM,EACpC,WAAW,CAAC,EAAE,MAAM,GACnB,eAAe,CAsEjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,aAAa,GACtB,gBAAgB,GAAG,SAAS,CAkE9B;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,cAAc,CAkChB"}
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,OAAO,EACP,aAAa,EAEb,yBAAyB,EAC1B,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAkJjD,MAAM,WAAW,eAAe;IAC9B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,yBAAyB,GAAG,SAAS,EAC/C,GAAG,EAAE,WAAW,GAAG,SAAS,EAC5B,OAAO,EAAE,OAAO,EAChB,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,2BAA2B,CAAC,EAAE,MAAM,EACpC,WAAW,CAAC,EAAE,MAAM,GACnB,eAAe,CA0EjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,aAAa,GACtB,gBAAgB,GAAG,SAAS,CAmE9B;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,eAAe,EACvB,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,cAAc,CAkChB"}
@@ -19,8 +19,8 @@ function getAdditionalAmountToDcaIn(dca) {
19
19
  }
20
20
  function getStandardTargetLiqUtilizationRateBps(state, settings) {
21
21
  const adjustedSettings = (0, generalUtils_1.getAdjustedSettingsFromAutomation)(settings, (0, generalUtils_2.currentUnixSeconds)());
22
- const repayFrom = adjustedSettings.repayToBps + adjustedSettings.repayGap;
23
- const boostFrom = adjustedSettings.boostToBps - adjustedSettings.boostGap;
22
+ const repayFrom = settings.repayToBps + settings.repayGap;
23
+ const boostFrom = adjustedSettings.boostToBps - settings.boostGap;
24
24
  if (state.liqUtilizationRateBps < boostFrom) {
25
25
  return adjustedSettings.boostToBps;
26
26
  }
@@ -63,7 +63,7 @@ function getTargetRateAndDcaAmount(state, settings, dca, currentUnixTime, target
63
63
  };
64
64
  }
65
65
  if (settings === undefined) {
66
- throw new Error("If rebalancing a self-managed position, settings, and DCA should be provided");
66
+ throw new Error("If rebalancing a self-managed position, settings and DCA should be provided");
67
67
  }
68
68
  if (isDcaRebalance(state, settings, dca, currentUnixTime)) {
69
69
  const amountToDcaIn = getAdditionalAmountToDcaIn(dca);
@@ -91,7 +91,7 @@ function getRebalanceValues(state, settings, dca, feeType, currentUnixTime, supp
91
91
  const increasingLeverage = amountUsdToDcaIn > 0 || state.liqUtilizationRateBps < targetRateBps;
92
92
  let adjustmentFeeBps = 0;
93
93
  if (increasingLeverage) {
94
- adjustmentFeeBps = (0, generalUtils_1.getSolautoFeesBps)(false, feeType).total;
94
+ adjustmentFeeBps = (0, numberUtils_1.getSolautoFeesBps)(false, feeType, (0, numberUtils_1.fromBaseUnit)(state.netWorth.baseAmountUsdValue, generalAccounts_1.USD_DECIMALS)).total;
95
95
  }
96
96
  const supplyUsd = (0, numberUtils_1.fromBaseUnit)(state.supply.amountUsed.baseAmountUsdValue, generalAccounts_1.USD_DECIMALS) +
97
97
  amountUsdToDcaIn;
@@ -133,7 +133,7 @@ function getFlashLoanDetails(client, values, jupQuote) {
133
133
  const tempLiqUtilizationRateBps = (0, numberUtils_1.getLiqUtilzationRateBps)(supplyUsd, debtUsd, client.solautoPositionState.liqThresholdBps);
134
134
  const requiresFlashLoan = supplyUsd <= 0 ||
135
135
  tempLiqUtilizationRateBps >
136
- (0, numberUtils_1.getMaxLiqUtilizationRateBps)(client.solautoPositionState.maxLtvBps, client.solautoPositionState.liqThresholdBps);
136
+ (0, numberUtils_1.getMaxLiqUtilizationRateBps)(client.solautoPositionState.maxLtvBps, client.solautoPositionState.liqThresholdBps, 0.01);
137
137
  let flashLoanToken = undefined;
138
138
  let flashLoanTokenPrice = 0;
139
139
  if (values.increasingLeverage) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haven-fi/solauto-sdk",
3
- "version": "1.0.68",
3
+ "version": "1.0.70",
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",
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  Instruction,
3
- Signer,
4
3
  TransactionBuilder,
5
4
  Umi,
6
5
  publicKey,
@@ -14,7 +13,6 @@ import {
14
13
  Account as SplTokenAccount,
15
14
  } from "@solana/spl-token";
16
15
  import {
17
- FeeType,
18
16
  LendingPlatform,
19
17
  ReferralState,
20
18
  SOLAUTO_PROGRAM_ID,
@@ -582,7 +580,7 @@ export async function buildSolautoRebalanceTransaction(
582
580
  client.solautoPositionState!,
583
581
  client.solautoPositionSettings(),
584
582
  client.solautoPositionActiveDca(),
585
- client.solautoPositionData?.feeType ?? FeeType.Small,
583
+ client.solautoPositionData!.feeType,
586
584
  currentUnixSeconds(),
587
585
  PRICES[client.supplyMint.toString()].price,
588
586
  PRICES[client.debtMint.toString()].price,
@@ -672,7 +670,8 @@ export async function buildSolautoRebalanceTransaction(
672
670
  client.solautoPositionState!.liqUtilizationRateBps >
673
671
  getMaxLiqUtilizationRateBps(
674
672
  client.solautoPositionState!.maxLtvBps,
675
- client.solautoPositionState!.liqThresholdBps
673
+ client.solautoPositionState!.liqThresholdBps,
674
+ 0.01
676
675
  )
677
676
  ) {
678
677
  tx = tx.prepend(client.refresh());
@@ -1,17 +1,22 @@
1
1
  import { MAX_REPAY_GAP_BPS } from "../constants";
2
+ import { FeeType } from "../generated";
2
3
 
3
- export function getLiqUtilzationRateBps(supplyUsd: number, debtUsd: number, liqThresholdBps: number): number {
4
+ export function getLiqUtilzationRateBps(
5
+ supplyUsd: number,
6
+ debtUsd: number,
7
+ liqThresholdBps: number
8
+ ): number {
4
9
  if (supplyUsd === 0) {
5
10
  return 0;
6
11
  }
7
-
12
+
8
13
  return toBps(debtUsd / (supplyUsd * fromBps(liqThresholdBps)));
9
14
  }
10
15
 
11
16
  export function toBaseUnit(value: number, decimals: number): bigint {
12
- return BigInt(Math.round(value * Math.pow(10, decimals)));
13
- }
14
-
17
+ return BigInt(Math.round(value * Math.pow(10, decimals)));
18
+ }
19
+
15
20
  export function fromBaseUnit(value: bigint, decimals: number): number {
16
21
  return Number(value) / Math.pow(10, decimals);
17
22
  }
@@ -26,7 +31,7 @@ export function toBps(value: number): number {
26
31
 
27
32
  export function bytesToI80F48(bytes: number[]): number {
28
33
  if (bytes.length !== 16) {
29
- throw new Error('Byte array must be exactly 16 bytes.');
34
+ throw new Error("Byte array must be exactly 16 bytes.");
30
35
  }
31
36
 
32
37
  const reversedBytes = bytes.slice().reverse();
@@ -44,12 +49,14 @@ export function bytesToI80F48(bytes: number[]): number {
44
49
 
45
50
  const fullValue = integerPart * BigInt(2 ** 48) + fractionalPart;
46
51
 
47
- return Number(fullValue) / (2 ** 48);
52
+ return Number(fullValue) / 2 ** 48;
48
53
  }
49
54
 
50
55
  export function uint8ArrayToBigInt(uint8Array: Uint8Array): bigint {
51
56
  if (uint8Array.length !== 8) {
52
- throw new Error('Uint8Array must be exactly 8 bytes long to convert to u64.');
57
+ throw new Error(
58
+ "Uint8Array must be exactly 8 bytes long to convert to u64."
59
+ );
53
60
  }
54
61
 
55
62
  const buffer = uint8Array.buffer;
@@ -59,7 +66,7 @@ export function uint8ArrayToBigInt(uint8Array: Uint8Array): bigint {
59
66
  const low = dataView.getUint32(0, true);
60
67
  const high = dataView.getUint32(4, true);
61
68
 
62
- return BigInt(high) << 32n | BigInt(low);
69
+ return (BigInt(high) << 32n) | BigInt(low);
63
70
  }
64
71
 
65
72
  export function getDebtAdjustmentUsd(
@@ -69,31 +76,79 @@ export function getDebtAdjustmentUsd(
69
76
  targetLiqUtilizationRateBps: number,
70
77
  adjustmentFeeBps?: number
71
78
  ) {
72
- const adjustmentFee = adjustmentFeeBps && adjustmentFeeBps > 0 ? fromBps(adjustmentFeeBps) : 0;
79
+ const adjustmentFee =
80
+ adjustmentFeeBps && adjustmentFeeBps > 0 ? fromBps(adjustmentFeeBps) : 0;
73
81
  const liqThreshold = fromBps(liqThresholdBps);
74
82
  const targetLiqUtilizationRate = fromBps(targetLiqUtilizationRateBps);
75
83
 
76
- const debtAdjustmentUsd = (targetLiqUtilizationRate * supplyUsd * liqThreshold - debtUsd) / (1 - targetLiqUtilizationRate * (1 - adjustmentFee) * liqThreshold);
84
+ const debtAdjustmentUsd =
85
+ (targetLiqUtilizationRate * supplyUsd * liqThreshold - debtUsd) /
86
+ (1 - targetLiqUtilizationRate * (1 - adjustmentFee) * liqThreshold);
77
87
  return debtAdjustmentUsd;
78
88
  }
79
89
 
90
+ export function getSolautoFeesBps(
91
+ isReferred: boolean,
92
+ feeType: FeeType,
93
+ positionNetWorthUsd: number
94
+ ): {
95
+ solauto: number;
96
+ referrer: number;
97
+ total: number;
98
+ } {
99
+ const minSize = 10000; // Minimum position size
100
+ const maxSize = 1000000; // Maximum position size
101
+ const maxFeeBps = 500; // Fee in basis points for minSize (5%)
102
+ const minFeeBps = 100; // Fee in basis points for maxSize (1%)
103
+
104
+ let feeBps: number = 0;
105
+ if (feeType === FeeType.Small) {
106
+ feeBps = 100;
107
+ } else if (positionNetWorthUsd <= minSize) {
108
+ feeBps = maxFeeBps;
109
+ } else if (positionNetWorthUsd >= maxSize) {
110
+ feeBps = minFeeBps;
111
+ } else {
112
+ const t =
113
+ (Math.log(positionNetWorthUsd) - Math.log(minSize)) /
114
+ (Math.log(maxSize) - Math.log(minSize));
115
+ feeBps = Math.round(minFeeBps + (maxFeeBps - minFeeBps) * (1 - t));
116
+ }
117
+
118
+ let referrer = 0;
119
+ if (isReferred) {
120
+ referrer = Math.floor(feeBps / 4);
121
+ }
122
+
123
+ return {
124
+ solauto: feeBps - referrer,
125
+ referrer,
126
+ total: feeBps,
127
+ };
128
+ }
129
+
80
130
  export function getMaxLiqUtilizationRateBps(
81
131
  maxLtvBps: number,
82
- liqThresholdBps: number
132
+ liqThresholdBps: number,
133
+ offsetFromMaxLtv: number
83
134
  ): number {
84
- return toBps((fromBps(maxLtvBps) - 0.015) / fromBps(liqThresholdBps)) - 1; // -1 to account for any rounding issues
135
+ return toBps((fromBps(maxLtvBps) - offsetFromMaxLtv) / fromBps(liqThresholdBps)) - 1; // -1 to account for any rounding issues
136
+ }
137
+
138
+ export function maxBoostToBps(maxLtvBps: number, liqThresholdBps: number) {
139
+ return getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps, 0.015);
85
140
  }
86
141
 
87
142
  export function maxRepayFromBps(maxLtvBps: number, liqThresholdBps: number) {
88
143
  return Math.min(
89
144
  9000,
90
- getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps - 1000)
145
+ getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps - 1000, 0.005)
91
146
  );
92
147
  }
93
148
 
94
149
  export function maxRepayToBps(maxLtvBps: number, liqThresholdBps: number) {
95
150
  return Math.min(
96
151
  maxRepayFromBps(maxLtvBps, liqThresholdBps) - MAX_REPAY_GAP_BPS,
97
- getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps)
152
+ getMaxLiqUtilizationRateBps(maxLtvBps, liqThresholdBps, 0.005)
98
153
  );
99
- }
154
+ }
@@ -4,7 +4,6 @@ import {
4
4
  AutomationSettings,
5
5
  DCASettings,
6
6
  DCASettingsInpArgs,
7
- FeeType,
8
7
  LendingPlatform,
9
8
  PositionState,
10
9
  SOLAUTO_PROGRAM_ID,
@@ -29,7 +28,6 @@ import {
29
28
  } from "../../constants";
30
29
  import {
31
30
  getAllMarginfiAccountsByAuthority,
32
- getMarginfiAccountPositionState,
33
31
  } from "../marginfiUtils";
34
32
  import { RebalanceAction, SolautoPositionDetails } from "../../types/solauto";
35
33
 
@@ -102,37 +100,16 @@ export function getAdjustedSettingsFromAutomation(
102
100
  };
103
101
  }
104
102
 
105
- export function getSolautoFeesBps(
106
- isReferred: boolean,
107
- feeType: FeeType
108
- ): {
109
- solauto: number;
110
- referrer: number;
111
- total: number;
112
- } {
113
- const fees = feeType === FeeType.Small ? 100 : 500;
114
- let referrer = 0;
115
- if (isReferred) {
116
- referrer = fees / 4;
117
- }
118
-
119
- return {
120
- solauto: fees - referrer,
121
- referrer,
122
- total: fees,
123
- };
124
- }
125
-
126
103
  export function eligibleForRebalance(
127
104
  positionState: PositionState,
128
105
  positionSettings: SolautoSettingsParameters,
129
106
  positionDca: DCASettings | undefined,
130
- currentUnixSecs: number
107
+ currentUnixTime: number
131
108
  ): RebalanceAction | undefined {
132
109
  if (
133
110
  positionDca &&
134
111
  positionDca.automation.targetPeriods > 0 &&
135
- eligibleForNextAutomationPeriod(positionDca.automation, currentUnixSecs)
112
+ eligibleForNextAutomationPeriod(positionDca.automation, currentUnixTime)
136
113
  ) {
137
114
  return "dca";
138
115
  }
@@ -142,13 +119,13 @@ export function eligibleForRebalance(
142
119
  }
143
120
 
144
121
  const boostToBps =
145
- eligibleForRefresh(positionState, positionSettings, currentUnixSecs) &&
122
+ eligibleForRefresh(positionState, positionSettings, currentUnixTime) &&
146
123
  positionSettings.automation.targetPeriods > 0
147
124
  ? getUpdatedValueFromAutomation(
148
125
  positionSettings.boostToBps,
149
126
  positionSettings.targetBoostToBps,
150
127
  positionSettings.automation,
151
- currentUnixSecs
128
+ currentUnixTime
152
129
  )
153
130
  : positionSettings.boostToBps;
154
131
  const repayFrom = positionSettings.repayToBps + positionSettings.repayGap;
@@ -10,7 +10,6 @@ import {
10
10
  import {
11
11
  eligibleForNextAutomationPeriod,
12
12
  getAdjustedSettingsFromAutomation,
13
- getSolautoFeesBps,
14
13
  getUpdatedValueFromAutomation,
15
14
  } from "./generalUtils";
16
15
  import { toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters";
@@ -23,6 +22,7 @@ import {
23
22
  getDebtAdjustmentUsd,
24
23
  getLiqUtilzationRateBps,
25
24
  getMaxLiqUtilizationRateBps,
25
+ getSolautoFeesBps,
26
26
  toBaseUnit,
27
27
  } from "../numberUtils";
28
28
  import { USD_DECIMALS } from "../../constants/generalAccounts";
@@ -57,8 +57,8 @@ function getStandardTargetLiqUtilizationRateBps(
57
57
  currentUnixSeconds()
58
58
  );
59
59
 
60
- const repayFrom = adjustedSettings.repayToBps + adjustedSettings.repayGap;
61
- const boostFrom = adjustedSettings.boostToBps - adjustedSettings.boostGap;
60
+ const repayFrom = settings.repayToBps + settings.repayGap;
61
+ const boostFrom = adjustedSettings.boostToBps - settings.boostGap;
62
62
 
63
63
  if (state.liqUtilizationRateBps < boostFrom) {
64
64
  return adjustedSettings.boostToBps;
@@ -136,7 +136,7 @@ function getTargetRateAndDcaAmount(
136
136
 
137
137
  if (settings === undefined) {
138
138
  throw new Error(
139
- "If rebalancing a self-managed position, settings, and DCA should be provided"
139
+ "If rebalancing a self-managed position, settings and DCA should be provided"
140
140
  );
141
141
  }
142
142
 
@@ -204,7 +204,11 @@ export function getRebalanceValues(
204
204
  amountUsdToDcaIn > 0 || state.liqUtilizationRateBps < targetRateBps;
205
205
  let adjustmentFeeBps = 0;
206
206
  if (increasingLeverage) {
207
- adjustmentFeeBps = getSolautoFeesBps(false, feeType).total;
207
+ adjustmentFeeBps = getSolautoFeesBps(
208
+ false,
209
+ feeType,
210
+ fromBaseUnit(state.netWorth.baseAmountUsdValue, USD_DECIMALS)
211
+ ).total;
208
212
  }
209
213
 
210
214
  const supplyUsd =
@@ -290,7 +294,8 @@ export function getFlashLoanDetails(
290
294
  tempLiqUtilizationRateBps >
291
295
  getMaxLiqUtilizationRateBps(
292
296
  client.solautoPositionState!.maxLtvBps,
293
- client.solautoPositionState!.liqThresholdBps
297
+ client.solautoPositionState!.liqThresholdBps,
298
+ 0.01
294
299
  );
295
300
 
296
301
  let flashLoanToken: PositionTokenUsage | undefined = undefined;
@@ -5,12 +5,11 @@ import {
5
5
  SolautoMarginfiClient,
6
6
  } from "../../src/clients/solautoMarginfiClient";
7
7
  import {
8
- LendingPlatform,
9
8
  solautoAction,
10
9
  SolautoSettingsParametersInpArgs,
11
10
  } from "../../src/generated";
12
11
  import { buildSolautoRebalanceTransaction } from "../../src/transactions/transactionUtils";
13
- import { getMaxLiqUtilizationRateBps, toBaseUnit } from "../../src/utils/numberUtils";
12
+ import { maxBoostToBps, maxRepayFromBps, maxRepayToBps, toBaseUnit } from "../../src/utils/numberUtils";
14
13
  import { NATIVE_MINT } from "@solana/spl-token";
15
14
  import { getTokenPrices } from "../../src/utils/generalUtils";
16
15
  import {
@@ -21,12 +20,12 @@ import { PublicKey } from "@solana/web3.js";
21
20
  import { USDC_MINT } from "../../src/constants";
22
21
 
23
22
  describe("Solauto Marginfi tests", async () => {
24
- // const signer = setupTest();
25
- const signer = setupTest("solauto-manager");
23
+ const signer = setupTest();
24
+ // const signer = setupTest("solauto-manager");
26
25
 
27
26
  const payForTransactions = false;
28
27
  const useJitoBundle = false;
29
- const positionId = 1;
28
+ const positionId = 2;
30
29
 
31
30
  it("open - deposit - borrow - rebalance to 0 - withdraw - close", async () => {
32
31
  const client = new SolautoMarginfiClient(process.env.HELIUS_API_KEY!, true);
@@ -67,22 +66,26 @@ describe("Solauto Marginfi tests", async () => {
67
66
  // }, "open position")
68
67
  // );
69
68
 
70
- // const initialSupplyUsd = 50;
71
- // transactionItems.push(
72
- // new TransactionItem(async () => {
73
- // const [supplyPrice] = await getTokenPrices([supply]);
74
- // return {
75
- // tx: client.protocolInteraction(
76
- // solautoAction("Deposit", [
77
- // toBaseUnit(initialSupplyUsd / supplyPrice, supplyDecimals),
78
- // ])
79
- // ),
80
- // };
81
- // }, "deposit")
82
- // );
69
+ // const initialSupplyUsd = 150;
70
+ // transactionItems.push(
71
+ // new TransactionItem(async () => {
72
+ // const [supplyPrice] = await getTokenPrices([supply]);
73
+ // return {
74
+ // tx: client.protocolInteraction(
75
+ // solautoAction("Deposit", [
76
+ // toBaseUnit(initialSupplyUsd / supplyPrice, supplyDecimals),
77
+ // ])
78
+ // ),
79
+ // };
80
+ // }, "deposit")
81
+ // );
83
82
  // }
84
83
 
85
- // const maxLiqRate = getMaxLiqUtilizationRateBps(client.solautoPositionState!.maxLtvBps, client.solautoPositionState!.liqThresholdBps);
84
+ // const maxLtvBps = client.solautoPositionState!.maxLtvBps;
85
+ // const liqThresholdBps = client.solautoPositionState!.liqThresholdBps;
86
+ // const maxRepayFrom = maxRepayFromBps(maxLtvBps, liqThresholdBps);
87
+ // const maxRepayTo = maxRepayToBps(maxLtvBps, liqThresholdBps);
88
+ // const maxBoostTo = maxBoostToBps(maxLtvBps, liqThresholdBps);
86
89
  // transactionItems.push(
87
90
  // new TransactionItem(
88
91
  // async () => ({
@@ -90,10 +93,10 @@ describe("Solauto Marginfi tests", async () => {
90
93
  // positionId: client.positionId,
91
94
  // settingParams: some({
92
95
  // ...settingParams,
96
+ // boostToBps: maxBoostTo,
93
97
  // boostGap: 50,
94
- // boostToBps: maxLiqRate,
95
- // repayGap: 100,
96
- // repayToBps: maxLiqRate
98
+ // repayToBps: maxRepayTo,
99
+ // repayGap: maxRepayFrom - maxRepayTo
97
100
  // }),
98
101
  // dca: null,
99
102
  // }),
@@ -18,6 +18,7 @@ import {
18
18
  fromBaseUnit,
19
19
  fromBps,
20
20
  getLiqUtilzationRateBps,
21
+ getSolautoFeesBps,
21
22
  toBaseUnit,
22
23
  } from "../../src/utils/numberUtils";
23
24
  import { USD_DECIMALS } from "../../src/constants/generalAccounts";
@@ -25,7 +26,6 @@ import {
25
26
  createFakePositionState,
26
27
  eligibleForNextAutomationPeriod,
27
28
  getAdjustedSettingsFromAutomation,
28
- getSolautoFeesBps,
29
29
  getUpdatedValueFromAutomation,
30
30
  positionStateWithLatestPrices,
31
31
  } from "../../src/utils/solauto/generalUtils";
@@ -49,7 +49,7 @@ function assertAccurateRebalance(
49
49
  client.solautoPositionState!,
50
50
  client.solautoPositionSettings(),
51
51
  client.solautoPositionActiveDca(),
52
- client.solautoPositionData?.feeType ?? FeeType.Small,
52
+ client.solautoPositionData!.feeType,
53
53
  currentUnixSeconds(),
54
54
  PRICES[client.supplyMint.toString()].price,
55
55
  PRICES[client.debtMint.toString()].price,
@@ -60,7 +60,11 @@ function assertAccurateRebalance(
60
60
  if (increasingLeverage) {
61
61
  adjustmentFeeBps = getSolautoFeesBps(
62
62
  client.referredByState !== undefined,
63
- client.solautoPositionData!.feeType
63
+ client.solautoPositionData!.feeType,
64
+ fromBaseUnit(
65
+ client.solautoPositionState?.netWorth.baseAmountUsdValue ?? BigInt(0),
66
+ USD_DECIMALS
67
+ )
64
68
  ).total;
65
69
  }
66
70
 
@@ -285,28 +289,28 @@ describe("Rebalance tests", async () => {
285
289
  ]);
286
290
  });
287
291
 
288
- // it("Standard rebalance with target rate", async () => {
289
- // const client = await getFakePosition(supplyPrice, debtPrice, 3450, {
290
- // boostToBps: 500,
291
- // boostGap: 100,
292
- // repayToBps: 7000,
293
- // repayGap: 250,
294
- // automation: {
295
- // targetPeriods: 0,
296
- // periodsPassed: 0,
297
- // unixStartDate: BigInt(0),
298
- // intervalSeconds: BigInt(0),
299
- // padding1: [],
300
- // padding: new Uint8Array([]),
301
- // },
302
- // targetBoostToBps: 0,
303
- // padding1: [],
304
- // padding: new Uint8Array([]),
305
- // });
292
+ it("Standard rebalance with target rate", async () => {
293
+ const client = await getFakePosition(supplyPrice, debtPrice, 3450, {
294
+ boostToBps: 500,
295
+ boostGap: 100,
296
+ repayToBps: 7000,
297
+ repayGap: 250,
298
+ automation: {
299
+ targetPeriods: 0,
300
+ periodsPassed: 0,
301
+ unixStartDate: BigInt(0),
302
+ intervalSeconds: BigInt(0),
303
+ padding1: [],
304
+ padding: new Uint8Array([]),
305
+ },
306
+ targetBoostToBps: 0,
307
+ padding1: [],
308
+ padding: new Uint8Array([]),
309
+ });
306
310
 
307
- // assertAccurateRebalance(client, 5000, 5000);
308
- // assertAccurateRebalance(client, 1000, 1000);
309
- // });
311
+ assertAccurateRebalance(client, 5000, 5000);
312
+ assertAccurateRebalance(client, 1000, 1000);
313
+ });
310
314
 
311
315
  it("Standard boost or repay", async () => {
312
316
  const settings: SolautoSettingsParameters = {