UNPKG

@kamino-finance/klend-sdk

Version:

Typescript SDK for interacting with the Kamino Lending (klend) protocol

474 lines 27.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.depositLeverageKtokenCalcs = exports.depositLeverageCalcs = exports.estimateDepositMode = exports.estimateAdjustMode = exports.estimateWithdrawMode = exports.calcBorrowAmount = exports.FormTabs = exports.toJson = void 0; exports.calculateMultiplyEffects = calculateMultiplyEffects; exports.calcWithdrawAmounts = calcWithdrawAmounts; exports.calcAdjustAmounts = calcAdjustAmounts; exports.simulateMintKToken = simulateMintKToken; exports.withdrawLeverageCalcs = withdrawLeverageCalcs; exports.adjustDepositLeverageCalcs = adjustDepositLeverageCalcs; exports.adjustWithdrawLeverageCalcs = adjustWithdrawLeverageCalcs; const decimal_js_1 = __importDefault(require("decimal.js")); const kliquidity_sdk_1 = require("@kamino-finance/kliquidity-sdk"); const utils_1 = require("./utils"); const utils_2 = require("../utils"); const toJson = (object) => { return JSON.stringify(object, null, 2); }; exports.toJson = toJson; const closingPositionDiffTolerance = 0.0001; var FormTabs; (function (FormTabs) { FormTabs["deposit"] = "Deposit"; FormTabs["withdraw"] = "Withdraw"; FormTabs["adjust"] = "Adjust"; FormTabs["close"] = "Close"; })(FormTabs || (exports.FormTabs = FormTabs = {})); async function calculateMultiplyEffects(getPriceByTokenMintDecimal, { depositAmount, withdrawAmount, deposited, borrowed, debtTokenMint, selectedTokenMint, collTokenMint, targetLeverage, activeTab, flashBorrowReserveFlashLoanFeePercentage, debtBorrowFactorPct, priceCollToDebt, priceDebtToColl, }) { // calculate estimations for deposit operation const { adjustDepositPosition: depositModeEstimatedDepositAmount, adjustBorrowPosition: depositModeEstimatedBorrowAmount, } = (0, exports.estimateDepositMode)({ priceCollToDebt, priceDebtToColl, amount: depositAmount, targetLeverage, selectedTokenMint, collTokenMint: collTokenMint, flashLoanFee: flashBorrowReserveFlashLoanFeePercentage, }); // calculate estimations for withdraw operation const { adjustDepositPosition: withdrawModeEstimatedDepositTokenWithdrawn, adjustBorrowPosition: withdrawModeEstimatedBorrowTokenWithdrawn, } = (0, exports.estimateWithdrawMode)({ priceCollToDebt: priceCollToDebt, collTokenMint, selectedTokenMint, amount: withdrawAmount, deposited: new decimal_js_1.default(deposited), borrowed: new decimal_js_1.default(borrowed), }); // calculate estimations for adjust operation const { adjustDepositPosition: adjustModeEstimatedDepositAmount, adjustBorrowPosition: adjustModeEstimateBorrowAmount, } = (0, exports.estimateAdjustMode)(priceCollToDebt, { targetLeverage, debtTokenMint, collTokenMint, totalDeposited: new decimal_js_1.default(deposited), totalBorrowed: new decimal_js_1.default(borrowed), flashLoanFee: flashBorrowReserveFlashLoanFeePercentage, // TODO: is this the right flash borrow? }); console.log('Estimations', (0, exports.toJson)({ activeTab, depositModeEstimatedDepositAmount, depositModeEstimatedBorrowAmount, withdrawModeEstimatedDepositTokenWithdrawn, withdrawModeEstimatedBorrowTokenWithdrawn, adjustModeEstimatedDepositAmount, adjustModeEstimateBorrowAmount, })); let [isClosingPosition, totalDeposited, totalBorrowed] = [false, new decimal_js_1.default(0), new decimal_js_1.default(0)]; switch (activeTab) { case FormTabs.deposit: { // Deposit and Adjust never clos the position isClosingPosition = false; totalDeposited = deposited.add(depositModeEstimatedDepositAmount); totalBorrowed = borrowed.add(depositModeEstimatedBorrowAmount); break; } case FormTabs.close: case FormTabs.withdraw: { isClosingPosition = (withdrawModeEstimatedDepositTokenWithdrawn.gte(new decimal_js_1.default(deposited)) || withdrawModeEstimatedBorrowTokenWithdrawn.gte(new decimal_js_1.default(borrowed)) || (0, utils_2.fuzzyEqual)(withdrawModeEstimatedDepositTokenWithdrawn, new decimal_js_1.default(deposited), closingPositionDiffTolerance) || (0, utils_2.fuzzyEqual)(withdrawModeEstimatedBorrowTokenWithdrawn, new decimal_js_1.default(borrowed), closingPositionDiffTolerance)) && !(0, utils_2.fuzzyEqual)(withdrawModeEstimatedDepositTokenWithdrawn, new decimal_js_1.default(0), closingPositionDiffTolerance); totalDeposited = isClosingPosition ? new decimal_js_1.default(0) : deposited.sub(withdrawModeEstimatedDepositTokenWithdrawn); totalBorrowed = isClosingPosition ? new decimal_js_1.default(0) : borrowed.sub(withdrawModeEstimatedBorrowTokenWithdrawn); break; } case FormTabs.adjust: { // Deposit and Adjust never clos the position isClosingPosition = false; totalDeposited = deposited.add(adjustModeEstimatedDepositAmount); totalBorrowed = borrowed.add(adjustModeEstimateBorrowAmount); break; } } const borrowTokenPrice = await getPriceByTokenMintDecimal(debtTokenMint); const depositTokenPrice = await getPriceByTokenMintDecimal(collTokenMint); const totalDepositedUsd = depositTokenPrice.mul(totalDeposited); const totalBorrowedUsd = borrowTokenPrice.mul(totalBorrowed); const netValueUsd = totalDepositedUsd.minus(totalBorrowedUsd); // TODO marius this is bad, do not convert to sol as we don't only do leveraged loops only const netValueSol = netValueUsd.div(borrowTokenPrice); const ltv = totalBorrowedUsd.mul(debtBorrowFactorPct.div(100)).div(totalDepositedUsd); return { earned: new decimal_js_1.default(0), totalDeposited, totalBorrowed, netValue: netValueSol, netValueUsd: netValueUsd, ltv, }; } /** * returns how much borrowToken will be borrowed to reach leverage given initial collateral amount * @param depositTokenAmount * @param leverage * @param priceAToB * @param flashBorrowFee */ const calcBorrowAmount = ({ depositTokenAmount, targetLeverage, priceCollToDebt, flashBorrowFee, }) => { const initialCollAmountInCollToken = depositTokenAmount; const finalCollAmountInCollToken = initialCollAmountInCollToken.mul(targetLeverage); const finalDebtAmountInCollToken = finalCollAmountInCollToken.sub(initialCollAmountInCollToken); const finalDebtAmountInDebtToken = finalDebtAmountInCollToken.mul(priceCollToDebt); const flashFeeFactor = new decimal_js_1.default(1).add(flashBorrowFee); const debtTokenToBorrow = finalDebtAmountInDebtToken.mul(flashFeeFactor); return debtTokenToBorrow; }; exports.calcBorrowAmount = calcBorrowAmount; const estimateWithdrawMode = (props) => { const { amount, collTokenMint, selectedTokenMint, deposited, borrowed, priceCollToDebt } = props; return calcWithdrawAmounts({ selectedTokenMint, collTokenMint, withdrawAmount: new decimal_js_1.default(amount), priceCollToDebt, currentBorrowPosition: borrowed, currentDepositPosition: deposited, }); }; exports.estimateWithdrawMode = estimateWithdrawMode; function calcWithdrawAmounts(params) { const { currentBorrowPosition, currentDepositPosition, priceCollToDebt, withdrawAmount, selectedTokenMint, collTokenMint, } = params; // MSOL/SOL const currentDepositInCollateralToken = currentDepositPosition; const currentDebtInCollateralToken = currentBorrowPosition.div(priceCollToDebt); const currentNetPositionInCollateralToken = currentDepositInCollateralToken.minus(currentDebtInCollateralToken); const targetLeverage = currentDepositInCollateralToken.div(currentNetPositionInCollateralToken); const initialDepositInCollateralToken = currentDepositPosition.minus(currentBorrowPosition.div(priceCollToDebt)); const amountToWithdrawDepositToken = selectedTokenMint.equals(collTokenMint) ? withdrawAmount : withdrawAmount.div(priceCollToDebt); const targetDeposit = initialDepositInCollateralToken.minus(amountToWithdrawDepositToken).mul(targetLeverage); const targetBorrow = (0, exports.calcBorrowAmount)({ depositTokenAmount: initialDepositInCollateralToken.minus(amountToWithdrawDepositToken), priceCollToDebt: new decimal_js_1.default(priceCollToDebt), targetLeverage: new decimal_js_1.default(targetLeverage), flashBorrowFee: new decimal_js_1.default(0), }); const adjustDepositPosition = currentDepositPosition.minus(targetDeposit); const adjustBorrowPosition = currentBorrowPosition.minus(targetBorrow); // TODO: add flashLoan fee here in final values return { adjustDepositPosition, adjustBorrowPosition, }; } /** * Calculate how much token will be deposited or withdrawn in case of position adjustment * @param leverage * @param totalDeposited * @param totalBorrowed */ const estimateAdjustMode = (priceCollToDebt, { targetLeverage, totalDeposited, totalBorrowed, flashLoanFee }) => { return calcAdjustAmounts({ currentBorrowPosition: totalBorrowed, currentDepositPosition: totalDeposited, priceCollToDebt, targetLeverage, flashLoanFee, }); }; exports.estimateAdjustMode = estimateAdjustMode; /** * Calculates the amounts of tokenA to deposit/withdraw and tokenB to borrow/repay proportionally to adjust the leverage of a position. * * @param {AdjustLeverageParams} params - Parameters for the calculation * @param {number} params.targetLeverage - The target leverage for the position * @param {Decimal} params.currentPositionTokenA - The current amount of tokenA in the position * @param {Decimal} params.currentPositionTokenB - The current amount of borrowed tokenB in the position * @param {number} params.priceAtoB - The conversion rate from tokenA to tokenB (tokenA price = tokenB price * priceAtoB) * @returns {AdjustLeverageResult} An object containing the amounts of tokenA to deposit/withdraw and tokenB to borrow/repay */ function calcAdjustAmounts({ targetLeverage, currentBorrowPosition, currentDepositPosition, priceCollToDebt, flashLoanFee, }) { const initialDeposit = currentDepositPosition.minus(currentBorrowPosition.div(priceCollToDebt)); const targetDeposit = initialDeposit.mul(targetLeverage); const targetBorrow = (0, exports.calcBorrowAmount)({ depositTokenAmount: initialDeposit, priceCollToDebt: new decimal_js_1.default(priceCollToDebt), targetLeverage: new decimal_js_1.default(targetLeverage), flashBorrowFee: flashLoanFee, }); const adjustDepositPosition = targetDeposit.minus(currentDepositPosition); const adjustBorrowPosition = targetBorrow.minus(currentBorrowPosition); return { adjustDepositPosition, adjustBorrowPosition, }; } // Given a deposit amount of Deposit|Borrow token // and a target leverage, calculate final { collateral, debt } value const estimateDepositMode = ({ priceCollToDebt, priceDebtToColl, amount, targetLeverage, selectedTokenMint, collTokenMint, flashLoanFee, slippagePct = new decimal_js_1.default(0), }) => { const isDepositingCollToken = selectedTokenMint.equals(collTokenMint); const finalCollTokenAmount = isDepositingCollToken ? new decimal_js_1.default(amount).mul(targetLeverage).toNumber() : new decimal_js_1.default(amount).mul(priceDebtToColl).mul(targetLeverage).toNumber(); const depositCollTokenAmount = isDepositingCollToken ? amount : amount.mul(priceDebtToColl); const borrowAmount = (0, exports.calcBorrowAmount)({ depositTokenAmount: depositCollTokenAmount, targetLeverage: new decimal_js_1.default(targetLeverage), priceCollToDebt: new decimal_js_1.default(priceCollToDebt), flashBorrowFee: new decimal_js_1.default(flashLoanFee), }); const slippageFactor = new decimal_js_1.default(1).add(slippagePct.div(new decimal_js_1.default(100))); const borrowAmountWithSlippage = borrowAmount.mul(slippageFactor); return { adjustDepositPosition: finalCollTokenAmount, adjustBorrowPosition: borrowAmountWithSlippage.toNumber(), }; }; exports.estimateDepositMode = estimateDepositMode; /** * Given an amount of ktokens, returns the estimated amount of token A and token B that need to be deposited * The amount of A and B may result in less ktokens being minted, the actual amount of ktokens minted is returned as well * @param kamino * @param strategy * @param mintAmount - desired amount of ktokens to mint * @param strategyHoldings - optional strategy holdings, if not provided will be fetched from the blockchain * @returns [tokenA, tokenB, actualMintAmount] */ async function simulateMintKToken(kamino, strategy, mintAmount, strategyHoldings) { let holdings = strategyHoldings; if (!holdings) { holdings = await kamino.getStrategyTokensHoldings(strategy, 'DEPOSIT'); } const sharesIssuedDecimal = new decimal_js_1.default(strategy.strategy.sharesIssued.toString()).div(10 ** strategy.strategy.sharesMintDecimals.toNumber()); // Add 1 because the sdk doesn't round up where the SC will const strategyA = holdings.a.div(10 ** strategy.strategy.tokenAMintDecimals.toNumber()); const strategyB = holdings.b.div(10 ** strategy.strategy.tokenBMintDecimals.toNumber()); const aPerShare = strategyA.div(sharesIssuedDecimal); const bPerShare = strategyB.div(sharesIssuedDecimal); const requiredA = aPerShare.mul(mintAmount); const requiredB = bPerShare.mul(mintAmount); const pxAInB = strategyB.div(strategyA); console.info(`Estimating kToken mint of ${mintAmount} ktokens on strategy ${strategy.address.toString()} requires: estimated A: ${requiredA}, estimated B: ${requiredB}. Current pool state:\n${(0, exports.toJson)({ ...holdings, sharesIssued: sharesIssuedDecimal, poolPxAInB: pxAInB })}`); // If we deposited with this exact ratio - how many ktokens do we actually get from the program? const RustDecimal = decimal_js_1.default.clone({ precision: 18, rounding: decimal_js_1.default.ROUND_FLOOR }); const usA = new RustDecimal(holdings.a); const usB = new RustDecimal(holdings.b); const uA = new RustDecimal(requiredA.mul(10 ** strategy.strategy.tokenAMintDecimals.toNumber()).ceil()); const uB = new RustDecimal(requiredB.mul(10 ** strategy.strategy.tokenBMintDecimals.toNumber()).ceil()); const ratio = usA.div(usB); const depositableB = uA.div(ratio).floor(); let actualA, actualB; if (depositableB.lte(uB)) { actualA = depositableB.mul(ratio).floor(); actualB = uB; } else { actualA = uB.mul(ratio).floor(); actualB = actualA.div(ratio).floor(); } const actualMintFromA = actualA.mul(strategy.strategy.sharesIssued.toString()).div(holdings.a).floor(); const actualMintFromB = actualB.mul(strategy.strategy.sharesIssued.toString()).div(holdings.b).floor(); const actualMint = decimal_js_1.default.min(actualMintFromA, actualMintFromB).div(10 ** strategy.strategy.sharesMintDecimals.toNumber()); console.log(`Actual deposit amounts: A: ${actualA}, B: ${actualB}, kTokens to mint: ${actualMint}`); return [requiredA, requiredB, actualMint]; } const depositLeverageCalcs = (props) => { // Initialize local variables from the props object const { depositAmount, depositTokenIsCollToken, depositTokenIsSol, priceDebtToColl, targetLeverage, slippagePct, flashLoanFee, } = props; const slippage = slippagePct.div('100'); const initDepositInSol = depositTokenIsSol ? depositAmount : new decimal_js_1.default(0); // Core logic if (depositTokenIsCollToken) { const y = targetLeverage.mul(priceDebtToColl); const x = flashLoanFee.add('1').mul(slippage.add('1')).div(priceDebtToColl); const finalColl = depositAmount.mul(x).div(x.sub(targetLeverage.sub('1').div(y))); const debt = finalColl.sub(depositAmount).mul(x); const flashBorrowColl = finalColl.sub(depositAmount).mul(flashLoanFee.add('1')); return { flashBorrowInCollToken: flashBorrowColl, initDepositInSol, debtTokenToBorrow: debt, collTokenToDeposit: finalColl, swapDebtTokenIn: debt, swapCollTokenExpectedOut: finalColl.sub(depositAmount), flashBorrowInDebtTokenKtokenOnly: new decimal_js_1.default(0), singleSidedDepositKtokenOnly: new decimal_js_1.default(0), requiredCollateralKtokenOnly: new decimal_js_1.default(0), }; } else { const y = targetLeverage.mul(priceDebtToColl); const x = flashLoanFee.add('1').mul(slippage.add('1')).div(priceDebtToColl); const finalColl = depositAmount.div(x.sub(targetLeverage.sub('1').div(y))); const flashBorrowColl = finalColl.mul(flashLoanFee.add('1')); const debt = targetLeverage.sub('1').mul(finalColl).div(y); return { flashBorrowInCollToken: flashBorrowColl, initDepositInSol, debtTokenToBorrow: debt, collTokenToDeposit: finalColl, swapDebtTokenIn: debt.add(depositAmount), swapCollTokenExpectedOut: finalColl, flashBorrowInDebtTokenKtokenOnly: new decimal_js_1.default(0), singleSidedDepositKtokenOnly: new decimal_js_1.default(0), requiredCollateralKtokenOnly: new decimal_js_1.default(0), }; } }; exports.depositLeverageCalcs = depositLeverageCalcs; const depositLeverageKtokenCalcs = async (props) => { const { kamino, strategy, debtTokenMint, depositAmount, depositTokenIsCollToken, depositTokenIsSol, priceDebtToColl, targetLeverage, slippagePct, flashLoanFee, priceAinB, strategyHoldings, } = props; const initDepositInSol = depositTokenIsSol ? depositAmount : new decimal_js_1.default(0); const slippage = slippagePct.div('100'); let flashBorrowInDebtToken; let collTokenToDeposit; let debtTokenToBorrow; if (depositTokenIsCollToken) { const x = slippage.add('1').div(priceDebtToColl); const y = flashLoanFee.add('1').mul(priceDebtToColl); const z = targetLeverage.mul(y).div(targetLeverage.sub(1)); flashBorrowInDebtToken = depositAmount.div(z.minus(new decimal_js_1.default(1).div(x))); collTokenToDeposit = depositAmount.add(flashBorrowInDebtToken.div(x)); debtTokenToBorrow = flashBorrowInDebtToken.mul(new decimal_js_1.default(1).add(flashLoanFee)); return { flashBorrowInCollToken: new decimal_js_1.default(0), initDepositInSol, collTokenToDeposit, debtTokenToBorrow, swapDebtTokenIn: new decimal_js_1.default(0), swapCollTokenExpectedOut: new decimal_js_1.default(0), flashBorrowInDebtTokenKtokenOnly: flashBorrowInDebtToken, requiredCollateralKtokenOnly: collTokenToDeposit.sub(depositAmount), // Assuming netValue is requiredCollateral, adjust as needed singleSidedDepositKtokenOnly: flashBorrowInDebtToken, }; } else { const y = targetLeverage.mul(priceDebtToColl); // although we will only swap ~half of the debt token, we account for the slippage on the entire amount as we are working backwards from the minimum collateral and do not know the exact swap proportion in advance // This also allows for some variation in the pool ratios between calculation + submitting the tx const x = flashLoanFee.add('1').mul(slippage.add('1')).div(priceDebtToColl); // Calculate the amount of collateral tokens we will deposit in order to achieve the desired leverage after swapping a portion of the debt token and flash loan fees const finalColl = depositAmount.div(x.sub(targetLeverage.sub('1').div(y))); // Calculate how many A and B tokens we will need to actually mint the desired amount of ktoken collateral // The actual amount of ktokens received may be less than the finalColl due to smart proportional contract logic // So we use the actualColl as the amount we will deposit const [estimatedA, estimatedB, actualColl] = await simulateMintKToken(kamino, strategy, finalColl, strategyHoldings); const pxAinB = await priceAinB(strategy.strategy.tokenAMint, strategy.strategy.tokenBMint); const isTokenADeposit = strategy.strategy.tokenAMint.equals(debtTokenMint); // Calculate the amount we need to flash borrow by combining value of A and B into the debt token const singleSidedDepositAmount = isTokenADeposit ? estimatedA.add(estimatedB.div(pxAinB)) : estimatedB.add(estimatedA.mul(pxAinB)); // Add slippage to the entire amount, add flash loan fee to part we will flash borrow flashBorrowInDebtToken = singleSidedDepositAmount .div(new decimal_js_1.default('1').sub(slippage)) .sub(depositAmount) .div(new decimal_js_1.default('1').sub(flashLoanFee)); // Deposit the min ktoken amount we calculated at the beginning // Any slippage will be left in the user's wallet as ktokens collTokenToDeposit = actualColl; debtTokenToBorrow = flashBorrowInDebtToken.div(new decimal_js_1.default('1').sub(flashLoanFee)); // Add slippage to ensure we try to swap/deposit as much as possible after flash loan fees const singleSidedDeposit = singleSidedDepositAmount.div(new decimal_js_1.default('1').sub(slippage)); return { flashBorrowInCollToken: new decimal_js_1.default(0), initDepositInSol, collTokenToDeposit, debtTokenToBorrow, swapDebtTokenIn: new decimal_js_1.default(0), swapCollTokenExpectedOut: new decimal_js_1.default(0), flashBorrowInDebtTokenKtokenOnly: flashBorrowInDebtToken, singleSidedDepositKtokenOnly: singleSidedDeposit, requiredCollateralKtokenOnly: collTokenToDeposit, // Assuming collTokenToDeposit is requiredCollateral, adjust as needed }; } }; exports.depositLeverageKtokenCalcs = depositLeverageKtokenCalcs; function withdrawLeverageCalcs(market, collReserve, debtReserve, priceCollToDebt, withdrawAmount, deposited, borrowed, currentSlot, isClosingPosition, selectedTokenIsCollToken, selectedTokenMint, obligation, flashLoanFee, slippagePct) { // 1. Calculate coll_amount and debt_amount to repay such that we maintain leverage and we withdraw to // the wallet `amountInDepositTokenToWithdrawToWallet` amount of collateral token // We need to withdraw withdrawAmountInDepositToken coll tokens // and repay repayAmountInBorrowToken debt tokens const { adjustDepositPosition: withdrawAmountCalculated, adjustBorrowPosition: initialRepayAmount } = isClosingPosition ? { adjustDepositPosition: deposited, adjustBorrowPosition: borrowed } : calcWithdrawAmounts({ collTokenMint: collReserve.getLiquidityMint(), priceCollToDebt: new decimal_js_1.default(priceCollToDebt), currentDepositPosition: deposited, currentBorrowPosition: borrowed, withdrawAmount: new decimal_js_1.default(withdrawAmount), selectedTokenMint: selectedTokenMint, }); // Add slippage for the accrued interest rate amount const irSlippageBpsForDebt = obligation .estimateObligationInterestRate(market, debtReserve, obligation?.state.borrows[0], currentSlot) .toDecimalPlaces(debtReserve?.state.liquidity.mintDecimals.toNumber(), decimal_js_1.default.ROUND_CEIL); // add 0.1 to irSlippageBpsForDebt because we don't want to estimate slightly less than SC and end up not reapying enough const repayAmount = initialRepayAmount .mul(irSlippageBpsForDebt.add('0.1').div('10_000').add('1')) .toDecimalPlaces(debtReserve?.state.liquidity.mintDecimals.toNumber(), decimal_js_1.default.ROUND_CEIL); // 6. Get swap ixns // 5. Get swap estimations to understand how much we need to borrow from borrow reserve // prevent withdrawing more then deposited if we close position const depositTokenWithdrawAmount = !isClosingPosition ? withdrawAmountCalculated.mul(new decimal_js_1.default(1).plus(flashLoanFee)) : withdrawAmountCalculated; // We are swapping debt token // When withdrawing coll, it means we just need to swap enough to pay for the flash borrow const swapAmountIfWithdrawingColl = repayAmount .mul(new decimal_js_1.default(1).plus(flashLoanFee)) .mul(new decimal_js_1.default(1).plus(slippagePct.div(100))) .div(priceCollToDebt); // When withdrawing debt, it means we need to swap just the collateral we are withdrwaing // enough to cover the debt we are repaying, leaving the remaining in the wallet const swapAmountIfWithdrawingDebt = withdrawAmountCalculated; const collTokenSwapIn = selectedTokenIsCollToken ? swapAmountIfWithdrawingColl : swapAmountIfWithdrawingDebt; const debtTokenExpectedSwapOut = collTokenSwapIn.mul(priceCollToDebt).div(new decimal_js_1.default(1).add(slippagePct.div(100))); return { withdrawAmount: withdrawAmountCalculated, repayAmount, collTokenSwapIn, debtTokenExpectedSwapOut, depositTokenWithdrawAmount, }; } async function adjustDepositLeverageCalcs(market, owner, debtReserve, adjustDepositPosition, adjustBorrowPosition, priceDebtToColl, flashLoanFee, slippagePct, collIsKtoken) { // used if coll is Ktoken and we borrow debt token instead const amountToFlashBorrowDebt = adjustDepositPosition .div(priceDebtToColl) .mul(new decimal_js_1.default(new decimal_js_1.default(1).add(slippagePct.div(100)))) .toDecimalPlaces(debtReserve.stats.decimals, decimal_js_1.default.ROUND_UP); const borrowAmount = adjustDepositPosition .mul(new decimal_js_1.default(1).plus(flashLoanFee)) .mul(new decimal_js_1.default(new decimal_js_1.default(1).add(slippagePct.div(100)))) .div(priceDebtToColl); const expectedDebtTokenAtaBalance = await (0, utils_1.getExpectedTokenBalanceAfterBorrow)(market.getConnection(), debtReserve.getLiquidityMint(), owner, (0, kliquidity_sdk_1.collToLamportsDecimal)(!collIsKtoken ? borrowAmount : amountToFlashBorrowDebt, debtReserve.stats.decimals).floor(), debtReserve.state.liquidity.mintDecimals.toNumber()); return { adjustDepositPosition, adjustBorrowPosition, amountToFlashBorrowDebt, borrowAmount, expectedDebtTokenAtaBalance, withdrawAmountWithSlippageAndFlashLoanFee: new decimal_js_1.default(0), }; } function adjustWithdrawLeverageCalcs(adjustDepositPosition, adjustBorrowPosition, flashLoanFee, slippagePct) { // used if coll is Ktoken and we borrow debt token instead const withdrawAmountWithSlippageAndFlashLoanFee = decimal_js_1.default.abs(adjustDepositPosition) .mul(new decimal_js_1.default(1).plus(flashLoanFee)) .mul(new decimal_js_1.default(1).add(slippagePct.div(100))); return { adjustDepositPosition, adjustBorrowPosition, amountToFlashBorrowDebt: new decimal_js_1.default(0), borrowAmount: new decimal_js_1.default(0), expectedDebtTokenAtaBalance: new decimal_js_1.default(0), withdrawAmountWithSlippageAndFlashLoanFee, }; } //# sourceMappingURL=calcs.js.map