@haven-fi/solauto-sdk 1.0.629 → 1.0.631
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/README.md +32 -2
- package/dist/constants/marginfiAccounts.d.ts.map +1 -1
- package/dist/constants/solautoConstants.d.ts +2 -1
- package/dist/constants/solautoConstants.d.ts.map +1 -1
- package/dist/generated/instructions/marginfiRebalance.d.ts +5 -3
- package/dist/generated/instructions/marginfiRebalance.d.ts.map +1 -1
- package/dist/generated/instructions/marginfiRebalance.js +2 -1
- package/dist/generated/instructions/marginfiRefreshData.d.ts +7 -2
- package/dist/generated/instructions/marginfiRefreshData.d.ts.map +1 -1
- package/dist/generated/instructions/marginfiRefreshData.js +8 -4
- package/dist/generated/types/index.d.ts +1 -0
- package/dist/generated/types/index.d.ts.map +1 -1
- package/dist/generated/types/index.js +1 -0
- package/dist/generated/types/priceType.d.ts +15 -0
- package/dist/generated/types/priceType.d.ts.map +1 -0
- package/dist/generated/types/priceType.js +22 -0
- package/dist/services/rebalance/rebalanceSwapManager.d.ts.map +1 -1
- package/dist/services/rebalance/rebalanceSwapManager.js +8 -8
- package/dist/services/rebalance/rebalanceTxBuilder.d.ts +2 -0
- package/dist/services/rebalance/rebalanceTxBuilder.d.ts.map +1 -1
- package/dist/services/rebalance/rebalanceTxBuilder.js +21 -10
- package/dist/services/rebalance/rebalanceValues.d.ts +2 -2
- package/dist/services/rebalance/rebalanceValues.d.ts.map +1 -1
- package/dist/services/rebalance/rebalanceValues.js +17 -17
- package/dist/services/solauto/solautoClient.d.ts +2 -2
- package/dist/services/solauto/solautoClient.d.ts.map +1 -1
- package/dist/services/solauto/solautoClient.js +27 -28
- package/dist/services/solauto/solautoMarginfiClient.d.ts +2 -2
- package/dist/services/solauto/solautoMarginfiClient.d.ts.map +1 -1
- package/dist/services/solauto/solautoMarginfiClient.js +12 -10
- package/dist/services/transactions/transactionUtils.d.ts.map +1 -1
- package/dist/services/transactions/transactionUtils.js +10 -9
- package/dist/solautoPosition/marginfiSolautoPositionEx.d.ts +3 -3
- package/dist/solautoPosition/marginfiSolautoPositionEx.d.ts.map +1 -1
- package/dist/solautoPosition/marginfiSolautoPositionEx.js +9 -9
- package/dist/solautoPosition/solautoPositionEx.d.ts +44 -33
- package/dist/solautoPosition/solautoPositionEx.d.ts.map +1 -1
- package/dist/solautoPosition/solautoPositionEx.js +112 -90
- package/dist/types/solauto.d.ts +2 -1
- package/dist/types/solauto.d.ts.map +1 -1
- package/dist/utils/instructionUtils.js +2 -2
- package/dist/utils/marginfiUtils.d.ts +2 -2
- package/dist/utils/marginfiUtils.d.ts.map +1 -1
- package/dist/utils/marginfiUtils.js +5 -5
- package/dist/utils/priceUtils.d.ts +11 -5
- package/dist/utils/priceUtils.d.ts.map +1 -1
- package/dist/utils/priceUtils.js +45 -21
- package/local/logPositions.ts +12 -12
- package/local/shared.ts +1 -1
- package/local/txSandbox.ts +29 -27
- package/local/updateMarginfiLUT.ts +13 -6
- package/package.json +1 -1
- package/src/constants/marginfiAccounts.ts +0 -1
- package/src/constants/solautoConstants.ts +1 -1
- package/src/generated/instructions/marginfiRebalance.ts +9 -3
- package/src/generated/instructions/marginfiRefreshData.ts +27 -7
- package/src/generated/types/index.ts +1 -0
- package/src/generated/types/priceType.ts +22 -0
- package/src/services/rebalance/rebalanceSwapManager.ts +8 -12
- package/src/services/rebalance/rebalanceTxBuilder.ts +41 -11
- package/src/services/rebalance/rebalanceValues.ts +22 -16
- package/src/services/solauto/solautoClient.ts +30 -30
- package/src/services/solauto/solautoMarginfiClient.ts +13 -10
- package/src/services/transactions/transactionUtils.ts +11 -9
- package/src/solautoPosition/marginfiSolautoPositionEx.ts +11 -10
- package/src/solautoPosition/solautoPositionEx.ts +145 -117
- package/src/types/solauto.ts +2 -0
- package/src/utils/instructionUtils.ts +2 -2
- package/src/utils/marginfiUtils.ts +12 -8
- package/src/utils/priceUtils.ts +66 -22
- package/tests/transactions/shared.ts +2 -5
- 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
|
59
|
+
throw confirmation.value.err;
|
60
60
|
}
|
61
61
|
console.log(txid);
|
62
62
|
}
|
package/local/txSandbox.ts
CHANGED
@@ -3,19 +3,19 @@ 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
12
|
rebalance,
|
12
|
-
RebalanceTxBuilder,
|
13
13
|
SOLAUTO_PROD_PROGRAM,
|
14
14
|
SOLAUTO_TEST_PROGRAM,
|
15
|
-
TransactionItem,
|
16
15
|
TransactionsManager,
|
17
16
|
} from "../src";
|
18
17
|
import { getSecretKey } from "./shared";
|
18
|
+
import { NATIVE_MINT } from "@solana/spl-token";
|
19
19
|
|
20
20
|
const payForTransaction = false;
|
21
21
|
const testProgram = true;
|
@@ -31,32 +31,34 @@ export async function main() {
|
|
31
31
|
fromWeb3JsKeypair(Keypair.fromSecretKey(getSecretKey("solauto-manager")))
|
32
32
|
);
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
const
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
34
|
+
await fetchTokenPrices([NATIVE_MINT]);
|
35
|
+
|
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
|
+
// });
|
42
|
+
|
43
|
+
// await client.initialize({
|
44
|
+
// positionId: 3,
|
45
|
+
// authority: new PublicKey("5UqsR2PGzbP8pGPbXEeXx86Gjz2N2UFBAuFZUSVydAEe"),
|
46
|
+
// });
|
47
|
+
|
48
|
+
// const transactionItems = [rebalance(client)];
|
49
|
+
|
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);
|
58
60
|
|
59
|
-
consoleLog(statuses);
|
61
|
+
// consoleLog(statuses);
|
60
62
|
}
|
61
63
|
|
62
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
|
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 =
|
28
|
-
|
29
|
-
|
30
|
-
|
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
@@ -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]: {
|
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 = {
|
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>(
|
57
|
-
|
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
|
50
|
-
: this.client.pos.state
|
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
|
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
|
110
|
-
: this.client.pos.state
|
108
|
+
? this.client.pos.state.debt
|
109
|
+
: this.client.pos.state.supply;
|
111
110
|
const output = this.isBoost()
|
112
|
-
? this.client.pos.state
|
113
|
-
: this.client.pos.state
|
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
|
111
|
-
this.client.pos.state
|
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
|
163
|
+
flashLoanToken = this.client.pos.state.debt;
|
160
164
|
} else {
|
161
|
-
flashLoanToken = this.client.pos.state
|
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.
|
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
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
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
|
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
|
221
|
+
lpBorrow: solautoPosition.state.debt.borrowFeeBps,
|
212
222
|
flashLoan: flFeeBps ?? 0,
|
213
223
|
};
|
214
224
|
|
215
225
|
const debtAdjustment = getDebtAdjustment(
|
216
|
-
solautoPosition.state
|
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,
|