@kamino-finance/klend-sdk 5.2.13 → 5.2.14
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 +2 -0
- package/dist/classes/obligation.d.ts.map +1 -1
- package/dist/classes/obligation.js +12 -6
- package/dist/classes/obligation.js.map +1 -1
- package/dist/classes/types.d.ts +1 -1
- package/dist/classes/types.d.ts.map +1 -1
- package/dist/classes/vault.d.ts +1 -1
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +16 -3
- package/dist/classes/vault.js.map +1 -1
- package/dist/client_kamino_manager.d.ts.map +1 -1
- package/dist/client_kamino_manager.js +38 -4
- package/dist/client_kamino_manager.js.map +1 -1
- package/dist/lending_operations/repay_with_collateral_calcs.d.ts +4 -2
- package/dist/lending_operations/repay_with_collateral_calcs.d.ts.map +1 -1
- package/dist/lending_operations/repay_with_collateral_calcs.js +45 -52
- package/dist/lending_operations/repay_with_collateral_calcs.js.map +1 -1
- package/dist/lending_operations/repay_with_collateral_operations.d.ts +7 -0
- package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
- package/dist/lending_operations/repay_with_collateral_operations.js +13 -3
- package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
- package/package.json +1 -1
- package/src/classes/obligation.ts +15 -6
- package/src/classes/types.ts +16 -17
- package/src/classes/vault.ts +18 -4
- package/src/client_kamino_manager.ts +55 -4
- package/src/lending_operations/repay_with_collateral_calcs.ts +55 -61
- package/src/lending_operations/repay_with_collateral_operations.ts +24 -4
- package/src/leverage/operations.ts +1 -1
|
@@ -46,63 +46,56 @@ const calcFlashRepayAmount = (props) => {
|
|
|
46
46
|
};
|
|
47
47
|
};
|
|
48
48
|
exports.calcFlashRepayAmount = calcFlashRepayAmount;
|
|
49
|
-
function calcMaxWithdrawCollateral(
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
remainingDebtAmountLamports = remainingDebtAmountLamports.sub(repayAmountLamports);
|
|
64
|
-
}
|
|
65
|
-
const remainingDebtBfWeightedValue = remainingDebtAmountLamports
|
|
66
|
-
.ceil()
|
|
67
|
-
.div(debtReserve.getMintFactor())
|
|
68
|
-
.mul(debtBorrowFactor)
|
|
69
|
-
.mul(debtOraclePx);
|
|
70
|
-
totalRemainingDebtValue = totalRemainingDebtValue.add(remainingDebtBfWeightedValue);
|
|
49
|
+
function calcMaxWithdrawCollateral(market, obligation, collReserveAddr, debtReserveAddr, repayAmountLamports) {
|
|
50
|
+
const deposit = obligation.getDepositByReserve(collReserveAddr);
|
|
51
|
+
const borrow = obligation.getBorrowByReserve(debtReserveAddr);
|
|
52
|
+
const depositReserve = market.getReserveByAddress(deposit.reserveAddress);
|
|
53
|
+
const debtReserve = market.getReserveByAddress(borrow.reserveAddress);
|
|
54
|
+
const depositTotalLamports = deposit.amount.floor();
|
|
55
|
+
const remainingBorrowLamports = borrow.amount.sub(repayAmountLamports).ceil();
|
|
56
|
+
const remainingBorrowAmount = remainingBorrowLamports.div(debtReserve.getMintFactor());
|
|
57
|
+
let remainingBorrowsValue = remainingBorrowAmount.mul(debtReserve.getOracleMarketPrice());
|
|
58
|
+
if (obligation.getBorrows().length > 1) {
|
|
59
|
+
remainingBorrowsValue = obligation
|
|
60
|
+
.getBorrows()
|
|
61
|
+
.filter((p) => !p.reserveAddress.equals(borrow.reserveAddress))
|
|
62
|
+
.reduce((acc, b) => acc.add(b.marketValueRefreshed), new decimal_js_1.default('0'));
|
|
71
63
|
}
|
|
72
|
-
let
|
|
73
|
-
if (
|
|
74
|
-
|
|
64
|
+
let remainingDepositsValueWithLtv = new decimal_js_1.default('0');
|
|
65
|
+
if (obligation.getDeposits().length > 1) {
|
|
66
|
+
remainingDepositsValueWithLtv = obligation
|
|
67
|
+
.getDeposits()
|
|
68
|
+
.filter((p) => !p.reserveAddress.equals(deposit.reserveAddress))
|
|
69
|
+
.reduce((acc, d) => {
|
|
70
|
+
const { maxLtv } = obligation.getLtvForReserve(market, market.getReserveByAddress(d.reserveAddress));
|
|
71
|
+
return acc.add(d.marketValueRefreshed.mul(maxLtv));
|
|
72
|
+
}, new decimal_js_1.default('0'));
|
|
75
73
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
.floor()
|
|
85
|
-
.div(otherCollReserve.getMintFactor())
|
|
86
|
-
.mul(otherCollOraclePx)
|
|
87
|
-
.mul(otherCollMaxLtv);
|
|
88
|
-
totalOtherCollateralValue = totalOtherCollateralValue.add(otherCollValue);
|
|
89
|
-
}
|
|
90
|
-
const numerator = initialCollValue.mul(collMaxLtv).add(totalOtherCollateralValue).sub(totalRemainingDebtValue);
|
|
91
|
-
// If all collateral cannot cover the remaining debt
|
|
92
|
-
if (numerator.lte('0')) {
|
|
93
|
-
return { canWithdrawRemainingColl: false, withdrawableCollLamports: new decimal_js_1.default(0) };
|
|
94
|
-
}
|
|
95
|
-
const denominator = collOraclePx.mul(collMaxLtv);
|
|
96
|
-
const maxCollWithdrawAmount = numerator.div(denominator);
|
|
97
|
-
const maxCollateralWithdrawalAmountLamports = maxCollWithdrawAmount.mul(collReserve.getMintFactor()).floor();
|
|
98
|
-
let withdrawableCollLamports;
|
|
99
|
-
if (canWithdrawRemainingColl) {
|
|
100
|
-
withdrawableCollLamports = decimal_js_1.default.min(maxCollateralWithdrawalAmountLamports, collPosition.amount).floor();
|
|
74
|
+
// can withdraw all coll
|
|
75
|
+
if (remainingDepositsValueWithLtv.gte(remainingBorrowsValue)) {
|
|
76
|
+
return {
|
|
77
|
+
repayAmountLamports: repayAmountLamports,
|
|
78
|
+
withdrawableCollLamports: depositTotalLamports,
|
|
79
|
+
canWithdrawAllColl: true,
|
|
80
|
+
repayingAllDebt: repayAmountLamports.gte(borrow.amount),
|
|
81
|
+
};
|
|
101
82
|
}
|
|
102
83
|
else {
|
|
103
|
-
|
|
84
|
+
const { maxLtv: collMaxLtv } = obligation.getLtvForReserve(market, market.getReserveByAddress(depositReserve.address));
|
|
85
|
+
const numerator = deposit.marketValueRefreshed
|
|
86
|
+
.mul(collMaxLtv)
|
|
87
|
+
.add(remainingDepositsValueWithLtv)
|
|
88
|
+
.sub(remainingBorrowsValue);
|
|
89
|
+
const denominator = depositReserve.getOracleMarketPrice().mul(collMaxLtv);
|
|
90
|
+
const maxCollWithdrawAmount = numerator.div(denominator);
|
|
91
|
+
const withdrawableCollLamports = maxCollWithdrawAmount.mul(depositReserve.getMintFactor()).floor();
|
|
92
|
+
return {
|
|
93
|
+
repayAmountLamports: repayAmountLamports,
|
|
94
|
+
withdrawableCollLamports,
|
|
95
|
+
canWithdrawAllColl: false,
|
|
96
|
+
repayingAllDebt: repayAmountLamports.gte(borrow.amount),
|
|
97
|
+
};
|
|
104
98
|
}
|
|
105
|
-
return { canWithdrawRemainingColl, withdrawableCollLamports };
|
|
106
99
|
}
|
|
107
100
|
function estimateDebtRepaymentWithColl(props) {
|
|
108
101
|
const { collAmount, priceDebtToColl, slippagePct, flashBorrowReserveFlashLoanFeePercentage, kaminoMarket, debtTokenMint, obligation, currentSlot, } = props;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repay_with_collateral_calcs.js","sourceRoot":"","sources":["../../src/lending_operations/repay_with_collateral_calcs.ts"],"names":[],"mappings":";;;;;;AAKA,kEAiDC;AAuBD,
|
|
1
|
+
{"version":3,"file":"repay_with_collateral_calcs.js","sourceRoot":"","sources":["../../src/lending_operations/repay_with_collateral_calcs.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,13 @@ export type RepayWithCollIxsResponse<QuoteResponse> = {
|
|
|
12
12
|
export type InitialInputs<QuoteResponse> = {
|
|
13
13
|
debtRepayAmountLamports: Decimal;
|
|
14
14
|
flashRepayAmountLamports: Decimal;
|
|
15
|
+
/**
|
|
16
|
+
* The amount of collateral available to withdraw, if this is less than the swap input amount, then the swap may fail due to slippage, or tokens may be debited from the user's ATA, so the caller needs to check this
|
|
17
|
+
*/
|
|
18
|
+
maxCollateralWithdrawLamports: Decimal;
|
|
19
|
+
/**
|
|
20
|
+
* The quote from the provided quoter
|
|
21
|
+
*/
|
|
15
22
|
swapQuote: SwapQuote<QuoteResponse>;
|
|
16
23
|
currentSlot: number;
|
|
17
24
|
klendAccounts: Array<PublicKey>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repay_with_collateral_operations.d.ts","sourceRoot":"","sources":["../../src/lending_operations/repay_with_collateral_operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,YAAY,EAAE,gBAAgB,EAAiB,MAAM,YAAY,CAAC;AACzF,OAAO,EAEL,UAAU,EACV,SAAS,EAET,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAIL,YAAY,EAGb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,yBAAyB,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,OAAO,MAAM,YAAY,CAAC;AAGjC,MAAM,MAAM,wBAAwB,CAAC,aAAa,IAAI;IACpD,GAAG,EAAE,sBAAsB,EAAE,CAAC;IAC9B,YAAY,EAAE,yBAAyB,EAAE,CAAC;IAC1C,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,aAAa,IAAI;IACzC,uBAAuB,EAAE,OAAO,CAAC;IACjC,wBAAwB,EAAE,OAAO,CAAC;IAClC,SAAS,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CACjC,CAAC;AAEF,UAAU,4BAA4B,CAAC,aAAa;IAClD,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,SAAS,CAAC;IACzB,aAAa,EAAE,SAAS,CAAC;IACzB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uBAAuB,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACnD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,MAAM,EAAE,iBAAiB,CAAC,aAAa,CAAC,CAAC;CAC1C;AAED,wBAAsB,0BAA0B,CAAC,aAAa,EAAE,EAC9D,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,EACV,MAAM,EACN,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,GACb,EAAE,4BAA4B,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC;IACvD,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;CAC7C,CAAC,
|
|
1
|
+
{"version":3,"file":"repay_with_collateral_operations.d.ts","sourceRoot":"","sources":["../../src/lending_operations/repay_with_collateral_operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,YAAY,EAAE,gBAAgB,EAAiB,MAAM,YAAY,CAAC;AACzF,OAAO,EAEL,UAAU,EACV,SAAS,EAET,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAIL,YAAY,EAGb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,yBAAyB,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,OAAO,MAAM,YAAY,CAAC;AAGjC,MAAM,MAAM,wBAAwB,CAAC,aAAa,IAAI;IACpD,GAAG,EAAE,sBAAsB,EAAE,CAAC;IAC9B,YAAY,EAAE,yBAAyB,EAAE,CAAC;IAC1C,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,aAAa,IAAI;IACzC,uBAAuB,EAAE,OAAO,CAAC;IACjC,wBAAwB,EAAE,OAAO,CAAC;IAClC;;OAEG;IACH,6BAA6B,EAAE,OAAO,CAAC;IACvC;;OAEG;IACH,SAAS,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CACjC,CAAC;AAEF,UAAU,4BAA4B,CAAC,aAAa;IAClD,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,SAAS,CAAC;IACzB,aAAa,EAAE,SAAS,CAAC;IACzB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uBAAuB,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACnD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,MAAM,EAAE,iBAAiB,CAAC,aAAa,CAAC,CAAC;CAC1C;AAED,wBAAsB,0BAA0B,CAAC,aAAa,EAAE,EAC9D,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,EACV,MAAM,EACN,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,GACb,EAAE,4BAA4B,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC;IACvD,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;CAC7C,CAAC,CAmGD;AAED,UAAU,qBAAqB,CAAC,aAAa,CAAE,SAAQ,4BAA4B,CAAC,aAAa,CAAC;IAChG,OAAO,EAAE,oBAAoB,CAAC,aAAa,CAAC,CAAC;IAC7C,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CACjD;AAED,wBAAsB,mBAAmB,CAAC,aAAa,EAAE,EACvD,WAAW,EACX,iBAAiB,EACjB,uBAAuB,EACvB,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,EACV,MAAM,EACN,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,MAAoB,GACrB,EAAE,qBAAqB,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,wBAAwB,CAAC,aAAa,CAAC,CAAC,CA8DzF"}
|
|
@@ -28,7 +28,7 @@ async function getRepayWithCollSwapInputs({ collTokenMint, currentSlot, debtToke
|
|
|
28
28
|
if (!collPosition) {
|
|
29
29
|
throw new Error(`Collateral position not found for ${collReserve.stats.symbol} reserve ${collReserve.address} in obligation ${obligation.obligationAddress}`);
|
|
30
30
|
}
|
|
31
|
-
const { withdrawableCollLamports } = (0, repay_with_collateral_calcs_1.calcMaxWithdrawCollateral)(kaminoMarket, collReserve.address, debtReserve.address,
|
|
31
|
+
const { withdrawableCollLamports } = (0, repay_with_collateral_calcs_1.calcMaxWithdrawCollateral)(kaminoMarket, obligation, collReserve.address, debtReserve.address, repayAmountLamports);
|
|
32
32
|
// 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
|
|
33
33
|
const maxCollNeededFromOracle = finalRepayAmount
|
|
34
34
|
.mul(debtReserve.getOracleMarketPrice())
|
|
@@ -68,6 +68,7 @@ async function getRepayWithCollSwapInputs({ collTokenMint, currentSlot, debtToke
|
|
|
68
68
|
initialInputs: {
|
|
69
69
|
debtRepayAmountLamports: repayAmountLamports,
|
|
70
70
|
flashRepayAmountLamports,
|
|
71
|
+
maxCollateralWithdrawLamports: withdrawableCollLamports,
|
|
71
72
|
swapQuote,
|
|
72
73
|
currentSlot,
|
|
73
74
|
klendAccounts: uniqueKlendAccounts,
|
|
@@ -88,11 +89,20 @@ async function getRepayWithCollIxs({ repayAmount, isClosingPosition, budgetAndPr
|
|
|
88
89
|
budgetAndPriorityFeeIxs,
|
|
89
90
|
scopeRefresh,
|
|
90
91
|
});
|
|
91
|
-
const { debtRepayAmountLamports, flashRepayAmountLamports, swapQuote } = initialInputs;
|
|
92
|
+
const { debtRepayAmountLamports, flashRepayAmountLamports, maxCollateralWithdrawLamports, swapQuote } = initialInputs;
|
|
92
93
|
const { inputAmountLamports: collSwapInLamports } = swapInputs;
|
|
93
94
|
const collReserve = kaminoMarket.getReserveByMint(collTokenMint);
|
|
94
95
|
const debtReserve = kaminoMarket.getReserveByMint(debtTokenMint);
|
|
95
|
-
|
|
96
|
+
// the client should use these values to prevent this input, but the tx may succeed, so we don't want to fail
|
|
97
|
+
// there is also a chance that the tx will consume debt token from the user's ata which they would not expect
|
|
98
|
+
if (collSwapInLamports.greaterThan(maxCollateralWithdrawLamports)) {
|
|
99
|
+
logger(`Collateral swap in amount ${collSwapInLamports} exceeds max withdrawable collateral ${maxCollateralWithdrawLamports}, tx may fail with slippage`);
|
|
100
|
+
swapInputs.inputAmountLamports = maxCollateralWithdrawLamports;
|
|
101
|
+
}
|
|
102
|
+
const actualSwapInLamports = decimal_js_1.default.min(collSwapInLamports, maxCollateralWithdrawLamports);
|
|
103
|
+
logger(`Expected to swap in: ${actualSwapInLamports.div(collReserve.getMintFactor())} ${collReserve.symbol}, for: ${flashRepayAmountLamports.div(debtReserve.getMintFactor())} ${debtReserve.symbol}, quoter px: ${swapQuote.priceAInB} ${debtReserve.symbol}/${collReserve.symbol}, required px: ${flashRepayAmountLamports
|
|
104
|
+
.div(debtReserve.getMintFactor())
|
|
105
|
+
.div(actualSwapInLamports.div(collReserve.getMintFactor()))} ${debtReserve.symbol}/${collReserve.symbol}`);
|
|
96
106
|
const swapResponse = await swapper(swapInputs, initialInputs.klendAccounts, swapQuote);
|
|
97
107
|
const ixs = await buildRepayWithCollateralIxs(kaminoMarket, debtReserve, collReserve, obligation, referrer, currentSlot, budgetAndPriorityFeeIxs, scopeRefresh, swapResponse, isClosingPosition, debtRepayAmountLamports, swapInputs.inputAmountLamports);
|
|
98
108
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repay_with_collateral_operations.js","sourceRoot":"","sources":["../../src/lending_operations/repay_with_collateral_operations.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"repay_with_collateral_operations.js","sourceRoot":"","sources":["../../src/lending_operations/repay_with_collateral_operations.ts"],"names":[],"mappings":";;;;;AAyDA,gEAkHC;AAOD,kDA4EC;AA9PD,wCAAyF;AACzF,0CAOqB;AACrB,oCAOkB;AAElB,4DAAiC;AACjC,+EAAuG;AAsChG,KAAK,UAAU,0BAA0B,CAAgB,EAC9D,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,EACV,MAAM,EACN,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,GACgC;IAI5C,MAAM,WAAW,GAAG,YAAY,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACjE,MAAM,WAAW,GAAG,YAAY,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACjE,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,gCAAgC,WAAW,wBAAwB,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAClH,CAAC;IACD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,0BAA0B,WAAW,wBAAwB,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC5G,CAAC;IAED,MAAM,EACJ,mBAAmB,EACnB,wBAAwB,EACxB,WAAW,EAAE,gBAAgB,GAC9B,GAAG,IAAA,yDAA2B,EAAC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IAE3G,MAAM,YAAY,GAAG,UAAU,CAAC,kBAAkB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACxE,MAAM,YAAY,GAAG,UAAU,CAAC,mBAAmB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACzE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,+BAA+B,WAAW,CAAC,KAAK,CAAC,MAAM,YAAY,WAAW,CAAC,OAAO,kBAAkB,UAAU,CAAC,iBAAiB,EAAE,CACvI,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,qCAAqC,WAAW,CAAC,KAAK,CAAC,MAAM,YAAY,WAAW,CAAC,OAAO,kBAAkB,UAAU,CAAC,iBAAiB,EAAE,CAC7I,CAAC;IACJ,CAAC;IACD,MAAM,EAAE,wBAAwB,EAAE,GAAG,IAAA,uDAAyB,EAC5D,YAAY,EACZ,UAAU,EACV,WAAW,CAAC,OAAO,EACnB,WAAW,CAAC,OAAO,EACnB,mBAAmB,CACpB,CAAC;IAEF,iIAAiI;IACjI,MAAM,uBAAuB,GAAG,gBAAgB;SAC7C,GAAG,CAAC,WAAW,CAAC,oBAAoB,EAAE,CAAC;SACvC,GAAG,CAAC,WAAW,CAAC,oBAAoB,EAAE,CAAC;SACvC,GAAG,CAAC,KAAK,CAAC;SACV,GAAG,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC;SAChC,IAAI,EAAE,CAAC;IACV,MAAM,mBAAmB,GAAG,oBAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,uBAAuB,CAAC,CAAC;IAE3F,yEAAyE;IACzE,MAAM,QAAQ,GAAG,MAAM,2BAA2B,CAChD,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,uBAAuB,EACvB,YAAY,EACZ;QACE,YAAY,EAAE,EAAE;QAChB,OAAO,EAAE,EAAE;QACX,YAAY,EAAE,EAAE;KACjB,EACD,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,CACpB,CAAC;IACF,MAAM,mBAAmB,GAAG,IAAA,sBAAc,EAAC,QAAQ,CAAC,CAAC;IAErD,MAAM,eAAe,GAAe;QAClC,mBAAmB;QACnB,SAAS,EAAE,aAAa;QACxB,UAAU,EAAE,aAAa;QACzB,oBAAoB,EAAE,IAAI,oBAAO,CAAC,CAAC,CAAC,EAAE,wBAAwB;KAC/D,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC;IAErE,MAAM,qBAAqB,GAAG,SAAS,CAAC,SAAS,CAAC;IAClD,MAAM,kBAAkB,GAAG,wBAAwB;SAChD,GAAG,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC;SAChC,GAAG,CAAC,qBAAqB,CAAC;SAC1B,GAAG,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC;SAChC,IAAI,EAAE,CAAC;IAEV,OAAO;QACL,UAAU,EAAE;YACV,mBAAmB,EAAE,kBAAkB;YACvC,oBAAoB,EAAE,wBAAwB;YAC9C,SAAS,EAAE,aAAa;YACxB,UAAU,EAAE,aAAa;YACzB,oBAAoB,EAAE,IAAI,oBAAO,CAAC,CAAC,CAAC,EAAE,wBAAwB;SAC/D;QACD,aAAa,EAAE;YACb,uBAAuB,EAAE,mBAAmB;YAC5C,wBAAwB;YACxB,6BAA6B,EAAE,wBAAwB;YACvD,SAAS;YACT,WAAW;YACX,aAAa,EAAE,mBAAmB;SACnC;KACF,CAAC;AACJ,CAAC;AAOM,KAAK,UAAU,mBAAmB,CAAgB,EACvD,WAAW,EACX,iBAAiB,EACjB,uBAAuB,EACvB,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,EACV,MAAM,EACN,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,MAAM,GAAG,OAAO,CAAC,GAAG,GACiB;IACrC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,MAAM,0BAA0B,CAAC;QACrE,aAAa;QACb,WAAW;QACX,aAAa;QACb,YAAY;QACZ,UAAU;QACV,MAAM;QACN,QAAQ;QACR,WAAW;QACX,iBAAiB;QACjB,uBAAuB;QACvB,YAAY;KACb,CAAC,CAAC;IACH,MAAM,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,6BAA6B,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC;IACtH,MAAM,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,GAAG,UAAU,CAAC;IAE/D,MAAM,WAAW,GAAG,YAAY,CAAC,gBAAgB,CAAC,aAAa,CAAE,CAAC;IAClE,MAAM,WAAW,GAAG,YAAY,CAAC,gBAAgB,CAAC,aAAa,CAAE,CAAC;IAElE,6GAA6G;IAC7G,6GAA6G;IAC7G,IAAI,kBAAkB,CAAC,WAAW,CAAC,6BAA6B,CAAC,EAAE,CAAC;QAClE,MAAM,CACJ,6BAA6B,kBAAkB,wCAAwC,6BAA6B,6BAA6B,CAClJ,CAAC;QACF,UAAU,CAAC,mBAAmB,GAAG,6BAA6B,CAAC;IACjE,CAAC;IAED,MAAM,oBAAoB,GAAG,oBAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,6BAA6B,CAAC,CAAC;IAC5F,MAAM,CACJ,wBAAwB,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC,IAC3E,WAAW,CAAC,MACd,UAAU,wBAAwB,CAAC,GAAG,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC,IAAI,WAAW,CAAC,MAAM,gBACvF,SAAS,CAAC,SACZ,IAAI,WAAW,CAAC,MAAM,IAAI,WAAW,CAAC,MAAM,kBAAkB,wBAAwB;SACnF,GAAG,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC;SAChC,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,WAAW,CAAC,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,CAC5G,CAAC;IAEF,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IACvF,MAAM,GAAG,GAAG,MAAM,2BAA2B,CAC3C,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,uBAAuB,EACvB,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,uBAAuB,EACvB,UAAU,CAAC,mBAAmB,CAC/B,CAAC;IAEF,OAAO;QACL,GAAG;QACH,YAAY,EAAE,YAAY,CAAC,YAAY;QACvC,UAAU;QACV,aAAa;KACd,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,2BAA2B,CACxC,MAAoB,EACpB,WAA0B,EAC1B,WAA0B,EAC1B,UAA4B,EAC5B,QAAmB,EACnB,WAAmB,EACnB,uBAA6D,EAC7D,YAAsC,EACtC,YAA0B,EAC1B,iBAA0B,EAC1B,uBAAgC,EAChC,oBAA6B;IAE7B,+BAA+B;IAC/B,MAAM,UAAU,GAAG,uBAAuB,IAAI,IAAA,0CAAkC,EAAC,SAAS,CAAC,CAAC;IAE5F,MAAM,IAAI,GAAG;QACX,EAAE,IAAI,EAAE,WAAW,CAAC,gBAAgB,EAAE,EAAE,YAAY,EAAE,WAAW,CAAC,wBAAwB,EAAE,EAAE;QAC9F,EAAE,IAAI,EAAE,WAAW,CAAC,gBAAgB,EAAE,EAAE,YAAY,EAAE,WAAW,CAAC,wBAAwB,EAAE,EAAE;KAC/F,CAAC;IAEF,MAAM,UAAU,GAAG,IAAA,4BAAoB,EAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,GAAG,UAAU,CAAC;IAE7C,0DAA0D;IAC1D,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,IAAA,mCAAwB,EAAC;QACjE,cAAc,EAAE,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM;QACrD,eAAe,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK;QACvC,sBAAsB,EAAE,MAAM,CAAC,yBAAyB,EAAE;QAC1D,oBAAoB,EAAE,MAAM,CAAC,UAAU,EAAE;QACzC,OAAO,EAAE,WAAW;QACpB,cAAc,EAAE,uBAAuB;QACvC,cAAc,EAAE,YAAY;QAC5B,eAAe,EAAE,MAAM,CAAC,SAAS;QACjC,kBAAkB,EAAE,MAAM,CAAC,SAAS;QACpC,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;IAEH,MAAM,qBAAqB,GAAG,CAAC,iBAAiB,IAAI,UAAU,CAAC,KAAK,CAAC,cAAc,KAAK,CAAC,CAAC;IAE1F,+FAA+F;IAC/F,MAAM,sBAAsB,GAAG,MAAM,sBAAY,CAAC,yBAAyB,CACzE,MAAM,EACN,iBAAiB,CAAC,CAAC,CAAC,eAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,QAAQ,EAAE,EAChE,WAAW,CAAC,gBAAgB,EAAE,EAC9B,iBAAiB,CAAC,CAAC,CAAC,eAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,QAAQ,EAAE,EAC7D,WAAW,CAAC,gBAAgB,EAAE,EAC9B,UAAU,CAAC,KAAK,CAAC,KAAK,EACtB,WAAW,EACX,UAAU,EACV,CAAC,EACD,KAAK,EACL,qBAAqB,EACrB,SAAS,EACT,QAAQ,EACR,YAAY,CACb,CAAC;IAEF,iDAAiD;IACjD,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC;IAC/C,MAAM,gBAAgB,GAAG,IAAA,8BAAsB,EAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAE7D,OAAO;QACL,GAAG,UAAU;QACb,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;QACvC,cAAc;QACd,GAAG,YAAY;QACf,GAAG,sBAAY,CAAC,WAAW,CAAC,sBAAsB,CAAC;QACnD,GAAG,gBAAgB;QACnB,aAAa;KACd,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -32,6 +32,7 @@ export type Position = {
|
|
|
32
32
|
export type ObligationStats = {
|
|
33
33
|
userTotalDeposit: Decimal;
|
|
34
34
|
userTotalCollateralDeposit: Decimal;
|
|
35
|
+
userTotalLiquidatableDeposit: Decimal;
|
|
35
36
|
userTotalBorrow: Decimal;
|
|
36
37
|
userTotalBorrowBorrowFactorAdjusted: Decimal;
|
|
37
38
|
borrowLimit: Decimal;
|
|
@@ -55,6 +56,7 @@ interface DepositStats {
|
|
|
55
56
|
deposits: Map<PublicKey, Position>;
|
|
56
57
|
userTotalDeposit: Decimal;
|
|
57
58
|
userTotalCollateralDeposit: Decimal;
|
|
59
|
+
userTotalLiquidatableDeposit: Decimal;
|
|
58
60
|
borrowLimit: Decimal;
|
|
59
61
|
liquidationLtv: Decimal;
|
|
60
62
|
borrowLiquidationLimit: Decimal;
|
|
@@ -639,7 +641,7 @@ export class KaminoObligation {
|
|
|
639
641
|
|
|
640
642
|
newStats.netAccountValue = newStats.userTotalDeposit.minus(newStats.userTotalBorrow);
|
|
641
643
|
newStats.loanToValue = valueOrZero(
|
|
642
|
-
newStats.userTotalBorrowBorrowFactorAdjusted.dividedBy(newStats.
|
|
644
|
+
newStats.userTotalBorrowBorrowFactorAdjusted.dividedBy(newStats.userTotalCollateralDeposit)
|
|
643
645
|
);
|
|
644
646
|
newStats.leverage = valueOrZero(newStats.userTotalDeposit.dividedBy(newStats.netAccountValue));
|
|
645
647
|
|
|
@@ -714,6 +716,7 @@ export class KaminoObligation {
|
|
|
714
716
|
userTotalBorrowBorrowFactorAdjusted: borrowStatsOraclePrice.userTotalBorrowBorrowFactorAdjusted,
|
|
715
717
|
userTotalDeposit: depositStatsOraclePrice.userTotalDeposit,
|
|
716
718
|
userTotalCollateralDeposit: depositStatsOraclePrice.userTotalCollateralDeposit,
|
|
719
|
+
userTotalLiquidatableDeposit: depositStatsOraclePrice.userTotalLiquidatableDeposit,
|
|
717
720
|
liquidationLtv: depositStatsOraclePrice.liquidationLtv,
|
|
718
721
|
borrowUtilization: borrowStatsOraclePrice.userTotalBorrowBorrowFactorAdjusted.dividedBy(
|
|
719
722
|
depositStatsOraclePrice.borrowLimit
|
|
@@ -721,7 +724,7 @@ export class KaminoObligation {
|
|
|
721
724
|
netAccountValue: netAccountValueScopeRefreshed,
|
|
722
725
|
leverage: depositStatsOraclePrice.userTotalDeposit.dividedBy(netAccountValueScopeRefreshed),
|
|
723
726
|
loanToValue: borrowStatsOraclePrice.userTotalBorrowBorrowFactorAdjusted.dividedBy(
|
|
724
|
-
depositStatsOraclePrice.
|
|
727
|
+
depositStatsOraclePrice.userTotalCollateralDeposit
|
|
725
728
|
),
|
|
726
729
|
potentialElevationGroupUpdate,
|
|
727
730
|
},
|
|
@@ -737,6 +740,7 @@ export class KaminoObligation {
|
|
|
737
740
|
): DepositStats {
|
|
738
741
|
let userTotalDeposit = new Decimal(0);
|
|
739
742
|
let userTotalCollateralDeposit = new Decimal(0);
|
|
743
|
+
let userTotalLiquidatableDeposit = new Decimal(0);
|
|
740
744
|
let borrowLimit = new Decimal(0);
|
|
741
745
|
let borrowLiquidationLimit = new Decimal(0);
|
|
742
746
|
|
|
@@ -770,6 +774,10 @@ export class KaminoObligation {
|
|
|
770
774
|
userTotalCollateralDeposit = userTotalCollateralDeposit.add(depositValueUsd);
|
|
771
775
|
}
|
|
772
776
|
|
|
777
|
+
if (!liquidationLtv.eq('0')) {
|
|
778
|
+
userTotalLiquidatableDeposit = userTotalLiquidatableDeposit.add(depositValueUsd);
|
|
779
|
+
}
|
|
780
|
+
|
|
773
781
|
borrowLimit = borrowLimit.add(depositValueUsd.mul(maxLtv));
|
|
774
782
|
borrowLiquidationLimit = borrowLiquidationLimit.add(depositValueUsd.mul(liquidationLtv));
|
|
775
783
|
|
|
@@ -786,8 +794,9 @@ export class KaminoObligation {
|
|
|
786
794
|
deposits,
|
|
787
795
|
userTotalDeposit,
|
|
788
796
|
userTotalCollateralDeposit,
|
|
797
|
+
userTotalLiquidatableDeposit,
|
|
789
798
|
borrowLimit,
|
|
790
|
-
liquidationLtv: valueOrZero(borrowLiquidationLimit.div(
|
|
799
|
+
liquidationLtv: valueOrZero(borrowLiquidationLimit.div(userTotalLiquidatableDeposit)),
|
|
791
800
|
borrowLiquidationLimit,
|
|
792
801
|
};
|
|
793
802
|
}
|
|
@@ -865,7 +874,7 @@ export class KaminoObligation {
|
|
|
865
874
|
const getOraclePx = (reserve: KaminoReserve) => reserve.getOracleMarketPrice();
|
|
866
875
|
const { collateralExchangeRates } = KaminoObligation.getRatesForObligation(market, this.state, slot);
|
|
867
876
|
|
|
868
|
-
const { borrowLimit,
|
|
877
|
+
const { borrowLimit, userTotalCollateralDeposit } = KaminoObligation.calculateObligationDeposits(
|
|
869
878
|
market,
|
|
870
879
|
this.state.deposits,
|
|
871
880
|
collateralExchangeRates,
|
|
@@ -873,11 +882,11 @@ export class KaminoObligation {
|
|
|
873
882
|
getOraclePx
|
|
874
883
|
);
|
|
875
884
|
|
|
876
|
-
if (borrowLimit.eq(0) ||
|
|
885
|
+
if (borrowLimit.eq(0) || userTotalCollateralDeposit.eq(0)) {
|
|
877
886
|
return new Decimal(0);
|
|
878
887
|
}
|
|
879
888
|
|
|
880
|
-
return borrowLimit.div(
|
|
889
|
+
return borrowLimit.div(userTotalCollateralDeposit);
|
|
881
890
|
}
|
|
882
891
|
|
|
883
892
|
/*
|
package/src/classes/types.ts
CHANGED
|
@@ -1,28 +1,27 @@
|
|
|
1
|
-
import { TransactionInstruction } from
|
|
2
|
-
|
|
1
|
+
import { TransactionInstruction } from '@solana/web3.js';
|
|
3
2
|
|
|
4
3
|
/** the populateLUTIxs should be executed in a separate transaction as we cannot create and populate a lookup table in the same tx */
|
|
5
4
|
export type InitVaultIxs = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
5
|
+
initVaultIxs: TransactionInstruction[];
|
|
6
|
+
populateLUTIxs: TransactionInstruction[];
|
|
7
|
+
};
|
|
9
8
|
|
|
10
9
|
export type AcceptVaultOwnershipIxs = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
10
|
+
acceptVaultOwnershipIx: TransactionInstruction;
|
|
11
|
+
updateLUTIxs: TransactionInstruction[];
|
|
12
|
+
};
|
|
14
13
|
|
|
15
14
|
export type UpdateReserveAllocationIxs = {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
15
|
+
updateReserveAllocationIx: TransactionInstruction;
|
|
16
|
+
updateLUTIxs: TransactionInstruction[];
|
|
17
|
+
};
|
|
19
18
|
|
|
20
19
|
export type UpdateVaultConfigIxs = {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
20
|
+
updateVaultConfigIx: TransactionInstruction;
|
|
21
|
+
updateLUTIxs: TransactionInstruction[];
|
|
22
|
+
};
|
|
24
23
|
|
|
25
24
|
export type SyncVaultLUTIxs = {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
25
|
+
setupLUTIfNeededIxs: TransactionInstruction[];
|
|
26
|
+
syncLUTIxs: TransactionInstruction[];
|
|
27
|
+
};
|
package/src/classes/vault.ts
CHANGED
|
@@ -829,10 +829,10 @@ export class KaminoVaultClient {
|
|
|
829
829
|
async investSingleReserveIxs(
|
|
830
830
|
payer: PublicKey,
|
|
831
831
|
vault: KaminoVault,
|
|
832
|
-
reserve: ReserveWithAddress
|
|
832
|
+
reserve: ReserveWithAddress,
|
|
833
|
+
vaultReservesMap?: PubkeyHashMap<PublicKey, KaminoReserve>
|
|
833
834
|
): Promise<TransactionInstruction[]> {
|
|
834
835
|
const vaultState = await vault.getState(this._connection);
|
|
835
|
-
|
|
836
836
|
const cTokenVault = getCTokenVaultPda(vault.address, reserve.address, this._kaminoVaultProgramId);
|
|
837
837
|
const lendingMarketAuth = lendingMarketAuthPda(reserve.state.lendingMarket, this._kaminoLendProgramId)[0];
|
|
838
838
|
|
|
@@ -864,10 +864,24 @@ export class KaminoVaultClient {
|
|
|
864
864
|
const investIx = invest(investAccounts, this._kaminoVaultProgramId);
|
|
865
865
|
|
|
866
866
|
const vaultReserves = this.getVaultReserves(vaultState);
|
|
867
|
-
const
|
|
868
|
-
|
|
867
|
+
const vaultReservesState = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
|
|
868
|
+
|
|
869
|
+
let vaultReservesAccountMetas: AccountMeta[] = [];
|
|
870
|
+
let vaultReservesLendingMarkets: AccountMeta[] = [];
|
|
871
|
+
vaultReserves.forEach((reserve) => {
|
|
872
|
+
const reserveState = vaultReservesState.get(reserve);
|
|
873
|
+
if (reserveState === undefined) {
|
|
874
|
+
throw new Error(`Reserve ${reserve.toBase58()} not found`);
|
|
875
|
+
}
|
|
876
|
+
vaultReservesAccountMetas = vaultReservesAccountMetas.concat([
|
|
877
|
+
{ pubkey: reserve, isSigner: false, isWritable: true },
|
|
878
|
+
]);
|
|
879
|
+
vaultReservesLendingMarkets = vaultReservesLendingMarkets.concat([
|
|
880
|
+
{ pubkey: reserveState.state.lendingMarket, isSigner: false, isWritable: false },
|
|
881
|
+
]);
|
|
869
882
|
});
|
|
870
883
|
investIx.keys = investIx.keys.concat(vaultReservesAccountMetas);
|
|
884
|
+
investIx.keys = investIx.keys.concat(vaultReservesLendingMarkets);
|
|
871
885
|
|
|
872
886
|
return [createAtaIx, investIx];
|
|
873
887
|
}
|
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
PerformanceFeeBps,
|
|
54
54
|
} from './idl_codegen_kamino_vault/types/VaultConfigField';
|
|
55
55
|
import { getAccountOwner } from './utils/rpc';
|
|
56
|
+
import { Farms, FarmState, getUserStatePDA } from '@kamino-finance/farms-sdk';
|
|
56
57
|
|
|
57
58
|
dotenv.config({
|
|
58
59
|
path: `.env${process.env.ENV ? '.' + process.env.ENV : ''}`,
|
|
@@ -519,6 +520,56 @@ async function main() {
|
|
|
519
520
|
mode === 'execute' && console.log('Pending fees withdrawn:', withdrawPendingFeesSig);
|
|
520
521
|
});
|
|
521
522
|
|
|
523
|
+
commands
|
|
524
|
+
.command('stake')
|
|
525
|
+
.requiredOption('--vault <string>', 'Vault address')
|
|
526
|
+
.requiredOption('--farm <string>', 'Farm address')
|
|
527
|
+
.requiredOption('--amount <string>', 'The number of kTokens to stake')
|
|
528
|
+
.requiredOption(
|
|
529
|
+
`--mode <string>`,
|
|
530
|
+
'simulate - to print txn simulation, inspect - to get txn simulation in explorer, execute - execute txn, multisig - to get bs58 txn for multisig usage'
|
|
531
|
+
)
|
|
532
|
+
.option(`--staging`, 'If true, will use the staging programs')
|
|
533
|
+
.option(`--multisig <string>`, 'If using multisig mode this is required, otherwise will be ignored')
|
|
534
|
+
.action(async ({ vault, farm, amount, mode, staging, multisig }) => {
|
|
535
|
+
const env = initializeClient(mode === 'multisig', staging);
|
|
536
|
+
const vaultAddress = new PublicKey(vault);
|
|
537
|
+
const farmAddress = new PublicKey(farm);
|
|
538
|
+
|
|
539
|
+
const farmClient = new Farms(env.connection);
|
|
540
|
+
|
|
541
|
+
const farmState = await FarmState.fetch(env.connection, farmAddress);
|
|
542
|
+
const vaultState = await new KaminoVault(vaultAddress, undefined, env.kVaultProgramId).getState(env.connection);
|
|
543
|
+
|
|
544
|
+
const scopePricesArg = farmState!.scopePrices.equals(PublicKey.default)
|
|
545
|
+
? farmClient.getProgramID()
|
|
546
|
+
: farmState!.scopePrices;
|
|
547
|
+
|
|
548
|
+
const ixns: TransactionInstruction[] = [];
|
|
549
|
+
const userState = getUserStatePDA(farmClient.getProgramID(), farmAddress, env.provider.publicKey);
|
|
550
|
+
if (!userState) {
|
|
551
|
+
const createUserIx = await farmClient.createNewUserIx(env.provider.publicKey, farmAddress);
|
|
552
|
+
ixns.push(createUserIx);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// todo: fix in farms sdk to make this not async
|
|
556
|
+
const stakeIx = await farmClient.stakeIx(
|
|
557
|
+
env.payer.publicKey,
|
|
558
|
+
farmAddress,
|
|
559
|
+
new Decimal(amount),
|
|
560
|
+
vaultState.sharesMint,
|
|
561
|
+
scopePricesArg
|
|
562
|
+
);
|
|
563
|
+
ixns.push(stakeIx);
|
|
564
|
+
|
|
565
|
+
if (mode === 'multisig' && !multisig) {
|
|
566
|
+
throw new Error('If using multisig mode, multisig is required');
|
|
567
|
+
}
|
|
568
|
+
const withdrawPendingFeesSig = await processTxn(env.client, env.payer, ixns, mode, 2500, []);
|
|
569
|
+
|
|
570
|
+
mode === 'execute' && console.log('Pending fees withdrawn:', withdrawPendingFeesSig);
|
|
571
|
+
});
|
|
572
|
+
|
|
522
573
|
commands
|
|
523
574
|
.command('update-vault-reserve-allocation')
|
|
524
575
|
.requiredOption('--vault <string>', 'Vault address')
|
|
@@ -661,7 +712,7 @@ async function main() {
|
|
|
661
712
|
for (let i = 0; i < instructions.length; i++) {
|
|
662
713
|
const txInstructions: TransactionInstruction[] = [];
|
|
663
714
|
txInstructions.push(instructions[i]);
|
|
664
|
-
const investReserveSig = await processTxn(env.client, env.payer, txInstructions, mode, 2500, [],
|
|
715
|
+
const investReserveSig = await processTxn(env.client, env.payer, txInstructions, mode, 2500, [], 800000);
|
|
665
716
|
|
|
666
717
|
mode === 'execute' && console.log('Reserve invested:', investReserveSig);
|
|
667
718
|
}
|
|
@@ -703,7 +754,7 @@ async function main() {
|
|
|
703
754
|
kaminoVault,
|
|
704
755
|
reserveWithAddress
|
|
705
756
|
);
|
|
706
|
-
const investReserveSig = await processTxn(env.client, env.payer, instructions, mode, 2500, [],
|
|
757
|
+
const investReserveSig = await processTxn(env.client, env.payer, instructions, mode, 2500, [], 800_000);
|
|
707
758
|
|
|
708
759
|
mode === 'execute' && console.log('Reserve invested:', investReserveSig);
|
|
709
760
|
});
|
|
@@ -1163,7 +1214,7 @@ async function processTxn(
|
|
|
1163
1214
|
if (simulation.value.logs && simulation.value.logs.length > 0) {
|
|
1164
1215
|
console.log('Simulation: \n' + simulation.value.logs);
|
|
1165
1216
|
} else {
|
|
1166
|
-
console.log('Simulation failed: \n' + simulation);
|
|
1217
|
+
console.log('Simulation failed: \n' + simulation.value.err);
|
|
1167
1218
|
}
|
|
1168
1219
|
} else if (mode === 'inspect') {
|
|
1169
1220
|
console.log(
|
|
@@ -1180,7 +1231,7 @@ async function processTxn(
|
|
|
1180
1231
|
function createAddExtraComputeUnitFeeTransaction(units: number, microLamports: number): TransactionInstruction[] {
|
|
1181
1232
|
const ixns: TransactionInstruction[] = [];
|
|
1182
1233
|
ixns.push(ComputeBudgetProgram.setComputeUnitLimit({ units }));
|
|
1183
|
-
ixns.push(ComputeBudgetProgram.setComputeUnitPrice({ microLamports }));
|
|
1234
|
+
ixns.push(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: new Decimal(microLamports).floor().toNumber() }));
|
|
1184
1235
|
return ixns;
|
|
1185
1236
|
}
|
|
1186
1237
|
|