@kamino-finance/klend-sdk 5.13.7 → 5.13.8
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/dist/classes/obligation.d.ts +1 -0
- package/dist/classes/obligation.d.ts.map +1 -1
- package/dist/classes/obligation.js +7 -0
- package/dist/classes/obligation.js.map +1 -1
- package/dist/classes/vault.d.ts +9 -1
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +37 -0
- package/dist/classes/vault.js.map +1 -1
- package/dist/classes/vault_types.d.ts +4 -0
- package/dist/classes/vault_types.d.ts.map +1 -1
- package/dist/client_kamino_manager.d.ts.map +1 -1
- package/dist/client_kamino_manager.js +8 -0
- package/dist/client_kamino_manager.js.map +1 -1
- package/dist/lending_operations/repay_with_collateral_calcs.d.ts +3 -4
- package/dist/lending_operations/repay_with_collateral_calcs.d.ts.map +1 -1
- package/dist/lending_operations/repay_with_collateral_calcs.js +36 -34
- package/dist/lending_operations/repay_with_collateral_calcs.js.map +1 -1
- package/dist/lending_operations/repay_with_collateral_operations.d.ts +3 -2
- package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
- package/dist/lending_operations/repay_with_collateral_operations.js +40 -30
- package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
- package/dist/utils/multisig.d.ts +11 -1
- package/dist/utils/multisig.d.ts.map +1 -1
- package/dist/utils/multisig.js +8 -5
- package/dist/utils/multisig.js.map +1 -1
- package/package.json +1 -1
- package/src/classes/obligation.ts +10 -0
- package/src/classes/vault.ts +51 -0
- package/src/classes/vault_types.ts +5 -0
- package/src/client_kamino_manager.ts +9 -0
- package/src/lending_operations/repay_with_collateral_calcs.ts +56 -39
- package/src/lending_operations/repay_with_collateral_operations.ts +84 -33
- package/src/utils/multisig.ts +19 -5
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.getMaxWithdrawLtvCheck = exports.MaxWithdrawLtvCheck = void 0;
|
|
7
7
|
exports.getRepayWithCollSwapInputs = getRepayWithCollSwapInputs;
|
|
8
8
|
exports.getRepayWithCollIxs = getRepayWithCollIxs;
|
|
9
|
+
exports.getMaxCollateralFromRepayAmount = getMaxCollateralFromRepayAmount;
|
|
9
10
|
const classes_1 = require("../classes");
|
|
10
11
|
const leverage_1 = require("../leverage");
|
|
11
12
|
const utils_1 = require("../utils");
|
|
@@ -17,14 +18,8 @@ var MaxWithdrawLtvCheck;
|
|
|
17
18
|
MaxWithdrawLtvCheck[MaxWithdrawLtvCheck["LIQUIDATION_THRESHOLD"] = 1] = "LIQUIDATION_THRESHOLD";
|
|
18
19
|
})(MaxWithdrawLtvCheck || (exports.MaxWithdrawLtvCheck = MaxWithdrawLtvCheck = {}));
|
|
19
20
|
async function getRepayWithCollSwapInputs({ collTokenMint, currentSlot, debtTokenMint, kaminoMarket, obligation, quoter, referrer, repayAmount, isClosingPosition, budgetAndPriorityFeeIxs, scopeRefreshConfig, useV2Ixs, }) {
|
|
20
|
-
const collReserve = kaminoMarket.
|
|
21
|
-
const debtReserve = kaminoMarket.
|
|
22
|
-
if (!collReserve) {
|
|
23
|
-
throw new Error(`Collateral reserve with mint ${collTokenMint} not found in market ${kaminoMarket.getAddress()}`);
|
|
24
|
-
}
|
|
25
|
-
if (!debtReserve) {
|
|
26
|
-
throw new Error(`Debt reserve with mint ${debtTokenMint} not found in market ${kaminoMarket.getAddress()}`);
|
|
27
|
-
}
|
|
21
|
+
const collReserve = kaminoMarket.getExistingReserveByMint(collTokenMint);
|
|
22
|
+
const debtReserve = kaminoMarket.getExistingReserveByMint(debtTokenMint);
|
|
28
23
|
const { repayAmountLamports, flashRepayAmountLamports, repayAmount: finalRepayAmount, } = (0, repay_with_collateral_calcs_1.calcRepayAmountWithSlippage)(kaminoMarket, debtReserve, currentSlot, obligation, repayAmount, referrer);
|
|
29
24
|
const debtPosition = obligation.getBorrowByReserve(debtReserve.address);
|
|
30
25
|
const collPosition = obligation.getDepositByReserve(collReserve.address);
|
|
@@ -34,15 +29,9 @@ async function getRepayWithCollSwapInputs({ collTokenMint, currentSlot, debtToke
|
|
|
34
29
|
if (!collPosition) {
|
|
35
30
|
throw new Error(`Collateral position not found for ${collReserve.stats.symbol} reserve ${collReserve.address} in obligation ${obligation.obligationAddress}`);
|
|
36
31
|
}
|
|
37
|
-
const {
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
.mul(debtReserve.getOracleMarketPrice())
|
|
41
|
-
.div(collReserve.getOracleMarketPrice())
|
|
42
|
-
.mul('1.1')
|
|
43
|
-
.mul(collReserve.getMintFactor())
|
|
44
|
-
.ceil();
|
|
45
|
-
const inputAmountLamports = decimal_js_1.default.min(withdrawableCollLamports, maxCollNeededFromOracle);
|
|
32
|
+
const { maxWithdrawableCollLamports } = (0, repay_with_collateral_calcs_1.calcMaxWithdrawCollateral)(kaminoMarket, obligation, collReserve.address, debtReserve.address, repayAmountLamports);
|
|
33
|
+
const maxCollNeededFromOracle = getMaxCollateralFromRepayAmount(finalRepayAmount, debtReserve, collReserve);
|
|
34
|
+
const inputAmountLamports = decimal_js_1.default.min(maxWithdrawableCollLamports, maxCollNeededFromOracle);
|
|
46
35
|
// Build the repay & withdraw collateral tx to get the number of accounts
|
|
47
36
|
const klendIxs = await buildRepayWithCollateralIxs(kaminoMarket, debtReserve, collReserve, obligation, referrer, currentSlot, budgetAndPriorityFeeIxs, scopeRefreshConfig, {
|
|
48
37
|
preActionIxs: [],
|
|
@@ -54,7 +43,7 @@ async function getRepayWithCollSwapInputs({ collTokenMint, currentSlot, debtToke
|
|
|
54
43
|
inputAmountLamports,
|
|
55
44
|
inputMint: collTokenMint,
|
|
56
45
|
outputMint: debtTokenMint,
|
|
57
|
-
amountDebtAtaBalance:
|
|
46
|
+
amountDebtAtaBalance: undefined, // only used for kTokens
|
|
58
47
|
};
|
|
59
48
|
const swapQuote = await quoter(swapQuoteInputs, uniqueKlendAccounts);
|
|
60
49
|
const swapQuotePxDebtToColl = swapQuote.priceAInB;
|
|
@@ -69,13 +58,13 @@ async function getRepayWithCollSwapInputs({ collTokenMint, currentSlot, debtToke
|
|
|
69
58
|
minOutAmountLamports: flashRepayAmountLamports,
|
|
70
59
|
inputMint: collTokenMint,
|
|
71
60
|
outputMint: debtTokenMint,
|
|
72
|
-
amountDebtAtaBalance:
|
|
61
|
+
amountDebtAtaBalance: undefined, // only used for kTokens
|
|
73
62
|
},
|
|
74
63
|
flashLoanInfo: klendIxs.flashLoanInfo,
|
|
75
64
|
initialInputs: {
|
|
76
65
|
debtRepayAmountLamports: repayAmountLamports,
|
|
77
66
|
flashRepayAmountLamports,
|
|
78
|
-
maxCollateralWithdrawLamports:
|
|
67
|
+
maxCollateralWithdrawLamports: maxWithdrawableCollLamports,
|
|
79
68
|
swapQuote,
|
|
80
69
|
currentSlot,
|
|
81
70
|
klendAccounts: uniqueKlendAccounts,
|
|
@@ -99,14 +88,8 @@ async function getRepayWithCollIxs({ repayAmount, isClosingPosition, budgetAndPr
|
|
|
99
88
|
});
|
|
100
89
|
const { debtRepayAmountLamports, flashRepayAmountLamports, maxCollateralWithdrawLamports, swapQuote } = initialInputs;
|
|
101
90
|
const { inputAmountLamports: collSwapInLamports } = swapInputs;
|
|
102
|
-
const collReserve = kaminoMarket.
|
|
103
|
-
|
|
104
|
-
throw new Error(`Collateral reserve with mint ${collTokenMint} not found in market ${kaminoMarket.getAddress()}`);
|
|
105
|
-
}
|
|
106
|
-
const debtReserve = kaminoMarket.getReserveByMint(debtTokenMint);
|
|
107
|
-
if (!debtReserve) {
|
|
108
|
-
throw new Error(`Debt reserve with mint ${debtTokenMint} not found in market ${kaminoMarket.getAddress()}`);
|
|
109
|
-
}
|
|
91
|
+
const collReserve = kaminoMarket.getExistingReserveByMint(collTokenMint);
|
|
92
|
+
const debtReserve = kaminoMarket.getExistingReserveByMint(debtTokenMint);
|
|
110
93
|
// the client should use these values to prevent this input, but the tx may succeed, so we don't want to fail
|
|
111
94
|
// there is also a chance that the tx will consume debt token from the user's ata which they would not expect
|
|
112
95
|
if (collSwapInLamports.greaterThan(maxCollateralWithdrawLamports)) {
|
|
@@ -152,7 +135,7 @@ async function buildRepayWithCollateralIxs(market, debtReserve, collReserve, obl
|
|
|
152
135
|
programId: market.programId,
|
|
153
136
|
});
|
|
154
137
|
const requestElevationGroup = !isClosingPosition && obligation.state.elevationGroup !== 0;
|
|
155
|
-
const maxWithdrawLtvCheck = (0, exports.getMaxWithdrawLtvCheck)(obligation);
|
|
138
|
+
const maxWithdrawLtvCheck = (0, exports.getMaxWithdrawLtvCheck)(obligation, debtRepayAmountLamports, debtReserve, collWithdrawLamports, collReserve);
|
|
156
139
|
// 3. Repay using the flash borrowed funds & withdraw collateral to swap and pay the flash loan
|
|
157
140
|
let repayAndWithdrawAction;
|
|
158
141
|
if (maxWithdrawLtvCheck === MaxWithdrawLtvCheck.MAX_LTV) {
|
|
@@ -183,10 +166,37 @@ async function buildRepayWithCollateralIxs(market, debtReserve, collReserve, obl
|
|
|
183
166
|
};
|
|
184
167
|
return res;
|
|
185
168
|
}
|
|
186
|
-
const getMaxWithdrawLtvCheck = (obligation) => {
|
|
169
|
+
const getMaxWithdrawLtvCheck = (obligation, repayAmountLamports, debtReserve, collWithdrawAmount, collReserve) => {
|
|
170
|
+
const [finalLtv, finalMaxLtv] = calculatePostOperationLtv(obligation, repayAmountLamports, debtReserve, collWithdrawAmount, collReserve);
|
|
171
|
+
if (finalLtv.lte(finalMaxLtv)) {
|
|
172
|
+
return MaxWithdrawLtvCheck.MAX_LTV;
|
|
173
|
+
}
|
|
187
174
|
return obligation.refreshedStats.userTotalBorrowBorrowFactorAdjusted.gte(obligation.refreshedStats.borrowLimit)
|
|
188
175
|
? MaxWithdrawLtvCheck.LIQUIDATION_THRESHOLD
|
|
189
176
|
: MaxWithdrawLtvCheck.MAX_LTV;
|
|
190
177
|
};
|
|
191
178
|
exports.getMaxWithdrawLtvCheck = getMaxWithdrawLtvCheck;
|
|
179
|
+
function calculatePostOperationLtv(obligation, repayAmountLamports, debtReserve, collWithdrawAmount, collReserve) {
|
|
180
|
+
const repayValue = repayAmountLamports
|
|
181
|
+
.div(debtReserve.getMintFactor())
|
|
182
|
+
.mul(debtReserve.getOracleMarketPrice())
|
|
183
|
+
.mul(debtReserve.getBorrowFactor());
|
|
184
|
+
const collWithdrawValue = collWithdrawAmount.div(collReserve.getMintFactor()).mul(collReserve.getOracleMarketPrice());
|
|
185
|
+
// Calculate new borrow value and deposit value
|
|
186
|
+
const newBorrowBfValue = decimal_js_1.default.max(new decimal_js_1.default(0), obligation.refreshedStats.userTotalBorrowBorrowFactorAdjusted.sub(repayValue));
|
|
187
|
+
const newDepositValue = decimal_js_1.default.max(new decimal_js_1.default(0), obligation.refreshedStats.userTotalDeposit.sub(collWithdrawValue));
|
|
188
|
+
const newMaxBorrowableValue = decimal_js_1.default.max(new decimal_js_1.default(0), obligation.refreshedStats.borrowLimit.sub(collWithdrawValue.mul(collReserve.stats.loanToValue)));
|
|
189
|
+
const newMaxLtv = newMaxBorrowableValue.div(newDepositValue);
|
|
190
|
+
// return final ltv and final max ltv
|
|
191
|
+
return [newBorrowBfValue.div(newDepositValue), newMaxLtv];
|
|
192
|
+
}
|
|
193
|
+
function getMaxCollateralFromRepayAmount(repayAmount, debtReserve, collReserve) {
|
|
194
|
+
// sanity check: we have extra collateral to swap, but we want to ensure we don't quote for way more than needed and get a bad px
|
|
195
|
+
return repayAmount
|
|
196
|
+
.mul(debtReserve.getOracleMarketPrice())
|
|
197
|
+
.div(collReserve.getOracleMarketPrice())
|
|
198
|
+
.mul('1.1')
|
|
199
|
+
.mul(collReserve.getMintFactor())
|
|
200
|
+
.ceil();
|
|
201
|
+
}
|
|
192
202
|
//# sourceMappingURL=repay_with_collateral_operations.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repay_with_collateral_operations.js","sourceRoot":"","sources":["../../src/lending_operations/repay_with_collateral_operations.ts"],"names":[],"mappings":";;;;;;AAmEA,
|
|
1
|
+
{"version":3,"file":"repay_with_collateral_operations.js","sourceRoot":"","sources":["../../src/lending_operations/repay_with_collateral_operations.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/multisig.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PublicKey } from '@solana/web3.js';
|
|
2
2
|
export declare function walletIsSquadsMultisig(wallet: PublicKey): Promise<boolean>;
|
|
3
|
-
export declare function getSquadsMultisigAdminsAndThreshold(
|
|
3
|
+
export declare function getSquadsMultisigAdminsAndThreshold(wallet: PublicKey): Promise<{
|
|
4
4
|
adminsNumber: number;
|
|
5
5
|
threshold: number;
|
|
6
6
|
}>;
|
|
@@ -13,4 +13,14 @@ export interface WalletType {
|
|
|
13
13
|
walletAdminsNumber: number;
|
|
14
14
|
walletThreshold: number;
|
|
15
15
|
}
|
|
16
|
+
export type SquadsMultisigAccountResponse = {
|
|
17
|
+
allow_external_execute: boolean;
|
|
18
|
+
authority_index: number;
|
|
19
|
+
bump: number;
|
|
20
|
+
create_key: string;
|
|
21
|
+
keys: number[][];
|
|
22
|
+
ms_change_index: number;
|
|
23
|
+
threshold: number;
|
|
24
|
+
transaction_index: number;
|
|
25
|
+
};
|
|
16
26
|
//# sourceMappingURL=multisig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multisig.d.ts","sourceRoot":"","sources":["../../src/utils/multisig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,SAAS,oBAK7D;AAGD,wBAAsB,mCAAmC,CAAC,
|
|
1
|
+
{"version":3,"file":"multisig.d.ts","sourceRoot":"","sources":["../../src/utils/multisig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,SAAS,oBAK7D;AAGD,wBAAsB,mCAAmC,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IACpF,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAQD;AAGD,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,cAAc,GAAG,gBAAgB,CAAC;IAC9C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,6BAA6B,GAAG;IAC1C,sBAAsB,EAAE,OAAO,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC"}
|
package/dist/utils/multisig.js
CHANGED
|
@@ -2,18 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.walletIsSquadsMultisig = walletIsSquadsMultisig;
|
|
4
4
|
exports.getSquadsMultisigAdminsAndThreshold = getSquadsMultisigAdminsAndThreshold;
|
|
5
|
-
const SQUADS_API_BASE_URL = 'https://4fnetmviidiqkjzenwxe66vgoa0soerr.lambda-url.us-east-1.on.aws
|
|
5
|
+
const SQUADS_API_BASE_URL = 'https://4fnetmviidiqkjzenwxe66vgoa0soerr.lambda-url.us-east-1.on.aws';
|
|
6
6
|
async function walletIsSquadsMultisig(wallet) {
|
|
7
|
-
const response = await fetch(`${SQUADS_API_BASE_URL}/
|
|
7
|
+
const response = await fetch(`${SQUADS_API_BASE_URL}/isSquad/${wallet.toBase58()}`);
|
|
8
8
|
const data = await response.json();
|
|
9
9
|
const squadsResponse = data;
|
|
10
10
|
return squadsResponse.isSquad;
|
|
11
11
|
}
|
|
12
12
|
// todo: find a way to get the admins number and threshold
|
|
13
|
-
async function getSquadsMultisigAdminsAndThreshold(
|
|
13
|
+
async function getSquadsMultisigAdminsAndThreshold(wallet) {
|
|
14
|
+
const response = await fetch(`${SQUADS_API_BASE_URL}/multisig/${wallet.toBase58()}`);
|
|
15
|
+
const data = await response.json();
|
|
16
|
+
const squadsResponse = data;
|
|
14
17
|
return {
|
|
15
|
-
adminsNumber:
|
|
16
|
-
threshold:
|
|
18
|
+
adminsNumber: squadsResponse.keys.length,
|
|
19
|
+
threshold: squadsResponse.threshold,
|
|
17
20
|
};
|
|
18
21
|
}
|
|
19
22
|
//# sourceMappingURL=multisig.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multisig.js","sourceRoot":"","sources":["../../src/utils/multisig.ts"],"names":[],"mappings":";;AAIA,wDAKC;AAGD,
|
|
1
|
+
{"version":3,"file":"multisig.js","sourceRoot":"","sources":["../../src/utils/multisig.ts"],"names":[],"mappings":";;AAIA,wDAKC;AAGD,kFAWC;AArBD,MAAM,mBAAmB,GAAG,sEAAsE,CAAC;AAE5F,KAAK,UAAU,sBAAsB,CAAC,MAAiB;IAC5D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,mBAAmB,YAAY,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,MAAM,cAAc,GAAG,IAA8B,CAAC;IACtD,OAAO,cAAc,CAAC,OAAO,CAAC;AAChC,CAAC;AAED,0DAA0D;AACnD,KAAK,UAAU,mCAAmC,CAAC,MAAiB;IAIzE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,mBAAmB,aAAa,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACrF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,MAAM,cAAc,GAAG,IAAqC,CAAC;IAC7D,OAAO;QACL,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,MAAM;QACxC,SAAS,EAAE,cAAc,CAAC,SAAS;KACpC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1458,6 +1458,16 @@ export class KaminoObligation {
|
|
|
1458
1458
|
);
|
|
1459
1459
|
}
|
|
1460
1460
|
|
|
1461
|
+
getObligationLiquidityByReserve(reserveAddress: PublicKey): ObligationLiquidity {
|
|
1462
|
+
const obligationLiquidity = this.state.borrows.find((borrow) => borrow.borrowReserve.equals(reserveAddress));
|
|
1463
|
+
|
|
1464
|
+
if (!obligationLiquidity) {
|
|
1465
|
+
throw new Error(`Obligation liquidity not found given reserve ${reserveAddress.toString()}`);
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
return obligationLiquidity;
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1461
1471
|
/**
|
|
1462
1472
|
*
|
|
1463
1473
|
* @returns Total borrowed amount for the specified obligation liquidity/borrow asset
|
package/src/classes/vault.ts
CHANGED
|
@@ -89,6 +89,7 @@ import {
|
|
|
89
89
|
UpdateReserveAllocationIxs,
|
|
90
90
|
UpdateVaultConfigIxs,
|
|
91
91
|
UserSharesForVault,
|
|
92
|
+
WithdrawAndBlockReserveIxs,
|
|
92
93
|
WithdrawIxs,
|
|
93
94
|
} from './vault_types';
|
|
94
95
|
import { batchFetch, collToLamportsDecimal, ZERO } from '@kamino-finance/kliquidity-sdk';
|
|
@@ -443,6 +444,56 @@ export class KaminoVaultClient {
|
|
|
443
444
|
return updateReserveAllocationIxs;
|
|
444
445
|
}
|
|
445
446
|
|
|
447
|
+
/**
|
|
448
|
+
* This method withdraws all the funds from a reserve and blocks it from being invested by setting its weight and ctoken allocation to 0
|
|
449
|
+
* @param vault - the vault to withdraw the funds from
|
|
450
|
+
* @param reserve - the reserve to withdraw the funds from
|
|
451
|
+
* @param payer - the payer of the transaction. If not provided, the admin of the vault will be used
|
|
452
|
+
* @returns - a struct with an instruction to update the reserve allocation and an optional list of instructions to update the lookup table for the allocation changes
|
|
453
|
+
*/
|
|
454
|
+
async withdrawEverythingAndBLockReserve(
|
|
455
|
+
vault: KaminoVault,
|
|
456
|
+
reserve: PublicKey,
|
|
457
|
+
payer?: PublicKey
|
|
458
|
+
): Promise<WithdrawAndBlockReserveIxs> {
|
|
459
|
+
const vaultState = await vault.getState(this.getConnection());
|
|
460
|
+
|
|
461
|
+
const reserveIsPartOfAllocation = vaultState.vaultAllocationStrategy.some((allocation) =>
|
|
462
|
+
allocation.reserve.equals(reserve)
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
const withdrawAndBlockReserveIxs: WithdrawAndBlockReserveIxs = {
|
|
466
|
+
updateReserveAllocationIxs: [],
|
|
467
|
+
investIxs: [],
|
|
468
|
+
};
|
|
469
|
+
if (!reserveIsPartOfAllocation) {
|
|
470
|
+
return withdrawAndBlockReserveIxs;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
const reserveState = await Reserve.fetch(this.getConnection(), reserve);
|
|
474
|
+
if (!reserveState) {
|
|
475
|
+
return withdrawAndBlockReserveIxs;
|
|
476
|
+
}
|
|
477
|
+
const reserveWithAddress: ReserveWithAddress = {
|
|
478
|
+
address: reserve,
|
|
479
|
+
state: reserveState,
|
|
480
|
+
};
|
|
481
|
+
const reserveAllocationConfig = new ReserveAllocationConfig(reserveWithAddress, 0, new Decimal(0));
|
|
482
|
+
|
|
483
|
+
// update allocation to have 0 weight and 0 cap
|
|
484
|
+
const updateAllocIxs = await this.updateReserveAllocationIxs(vault, reserveAllocationConfig);
|
|
485
|
+
|
|
486
|
+
const investPayer = payer ? payer : vaultState.vaultAdminAuthority;
|
|
487
|
+
const investIx = await this.investSingleReserveIxs(investPayer, vault, reserveWithAddress);
|
|
488
|
+
withdrawAndBlockReserveIxs.updateReserveAllocationIxs = [
|
|
489
|
+
updateAllocIxs.updateReserveAllocationIx,
|
|
490
|
+
...updateAllocIxs.updateLUTIxs,
|
|
491
|
+
];
|
|
492
|
+
withdrawAndBlockReserveIxs.investIxs = investIx;
|
|
493
|
+
|
|
494
|
+
return withdrawAndBlockReserveIxs;
|
|
495
|
+
}
|
|
496
|
+
|
|
446
497
|
/**
|
|
447
498
|
* This method removes a reserve from the vault allocation strategy if already part of the allocation strategy
|
|
448
499
|
* @param vault - vault to remove the reserve from
|
|
@@ -22,6 +22,11 @@ export type UpdateReserveAllocationIxs = {
|
|
|
22
22
|
updateLUTIxs: TransactionInstruction[];
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
+
export type WithdrawAndBlockReserveIxs = {
|
|
26
|
+
updateReserveAllocationIxs: TransactionInstruction[];
|
|
27
|
+
investIxs: TransactionInstruction[];
|
|
28
|
+
};
|
|
29
|
+
|
|
25
30
|
export type UpdateVaultConfigIxs = {
|
|
26
31
|
updateVaultConfigIx: TransactionInstruction;
|
|
27
32
|
updateLUTIxs: TransactionInstruction[];
|
|
@@ -1484,6 +1484,15 @@ async function main() {
|
|
|
1484
1484
|
);
|
|
1485
1485
|
});
|
|
1486
1486
|
|
|
1487
|
+
commands
|
|
1488
|
+
.command('get-market-or-vault-admin-info')
|
|
1489
|
+
.requiredOption('--address <string>', 'Address of the market or vault')
|
|
1490
|
+
.action(async ({ address }) => {
|
|
1491
|
+
const env = initializeClient(false, false);
|
|
1492
|
+
const adminInfo = await KaminoManager.getMarketOrVaultAdminInfo(env.connection, new PublicKey(address));
|
|
1493
|
+
console.log(adminInfo);
|
|
1494
|
+
});
|
|
1495
|
+
|
|
1487
1496
|
await commands.parseAsync();
|
|
1488
1497
|
}
|
|
1489
1498
|
|
|
@@ -2,7 +2,11 @@ import Decimal from 'decimal.js';
|
|
|
2
2
|
import { KaminoMarket, KaminoObligation, KaminoReserve, numberToLamportsDecimal } from '../classes';
|
|
3
3
|
import { PublicKey } from '@solana/web3.js';
|
|
4
4
|
import { lamportsToDecimal } from '../classes/utils';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
MaxWithdrawLtvCheck,
|
|
7
|
+
getMaxCollateralFromRepayAmount,
|
|
8
|
+
getMaxWithdrawLtvCheck,
|
|
9
|
+
} from './repay_with_collateral_operations';
|
|
6
10
|
|
|
7
11
|
export function calcRepayAmountWithSlippage(
|
|
8
12
|
kaminoMarket: KaminoMarket,
|
|
@@ -16,7 +20,7 @@ export function calcRepayAmountWithSlippage(
|
|
|
16
20
|
repayAmountLamports: Decimal;
|
|
17
21
|
flashRepayAmountLamports: Decimal;
|
|
18
22
|
} {
|
|
19
|
-
const
|
|
23
|
+
const interestRateAccrued = obligation
|
|
20
24
|
.estimateObligationInterestRate(
|
|
21
25
|
kaminoMarket,
|
|
22
26
|
debtReserve,
|
|
@@ -24,9 +28,9 @@ export function calcRepayAmountWithSlippage(
|
|
|
24
28
|
currentSlot
|
|
25
29
|
)
|
|
26
30
|
.toDecimalPlaces(debtReserve.state.liquidity.mintDecimals.toNumber(), Decimal.ROUND_CEIL);
|
|
27
|
-
// add 0.1% to
|
|
31
|
+
// add 0.1% to interestRateAccrued because we don't want to estimate slightly less than SC and end up not repaying enough
|
|
28
32
|
const repayAmountIrAdjusted = amount
|
|
29
|
-
.mul(
|
|
33
|
+
.mul(interestRateAccrued.mul(new Decimal('1.001')))
|
|
30
34
|
.toDecimalPlaces(debtReserve.state.liquidity.mintDecimals.toNumber(), Decimal.ROUND_CEIL);
|
|
31
35
|
|
|
32
36
|
let repayAmount: Decimal;
|
|
@@ -34,7 +38,7 @@ export function calcRepayAmountWithSlippage(
|
|
|
34
38
|
if (
|
|
35
39
|
repayAmountIrAdjusted.greaterThanOrEqualTo(
|
|
36
40
|
lamportsToDecimal(
|
|
37
|
-
obligation.
|
|
41
|
+
obligation.getBorrowByReserve(debtReserve.address)?.amount || new Decimal(0),
|
|
38
42
|
debtReserve.stats.decimals
|
|
39
43
|
)
|
|
40
44
|
)
|
|
@@ -83,8 +87,7 @@ export function calcMaxWithdrawCollateral(
|
|
|
83
87
|
debtReserveAddr: PublicKey,
|
|
84
88
|
repayAmountLamports: Decimal
|
|
85
89
|
): {
|
|
86
|
-
|
|
87
|
-
withdrawableCollLamports: Decimal;
|
|
90
|
+
maxWithdrawableCollLamports: Decimal;
|
|
88
91
|
canWithdrawAllColl: boolean;
|
|
89
92
|
repayingAllDebt: boolean;
|
|
90
93
|
} {
|
|
@@ -92,8 +95,9 @@ export function calcMaxWithdrawCollateral(
|
|
|
92
95
|
const borrow = obligation.getBorrowByReserve(debtReserveAddr)!;
|
|
93
96
|
const depositReserve = market.getReserveByAddress(deposit.reserveAddress)!;
|
|
94
97
|
const debtReserve = market.getReserveByAddress(borrow.reserveAddress)!;
|
|
95
|
-
const depositTotalLamports = deposit.amount.floor();
|
|
98
|
+
const depositTotalLamports = deposit.amount.floor(); // TODO: can remove floor, we have lamports only for deposits
|
|
96
99
|
|
|
100
|
+
// Calculate the market value of the remaining debt after repaying
|
|
97
101
|
const remainingBorrowLamports = borrow.amount.sub(repayAmountLamports).ceil();
|
|
98
102
|
const remainingBorrowAmount = remainingBorrowLamports.div(debtReserve.getMintFactor());
|
|
99
103
|
let remainingBorrowsValue = remainingBorrowAmount.mul(debtReserve.getOracleMarketPrice());
|
|
@@ -103,17 +107,31 @@ export function calcMaxWithdrawCollateral(
|
|
|
103
107
|
.filter((p) => !p.reserveAddress.equals(borrow.reserveAddress))
|
|
104
108
|
.reduce((acc, b) => acc.add(b.marketValueRefreshed), new Decimal('0'));
|
|
105
109
|
}
|
|
106
|
-
const maxWithdrawLtvCheck = getMaxWithdrawLtvCheck(obligation);
|
|
107
110
|
|
|
108
|
-
|
|
111
|
+
const hypotheticalWithdrawLamports = getMaxCollateralFromRepayAmount(
|
|
112
|
+
repayAmountLamports.div(debtReserve.getMintFactor()),
|
|
113
|
+
debtReserve,
|
|
114
|
+
depositReserve
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
// Calculate the max withdraw ltv we can withdraw up to
|
|
118
|
+
const maxWithdrawLtvCheck = getMaxWithdrawLtvCheck(
|
|
119
|
+
obligation,
|
|
120
|
+
repayAmountLamports,
|
|
121
|
+
debtReserve,
|
|
122
|
+
hypotheticalWithdrawLamports,
|
|
123
|
+
depositReserve
|
|
124
|
+
);
|
|
125
|
+
// Calculate the max borrowable value remaining against deposits
|
|
126
|
+
let maxBorrowableValueRemainingAgainstDeposits = new Decimal('0');
|
|
109
127
|
if (obligation.getDeposits().length > 1) {
|
|
110
|
-
|
|
128
|
+
maxBorrowableValueRemainingAgainstDeposits = obligation
|
|
111
129
|
.getDeposits()
|
|
112
130
|
.filter((p) => !p.reserveAddress.equals(deposit.reserveAddress))
|
|
113
131
|
.reduce((acc, d) => {
|
|
114
132
|
const { maxLtv, liquidationLtv } = obligation.getLtvForReserve(
|
|
115
133
|
market,
|
|
116
|
-
market.
|
|
134
|
+
market.getExistingReserveByAddress(d.reserveAddress)
|
|
117
135
|
);
|
|
118
136
|
const maxWithdrawLtv =
|
|
119
137
|
maxWithdrawLtvCheck === MaxWithdrawLtvCheck.LIQUIDATION_THRESHOLD ? liquidationLtv : maxLtv;
|
|
@@ -121,11 +139,11 @@ export function calcMaxWithdrawCollateral(
|
|
|
121
139
|
}, new Decimal('0'));
|
|
122
140
|
}
|
|
123
141
|
|
|
124
|
-
//
|
|
125
|
-
|
|
142
|
+
// if the remaining borrow value is less than the
|
|
143
|
+
// this means that the user's ltv is less or equal to the max ltv
|
|
144
|
+
if (maxBorrowableValueRemainingAgainstDeposits.gte(remainingBorrowsValue)) {
|
|
126
145
|
return {
|
|
127
|
-
|
|
128
|
-
withdrawableCollLamports: depositTotalLamports,
|
|
146
|
+
maxWithdrawableCollLamports: depositTotalLamports,
|
|
129
147
|
canWithdrawAllColl: true,
|
|
130
148
|
repayingAllDebt: repayAmountLamports.gte(borrow.amount),
|
|
131
149
|
};
|
|
@@ -138,16 +156,15 @@ export function calcMaxWithdrawCollateral(
|
|
|
138
156
|
maxWithdrawLtvCheck === MaxWithdrawLtvCheck.LIQUIDATION_THRESHOLD ? collLiquidationLtv : collMaxLtv;
|
|
139
157
|
const numerator = deposit.marketValueRefreshed
|
|
140
158
|
.mul(maxWithdrawLtv)
|
|
141
|
-
.add(
|
|
159
|
+
.add(maxBorrowableValueRemainingAgainstDeposits)
|
|
142
160
|
.sub(remainingBorrowsValue);
|
|
143
161
|
|
|
144
162
|
const denominator = depositReserve.getOracleMarketPrice().mul(maxWithdrawLtv);
|
|
145
163
|
const maxCollWithdrawAmount = numerator.div(denominator);
|
|
146
|
-
const
|
|
164
|
+
const maxWithdrawableCollLamports = maxCollWithdrawAmount.mul(depositReserve.getMintFactor()).floor();
|
|
147
165
|
|
|
148
166
|
return {
|
|
149
|
-
|
|
150
|
-
withdrawableCollLamports,
|
|
167
|
+
maxWithdrawableCollLamports,
|
|
151
168
|
canWithdrawAllColl: false,
|
|
152
169
|
repayingAllDebt: repayAmountLamports.gte(borrow.amount),
|
|
153
170
|
};
|
|
@@ -158,7 +175,7 @@ export function estimateDebtRepaymentWithColl(props: {
|
|
|
158
175
|
collAmount: Decimal; // in decimals
|
|
159
176
|
priceDebtToColl: Decimal;
|
|
160
177
|
slippagePct: Decimal;
|
|
161
|
-
|
|
178
|
+
flashLoanFeePct: Decimal;
|
|
162
179
|
kaminoMarket: KaminoMarket;
|
|
163
180
|
debtTokenMint: PublicKey;
|
|
164
181
|
obligation: KaminoObligation;
|
|
@@ -168,34 +185,32 @@ export function estimateDebtRepaymentWithColl(props: {
|
|
|
168
185
|
collAmount,
|
|
169
186
|
priceDebtToColl,
|
|
170
187
|
slippagePct,
|
|
171
|
-
|
|
188
|
+
flashLoanFeePct,
|
|
172
189
|
kaminoMarket,
|
|
173
190
|
debtTokenMint,
|
|
174
191
|
obligation,
|
|
175
192
|
currentSlot,
|
|
176
193
|
} = props;
|
|
177
|
-
const
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
throw new Error('Debt reserve not found');
|
|
182
|
-
}
|
|
194
|
+
const slippageMultiplier = new Decimal(1.0).add(slippagePct.div('100'));
|
|
195
|
+
const flashLoanFeeMultiplier = new Decimal(1.0).add(flashLoanFeePct.div('100'));
|
|
196
|
+
|
|
197
|
+
const debtReserve = kaminoMarket.getExistingReserveByMint(debtTokenMint);
|
|
183
198
|
|
|
184
|
-
const debtAfterSwap = collAmount.div(
|
|
185
|
-
const debtAfterFlashLoanRepay = debtAfterSwap.div(
|
|
199
|
+
const debtAfterSwap = collAmount.div(slippageMultiplier).div(priceDebtToColl);
|
|
200
|
+
const debtAfterFlashLoanRepay = debtAfterSwap.div(flashLoanFeeMultiplier);
|
|
186
201
|
|
|
187
|
-
const
|
|
202
|
+
const accruedInterestRate = obligation
|
|
188
203
|
.estimateObligationInterestRate(
|
|
189
204
|
kaminoMarket,
|
|
190
205
|
debtReserve,
|
|
191
|
-
obligation
|
|
206
|
+
obligation.getObligationLiquidityByReserve(debtReserve.address),
|
|
192
207
|
currentSlot
|
|
193
208
|
)
|
|
194
209
|
.toDecimalPlaces(debtReserve.state.liquidity.mintDecimals.toNumber(), Decimal.ROUND_CEIL);
|
|
195
210
|
|
|
196
211
|
// Estimate slightly more, by adding 1% to IR in order to avoid the case where UI users can repay the max we allow them
|
|
197
212
|
const debtIrAdjusted = debtAfterFlashLoanRepay
|
|
198
|
-
.div(
|
|
213
|
+
.div(accruedInterestRate.mul(new Decimal('1.01')))
|
|
199
214
|
.toDecimalPlaces(debtReserve.state.liquidity.mintDecimals.toNumber(), Decimal.ROUND_CEIL);
|
|
200
215
|
|
|
201
216
|
return debtIrAdjusted;
|
|
@@ -205,19 +220,21 @@ export function estimateCollNeededForDebtRepayment(props: {
|
|
|
205
220
|
debtAmount: Decimal; // in decimals
|
|
206
221
|
priceDebtToColl: Decimal;
|
|
207
222
|
slippagePct: Decimal;
|
|
208
|
-
|
|
223
|
+
flashLoanFeePct: Decimal;
|
|
209
224
|
}): Decimal {
|
|
210
225
|
const {
|
|
211
226
|
debtAmount, // in decimals
|
|
212
227
|
priceDebtToColl,
|
|
213
228
|
slippagePct,
|
|
214
|
-
|
|
229
|
+
flashLoanFeePct,
|
|
215
230
|
} = props;
|
|
216
|
-
const
|
|
217
|
-
const
|
|
231
|
+
const slippageRatio = slippagePct.div('100');
|
|
232
|
+
const flashLoanFeeRatio = flashLoanFeePct.div('100');
|
|
233
|
+
const slippageMultiplier = new Decimal(1.0).add(slippageRatio);
|
|
234
|
+
const flashLoanFeeMultiplier = new Decimal(1.0).add(flashLoanFeeRatio);
|
|
218
235
|
|
|
219
|
-
const debtFlashLoanRepay = debtAmount.mul(
|
|
220
|
-
const collToSwap = debtFlashLoanRepay.mul(
|
|
236
|
+
const debtFlashLoanRepay = debtAmount.mul(flashLoanFeeMultiplier);
|
|
237
|
+
const collToSwap = debtFlashLoanRepay.mul(slippageMultiplier).mul(priceDebtToColl);
|
|
221
238
|
|
|
222
239
|
return collToSwap;
|
|
223
240
|
}
|