@kamino-finance/klend-sdk 3.2.22 → 3.2.23
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.
|
@@ -642,27 +642,29 @@ class KaminoObligation {
|
|
|
642
642
|
// - essentially checks if a loan can be migrated or not
|
|
643
643
|
// - [x] due to collateral / debt reserves combination
|
|
644
644
|
// - [x] due to LTV, etc
|
|
645
|
-
if (elevationGroup === 0) {
|
|
646
|
-
return true;
|
|
647
|
-
}
|
|
648
645
|
const reserveDeposits = Array.from(this.deposits.keys()).map((x) => x.toString());
|
|
649
646
|
const reserveBorrows = Array.from(this.borrows.keys()).map((x) => x.toString());
|
|
650
647
|
if (reserveBorrows.length > 1) {
|
|
651
648
|
return false;
|
|
652
649
|
}
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
650
|
+
if (elevationGroup > 0) {
|
|
651
|
+
// Elevation group 0 doesn't need to do reserve checks, as all are included by default
|
|
652
|
+
const allElevationGroups = market.getMarketElevationGroupDescriptions();
|
|
653
|
+
const elevationGroupDescription = allElevationGroups[elevationGroup - 1];
|
|
654
|
+
// Has to be a subset
|
|
655
|
+
const allCollsIncluded = reserveDeposits.every((reserve) => elevationGroupDescription.collateralReserves.includes(reserve));
|
|
656
|
+
const allDebtsIncluded = reserveBorrows.length === 0 ||
|
|
657
|
+
(reserveBorrows.length === 1 && elevationGroupDescription.debtReserve === reserveBorrows[0]);
|
|
658
|
+
if (!allCollsIncluded || !allDebtsIncluded) {
|
|
659
|
+
return false;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
// Check if the loan can be migrated based on LTV
|
|
661
663
|
const getOraclePx = (reserve) => reserve.getOracleMarketPrice();
|
|
662
664
|
const { collateralExchangeRates } = KaminoObligation.getRatesForObligation(market, this.state, slot);
|
|
663
665
|
const { borrowLimit } = KaminoObligation.calculateObligationDeposits(market, this.state, collateralExchangeRates, elevationGroup, getOraclePx);
|
|
664
666
|
const isEligibleBasedOnLtv = this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.lte(borrowLimit);
|
|
665
|
-
return
|
|
667
|
+
return isEligibleBasedOnLtv;
|
|
666
668
|
}
|
|
667
669
|
/*
|
|
668
670
|
Returns all elevation groups for a given obligation, except the default one
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"obligation.js","sourceRoot":"","sources":["../../src/classes/obligation.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-classes-per-file */\nimport { PublicKey } from '@solana/web3.js';\nimport Decimal from 'decimal.js';\nimport { KaminoReserve } from './reserve';\nimport { Obligation } from '../idl_codegen/accounts';\nimport { ElevationGroupDescription, KaminoMarket } from './market';\nimport BN from 'bn.js';\nimport { Fraction } from './fraction';\nimport { ObligationCollateral, ObligationLiquidity } from '../idl_codegen/types';\nimport { positiveOrZero, valueOrZero } from './utils';\nimport { isNotNullPubkey, PubkeyHashMap, U64_MAX } from '../utils';\nimport { ActionType } from './action';\n\nexport type Position = {\n reserveAddress: PublicKey;\n mintAddress: PublicKey;\n /**\n * Amount of tokens in lamports, including decimal places for interest accrued (no borrow factor weighting)\n */\n amount: Decimal;\n /**\n * Market value of the position in USD (no borrow factor weighting)\n */\n marketValueRefreshed: Decimal;\n};\n\nexport type ObligationStats = {\n userTotalDeposit: Decimal;\n userTotalBorrow: Decimal;\n userTotalBorrowBorrowFactorAdjusted: Decimal;\n borrowLimit: Decimal;\n borrowLiquidationLimit: Decimal;\n borrowUtilization: Decimal;\n netAccountValue: Decimal;\n loanToValue: Decimal;\n liquidationLtv: Decimal;\n leverage: Decimal;\n potentialElevationGroupUpdate: number;\n};\n\ninterface BorrowStats {\n borrows: Map<PublicKey, Position>;\n userTotalBorrow: Decimal;\n userTotalBorrowBorrowFactorAdjusted: Decimal;\n positions: number;\n}\n\nexport class KaminoObligation {\n obligationAddress: PublicKey;\n\n state: Obligation;\n\n /**\n * Deposits stored in a map of reserve address to position\n */\n deposits: Map<PublicKey, Position>;\n\n /**\n * Borrows stored in a map of reserve address to position\n */\n borrows: Map<PublicKey, Position>;\n\n refreshedStats: ObligationStats;\n\n obligationTag: number;\n\n /**\n * Initialise a new Obligation from the deserialized state\n * @param market\n * @param obligationAddress\n * @param obligation\n * @param collateralExchangeRates - rates from the market by reserve address, will be calculated if not provided\n * @param cumulativeBorrowRates - rates from the market by reserve address, will be calculated if not provided\n */\n constructor(\n market: KaminoMarket,\n obligationAddress: PublicKey,\n obligation: Obligation,\n collateralExchangeRates: Map<PublicKey, Decimal>,\n cumulativeBorrowRates: Map<PublicKey, Decimal>\n ) {\n this.obligationAddress = obligationAddress;\n this.state = obligation;\n const { borrows, deposits, refreshedStats } = this.calculatePositions(\n market,\n obligation,\n collateralExchangeRates,\n cumulativeBorrowRates\n );\n this.deposits = deposits;\n this.borrows = borrows;\n this.refreshedStats = refreshedStats;\n this.obligationTag = obligation.tag.toNumber();\n }\n\n static async load(kaminoMarket: KaminoMarket, obligationAddress: PublicKey): Promise<KaminoObligation | null> {\n const res = await kaminoMarket.getConnection().getAccountInfoAndContext(obligationAddress);\n if (res.value === null) {\n return null;\n }\n const accInfo = res.value;\n if (!accInfo.owner.equals(kaminoMarket.programId)) {\n throw new Error(\"account doesn't belong to this program\");\n }\n const obligation = Obligation.decode(accInfo.data);\n\n if (obligation === null) {\n return null;\n }\n const { collateralExchangeRates, cumulativeBorrowRates } = KaminoObligation.getRatesForObligation(\n kaminoMarket,\n obligation,\n res.context.slot\n );\n return new KaminoObligation(\n kaminoMarket,\n obligationAddress,\n obligation,\n collateralExchangeRates,\n cumulativeBorrowRates\n );\n }\n\n static async loadAll(\n kaminoMarket: KaminoMarket,\n obligationAddresses: PublicKey[],\n slot?: number\n ): Promise<(KaminoObligation | null)[]> {\n let currentSlot = slot;\n let obligations: (Obligation | null)[];\n if (!currentSlot) {\n [currentSlot, obligations] = await Promise.all([\n kaminoMarket.getConnection().getSlot(),\n Obligation.fetchMultiple(kaminoMarket.getConnection(), obligationAddresses, kaminoMarket.programId),\n ]);\n } else {\n obligations = await Obligation.fetchMultiple(\n kaminoMarket.getConnection(),\n obligationAddresses,\n kaminoMarket.programId\n );\n }\n const cumulativeBorrowRates = new PubkeyHashMap<PublicKey, Decimal>();\n const collateralExchangeRates = new PubkeyHashMap<PublicKey, Decimal>();\n for (const obligation of obligations) {\n if (obligation !== null) {\n KaminoObligation.addRatesForObligation(\n kaminoMarket,\n obligation,\n collateralExchangeRates,\n cumulativeBorrowRates,\n currentSlot\n );\n }\n }\n\n return obligations.map((obligation, i) => {\n if (obligation === null) {\n return null;\n }\n return new KaminoObligation(\n kaminoMarket,\n obligationAddresses[i],\n obligation,\n collateralExchangeRates,\n cumulativeBorrowRates\n );\n });\n }\n\n /**\n * @returns the obligation borrows as a list\n */\n getBorrows(): Array<Position> {\n return [...this.borrows.values()];\n }\n\n /**\n * @returns the obligation borrows as a list\n */\n getDeposits(): Array<Position> {\n return [...this.deposits.values()];\n }\n\n /**\n * @returns the total deposited value of the obligation (sum of all deposits)\n */\n getDepositedValue(): Decimal {\n return new Fraction(this.state.depositedValueSf).toDecimal();\n }\n\n /**\n * @returns the total borrowed value of the obligation (sum of all borrows -- no borrow factor)\n */\n getBorrowedMarketValue(): Decimal {\n return new Fraction(this.state.borrowedAssetsMarketValueSf).toDecimal();\n }\n\n /**\n * @returns the total borrowed value of the obligation (sum of all borrows -- with borrow factor weighting)\n */\n getBorrowedMarketValueBFAdjusted(): Decimal {\n return new Fraction(this.state.borrowFactorAdjustedDebtValueSf).toDecimal();\n }\n\n /**\n * @returns total borrow power of the obligation, relative to max LTV of each asset's reserve\n */\n getAllowedBorrowValue(): Decimal {\n return new Fraction(this.state.allowedBorrowValueSf).toDecimal();\n }\n\n /**\n * @returns the borrow value at which the obligation gets liquidatable\n * (relative to the liquidation threshold of each asset's reserve)\n */\n getUnhealthyBorrowValue(): Decimal {\n return new Fraction(this.state.unhealthyBorrowValueSf).toDecimal();\n }\n\n /**\n *\n * @returns Market value of the deposit in the specified obligation collateral/deposit asset (USD)\n */\n getDepositMarketValue(deposit: ObligationCollateral): Decimal {\n return new Fraction(deposit.marketValueSf).toDecimal();\n }\n\n getBorrowByReserve(reserve: PublicKey): Position | undefined {\n return this.borrows.get(reserve);\n }\n\n getDepositByReserve(reserve: PublicKey): Position | undefined {\n return this.deposits.get(reserve);\n }\n\n getBorrowByMint(mint: PublicKey): Position | undefined {\n for (const value of this.borrows.values()) {\n if (value.mintAddress.equals(mint)) {\n return value;\n }\n }\n return undefined;\n }\n\n getDepositByMint(mint: PublicKey): Position | undefined {\n for (const value of this.deposits.values()) {\n if (value.mintAddress.equals(mint)) {\n return value;\n }\n }\n return undefined;\n }\n\n /**\n *\n * @returns Market value of the borrow in the specified obligation liquidity/borrow asset (USD) (no borrow factor weighting)\n */\n getBorrowMarketValue(borrow: ObligationLiquidity): Decimal {\n return new Fraction(borrow.marketValueSf).toDecimal();\n }\n\n /**\n *\n * @returns Market value of the borrow in the specified obligation liquidity/borrow asset (USD) (with borrow factor weighting)\n */\n getBorrowMarketValueBFAdjusted(borrow: ObligationLiquidity): Decimal {\n return new Fraction(borrow.borrowFactorAdjustedMarketValueSf).toDecimal();\n }\n\n /**\n * Calculate the current ratio of borrowed value to deposited value\n */\n loanToValue(): Decimal {\n if (this.refreshedStats.userTotalDeposit.eq(0)) {\n return new Decimal(0);\n }\n return this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.div(this.refreshedStats.userTotalDeposit);\n }\n\n /**\n * @returns the total number of positions (deposits + borrows)\n */\n getNumberOfPositions(): number {\n return this.deposits.size + this.borrows.size;\n }\n\n getNetAccountValue(): Decimal {\n return this.refreshedStats.netAccountValue;\n }\n\n /**\n * Get the loan to value and liquidation loan to value for a collateral token reserve as ratios, accounting for the obligation elevation group if it is active\n * @param market\n * @param reserve\n */\n public getLtvForReserve(market: KaminoMarket, reserve: KaminoReserve): { maxLtv: Decimal; liquidationLtv: Decimal } {\n return KaminoObligation.getLtvForReserve(market, reserve, this.state.elevationGroup);\n }\n\n /**\n * Get the borrow factor for a borrow reserve, accounting for the obligation elevation group if it is active\n * @param reserve\n */\n public getBorrowFactorForReserve(reserve: KaminoReserve): Decimal {\n return KaminoObligation.getBorrowFactorForReserve(reserve, this.state.elevationGroup);\n }\n\n /**\n * @returns the potential elevation groups the obligation qualifies for\n */\n getElevationGroups(kaminoMarket: KaminoMarket): Array<number> {\n const reserves = new PubkeyHashMap<PublicKey, KaminoReserve>();\n for (const deposit of this.state.deposits.values()) {\n if (isNotNullPubkey(deposit.depositReserve) && !reserves.has(deposit.depositReserve)) {\n reserves.set(deposit.depositReserve, kaminoMarket.getReserveByAddress(deposit.depositReserve)!);\n }\n }\n for (const borrow of this.state.borrows.values()) {\n if (isNotNullPubkey(borrow.borrowReserve) && !reserves.has(borrow.borrowReserve)) {\n reserves.set(borrow.borrowReserve, kaminoMarket.getReserveByAddress(borrow.borrowReserve)!);\n }\n }\n return KaminoObligation.getElevationGroupsForReserves([...reserves.values()]);\n }\n\n static getElevationGroupsForReserves(reserves: Array<KaminoReserve>): Array<number> {\n const elevationGroupsCounts = new Map<number, number>();\n for (const reserve of reserves) {\n for (const elevationGroup of reserve.state.config.elevationGroups) {\n if (elevationGroup !== 0) {\n const count = elevationGroupsCounts.get(elevationGroup);\n if (count) {\n elevationGroupsCounts.set(elevationGroup, count + 1);\n } else {\n elevationGroupsCounts.set(elevationGroup, 1);\n }\n }\n }\n }\n const activeElevationGroups = new Array<number>();\n for (const [group, count] of elevationGroupsCounts.entries()) {\n if (count === reserves.length) {\n activeElevationGroups.push(group);\n }\n }\n return activeElevationGroups;\n }\n\n calculateSimulatedBorrow(\n oldStats: ObligationStats,\n oldBorrows: Map<PublicKey, Position>,\n borrowAmount: Decimal,\n mint: PublicKey,\n reserves: Map<PublicKey, KaminoReserve>\n ): {\n stats: ObligationStats;\n borrows: Map<PublicKey, Position>;\n } {\n const newStats = { ...oldStats };\n const newBorrows = new PubkeyHashMap<PublicKey, Position>([...oldBorrows.entries()]);\n let borrowPosition: Position | undefined = undefined;\n for (const oldBorrow of oldBorrows.values()) {\n if (oldBorrow.mintAddress.equals(mint)) {\n borrowPosition = { ...oldBorrow };\n }\n }\n let reserve: KaminoReserve | undefined = undefined;\n for (const kaminoReserve of reserves.values()) {\n if (kaminoReserve.getLiquidityMint().equals(mint)) {\n reserve = kaminoReserve;\n }\n }\n\n if (!reserve) {\n throw new Error(`No reserve found for mint ${mint}`);\n }\n\n if (!borrowPosition) {\n borrowPosition = {\n reserveAddress: reserve!.address,\n mintAddress: mint,\n amount: new Decimal(0),\n marketValueRefreshed: new Decimal(0),\n };\n }\n\n if (!reserve.state.config.elevationGroups.includes(this.state.elevationGroup)) {\n throw new Error(\n `User would have to downgrade the elevation group in order to be able to borrow from this reserve`\n );\n }\n\n const borrowFactor = this.getBorrowFactorForReserve(reserve);\n\n const borrowValueUSD = borrowAmount.mul(reserve.getOracleMarketPrice()).dividedBy(reserve.getMintFactor());\n\n const borrowValueBorrowFactorAdjustedUSD = borrowValueUSD.mul(borrowFactor);\n\n newStats.userTotalBorrow = positiveOrZero(newStats.userTotalBorrow.plus(borrowValueUSD));\n newStats.userTotalBorrowBorrowFactorAdjusted = positiveOrZero(\n newStats.userTotalBorrowBorrowFactorAdjusted.plus(borrowValueBorrowFactorAdjustedUSD)\n );\n\n borrowPosition.amount = positiveOrZero(borrowPosition.amount.plus(borrowAmount));\n borrowPosition.mintAddress = mint;\n borrowPosition.marketValueRefreshed = positiveOrZero(borrowPosition.marketValueRefreshed.plus(borrowValueUSD));\n\n newBorrows.set(borrowPosition.reserveAddress, borrowPosition);\n return {\n borrows: newBorrows,\n stats: newStats,\n };\n }\n\n calculateSimulatedDeposit(\n oldStats: ObligationStats,\n oldDeposits: Map<PublicKey, Position>,\n amount: Decimal,\n mint: PublicKey,\n reserves: Map<PublicKey, KaminoReserve>,\n market: KaminoMarket\n ): {\n stats: ObligationStats;\n deposits: Map<PublicKey, Position>;\n } {\n const newStats = { ...oldStats };\n const newDeposits = new PubkeyHashMap<PublicKey, Position>([...oldDeposits.entries()]);\n\n let depositPosition: Position | undefined = undefined;\n for (const oldDeposit of oldDeposits.values()) {\n if (oldDeposit.mintAddress.equals(mint)) {\n depositPosition = { ...oldDeposit };\n }\n }\n let reserve: KaminoReserve | undefined = undefined;\n for (const kaminoReserve of reserves.values()) {\n if (kaminoReserve.getLiquidityMint().equals(mint)) {\n reserve = kaminoReserve;\n }\n }\n if (!reserve) {\n throw new Error(`No reserve found for mint ${mint}`);\n }\n\n if (!depositPosition) {\n depositPosition = {\n reserveAddress: reserve!.address,\n mintAddress: mint,\n amount: new Decimal(0),\n marketValueRefreshed: new Decimal(0),\n };\n }\n\n if (!reserve.state.config.elevationGroups.includes(this.state.elevationGroup)) {\n throw new Error(\n `User would have to downgrade the elevation group in order to be able to deposit in this reserve`\n );\n }\n const { maxLtv, liquidationLtv } = this.getLtvForReserve(market, reserve);\n\n const supplyAmount = amount; //.mul(reserve.getCollateralExchangeRate()).floor();\n const supplyAmountMultiplierUSD = supplyAmount\n .mul(reserve.getOracleMarketPrice())\n .dividedBy('1'.concat(Array(reserve.stats.decimals + 1).join('0')));\n\n newStats.userTotalDeposit = positiveOrZero(newStats.userTotalDeposit.plus(supplyAmountMultiplierUSD));\n newStats.borrowLimit = positiveOrZero(newStats.borrowLimit.plus(supplyAmountMultiplierUSD.mul(maxLtv)));\n newStats.borrowLiquidationLimit = positiveOrZero(\n newStats.borrowLiquidationLimit.plus(supplyAmountMultiplierUSD.mul(liquidationLtv))\n );\n newStats.liquidationLtv = valueOrZero(newStats.borrowLiquidationLimit.div(newStats.userTotalDeposit));\n\n depositPosition.amount = positiveOrZero(depositPosition.amount.plus(amount));\n depositPosition.mintAddress = mint;\n depositPosition.marketValueRefreshed = positiveOrZero(\n depositPosition.marketValueRefreshed.plus(\n supplyAmount.mul(reserve.getOracleMarketPrice()).dividedBy(reserve.getMintFactor())\n )\n );\n\n newDeposits.set(depositPosition.reserveAddress, depositPosition);\n\n return {\n deposits: newDeposits,\n stats: newStats,\n };\n }\n\n /**\n * Calculate the newly modified stats of the obligation\n */\n // TODO: Elevation group problems\n // TODO: Shall we set up position limits?\n getSimulatedObligationStats(params: {\n amountCollateral?: Decimal;\n amountDebt?: Decimal;\n action: ActionType;\n mintCollateral?: PublicKey;\n mintDebt?: PublicKey;\n market: KaminoMarket;\n reserves: Map<PublicKey, KaminoReserve>;\n }): {\n stats: ObligationStats;\n deposits: Map<PublicKey, Position>;\n borrows: Map<PublicKey, Position>;\n } {\n const { amountCollateral, amountDebt, action, mintCollateral, mintDebt, market, reserves } = params;\n let newStats = { ...this.refreshedStats };\n let newDeposits: Map<PublicKey, Position> = new PubkeyHashMap<PublicKey, Position>([...this.deposits.entries()]);\n let newBorrows: Map<PublicKey, Position> = new PubkeyHashMap<PublicKey, Position>([...this.borrows.entries()]);\n\n switch (action) {\n case 'deposit': {\n if (amountCollateral === undefined || mintCollateral === undefined) {\n throw Error('amountCollateral & mintCollateral are required for deposit action');\n }\n const { stats, deposits } = this.calculateSimulatedDeposit(\n this.refreshedStats,\n this.deposits,\n amountCollateral,\n mintCollateral,\n reserves,\n market\n );\n\n newStats = stats;\n newDeposits = deposits;\n\n break;\n }\n case 'borrow': {\n if (amountDebt === undefined || mintDebt === undefined) {\n throw Error('amountDebt & mintDebt are required for borrow action');\n }\n const { stats, borrows } = this.calculateSimulatedBorrow(\n this.refreshedStats,\n this.borrows,\n amountDebt,\n mintDebt,\n reserves\n );\n newStats = stats;\n newBorrows = borrows;\n break;\n }\n case 'repay': {\n if (amountDebt === undefined || mintDebt === undefined) {\n throw Error('amountDebt & mintDebt are required for repay action');\n }\n const { stats, borrows } = this.calculateSimulatedBorrow(\n this.refreshedStats,\n this.borrows,\n new Decimal(amountDebt).neg(),\n mintDebt,\n reserves\n );\n newStats = stats;\n newBorrows = borrows;\n break;\n }\n\n case 'withdraw': {\n if (amountCollateral === undefined || mintCollateral === undefined) {\n throw Error('amountCollateral & mintCollateral are required for withdraw action');\n }\n const { stats, deposits } = this.calculateSimulatedDeposit(\n this.refreshedStats,\n this.deposits,\n new Decimal(amountCollateral).neg(),\n mintCollateral,\n reserves,\n market\n );\n newStats = stats;\n newDeposits = deposits;\n break;\n }\n case 'depositAndBorrow': {\n if (\n amountCollateral === undefined ||\n amountDebt === undefined ||\n mintCollateral === undefined ||\n mintDebt === undefined\n ) {\n throw Error('amountColl & amountDebt & mintCollateral & mintDebt are required for depositAndBorrow action');\n }\n const { stats: statsAfterDeposit, deposits } = this.calculateSimulatedDeposit(\n this.refreshedStats,\n this.deposits,\n amountCollateral,\n mintCollateral,\n reserves,\n market\n );\n const { stats, borrows } = this.calculateSimulatedBorrow(\n statsAfterDeposit,\n this.borrows,\n amountDebt,\n mintDebt,\n reserves\n );\n\n newStats = stats;\n newDeposits = deposits;\n newBorrows = borrows;\n break;\n }\n case 'repayAndWithdraw': {\n if (\n amountCollateral === undefined ||\n amountDebt === undefined ||\n mintCollateral === undefined ||\n mintDebt === undefined\n ) {\n throw Error('amountColl & amountDebt & mintCollateral & mintDebt are required for repayAndWithdraw action');\n }\n const { stats: statsAfterRepay, borrows } = this.calculateSimulatedBorrow(\n this.refreshedStats,\n this.borrows,\n new Decimal(amountDebt).neg(),\n mintDebt,\n reserves\n );\n const { stats: statsAfterWithdraw, deposits } = this.calculateSimulatedDeposit(\n statsAfterRepay,\n this.deposits,\n new Decimal(amountCollateral).neg(),\n mintCollateral,\n reserves,\n market\n );\n newStats = statsAfterWithdraw;\n newDeposits = deposits;\n newBorrows = borrows;\n break;\n }\n default: {\n throw Error(`Invalid action type ${action} for getSimulatedObligationStats`);\n }\n }\n newStats.netAccountValue = newStats.userTotalDeposit.minus(newStats.userTotalBorrow);\n newStats.loanToValue = valueOrZero(\n newStats.userTotalBorrowBorrowFactorAdjusted.dividedBy(newStats.userTotalDeposit)\n );\n newStats.leverage = valueOrZero(newStats.userTotalDeposit.dividedBy(newStats.netAccountValue));\n\n return {\n stats: newStats,\n deposits: newDeposits,\n borrows: newBorrows,\n };\n }\n\n estimateObligationInterestRate = (\n market: KaminoMarket,\n reserve: KaminoReserve,\n borrow: ObligationLiquidity,\n currentSlot: number\n ): Decimal => {\n const estimatedCumulativeBorrowRate = reserve.getEstimatedCumulativeBorrowRate(\n currentSlot,\n market.state.referralFeeBps\n );\n\n const currentCumulativeBorrowRate = KaminoObligation.getCumulativeBorrowRate(borrow);\n\n if (estimatedCumulativeBorrowRate.gt(currentCumulativeBorrowRate)) {\n return estimatedCumulativeBorrowRate.div(currentCumulativeBorrowRate);\n }\n\n return new Decimal(0);\n };\n\n private calculateDeposits(\n market: KaminoMarket,\n obligation: Obligation,\n collateralExchangeRates: Map<PublicKey, Decimal>,\n getPx: (reserve: KaminoReserve) => Decimal\n ): {\n deposits: Map<PublicKey, Position>;\n userTotalDeposit: Decimal;\n borrowLimit: Decimal;\n liquidationLtv: Decimal;\n borrowLiquidationLimit: Decimal;\n } {\n return KaminoObligation.calculateObligationDeposits(\n market,\n obligation,\n collateralExchangeRates,\n obligation.elevationGroup,\n getPx\n );\n }\n\n private calculateBorrows(\n market: KaminoMarket,\n obligation: Obligation,\n cumulativeBorrowRates: Map<PublicKey, Decimal>,\n getPx: (reserve: KaminoReserve) => Decimal\n ): BorrowStats {\n return KaminoObligation.calculateObligationBorrows(\n market,\n obligation,\n cumulativeBorrowRates,\n obligation.elevationGroup,\n getPx\n );\n }\n\n private calculatePositions(\n market: KaminoMarket,\n obligation: Obligation,\n collateralExchangeRates: Map<PublicKey, Decimal>,\n cumulativeBorrowRates: Map<PublicKey, Decimal>\n ): {\n borrows: Map<PublicKey, Position>;\n deposits: Map<PublicKey, Position>;\n refreshedStats: ObligationStats;\n } {\n const getOraclePx = (reserve: KaminoReserve) => reserve.getOracleMarketPrice();\n const depositStatsOraclePrice = this.calculateDeposits(market, obligation, collateralExchangeRates, getOraclePx);\n\n const borrowStatsOraclePrice = this.calculateBorrows(market, obligation, cumulativeBorrowRates, getOraclePx);\n\n const netAccountValueScopeRefreshed = depositStatsOraclePrice.userTotalDeposit.minus(\n borrowStatsOraclePrice.userTotalBorrow\n );\n\n const potentialElevationGroupUpdate = 0;\n\n return {\n deposits: depositStatsOraclePrice.deposits,\n borrows: borrowStatsOraclePrice.borrows,\n refreshedStats: {\n borrowLimit: depositStatsOraclePrice.borrowLimit,\n borrowLiquidationLimit: depositStatsOraclePrice.borrowLiquidationLimit,\n userTotalBorrow: borrowStatsOraclePrice.userTotalBorrow,\n userTotalBorrowBorrowFactorAdjusted: borrowStatsOraclePrice.userTotalBorrowBorrowFactorAdjusted,\n userTotalDeposit: depositStatsOraclePrice.userTotalDeposit,\n liquidationLtv: depositStatsOraclePrice.liquidationLtv,\n borrowUtilization: borrowStatsOraclePrice.userTotalBorrowBorrowFactorAdjusted.dividedBy(\n depositStatsOraclePrice.borrowLimit\n ),\n netAccountValue: netAccountValueScopeRefreshed,\n leverage: depositStatsOraclePrice.userTotalDeposit.dividedBy(netAccountValueScopeRefreshed),\n loanToValue: borrowStatsOraclePrice.userTotalBorrowBorrowFactorAdjusted.dividedBy(\n depositStatsOraclePrice.userTotalDeposit\n ),\n potentialElevationGroupUpdate,\n },\n };\n }\n\n public static calculateObligationDeposits(\n market: KaminoMarket,\n obligation: Obligation,\n collateralExchangeRates: Map<PublicKey, Decimal> | null,\n elevationGroup: number,\n getPx: (reserve: KaminoReserve) => Decimal\n ): {\n deposits: Map<PublicKey, Position>;\n userTotalDeposit: Decimal;\n userTotalCollateralDeposit: Decimal;\n borrowLimit: Decimal;\n liquidationLtv: Decimal;\n borrowLiquidationLimit: Decimal;\n } {\n let userTotalDeposit = new Decimal(0);\n let userTotalCollateralDeposit = new Decimal(0);\n let borrowLimit = new Decimal(0);\n let borrowLiquidationLimit = new Decimal(0);\n\n const deposits = new PubkeyHashMap<PublicKey, Position>();\n for (let i = 0; i < obligation.deposits.length; i++) {\n if (!isNotNullPubkey(obligation.deposits[i].depositReserve)) {\n continue;\n }\n const deposit = obligation.deposits[i];\n const reserve = market.getReserveByAddress(deposit.depositReserve);\n if (!reserve) {\n throw new Error(\n `Obligation contains a deposit belonging to reserve: ${deposit.depositReserve} but the reserve was not found on the market. Deposit amount: ${deposit.depositedAmount}`\n );\n }\n const { maxLtv, liquidationLtv } = KaminoObligation.getLtvForReserve(market, reserve, elevationGroup);\n\n let exchangeRate: Decimal;\n if (collateralExchangeRates !== null) {\n exchangeRate = collateralExchangeRates.get(reserve.address)!;\n } else {\n exchangeRate = reserve.getCollateralExchangeRate();\n }\n const supplyAmount = new Decimal(deposit.depositedAmount.toString()).div(exchangeRate);\n\n const depositValueUsd = supplyAmount.mul(getPx(reserve)).div(reserve.getMintFactor());\n\n userTotalDeposit = userTotalDeposit.add(depositValueUsd);\n\n if (!maxLtv.eq('0')) {\n userTotalCollateralDeposit = userTotalCollateralDeposit.add(depositValueUsd);\n }\n\n borrowLimit = borrowLimit.add(depositValueUsd.mul(maxLtv));\n borrowLiquidationLimit = borrowLiquidationLimit.add(depositValueUsd.mul(liquidationLtv));\n\n const position: Position = {\n reserveAddress: reserve.address,\n mintAddress: reserve.getLiquidityMint(),\n amount: supplyAmount,\n marketValueRefreshed: depositValueUsd,\n };\n deposits.set(reserve.address, position);\n }\n\n return {\n deposits,\n userTotalDeposit,\n userTotalCollateralDeposit,\n borrowLimit,\n liquidationLtv: valueOrZero(borrowLiquidationLimit.div(userTotalDeposit)),\n borrowLiquidationLimit,\n };\n }\n\n public static calculateObligationBorrows(\n market: KaminoMarket,\n obligation: Obligation,\n cumulativeBorrowRates: Map<PublicKey, Decimal> | null,\n elevationGroup: number,\n getPx: (reserve: KaminoReserve) => Decimal\n ): BorrowStats {\n let userTotalBorrow = new Decimal(0);\n let userTotalBorrowBorrowFactorAdjusted = new Decimal(0);\n let positions = 0;\n\n const borrows = new PubkeyHashMap<PublicKey, Position>();\n for (let i = 0; i < obligation.borrows.length; i++) {\n if (!isNotNullPubkey(obligation.borrows[i].borrowReserve)) {\n continue;\n }\n const borrow = obligation.borrows[i];\n const reserve = market.getReserveByAddress(borrow.borrowReserve);\n if (!reserve) {\n throw new Error(\n `Obligation contains a borrow belonging to reserve: ${\n borrow.borrowReserve\n } but the reserve was not found on the market. Borrow amount: ${KaminoObligation.getBorrowAmount(borrow)}`\n );\n }\n\n const obligationCumulativeBorrowRate = KaminoObligation.getCumulativeBorrowRate(borrow);\n let cumulativeBorrowRate;\n if (cumulativeBorrowRates !== null) {\n cumulativeBorrowRate = cumulativeBorrowRates.get(reserve.address)!;\n } else {\n cumulativeBorrowRate = reserve.getCumulativeBorrowRate();\n }\n\n const borrowAmount = KaminoObligation.getBorrowAmount(borrow)\n .mul(cumulativeBorrowRate)\n .dividedBy(obligationCumulativeBorrowRate);\n\n const borrowValueUsd = borrowAmount.mul(getPx(reserve)).dividedBy(reserve.getMintFactor());\n\n const borrowFactor = KaminoObligation.getBorrowFactorForReserve(reserve, elevationGroup);\n const borrowValueBorrowFactorAdjustedUsd = borrowValueUsd.mul(borrowFactor);\n\n if (!borrowAmount.eq(new Decimal('0'))) {\n positions += 1;\n }\n\n userTotalBorrow = userTotalBorrow.plus(borrowValueUsd);\n userTotalBorrowBorrowFactorAdjusted = userTotalBorrowBorrowFactorAdjusted.plus(\n borrowValueBorrowFactorAdjustedUsd\n );\n\n const position: Position = {\n reserveAddress: reserve.address,\n mintAddress: reserve.getLiquidityMint(),\n amount: borrowAmount,\n marketValueRefreshed: borrowValueUsd,\n };\n borrows.set(reserve.address, position);\n }\n\n return {\n borrows,\n userTotalBorrow,\n userTotalBorrowBorrowFactorAdjusted,\n positions,\n };\n }\n\n /* \n How much of a given token can a user borrow extra given an elevation group, \n regardless of caps and liquidity or assuming infinite liquidity and infinite caps,\n until it hits max LTV.\n\n This is purely a function about the borrow power of an obligation, \n not a reserve-specific, caps-specific, liquidity-specific function.\n\n * @param market - The KaminoMarket instance.\n * @param liquidityMint - The liquidity mint PublicKey.\n * @param slot - The slot number.\n * @param elevationGroup - The elevation group number (default: this.state.elevationGroup).\n * @returns The borrow power as a Decimal.\n * @throws Error if the reserve is not found.\n */\n getBorrowPower(\n market: KaminoMarket,\n liquidityMint: PublicKey,\n slot: number,\n elevationGroup: number = this.state.elevationGroup\n ): Decimal {\n const reserve = market.getReserveByMint(liquidityMint);\n if (!reserve) {\n throw new Error('Reserve not found');\n }\n\n const elevationGroupActivated =\n reserve.state.config.elevationGroups.includes(elevationGroup) && elevationGroup !== 0;\n\n const borrowFactor = KaminoObligation.getBorrowFactorForReserve(reserve, elevationGroup);\n\n const getOraclePx = (reserve: KaminoReserve) => reserve.getOracleMarketPrice();\n const { collateralExchangeRates, cumulativeBorrowRates } = KaminoObligation.getRatesForObligation(\n market,\n this.state,\n slot\n );\n\n const { borrowLimit } = KaminoObligation.calculateObligationDeposits(\n market,\n this.state,\n collateralExchangeRates,\n elevationGroup,\n getOraclePx\n );\n\n const { userTotalBorrowBorrowFactorAdjusted } = KaminoObligation.calculateObligationBorrows(\n market,\n this.state,\n cumulativeBorrowRates,\n elevationGroup,\n getOraclePx\n );\n\n const maxObligationBorrowPower = borrowLimit // adjusted available amount\n .minus(userTotalBorrowBorrowFactorAdjusted)\n .div(borrowFactor)\n .div(reserve.getOracleMarketPrice())\n .mul(reserve.getMintFactor());\n\n // If it has any collateral outside emode, then return 0\n for (const [_, value] of this.deposits.entries()) {\n const depositReserve = market.getReserveByAddress(value.reserveAddress);\n if (!depositReserve) {\n throw new Error('Reserve not found');\n }\n if (depositReserve.state.config.disableUsageAsCollOutsideEmode && !elevationGroupActivated) {\n return new Decimal(0);\n }\n }\n\n // This is not amazing because it assumes max borrow, which is not true\n let originationFeeRate = reserve.getBorrowFee();\n\n // Inclusive fee rate\n originationFeeRate = originationFeeRate.div(originationFeeRate.add(new Decimal(1)));\n const borrowFee = maxObligationBorrowPower.mul(originationFeeRate);\n\n const maxBorrowAmount = maxObligationBorrowPower.sub(borrowFee);\n\n return Decimal.max(new Decimal(0), maxBorrowAmount);\n }\n\n /* \n How much of a given token can a user borrow extra given an elevation group,\n and a specific reserve, until it hits max LTV and given available liquidity and caps.\n\n * @param market - The KaminoMarket instance.\n * @param liquidityMint - The liquidity mint PublicKey.\n * @param slot - The slot number.\n * @param elevationGroup - The elevation group number (default: this.state.elevationGroup).\n * @returns The maximum borrow amount as a Decimal.\n * @throws Error if the reserve is not found.\n */\n getMaxBorrowAmountV2(\n market: KaminoMarket,\n liquidityMint: PublicKey,\n slot: number,\n elevationGroup: number = this.state.elevationGroup\n ): Decimal {\n const reserve = market.getReserveByMint(liquidityMint);\n if (!reserve) {\n throw new Error('Reserve not found');\n }\n\n const liquidityAvailable = reserve.getLiquidityAvailableForDebtReserveGivenCaps(market, [elevationGroup])[0];\n const maxBorrowAmount = this.getBorrowPower(market, liquidityMint, slot, elevationGroup);\n\n if (elevationGroup === this.state.elevationGroup) {\n return Decimal.min(maxBorrowAmount, liquidityAvailable);\n } else {\n const { amount: debtThisReserve } = this.borrows.get(reserve.address) || { amount: new Decimal(0) };\n const liquidityAvailablePostMigration = Decimal.max(0, liquidityAvailable.minus(debtThisReserve));\n return Decimal.min(maxBorrowAmount, liquidityAvailablePostMigration);\n }\n }\n\n /* \n Returns true if the loan is eligible for the elevation group, including for the default one.\n * @param market - The KaminoMarket object representing the market.\n * @param slot - The slot number of the loan.\n * @param elevationGroup - The elevation group number.\n * @returns A boolean indicating whether the loan is eligible for elevation.\n */\n isLoanEligibleForElevationGroup(market: KaminoMarket, slot: number, elevationGroup: number): boolean {\n // - isLoanEligibleForEmode(obligation, emode: 0 | number): <boolean, ErrorMessage>\n // - essentially checks if a loan can be migrated or not\n // - [x] due to collateral / debt reserves combination\n // - [x] due to LTV, etc\n\n if (elevationGroup === 0) {\n return true;\n }\n\n const reserveDeposits: string[] = Array.from(this.deposits.keys()).map((x) => x.toString());\n const reserveBorrows: string[] = Array.from(this.borrows.keys()).map((x) => x.toString());\n\n if (reserveBorrows.length > 1) {\n return false;\n }\n\n const allElevationGroups = market.getMarketElevationGroupDescriptions();\n const elevationGroupDescription = allElevationGroups[elevationGroup - 1];\n\n // Has to be a subset\n const allCollsIncluded = reserveDeposits.every((reserve) =>\n elevationGroupDescription.collateralReserves.includes(reserve)\n );\n const allDebtsIncluded =\n reserveBorrows.length === 0 ||\n (reserveBorrows.length === 1 && elevationGroupDescription.debtReserve === reserveBorrows[0]);\n\n const isEligibleBasedOnReserves = allCollsIncluded && allDebtsIncluded;\n\n // Check if the loan can be migrated\n\n const getOraclePx = (reserve: KaminoReserve) => reserve.getOracleMarketPrice();\n const { collateralExchangeRates } = KaminoObligation.getRatesForObligation(market, this.state, slot);\n\n const { borrowLimit } = KaminoObligation.calculateObligationDeposits(\n market,\n this.state,\n collateralExchangeRates,\n elevationGroup,\n getOraclePx\n );\n\n const isEligibleBasedOnLtv = this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.lte(borrowLimit);\n\n return isEligibleBasedOnReserves && isEligibleBasedOnLtv;\n }\n\n /* \n Returns all elevation groups for a given obligation, except the default one\n * @param market - The KaminoMarket instance.\n * @returns An array of ElevationGroupDescription objects representing the elevation groups for the obligation.\n */\n getElevationGroupsForObligation(market: KaminoMarket): ElevationGroupDescription[] {\n if (this.borrows.size > 1) {\n return [];\n }\n\n const collReserves = Array.from(this.deposits.keys());\n if (this.borrows.size === 0) {\n return market.getElevationGroupsForReservesCombination(collReserves);\n } else {\n const debtReserve = Array.from(this.borrows.keys())[0];\n return market.getElevationGroupsForReservesCombination(collReserves, debtReserve);\n }\n }\n\n /* Deprecated function, also broken */\n getMaxBorrowAmount(\n market: KaminoMarket,\n liquidityMint: PublicKey,\n slot: number,\n requestElevationGroup: boolean\n ): Decimal {\n const reserve = market.getReserveByMint(liquidityMint);\n\n if (!reserve) {\n throw new Error('Reserve not found');\n }\n\n const groups = market.state.elevationGroups;\n const emodeGroupsDebtReserve = reserve.state.config.elevationGroups;\n let commonElevationGroups = [...emodeGroupsDebtReserve].filter(\n (item) => item !== 0 && groups[item - 1].debtReserve.equals(reserve.address)\n );\n\n for (const [_, value] of this.deposits.entries()) {\n const depositReserve = market.getReserveByAddress(value.reserveAddress);\n\n if (!depositReserve) {\n throw new Error('Reserve not found');\n }\n\n const depositReserveEmodeGroups = depositReserve.state.config.elevationGroups;\n\n commonElevationGroups = commonElevationGroups.filter((item) => depositReserveEmodeGroups.includes(item));\n }\n\n let elevationGroup = this.state.elevationGroup;\n if (commonElevationGroups.length != 0) {\n const eModeGroupWithMaxLtvAndDebtReserve = commonElevationGroups.reduce((prev, curr) => {\n const prevGroup = groups.find((group) => group.id === prev);\n const currGroup = groups.find((group) => group.id === curr);\n return prevGroup!.ltvPct > currGroup!.ltvPct ? prev : curr;\n });\n\n if (requestElevationGroup) {\n elevationGroup = eModeGroupWithMaxLtvAndDebtReserve;\n }\n }\n\n const elevationGroupActivated =\n reserve.state.config.elevationGroups.includes(elevationGroup) && elevationGroup !== 0;\n\n const borrowFactor = this.getBorrowFactorForReserve(reserve);\n\n const maxObligationBorrowPower = this.refreshedStats.borrowLimit // adjusted available amount\n .minus(this.refreshedStats.userTotalBorrowBorrowFactorAdjusted)\n .div(borrowFactor)\n .div(reserve.getOracleMarketPrice())\n .mul(reserve.getMintFactor());\n const reserveAvailableAmount = reserve.getLiquidityAvailableAmount();\n let reserveBorrowCapRemained = reserve.stats.reserveBorrowLimit.sub(reserve.getBorrowedAmount());\n\n this.deposits.forEach((deposit) => {\n const depositReserve = market.getReserveByAddress(deposit.reserveAddress);\n if (!depositReserve) {\n throw new Error('Reserve not found');\n }\n if (depositReserve.state.config.disableUsageAsCollOutsideEmode && !elevationGroupActivated) {\n reserveBorrowCapRemained = new Decimal(0);\n }\n });\n\n let maxBorrowAmount = Decimal.min(maxObligationBorrowPower, reserveAvailableAmount, reserveBorrowCapRemained);\n\n const debtWithdrawalCap = reserve.getDebtWithdrawalCapCapacity().sub(reserve.getDebtWithdrawalCapCurrent(slot));\n maxBorrowAmount = reserve.getDebtWithdrawalCapCapacity().gt(0)\n ? Decimal.min(maxBorrowAmount, debtWithdrawalCap)\n : maxBorrowAmount;\n\n let originationFeeRate = reserve.getBorrowFee();\n\n // Inclusive fee rate\n originationFeeRate = originationFeeRate.div(originationFeeRate.add(new Decimal(1)));\n const borrowFee = maxBorrowAmount.mul(originationFeeRate);\n\n maxBorrowAmount = maxBorrowAmount.sub(borrowFee);\n\n const utilizationRatioLimit = reserve.state.config.utilizationLimitBlockBorrowingAbove / 100;\n const currentUtilizationRatio = reserve.calculateUtilizationRatio();\n\n if (utilizationRatioLimit > 0 && currentUtilizationRatio > utilizationRatioLimit) {\n return new Decimal(0);\n } else if (utilizationRatioLimit > 0 && currentUtilizationRatio < utilizationRatioLimit) {\n const maxBorrowBasedOnUtilization = new Decimal(utilizationRatioLimit - currentUtilizationRatio).mul(\n reserve.getTotalSupply()\n );\n maxBorrowAmount = Decimal.min(maxBorrowAmount, maxBorrowBasedOnUtilization);\n }\n\n let borrowLimitDependentOnElevationGroup = new Decimal(U64_MAX);\n\n if (!elevationGroupActivated) {\n borrowLimitDependentOnElevationGroup = reserve\n .getBorrowLimitOutsideElevationGroup()\n .sub(reserve.getBorrowedAmountOutsideElevationGroup());\n } else {\n let maxDebtTakenAgainstCollaterals = new Decimal(U64_MAX);\n for (const [_, value] of this.deposits.entries()) {\n const depositReserve = market.getReserveByAddress(value.reserveAddress);\n\n if (!depositReserve) {\n throw new Error('Reserve not found');\n }\n\n const maxDebtAllowedAgainstCollateral = depositReserve\n .getBorrowLimitAgainstCollateralInElevationGroup(elevationGroup - 1)\n .sub(depositReserve.getBorrowedAmountAgainstCollateralInElevationGroup(elevationGroup - 1));\n\n maxDebtTakenAgainstCollaterals = Decimal.max(\n new Decimal(0),\n Decimal.min(maxDebtAllowedAgainstCollateral, maxDebtTakenAgainstCollaterals)\n );\n }\n borrowLimitDependentOnElevationGroup = maxDebtTakenAgainstCollaterals;\n }\n\n maxBorrowAmount = Decimal.min(maxBorrowAmount, borrowLimitDependentOnElevationGroup);\n\n return Decimal.max(new Decimal(0), maxBorrowAmount);\n }\n\n getMaxWithdrawAmount(market: KaminoMarket, tokenMint: PublicKey, slot: number): Decimal {\n const depositReserve = market.getReserveByMint(tokenMint);\n\n if (!depositReserve) {\n throw new Error('Reserve not found');\n }\n\n const userDepositPosition = this.getDepositByReserve(depositReserve.address);\n\n if (!userDepositPosition) {\n throw new Error('Deposit reserve not found');\n }\n\n const userDepositPositionAmount = userDepositPosition.amount;\n\n if (this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.equals(new Decimal(0))) {\n return new Decimal(userDepositPositionAmount);\n }\n\n const { maxLtv: reserveMaxLtv } = this.getLtvForReserve(market, depositReserve);\n // bf adjusted debt value > allowed_borrow_value\n if (this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.gte(this.refreshedStats.borrowLimit)) {\n return new Decimal(0);\n }\n\n let maxWithdrawValue: Decimal;\n if (reserveMaxLtv.eq(0)) {\n maxWithdrawValue = userDepositPositionAmount;\n } else {\n // borrowLimit / userTotalDeposit = maxLtv\n // maxWithdrawValue = userTotalDeposit - userTotalBorrow / maxLtv\n maxWithdrawValue = this.refreshedStats.borrowLimit\n .sub(this.refreshedStats.userTotalBorrowBorrowFactorAdjusted)\n .div(reserveMaxLtv)\n .mul(0.999); // remove 0.1% to prevent going over max ltv\n }\n\n const maxWithdrawAmount = maxWithdrawValue\n .div(depositReserve.getOracleMarketPrice())\n .mul(depositReserve.getMintFactor());\n const reserveAvailableLiquidity = depositReserve.getLiquidityAvailableAmount();\n\n const withdrawalCapRemained = depositReserve\n .getDepositWithdrawalCapCapacity()\n .sub(depositReserve.getDepositWithdrawalCapCurrent(slot));\n return Decimal.max(\n 0,\n Decimal.min(userDepositPositionAmount, maxWithdrawAmount, reserveAvailableLiquidity, withdrawalCapRemained)\n );\n }\n\n /**\n *\n * @returns Total borrowed amount for the specified obligation liquidity/borrow asset\n */\n static getBorrowAmount(borrow: ObligationLiquidity): Decimal {\n return new Fraction(borrow.borrowedAmountSf).toDecimal();\n }\n\n /**\n *\n * @returns Cumulative borrow rate for the specified obligation liquidity/borrow asset\n */\n static getCumulativeBorrowRate(borrow: ObligationLiquidity): Decimal {\n let accSf = new BN(0);\n for (const value of borrow.cumulativeBorrowRateBsf.value.reverse()) {\n accSf = accSf.add(value);\n accSf.shrn(64);\n }\n return new Fraction(accSf).toDecimal();\n }\n\n public static getRatesForObligation(\n kaminoMarket: KaminoMarket,\n obligation: Obligation,\n slot: number\n ): {\n collateralExchangeRates: Map<PublicKey, Decimal>;\n cumulativeBorrowRates: Map<PublicKey, Decimal>;\n } {\n const collateralExchangeRates = KaminoObligation.getCollateralExchangeRatesForObligation(\n kaminoMarket,\n obligation,\n slot\n );\n const cumulativeBorrowRates = KaminoObligation.getCumulativeBorrowRatesForObligation(\n kaminoMarket,\n obligation,\n slot\n );\n\n return {\n collateralExchangeRates,\n cumulativeBorrowRates,\n };\n }\n\n public static addRatesForObligation(\n kaminoMarket: KaminoMarket,\n obligation: Obligation,\n collateralExchangeRates: Map<PublicKey, Decimal>,\n cumulativeBorrowRates: Map<PublicKey, Decimal>,\n slot: number\n ): void {\n KaminoObligation.addCollateralExchangeRatesForObligation(kaminoMarket, collateralExchangeRates, obligation, slot);\n KaminoObligation.addCumulativeBorrowRatesForObligation(kaminoMarket, cumulativeBorrowRates, obligation, slot);\n }\n\n static getCollateralExchangeRatesForObligation(\n kaminoMarket: KaminoMarket,\n obligation: Obligation,\n slot: number\n ): Map<PublicKey, Decimal> {\n const collateralExchangeRates = new PubkeyHashMap<PublicKey, Decimal>();\n for (let i = 0; i < obligation.deposits.length; i++) {\n const deposit = obligation.deposits[i];\n if (isNotNullPubkey(deposit.depositReserve) && !collateralExchangeRates.has(deposit.depositReserve)) {\n const reserve = kaminoMarket.getReserveByAddress(deposit.depositReserve)!;\n const collateralExchangeRate = reserve.getEstimatedCollateralExchangeRate(\n slot,\n kaminoMarket.state.referralFeeBps\n );\n collateralExchangeRates.set(reserve.address, collateralExchangeRate);\n }\n }\n return collateralExchangeRates;\n }\n\n static addCollateralExchangeRatesForObligation(\n kaminoMarket: KaminoMarket,\n collateralExchangeRates: Map<PublicKey, Decimal>,\n obligation: Obligation,\n slot: number\n ) {\n for (let i = 0; i < obligation.deposits.length; i++) {\n const deposit = obligation.deposits[i];\n if (isNotNullPubkey(deposit.depositReserve) && !collateralExchangeRates.has(deposit.depositReserve)) {\n const reserve = kaminoMarket.getReserveByAddress(deposit.depositReserve)!;\n const collateralExchangeRate = reserve.getEstimatedCollateralExchangeRate(\n slot,\n kaminoMarket.state.referralFeeBps\n );\n collateralExchangeRates.set(reserve.address, collateralExchangeRate);\n }\n }\n }\n\n static getCumulativeBorrowRatesForObligation(kaminoMarket: KaminoMarket, obligation: Obligation, slot: number) {\n const cumulativeBorrowRates = new PubkeyHashMap<PublicKey, Decimal>();\n for (let i = 0; i < obligation.borrows.length; i++) {\n const borrow = obligation.borrows[i];\n if (isNotNullPubkey(borrow.borrowReserve) && !cumulativeBorrowRates.has(borrow.borrowReserve)) {\n const reserve = kaminoMarket.getReserveByAddress(borrow.borrowReserve)!;\n const cumulativeBorrowRate = reserve.getEstimatedCumulativeBorrowRate(slot, kaminoMarket.state.referralFeeBps);\n cumulativeBorrowRates.set(reserve.address, cumulativeBorrowRate);\n }\n }\n return cumulativeBorrowRates;\n }\n\n static addCumulativeBorrowRatesForObligation(\n kaminoMarket: KaminoMarket,\n cumulativeBorrowRates: Map<PublicKey, Decimal>,\n obligation: Obligation,\n slot: number\n ) {\n for (let i = 0; i < obligation.borrows.length; i++) {\n const borrow = obligation.borrows[i];\n if (isNotNullPubkey(borrow.borrowReserve) && !cumulativeBorrowRates.has(borrow.borrowReserve)) {\n const reserve = kaminoMarket.getReserveByAddress(borrow.borrowReserve)!;\n const cumulativeBorrowRate = reserve.getEstimatedCumulativeBorrowRate(slot, kaminoMarket.state.referralFeeBps);\n cumulativeBorrowRates.set(reserve.address, cumulativeBorrowRate);\n }\n }\n }\n\n /**\n * Get the borrow factor for a borrow reserve, accounting for the obligation elevation group if it is active\n * @param reserve\n * @param elevationGroup\n */\n public static getBorrowFactorForReserve(reserve: KaminoReserve, elevationGroup: number): Decimal {\n const elevationGroupActivated =\n reserve.state.config.elevationGroups.includes(elevationGroup) && elevationGroup !== 0;\n if (elevationGroupActivated) {\n return new Decimal('1');\n }\n return new Decimal(reserve.stats.borrowFactor).div('100');\n }\n\n /**\n * Get the loan to value and liquidation loan to value for a collateral reserve as ratios, accounting for the obligation elevation group if it is active\n * @param market\n * @param reserve\n * @param elevationGroup\n */\n public static getLtvForReserve(\n market: KaminoMarket,\n reserve: KaminoReserve,\n elevationGroup: number\n ): { maxLtv: Decimal; liquidationLtv: Decimal } {\n const elevationGroupActivated =\n elevationGroup !== 0 && reserve.state.config.elevationGroups.includes(elevationGroup);\n if (elevationGroupActivated) {\n const { ltvPct, liquidationThresholdPct } = market.getElevationGroup(elevationGroup);\n return {\n maxLtv: new Decimal(ltvPct).div('100'),\n liquidationLtv: new Decimal(liquidationThresholdPct).div('100'),\n };\n } else {\n const { loanToValue, liquidationThreshold } = reserve.stats;\n return {\n maxLtv: new Decimal(loanToValue),\n liquidationLtv: new Decimal(liquidationThreshold),\n };\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"obligation.js","sourceRoot":"","sources":["../../src/classes/obligation.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAEA,4DAAiC;AAEjC,sDAAqD;AAErD,kDAAuB;AACvB,yCAAsC;AAEtC,mCAAsD;AACtD,oCAAmE;AAqCnE,MAAa,gBAAgB;IAmB3B;;;;;;;OAOG;IACH,YACE,MAAoB,EACpB,iBAA4B,EAC5B,UAAsB,EACtB,uBAAgD,EAChD,qBAA8C;QA+jBhD,mCAA8B,GAAG,CAC/B,MAAoB,EACpB,OAAsB,EACtB,MAA2B,EAC3B,WAAmB,EACV,EAAE;YACX,MAAM,6BAA6B,GAAG,OAAO,CAAC,gCAAgC,CAC5E,WAAW,EACX,MAAM,CAAC,KAAK,CAAC,cAAc,CAC5B,CAAC;YAEF,MAAM,2BAA2B,GAAG,gBAAgB,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;YAErF,IAAI,6BAA6B,CAAC,EAAE,CAAC,2BAA2B,CAAC,EAAE,CAAC;gBAClE,OAAO,6BAA6B,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACxE,CAAC;YAED,OAAO,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC,CAAC;QA/kBA,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC;QACxB,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,kBAAkB,CACnE,MAAM,EACN,UAAU,EACV,uBAAuB,EACvB,qBAAqB,CACtB,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;IACjD,CAAC;IAED,MAAM,CAAO,IAAI,CAAC,YAA0B,EAAE,iBAA4B;;YACxE,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,aAAa,EAAE,CAAC,wBAAwB,CAAC,iBAAiB,CAAC,CAAC;YAC3F,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;gBACvB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC;YAC1B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;gBAClD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;YAC5D,CAAC;YACD,MAAM,UAAU,GAAG,qBAAU,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAEnD,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;gBACxB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,GAAG,gBAAgB,CAAC,qBAAqB,CAC/F,YAAY,EACZ,UAAU,EACV,GAAG,CAAC,OAAO,CAAC,IAAI,CACjB,CAAC;YACF,OAAO,IAAI,gBAAgB,CACzB,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,uBAAuB,EACvB,qBAAqB,CACtB,CAAC;QACJ,CAAC;KAAA;IAED,MAAM,CAAO,OAAO,CAClB,YAA0B,EAC1B,mBAAgC,EAChC,IAAa;;YAEb,IAAI,WAAW,GAAG,IAAI,CAAC;YACvB,IAAI,WAAkC,CAAC;YACvC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;oBAC7C,YAAY,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE;oBACtC,qBAAU,CAAC,aAAa,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,mBAAmB,EAAE,YAAY,CAAC,SAAS,CAAC;iBACpG,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,WAAW,GAAG,MAAM,qBAAU,CAAC,aAAa,CAC1C,YAAY,CAAC,aAAa,EAAE,EAC5B,mBAAmB,EACnB,YAAY,CAAC,SAAS,CACvB,CAAC;YACJ,CAAC;YACD,MAAM,qBAAqB,GAAG,IAAI,qBAAa,EAAsB,CAAC;YACtE,MAAM,uBAAuB,GAAG,IAAI,qBAAa,EAAsB,CAAC;YACxE,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;gBACrC,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;oBACxB,gBAAgB,CAAC,qBAAqB,CACpC,YAAY,EACZ,UAAU,EACV,uBAAuB,EACvB,qBAAqB,EACrB,WAAW,CACZ,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE;gBACvC,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;oBACxB,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,OAAO,IAAI,gBAAgB,CACzB,YAAY,EACZ,mBAAmB,CAAC,CAAC,CAAC,EACtB,UAAU,EACV,uBAAuB,EACvB,qBAAqB,CACtB,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;KAAA;IAED;;OAEG;IACH,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,iBAAiB;QACf,OAAO,IAAI,mBAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,SAAS,EAAE,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,sBAAsB;QACpB,OAAO,IAAI,mBAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,SAAS,EAAE,CAAC;IAC1E,CAAC;IAED;;OAEG;IACH,gCAAgC;QAC9B,OAAO,IAAI,mBAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC,SAAS,EAAE,CAAC;IAC9E,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,OAAO,IAAI,mBAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,SAAS,EAAE,CAAC;IACnE,CAAC;IAED;;;OAGG;IACH,uBAAuB;QACrB,OAAO,IAAI,mBAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,SAAS,EAAE,CAAC;IACrE,CAAC;IAED;;;OAGG;IACH,qBAAqB,CAAC,OAA6B;QACjD,OAAO,IAAI,mBAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,SAAS,EAAE,CAAC;IACzD,CAAC;IAED,kBAAkB,CAAC,OAAkB;QACnC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,mBAAmB,CAAC,OAAkB;QACpC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,eAAe,CAAC,IAAe;QAC7B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1C,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnC,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,gBAAgB,CAAC,IAAe;QAC9B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnC,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;OAGG;IACH,oBAAoB,CAAC,MAA2B;QAC9C,OAAO,IAAI,mBAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,SAAS,EAAE,CAAC;IACxD,CAAC;IAED;;;OAGG;IACH,8BAA8B,CAAC,MAA2B;QACxD,OAAO,IAAI,mBAAQ,CAAC,MAAM,CAAC,iCAAiC,CAAC,CAAC,SAAS,EAAE,CAAC;IAC5E,CAAC;IAED;;OAEG;IACH,WAAW;QACT,IAAI,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,OAAO,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,mCAAmC,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;IAC3G,CAAC;IAED;;OAEG;IACH,oBAAoB;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAChD,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC;IAC7C,CAAC;IAED;;;;OAIG;IACI,gBAAgB,CAAC,MAAoB,EAAE,OAAsB;QAClE,OAAO,gBAAgB,CAAC,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACvF,CAAC;IAED;;;OAGG;IACI,yBAAyB,CAAC,OAAsB;QACrD,OAAO,gBAAgB,CAAC,yBAAyB,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACxF,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,YAA0B;QAC3C,MAAM,QAAQ,GAAG,IAAI,qBAAa,EAA4B,CAAC;QAC/D,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YACnD,IAAI,IAAA,uBAAe,EAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;gBACrF,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,YAAY,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAE,CAAC,CAAC;YAClG,CAAC;QACH,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACjD,IAAI,IAAA,uBAAe,EAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;gBACjF,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,aAAa,CAAE,CAAC,CAAC;YAC9F,CAAC;QACH,CAAC;QACD,OAAO,gBAAgB,CAAC,6BAA6B,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,MAAM,CAAC,6BAA6B,CAAC,QAA8B;QACjE,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAkB,CAAC;QACxD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,KAAK,MAAM,cAAc,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;gBAClE,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;oBACzB,MAAM,KAAK,GAAG,qBAAqB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;oBACxD,IAAI,KAAK,EAAE,CAAC;wBACV,qBAAqB,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;oBACvD,CAAC;yBAAM,CAAC;wBACN,qBAAqB,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;oBAC/C,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,MAAM,qBAAqB,GAAG,IAAI,KAAK,EAAU,CAAC;QAClD,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,qBAAqB,CAAC,OAAO,EAAE,EAAE,CAAC;YAC7D,IAAI,KAAK,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;gBAC9B,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QACD,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,wBAAwB,CACtB,QAAyB,EACzB,UAAoC,EACpC,YAAqB,EACrB,IAAe,EACf,QAAuC;QAKvC,MAAM,QAAQ,qBAAQ,QAAQ,CAAE,CAAC;QACjC,MAAM,UAAU,GAAG,IAAI,qBAAa,CAAsB,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACrF,IAAI,cAAc,GAAyB,SAAS,CAAC;QACrD,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5C,IAAI,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvC,cAAc,qBAAQ,SAAS,CAAE,CAAC;YACpC,CAAC;QACH,CAAC;QACD,IAAI,OAAO,GAA8B,SAAS,CAAC;QACnD,KAAK,MAAM,aAAa,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC9C,IAAI,aAAa,CAAC,gBAAgB,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClD,OAAO,GAAG,aAAa,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,cAAc,GAAG;gBACf,cAAc,EAAE,OAAQ,CAAC,OAAO;gBAChC,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,IAAI,oBAAO,CAAC,CAAC,CAAC;gBACtB,oBAAoB,EAAE,IAAI,oBAAO,CAAC,CAAC,CAAC;aACrC,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YAC9E,MAAM,IAAI,KAAK,CACb,kGAAkG,CACnG,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;QAE7D,MAAM,cAAc,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;QAE3G,MAAM,kCAAkC,GAAG,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAE5E,QAAQ,CAAC,eAAe,GAAG,IAAA,sBAAc,EAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QACzF,QAAQ,CAAC,mCAAmC,GAAG,IAAA,sBAAc,EAC3D,QAAQ,CAAC,mCAAmC,CAAC,IAAI,CAAC,kCAAkC,CAAC,CACtF,CAAC;QAEF,cAAc,CAAC,MAAM,GAAG,IAAA,sBAAc,EAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QACjF,cAAc,CAAC,WAAW,GAAG,IAAI,CAAC;QAClC,cAAc,CAAC,oBAAoB,GAAG,IAAA,sBAAc,EAAC,cAAc,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QAE/G,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;QAC9D,OAAO;YACL,OAAO,EAAE,UAAU;YACnB,KAAK,EAAE,QAAQ;SAChB,CAAC;IACJ,CAAC;IAED,yBAAyB,CACvB,QAAyB,EACzB,WAAqC,EACrC,MAAe,EACf,IAAe,EACf,QAAuC,EACvC,MAAoB;QAKpB,MAAM,QAAQ,qBAAQ,QAAQ,CAAE,CAAC;QACjC,MAAM,WAAW,GAAG,IAAI,qBAAa,CAAsB,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAEvF,IAAI,eAAe,GAAyB,SAAS,CAAC;QACtD,KAAK,MAAM,UAAU,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YAC9C,IAAI,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxC,eAAe,qBAAQ,UAAU,CAAE,CAAC;YACtC,CAAC;QACH,CAAC;QACD,IAAI,OAAO,GAA8B,SAAS,CAAC;QACnD,KAAK,MAAM,aAAa,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC9C,IAAI,aAAa,CAAC,gBAAgB,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClD,OAAO,GAAG,aAAa,CAAC;YAC1B,CAAC;QACH,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,eAAe,GAAG;gBAChB,cAAc,EAAE,OAAQ,CAAC,OAAO;gBAChC,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,IAAI,oBAAO,CAAC,CAAC,CAAC;gBACtB,oBAAoB,EAAE,IAAI,oBAAO,CAAC,CAAC,CAAC;aACrC,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YAC9E,MAAM,IAAI,KAAK,CACb,iGAAiG,CAClG,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAE1E,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,oDAAoD;QACjF,MAAM,yBAAyB,GAAG,YAAY;aAC3C,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;aACnC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAEtE,QAAQ,CAAC,gBAAgB,GAAG,IAAA,sBAAc,EAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACtG,QAAQ,CAAC,WAAW,GAAG,IAAA,sBAAc,EAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACxG,QAAQ,CAAC,sBAAsB,GAAG,IAAA,sBAAc,EAC9C,QAAQ,CAAC,sBAAsB,CAAC,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CACpF,CAAC;QACF,QAAQ,CAAC,cAAc,GAAG,IAAA,mBAAW,EAAC,QAAQ,CAAC,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAEtG,eAAe,CAAC,MAAM,GAAG,IAAA,sBAAc,EAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7E,eAAe,CAAC,WAAW,GAAG,IAAI,CAAC;QACnC,eAAe,CAAC,oBAAoB,GAAG,IAAA,sBAAc,EACnD,eAAe,CAAC,oBAAoB,CAAC,IAAI,CACvC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CACpF,CACF,CAAC;QAEF,WAAW,CAAC,GAAG,CAAC,eAAe,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;QAEjE,OAAO;YACL,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,QAAQ;SAChB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,iCAAiC;IACjC,yCAAyC;IACzC,2BAA2B,CAAC,MAQ3B;QAKC,MAAM,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;QACpG,IAAI,QAAQ,qBAAQ,IAAI,CAAC,cAAc,CAAE,CAAC;QAC1C,IAAI,WAAW,GAA6B,IAAI,qBAAa,CAAsB,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACjH,IAAI,UAAU,GAA6B,IAAI,qBAAa,CAAsB,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAE/G,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,IAAI,gBAAgB,KAAK,SAAS,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;oBACnE,MAAM,KAAK,CAAC,mEAAmE,CAAC,CAAC;gBACnF,CAAC;gBACD,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,yBAAyB,CACxD,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,QAAQ,EACb,gBAAgB,EAChB,cAAc,EACd,QAAQ,EACR,MAAM,CACP,CAAC;gBAEF,QAAQ,GAAG,KAAK,CAAC;gBACjB,WAAW,GAAG,QAAQ,CAAC;gBAEvB,MAAM;YACR,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,IAAI,UAAU,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;oBACvD,MAAM,KAAK,CAAC,sDAAsD,CAAC,CAAC;gBACtE,CAAC;gBACD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,wBAAwB,CACtD,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,OAAO,EACZ,UAAU,EACV,QAAQ,EACR,QAAQ,CACT,CAAC;gBACF,QAAQ,GAAG,KAAK,CAAC;gBACjB,UAAU,GAAG,OAAO,CAAC;gBACrB,MAAM;YACR,CAAC;YACD,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,IAAI,UAAU,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;oBACvD,MAAM,KAAK,CAAC,qDAAqD,CAAC,CAAC;gBACrE,CAAC;gBACD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,wBAAwB,CACtD,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,OAAO,EACZ,IAAI,oBAAO,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,EAC7B,QAAQ,EACR,QAAQ,CACT,CAAC;gBACF,QAAQ,GAAG,KAAK,CAAC;gBACjB,UAAU,GAAG,OAAO,CAAC;gBACrB,MAAM;YACR,CAAC;YAED,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,IAAI,gBAAgB,KAAK,SAAS,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;oBACnE,MAAM,KAAK,CAAC,oEAAoE,CAAC,CAAC;gBACpF,CAAC;gBACD,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,yBAAyB,CACxD,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,QAAQ,EACb,IAAI,oBAAO,CAAC,gBAAgB,CAAC,CAAC,GAAG,EAAE,EACnC,cAAc,EACd,QAAQ,EACR,MAAM,CACP,CAAC;gBACF,QAAQ,GAAG,KAAK,CAAC;gBACjB,WAAW,GAAG,QAAQ,CAAC;gBACvB,MAAM;YACR,CAAC;YACD,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,IACE,gBAAgB,KAAK,SAAS;oBAC9B,UAAU,KAAK,SAAS;oBACxB,cAAc,KAAK,SAAS;oBAC5B,QAAQ,KAAK,SAAS,EACtB,CAAC;oBACD,MAAM,KAAK,CAAC,8FAA8F,CAAC,CAAC;gBAC9G,CAAC;gBACD,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,yBAAyB,CAC3E,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,QAAQ,EACb,gBAAgB,EAChB,cAAc,EACd,QAAQ,EACR,MAAM,CACP,CAAC;gBACF,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,wBAAwB,CACtD,iBAAiB,EACjB,IAAI,CAAC,OAAO,EACZ,UAAU,EACV,QAAQ,EACR,QAAQ,CACT,CAAC;gBAEF,QAAQ,GAAG,KAAK,CAAC;gBACjB,WAAW,GAAG,QAAQ,CAAC;gBACvB,UAAU,GAAG,OAAO,CAAC;gBACrB,MAAM;YACR,CAAC;YACD,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,IACE,gBAAgB,KAAK,SAAS;oBAC9B,UAAU,KAAK,SAAS;oBACxB,cAAc,KAAK,SAAS;oBAC5B,QAAQ,KAAK,SAAS,EACtB,CAAC;oBACD,MAAM,KAAK,CAAC,8FAA8F,CAAC,CAAC;gBAC9G,CAAC;gBACD,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,wBAAwB,CACvE,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,OAAO,EACZ,IAAI,oBAAO,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,EAC7B,QAAQ,EACR,QAAQ,CACT,CAAC;gBACF,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,yBAAyB,CAC5E,eAAe,EACf,IAAI,CAAC,QAAQ,EACb,IAAI,oBAAO,CAAC,gBAAgB,CAAC,CAAC,GAAG,EAAE,EACnC,cAAc,EACd,QAAQ,EACR,MAAM,CACP,CAAC;gBACF,QAAQ,GAAG,kBAAkB,CAAC;gBAC9B,WAAW,GAAG,QAAQ,CAAC;gBACvB,UAAU,GAAG,OAAO,CAAC;gBACrB,MAAM;YACR,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACR,MAAM,KAAK,CAAC,uBAAuB,MAAM,kCAAkC,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC;QACD,QAAQ,CAAC,eAAe,GAAG,QAAQ,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QACrF,QAAQ,CAAC,WAAW,GAAG,IAAA,mBAAW,EAChC,QAAQ,CAAC,mCAAmC,CAAC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAClF,CAAC;QACF,QAAQ,CAAC,QAAQ,GAAG,IAAA,mBAAW,EAAC,QAAQ,CAAC,gBAAgB,CAAC,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;QAE/F,OAAO;YACL,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,WAAW;YACrB,OAAO,EAAE,UAAU;SACpB,CAAC;IACJ,CAAC;IAsBO,iBAAiB,CACvB,MAAoB,EACpB,UAAsB,EACtB,uBAAgD,EAChD,KAA0C;QAQ1C,OAAO,gBAAgB,CAAC,2BAA2B,CACjD,MAAM,EACN,UAAU,EACV,uBAAuB,EACvB,UAAU,CAAC,cAAc,EACzB,KAAK,CACN,CAAC;IACJ,CAAC;IAEO,gBAAgB,CACtB,MAAoB,EACpB,UAAsB,EACtB,qBAA8C,EAC9C,KAA0C;QAE1C,OAAO,gBAAgB,CAAC,0BAA0B,CAChD,MAAM,EACN,UAAU,EACV,qBAAqB,EACrB,UAAU,CAAC,cAAc,EACzB,KAAK,CACN,CAAC;IACJ,CAAC;IAEO,kBAAkB,CACxB,MAAoB,EACpB,UAAsB,EACtB,uBAAgD,EAChD,qBAA8C;QAM9C,MAAM,WAAW,GAAG,CAAC,OAAsB,EAAE,EAAE,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;QAC/E,MAAM,uBAAuB,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,uBAAuB,EAAE,WAAW,CAAC,CAAC;QACjH,MAAM,sBAAsB,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,qBAAqB,EAAE,WAAW,CAAC,CAAC;QAE7G,MAAM,6BAA6B,GAAG,uBAAuB,CAAC,gBAAgB,CAAC,KAAK,CAClF,sBAAsB,CAAC,eAAe,CACvC,CAAC;QAEF,MAAM,6BAA6B,GAAG,CAAC,CAAC;QAExC,OAAO;YACL,QAAQ,EAAE,uBAAuB,CAAC,QAAQ;YAC1C,OAAO,EAAE,sBAAsB,CAAC,OAAO;YACvC,cAAc,EAAE;gBACd,WAAW,EAAE,uBAAuB,CAAC,WAAW;gBAChD,sBAAsB,EAAE,uBAAuB,CAAC,sBAAsB;gBACtE,eAAe,EAAE,sBAAsB,CAAC,eAAe;gBACvD,mCAAmC,EAAE,sBAAsB,CAAC,mCAAmC;gBAC/F,gBAAgB,EAAE,uBAAuB,CAAC,gBAAgB;gBAC1D,cAAc,EAAE,uBAAuB,CAAC,cAAc;gBACtD,iBAAiB,EAAE,sBAAsB,CAAC,mCAAmC,CAAC,SAAS,CACrF,uBAAuB,CAAC,WAAW,CACpC;gBACD,eAAe,EAAE,6BAA6B;gBAC9C,QAAQ,EAAE,uBAAuB,CAAC,gBAAgB,CAAC,SAAS,CAAC,6BAA6B,CAAC;gBAC3F,WAAW,EAAE,sBAAsB,CAAC,mCAAmC,CAAC,SAAS,CAC/E,uBAAuB,CAAC,gBAAgB,CACzC;gBACD,6BAA6B;aAC9B;SACF,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,2BAA2B,CACvC,MAAoB,EACpB,UAAsB,EACtB,uBAAuD,EACvD,cAAsB,EACtB,KAA0C;QAS1C,IAAI,gBAAgB,GAAG,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,0BAA0B,GAAG,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;QAChD,IAAI,WAAW,GAAG,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,sBAAsB,GAAG,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;QAE5C,MAAM,QAAQ,GAAG,IAAI,qBAAa,EAAuB,CAAC;QAC1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC,IAAA,uBAAe,EAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC5D,SAAS;YACX,CAAC;YACD,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACvC,MAAM,OAAO,GAAG,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YACnE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CACb,uDAAuD,OAAO,CAAC,cAAc,iEAAiE,OAAO,CAAC,eAAe,EAAE,CACxK,CAAC;YACJ,CAAC;YACD,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;YAEtG,IAAI,YAAqB,CAAC;YAC1B,IAAI,uBAAuB,KAAK,IAAI,EAAE,CAAC;gBACrC,YAAY,GAAG,uBAAuB,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAE,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACN,YAAY,GAAG,OAAO,CAAC,yBAAyB,EAAE,CAAC;YACrD,CAAC;YACD,MAAM,YAAY,GAAG,IAAI,oBAAO,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAEvF,MAAM,eAAe,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;YAEtF,gBAAgB,GAAG,gBAAgB,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAEzD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpB,0BAA0B,GAAG,0BAA0B,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC/E,CAAC;YAED,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3D,sBAAsB,GAAG,sBAAsB,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;YAEzF,MAAM,QAAQ,GAAa;gBACzB,cAAc,EAAE,OAAO,CAAC,OAAO;gBAC/B,WAAW,EAAE,OAAO,CAAC,gBAAgB,EAAE;gBACvC,MAAM,EAAE,YAAY;gBACpB,oBAAoB,EAAE,eAAe;aACtC,CAAC;YACF,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1C,CAAC;QAED,OAAO;YACL,QAAQ;YACR,gBAAgB;YAChB,0BAA0B;YAC1B,WAAW;YACX,cAAc,EAAE,IAAA,mBAAW,EAAC,sBAAsB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YACzE,sBAAsB;SACvB,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,0BAA0B,CACtC,MAAoB,EACpB,UAAsB,EACtB,qBAAqD,EACrD,cAAsB,EACtB,KAA0C;QAE1C,IAAI,eAAe,GAAG,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,mCAAmC,GAAG,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;QACzD,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,MAAM,OAAO,GAAG,IAAI,qBAAa,EAAuB,CAAC;QACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnD,IAAI,CAAC,IAAA,uBAAe,EAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC1D,SAAS;YACX,CAAC;YACD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACrC,MAAM,OAAO,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YACjE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CACb,sDACE,MAAM,CAAC,aACT,gEAAgE,gBAAgB,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAC3G,CAAC;YACJ,CAAC;YAED,MAAM,8BAA8B,GAAG,gBAAgB,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;YACxF,IAAI,oBAAoB,CAAC;YACzB,IAAI,qBAAqB,KAAK,IAAI,EAAE,CAAC;gBACnC,oBAAoB,GAAG,qBAAqB,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAE,CAAC;YACrE,CAAC;iBAAM,CAAC;gBACN,oBAAoB,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC;YAC3D,CAAC;YAED,MAAM,YAAY,GAAG,gBAAgB,CAAC,eAAe,CAAC,MAAM,CAAC;iBAC1D,GAAG,CAAC,oBAAoB,CAAC;iBACzB,SAAS,CAAC,8BAA8B,CAAC,CAAC;YAE7C,MAAM,cAAc,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;YAE3F,MAAM,YAAY,GAAG,gBAAgB,CAAC,yBAAyB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;YACzF,MAAM,kCAAkC,GAAG,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAE5E,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,oBAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBACvC,SAAS,IAAI,CAAC,CAAC;YACjB,CAAC;YAED,eAAe,GAAG,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACvD,mCAAmC,GAAG,mCAAmC,CAAC,IAAI,CAC5E,kCAAkC,CACnC,CAAC;YAEF,MAAM,QAAQ,GAAa;gBACzB,cAAc,EAAE,OAAO,CAAC,OAAO;gBAC/B,WAAW,EAAE,OAAO,CAAC,gBAAgB,EAAE;gBACvC,MAAM,EAAE,YAAY;gBACpB,oBAAoB,EAAE,cAAc;aACrC,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;QAED,OAAO;YACL,OAAO;YACP,eAAe;YACf,mCAAmC;YACnC,SAAS;SACV,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;MAcE;IACF,cAAc,CACZ,MAAoB,EACpB,aAAwB,EACxB,IAAY,EACZ,iBAAyB,IAAI,CAAC,KAAK,CAAC,cAAc;QAElD,MAAM,OAAO,GAAG,MAAM,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,uBAAuB,GAC3B,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,cAAc,KAAK,CAAC,CAAC;QAExF,MAAM,YAAY,GAAG,gBAAgB,CAAC,yBAAyB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QAEzF,MAAM,WAAW,GAAG,CAAC,OAAsB,EAAE,EAAE,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;QAC/E,MAAM,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,GAAG,gBAAgB,CAAC,qBAAqB,CAC/F,MAAM,EACN,IAAI,CAAC,KAAK,EACV,IAAI,CACL,CAAC;QAEF,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,2BAA2B,CAClE,MAAM,EACN,IAAI,CAAC,KAAK,EACV,uBAAuB,EACvB,cAAc,EACd,WAAW,CACZ,CAAC;QAEF,MAAM,EAAE,mCAAmC,EAAE,GAAG,gBAAgB,CAAC,0BAA0B,CACzF,MAAM,EACN,IAAI,CAAC,KAAK,EACV,qBAAqB,EACrB,cAAc,EACd,WAAW,CACZ,CAAC;QAEF,MAAM,wBAAwB,GAAG,WAAW,CAAC,4BAA4B;aACtE,KAAK,CAAC,mCAAmC,CAAC;aAC1C,GAAG,CAAC,YAAY,CAAC;aACjB,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;aACnC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;QAEhC,wDAAwD;QACxD,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;YACjD,MAAM,cAAc,GAAG,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YACxE,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;YACD,IAAI,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,8BAA8B,IAAI,CAAC,uBAAuB,EAAE,CAAC;gBAC3F,OAAO,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QAED,uEAAuE;QACvE,IAAI,kBAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QAEhD,qBAAqB;QACrB,kBAAkB,GAAG,kBAAkB,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpF,MAAM,SAAS,GAAG,wBAAwB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAEnE,MAAM,eAAe,GAAG,wBAAwB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEhE,OAAO,oBAAO,CAAC,GAAG,CAAC,IAAI,oBAAO,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;IACtD,CAAC;IAED;;;;;;;;;;MAUE;IACF,oBAAoB,CAClB,MAAoB,EACpB,aAAwB,EACxB,IAAY,EACZ,iBAAyB,IAAI,CAAC,KAAK,CAAC,cAAc;QAElD,MAAM,OAAO,GAAG,MAAM,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,kBAAkB,GAAG,OAAO,CAAC,4CAA4C,CAAC,MAAM,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7G,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QAEzF,IAAI,cAAc,KAAK,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;YACjD,OAAO,oBAAO,CAAC,GAAG,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,oBAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YACpG,MAAM,+BAA+B,GAAG,oBAAO,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;YAClG,OAAO,oBAAO,CAAC,GAAG,CAAC,eAAe,EAAE,+BAA+B,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED;;;;;;MAME;IACF,+BAA+B,CAAC,MAAoB,EAAE,IAAY,EAAE,cAAsB;QACxF,mFAAmF;QACnF,2DAA2D;QAC3D,yDAAyD;QACzD,2BAA2B;QAE3B,MAAM,eAAe,GAAa,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC5F,MAAM,cAAc,GAAa,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAE1F,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;YACvB,sFAAsF;YACtF,MAAM,kBAAkB,GAAG,MAAM,CAAC,mCAAmC,EAAE,CAAC;YACxE,MAAM,yBAAyB,GAAG,kBAAkB,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;YAEzE,qBAAqB;YACrB,MAAM,gBAAgB,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CACzD,yBAAyB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC/D,CAAC;YACF,MAAM,gBAAgB,GACpB,cAAc,CAAC,MAAM,KAAK,CAAC;gBAC3B,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,yBAAyB,CAAC,WAAW,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;YAE/F,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC3C,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,iDAAiD;QACjD,MAAM,WAAW,GAAG,CAAC,OAAsB,EAAE,EAAE,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;QAC/E,MAAM,EAAE,uBAAuB,EAAE,GAAG,gBAAgB,CAAC,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAErG,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,2BAA2B,CAClE,MAAM,EACN,IAAI,CAAC,KAAK,EACV,uBAAuB,EACvB,cAAc,EACd,WAAW,CACZ,CAAC;QAEF,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,CAAC,mCAAmC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAEtG,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED;;;;MAIE;IACF,+BAA+B,CAAC,MAAoB;QAClD,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QACtD,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC,wCAAwC,CAAC,YAAY,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YACN,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACvD,OAAO,MAAM,CAAC,wCAAwC,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,kBAAkB,CAChB,MAAoB,EACpB,aAAwB,EACxB,IAAY,EACZ,qBAA8B;QAE9B,MAAM,OAAO,GAAG,MAAM,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;QAEvD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC;QAC5C,MAAM,sBAAsB,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC;QACpE,IAAI,qBAAqB,GAAG,CAAC,GAAG,sBAAsB,CAAC,CAAC,MAAM,CAC5D,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAC7E,CAAC;QAEF,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;YACjD,MAAM,cAAc,GAAG,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAExE,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;YAED,MAAM,yBAAyB,GAAG,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC;YAE9E,qBAAqB,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,yBAAyB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3G,CAAC;QAED,IAAI,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC;QAC/C,IAAI,qBAAqB,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACtC,MAAM,kCAAkC,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;gBACrF,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;gBAC5D,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;gBAC5D,OAAO,SAAU,CAAC,MAAM,GAAG,SAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7D,CAAC,CAAC,CAAC;YAEH,IAAI,qBAAqB,EAAE,CAAC;gBAC1B,cAAc,GAAG,kCAAkC,CAAC;YACtD,CAAC;QACH,CAAC;QAED,MAAM,uBAAuB,GAC3B,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,cAAc,KAAK,CAAC,CAAC;QAExF,MAAM,YAAY,GAAG,IAAI,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;QAE7D,MAAM,wBAAwB,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,4BAA4B;aAC1F,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,mCAAmC,CAAC;aAC9D,GAAG,CAAC,YAAY,CAAC;aACjB,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,CAAC;aACnC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;QAChC,MAAM,sBAAsB,GAAG,OAAO,CAAC,2BAA2B,EAAE,CAAC;QACrE,IAAI,wBAAwB,GAAG,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAEjG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAChC,MAAM,cAAc,GAAG,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAC1E,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;YACD,IAAI,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,8BAA8B,IAAI,CAAC,uBAAuB,EAAE,CAAC;gBAC3F,wBAAwB,GAAG,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,eAAe,GAAG,oBAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,sBAAsB,EAAE,wBAAwB,CAAC,CAAC;QAE9G,MAAM,iBAAiB,GAAG,OAAO,CAAC,4BAA4B,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC;QAChH,eAAe,GAAG,OAAO,CAAC,4BAA4B,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5D,CAAC,CAAC,oBAAO,CAAC,GAAG,CAAC,eAAe,EAAE,iBAAiB,CAAC;YACjD,CAAC,CAAC,eAAe,CAAC;QAEpB,IAAI,kBAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QAEhD,qBAAqB;QACrB,kBAAkB,GAAG,kBAAkB,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpF,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAE1D,eAAe,GAAG,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEjD,MAAM,qBAAqB,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,mCAAmC,GAAG,GAAG,CAAC;QAC7F,MAAM,uBAAuB,GAAG,OAAO,CAAC,yBAAyB,EAAE,CAAC;QAEpE,IAAI,qBAAqB,GAAG,CAAC,IAAI,uBAAuB,GAAG,qBAAqB,EAAE,CAAC;YACjF,OAAO,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;aAAM,IAAI,qBAAqB,GAAG,CAAC,IAAI,uBAAuB,GAAG,qBAAqB,EAAE,CAAC;YACxF,MAAM,2BAA2B,GAAG,IAAI,oBAAO,CAAC,qBAAqB,GAAG,uBAAuB,CAAC,CAAC,GAAG,CAClG,OAAO,CAAC,cAAc,EAAE,CACzB,CAAC;YACF,eAAe,GAAG,oBAAO,CAAC,GAAG,CAAC,eAAe,EAAE,2BAA2B,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,oCAAoC,GAAG,IAAI,oBAAO,CAAC,eAAO,CAAC,CAAC;QAEhE,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC7B,oCAAoC,GAAG,OAAO;iBAC3C,mCAAmC,EAAE;iBACrC,GAAG,CAAC,OAAO,CAAC,sCAAsC,EAAE,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACN,IAAI,8BAA8B,GAAG,IAAI,oBAAO,CAAC,eAAO,CAAC,CAAC;YAC1D,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;gBACjD,MAAM,cAAc,GAAG,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;gBAExE,IAAI,CAAC,cAAc,EAAE,CAAC;oBACpB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;gBACvC,CAAC;gBAED,MAAM,+BAA+B,GAAG,cAAc;qBACnD,+CAA+C,CAAC,cAAc,GAAG,CAAC,CAAC;qBACnE,GAAG,CAAC,cAAc,CAAC,kDAAkD,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC;gBAE9F,8BAA8B,GAAG,oBAAO,CAAC,GAAG,CAC1C,IAAI,oBAAO,CAAC,CAAC,CAAC,EACd,oBAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,8BAA8B,CAAC,CAC7E,CAAC;YACJ,CAAC;YACD,oCAAoC,GAAG,8BAA8B,CAAC;QACxE,CAAC;QAED,eAAe,GAAG,oBAAO,CAAC,GAAG,CAAC,eAAe,EAAE,oCAAoC,CAAC,CAAC;QAErF,OAAO,oBAAO,CAAC,GAAG,CAAC,IAAI,oBAAO,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;IACtD,CAAC;IAED,oBAAoB,CAAC,MAAoB,EAAE,SAAoB,EAAE,IAAY;QAC3E,MAAM,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAE1D,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAE7E,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,yBAAyB,GAAG,mBAAmB,CAAC,MAAM,CAAC;QAE7D,IAAI,IAAI,CAAC,cAAc,CAAC,mCAAmC,CAAC,MAAM,CAAC,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACnF,OAAO,IAAI,oBAAO,CAAC,yBAAyB,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAChF,gDAAgD;QAChD,IAAI,IAAI,CAAC,cAAc,CAAC,mCAAmC,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC;YACjG,OAAO,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;QAED,IAAI,gBAAyB,CAAC;QAC9B,IAAI,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxB,gBAAgB,GAAG,yBAAyB,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,0CAA0C;YAC1C,iEAAiE;YACjE,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW;iBAC/C,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,mCAAmC,CAAC;iBAC5D,GAAG,CAAC,aAAa,CAAC;iBAClB,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,4CAA4C;QAC7D,CAAC;QAED,MAAM,iBAAiB,GAAG,gBAAgB;aACvC,GAAG,CAAC,cAAc,CAAC,oBAAoB,EAAE,CAAC;aAC1C,GAAG,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC;QACvC,MAAM,yBAAyB,GAAG,cAAc,CAAC,2BAA2B,EAAE,CAAC;QAE/E,MAAM,qBAAqB,GAAG,cAAc;aACzC,+BAA+B,EAAE;aACjC,GAAG,CAAC,cAAc,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,OAAO,oBAAO,CAAC,GAAG,CAChB,CAAC,EACD,oBAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,qBAAqB,CAAC,CAC5G,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,eAAe,CAAC,MAA2B;QAChD,OAAO,IAAI,mBAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,SAAS,EAAE,CAAC;IAC3D,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,uBAAuB,CAAC,MAA2B;QACxD,IAAI,KAAK,GAAG,IAAI,eAAE,CAAC,CAAC,CAAC,CAAC;QACtB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,uBAAuB,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YACnE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QACD,OAAO,IAAI,mBAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;IACzC,CAAC;IAEM,MAAM,CAAC,qBAAqB,CACjC,YAA0B,EAC1B,UAAsB,EACtB,IAAY;QAKZ,MAAM,uBAAuB,GAAG,gBAAgB,CAAC,uCAAuC,CACtF,YAAY,EACZ,UAAU,EACV,IAAI,CACL,CAAC;QACF,MAAM,qBAAqB,GAAG,gBAAgB,CAAC,qCAAqC,CAClF,YAAY,EACZ,UAAU,EACV,IAAI,CACL,CAAC;QAEF,OAAO;YACL,uBAAuB;YACvB,qBAAqB;SACtB,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,qBAAqB,CACjC,YAA0B,EAC1B,UAAsB,EACtB,uBAAgD,EAChD,qBAA8C,EAC9C,IAAY;QAEZ,gBAAgB,CAAC,uCAAuC,CAAC,YAAY,EAAE,uBAAuB,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QAClH,gBAAgB,CAAC,qCAAqC,CAAC,YAAY,EAAE,qBAAqB,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IAChH,CAAC;IAED,MAAM,CAAC,uCAAuC,CAC5C,YAA0B,EAC1B,UAAsB,EACtB,IAAY;QAEZ,MAAM,uBAAuB,GAAG,IAAI,qBAAa,EAAsB,CAAC;QACxE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACvC,IAAI,IAAA,uBAAe,EAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;gBACpG,MAAM,OAAO,GAAG,YAAY,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAE,CAAC;gBAC1E,MAAM,sBAAsB,GAAG,OAAO,CAAC,kCAAkC,CACvE,IAAI,EACJ,YAAY,CAAC,KAAK,CAAC,cAAc,CAClC,CAAC;gBACF,uBAAuB,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;QACD,OAAO,uBAAuB,CAAC;IACjC,CAAC;IAED,MAAM,CAAC,uCAAuC,CAC5C,YAA0B,EAC1B,uBAAgD,EAChD,UAAsB,EACtB,IAAY;QAEZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACvC,IAAI,IAAA,uBAAe,EAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;gBACpG,MAAM,OAAO,GAAG,YAAY,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAE,CAAC;gBAC1E,MAAM,sBAAsB,GAAG,OAAO,CAAC,kCAAkC,CACvE,IAAI,EACJ,YAAY,CAAC,KAAK,CAAC,cAAc,CAClC,CAAC;gBACF,uBAAuB,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,qCAAqC,CAAC,YAA0B,EAAE,UAAsB,EAAE,IAAY;QAC3G,MAAM,qBAAqB,GAAG,IAAI,qBAAa,EAAsB,CAAC;QACtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACrC,IAAI,IAAA,uBAAe,EAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC9F,MAAM,OAAO,GAAG,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,aAAa,CAAE,CAAC;gBACxE,MAAM,oBAAoB,GAAG,OAAO,CAAC,gCAAgC,CAAC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;gBAC/G,qBAAqB,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;QACD,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,MAAM,CAAC,qCAAqC,CAC1C,YAA0B,EAC1B,qBAA8C,EAC9C,UAAsB,EACtB,IAAY;QAEZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACrC,IAAI,IAAA,uBAAe,EAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC9F,MAAM,OAAO,GAAG,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,aAAa,CAAE,CAAC;gBACxE,MAAM,oBAAoB,GAAG,OAAO,CAAC,gCAAgC,CAAC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;gBAC/G,qBAAqB,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,yBAAyB,CAAC,OAAsB,EAAE,cAAsB;QACpF,MAAM,uBAAuB,GAC3B,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,cAAc,KAAK,CAAC,CAAC;QACxF,IAAI,uBAAuB,EAAE,CAAC;YAC5B,OAAO,IAAI,oBAAO,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,oBAAO,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,gBAAgB,CAC5B,MAAoB,EACpB,OAAsB,EACtB,cAAsB;QAEtB,MAAM,uBAAuB,GAC3B,cAAc,KAAK,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QACxF,IAAI,uBAAuB,EAAE,CAAC;YAC5B,MAAM,EAAE,MAAM,EAAE,uBAAuB,EAAE,GAAG,MAAM,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;YACrF,OAAO;gBACL,MAAM,EAAE,IAAI,oBAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;gBACtC,cAAc,EAAE,IAAI,oBAAO,CAAC,uBAAuB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;aAChE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,WAAW,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;YAC5D,OAAO;gBACL,MAAM,EAAE,IAAI,oBAAO,CAAC,WAAW,CAAC;gBAChC,cAAc,EAAE,IAAI,oBAAO,CAAC,oBAAoB,CAAC;aAClD,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AAp2CD,4CAo2CC","sourcesContent":["/* eslint-disable max-classes-per-file */\nimport { PublicKey } from '@solana/web3.js';\nimport Decimal from 'decimal.js';\nimport { KaminoReserve } from './reserve';\nimport { Obligation } from '../idl_codegen/accounts';\nimport { ElevationGroupDescription, KaminoMarket } from './market';\nimport BN from 'bn.js';\nimport { Fraction } from './fraction';\nimport { ObligationCollateral, ObligationLiquidity } from '../idl_codegen/types';\nimport { positiveOrZero, valueOrZero } from './utils';\nimport { isNotNullPubkey, PubkeyHashMap, U64_MAX } from '../utils';\nimport { ActionType } from './action';\n\nexport type Position = {\n reserveAddress: PublicKey;\n mintAddress: PublicKey;\n /**\n * Amount of tokens in lamports, including decimal places for interest accrued (no borrow factor weighting)\n */\n amount: Decimal;\n /**\n * Market value of the position in USD (no borrow factor weighting)\n */\n marketValueRefreshed: Decimal;\n};\n\nexport type ObligationStats = {\n userTotalDeposit: Decimal;\n userTotalBorrow: Decimal;\n userTotalBorrowBorrowFactorAdjusted: Decimal;\n borrowLimit: Decimal;\n borrowLiquidationLimit: Decimal;\n borrowUtilization: Decimal;\n netAccountValue: Decimal;\n loanToValue: Decimal;\n liquidationLtv: Decimal;\n leverage: Decimal;\n potentialElevationGroupUpdate: number;\n};\n\ninterface BorrowStats {\n borrows: Map<PublicKey, Position>;\n userTotalBorrow: Decimal;\n userTotalBorrowBorrowFactorAdjusted: Decimal;\n positions: number;\n}\n\nexport class KaminoObligation {\n obligationAddress: PublicKey;\n\n state: Obligation;\n\n /**\n * Deposits stored in a map of reserve address to position\n */\n deposits: Map<PublicKey, Position>;\n\n /**\n * Borrows stored in a map of reserve address to position\n */\n borrows: Map<PublicKey, Position>;\n\n refreshedStats: ObligationStats;\n\n obligationTag: number;\n\n /**\n * Initialise a new Obligation from the deserialized state\n * @param market\n * @param obligationAddress\n * @param obligation\n * @param collateralExchangeRates - rates from the market by reserve address, will be calculated if not provided\n * @param cumulativeBorrowRates - rates from the market by reserve address, will be calculated if not provided\n */\n constructor(\n market: KaminoMarket,\n obligationAddress: PublicKey,\n obligation: Obligation,\n collateralExchangeRates: Map<PublicKey, Decimal>,\n cumulativeBorrowRates: Map<PublicKey, Decimal>\n ) {\n this.obligationAddress = obligationAddress;\n this.state = obligation;\n const { borrows, deposits, refreshedStats } = this.calculatePositions(\n market,\n obligation,\n collateralExchangeRates,\n cumulativeBorrowRates\n );\n this.deposits = deposits;\n this.borrows = borrows;\n this.refreshedStats = refreshedStats;\n this.obligationTag = obligation.tag.toNumber();\n }\n\n static async load(kaminoMarket: KaminoMarket, obligationAddress: PublicKey): Promise<KaminoObligation | null> {\n const res = await kaminoMarket.getConnection().getAccountInfoAndContext(obligationAddress);\n if (res.value === null) {\n return null;\n }\n const accInfo = res.value;\n if (!accInfo.owner.equals(kaminoMarket.programId)) {\n throw new Error(\"account doesn't belong to this program\");\n }\n const obligation = Obligation.decode(accInfo.data);\n\n if (obligation === null) {\n return null;\n }\n const { collateralExchangeRates, cumulativeBorrowRates } = KaminoObligation.getRatesForObligation(\n kaminoMarket,\n obligation,\n res.context.slot\n );\n return new KaminoObligation(\n kaminoMarket,\n obligationAddress,\n obligation,\n collateralExchangeRates,\n cumulativeBorrowRates\n );\n }\n\n static async loadAll(\n kaminoMarket: KaminoMarket,\n obligationAddresses: PublicKey[],\n slot?: number\n ): Promise<(KaminoObligation | null)[]> {\n let currentSlot = slot;\n let obligations: (Obligation | null)[];\n if (!currentSlot) {\n [currentSlot, obligations] = await Promise.all([\n kaminoMarket.getConnection().getSlot(),\n Obligation.fetchMultiple(kaminoMarket.getConnection(), obligationAddresses, kaminoMarket.programId),\n ]);\n } else {\n obligations = await Obligation.fetchMultiple(\n kaminoMarket.getConnection(),\n obligationAddresses,\n kaminoMarket.programId\n );\n }\n const cumulativeBorrowRates = new PubkeyHashMap<PublicKey, Decimal>();\n const collateralExchangeRates = new PubkeyHashMap<PublicKey, Decimal>();\n for (const obligation of obligations) {\n if (obligation !== null) {\n KaminoObligation.addRatesForObligation(\n kaminoMarket,\n obligation,\n collateralExchangeRates,\n cumulativeBorrowRates,\n currentSlot\n );\n }\n }\n\n return obligations.map((obligation, i) => {\n if (obligation === null) {\n return null;\n }\n return new KaminoObligation(\n kaminoMarket,\n obligationAddresses[i],\n obligation,\n collateralExchangeRates,\n cumulativeBorrowRates\n );\n });\n }\n\n /**\n * @returns the obligation borrows as a list\n */\n getBorrows(): Array<Position> {\n return [...this.borrows.values()];\n }\n\n /**\n * @returns the obligation borrows as a list\n */\n getDeposits(): Array<Position> {\n return [...this.deposits.values()];\n }\n\n /**\n * @returns the total deposited value of the obligation (sum of all deposits)\n */\n getDepositedValue(): Decimal {\n return new Fraction(this.state.depositedValueSf).toDecimal();\n }\n\n /**\n * @returns the total borrowed value of the obligation (sum of all borrows -- no borrow factor)\n */\n getBorrowedMarketValue(): Decimal {\n return new Fraction(this.state.borrowedAssetsMarketValueSf).toDecimal();\n }\n\n /**\n * @returns the total borrowed value of the obligation (sum of all borrows -- with borrow factor weighting)\n */\n getBorrowedMarketValueBFAdjusted(): Decimal {\n return new Fraction(this.state.borrowFactorAdjustedDebtValueSf).toDecimal();\n }\n\n /**\n * @returns total borrow power of the obligation, relative to max LTV of each asset's reserve\n */\n getAllowedBorrowValue(): Decimal {\n return new Fraction(this.state.allowedBorrowValueSf).toDecimal();\n }\n\n /**\n * @returns the borrow value at which the obligation gets liquidatable\n * (relative to the liquidation threshold of each asset's reserve)\n */\n getUnhealthyBorrowValue(): Decimal {\n return new Fraction(this.state.unhealthyBorrowValueSf).toDecimal();\n }\n\n /**\n *\n * @returns Market value of the deposit in the specified obligation collateral/deposit asset (USD)\n */\n getDepositMarketValue(deposit: ObligationCollateral): Decimal {\n return new Fraction(deposit.marketValueSf).toDecimal();\n }\n\n getBorrowByReserve(reserve: PublicKey): Position | undefined {\n return this.borrows.get(reserve);\n }\n\n getDepositByReserve(reserve: PublicKey): Position | undefined {\n return this.deposits.get(reserve);\n }\n\n getBorrowByMint(mint: PublicKey): Position | undefined {\n for (const value of this.borrows.values()) {\n if (value.mintAddress.equals(mint)) {\n return value;\n }\n }\n return undefined;\n }\n\n getDepositByMint(mint: PublicKey): Position | undefined {\n for (const value of this.deposits.values()) {\n if (value.mintAddress.equals(mint)) {\n return value;\n }\n }\n return undefined;\n }\n\n /**\n *\n * @returns Market value of the borrow in the specified obligation liquidity/borrow asset (USD) (no borrow factor weighting)\n */\n getBorrowMarketValue(borrow: ObligationLiquidity): Decimal {\n return new Fraction(borrow.marketValueSf).toDecimal();\n }\n\n /**\n *\n * @returns Market value of the borrow in the specified obligation liquidity/borrow asset (USD) (with borrow factor weighting)\n */\n getBorrowMarketValueBFAdjusted(borrow: ObligationLiquidity): Decimal {\n return new Fraction(borrow.borrowFactorAdjustedMarketValueSf).toDecimal();\n }\n\n /**\n * Calculate the current ratio of borrowed value to deposited value\n */\n loanToValue(): Decimal {\n if (this.refreshedStats.userTotalDeposit.eq(0)) {\n return new Decimal(0);\n }\n return this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.div(this.refreshedStats.userTotalDeposit);\n }\n\n /**\n * @returns the total number of positions (deposits + borrows)\n */\n getNumberOfPositions(): number {\n return this.deposits.size + this.borrows.size;\n }\n\n getNetAccountValue(): Decimal {\n return this.refreshedStats.netAccountValue;\n }\n\n /**\n * Get the loan to value and liquidation loan to value for a collateral token reserve as ratios, accounting for the obligation elevation group if it is active\n * @param market\n * @param reserve\n */\n public getLtvForReserve(market: KaminoMarket, reserve: KaminoReserve): { maxLtv: Decimal; liquidationLtv: Decimal } {\n return KaminoObligation.getLtvForReserve(market, reserve, this.state.elevationGroup);\n }\n\n /**\n * Get the borrow factor for a borrow reserve, accounting for the obligation elevation group if it is active\n * @param reserve\n */\n public getBorrowFactorForReserve(reserve: KaminoReserve): Decimal {\n return KaminoObligation.getBorrowFactorForReserve(reserve, this.state.elevationGroup);\n }\n\n /**\n * @returns the potential elevation groups the obligation qualifies for\n */\n getElevationGroups(kaminoMarket: KaminoMarket): Array<number> {\n const reserves = new PubkeyHashMap<PublicKey, KaminoReserve>();\n for (const deposit of this.state.deposits.values()) {\n if (isNotNullPubkey(deposit.depositReserve) && !reserves.has(deposit.depositReserve)) {\n reserves.set(deposit.depositReserve, kaminoMarket.getReserveByAddress(deposit.depositReserve)!);\n }\n }\n for (const borrow of this.state.borrows.values()) {\n if (isNotNullPubkey(borrow.borrowReserve) && !reserves.has(borrow.borrowReserve)) {\n reserves.set(borrow.borrowReserve, kaminoMarket.getReserveByAddress(borrow.borrowReserve)!);\n }\n }\n return KaminoObligation.getElevationGroupsForReserves([...reserves.values()]);\n }\n\n static getElevationGroupsForReserves(reserves: Array<KaminoReserve>): Array<number> {\n const elevationGroupsCounts = new Map<number, number>();\n for (const reserve of reserves) {\n for (const elevationGroup of reserve.state.config.elevationGroups) {\n if (elevationGroup !== 0) {\n const count = elevationGroupsCounts.get(elevationGroup);\n if (count) {\n elevationGroupsCounts.set(elevationGroup, count + 1);\n } else {\n elevationGroupsCounts.set(elevationGroup, 1);\n }\n }\n }\n }\n const activeElevationGroups = new Array<number>();\n for (const [group, count] of elevationGroupsCounts.entries()) {\n if (count === reserves.length) {\n activeElevationGroups.push(group);\n }\n }\n return activeElevationGroups;\n }\n\n calculateSimulatedBorrow(\n oldStats: ObligationStats,\n oldBorrows: Map<PublicKey, Position>,\n borrowAmount: Decimal,\n mint: PublicKey,\n reserves: Map<PublicKey, KaminoReserve>\n ): {\n stats: ObligationStats;\n borrows: Map<PublicKey, Position>;\n } {\n const newStats = { ...oldStats };\n const newBorrows = new PubkeyHashMap<PublicKey, Position>([...oldBorrows.entries()]);\n let borrowPosition: Position | undefined = undefined;\n for (const oldBorrow of oldBorrows.values()) {\n if (oldBorrow.mintAddress.equals(mint)) {\n borrowPosition = { ...oldBorrow };\n }\n }\n let reserve: KaminoReserve | undefined = undefined;\n for (const kaminoReserve of reserves.values()) {\n if (kaminoReserve.getLiquidityMint().equals(mint)) {\n reserve = kaminoReserve;\n }\n }\n\n if (!reserve) {\n throw new Error(`No reserve found for mint ${mint}`);\n }\n\n if (!borrowPosition) {\n borrowPosition = {\n reserveAddress: reserve!.address,\n mintAddress: mint,\n amount: new Decimal(0),\n marketValueRefreshed: new Decimal(0),\n };\n }\n\n if (!reserve.state.config.elevationGroups.includes(this.state.elevationGroup)) {\n throw new Error(\n `User would have to downgrade the elevation group in order to be able to borrow from this reserve`\n );\n }\n\n const borrowFactor = this.getBorrowFactorForReserve(reserve);\n\n const borrowValueUSD = borrowAmount.mul(reserve.getOracleMarketPrice()).dividedBy(reserve.getMintFactor());\n\n const borrowValueBorrowFactorAdjustedUSD = borrowValueUSD.mul(borrowFactor);\n\n newStats.userTotalBorrow = positiveOrZero(newStats.userTotalBorrow.plus(borrowValueUSD));\n newStats.userTotalBorrowBorrowFactorAdjusted = positiveOrZero(\n newStats.userTotalBorrowBorrowFactorAdjusted.plus(borrowValueBorrowFactorAdjustedUSD)\n );\n\n borrowPosition.amount = positiveOrZero(borrowPosition.amount.plus(borrowAmount));\n borrowPosition.mintAddress = mint;\n borrowPosition.marketValueRefreshed = positiveOrZero(borrowPosition.marketValueRefreshed.plus(borrowValueUSD));\n\n newBorrows.set(borrowPosition.reserveAddress, borrowPosition);\n return {\n borrows: newBorrows,\n stats: newStats,\n };\n }\n\n calculateSimulatedDeposit(\n oldStats: ObligationStats,\n oldDeposits: Map<PublicKey, Position>,\n amount: Decimal,\n mint: PublicKey,\n reserves: Map<PublicKey, KaminoReserve>,\n market: KaminoMarket\n ): {\n stats: ObligationStats;\n deposits: Map<PublicKey, Position>;\n } {\n const newStats = { ...oldStats };\n const newDeposits = new PubkeyHashMap<PublicKey, Position>([...oldDeposits.entries()]);\n\n let depositPosition: Position | undefined = undefined;\n for (const oldDeposit of oldDeposits.values()) {\n if (oldDeposit.mintAddress.equals(mint)) {\n depositPosition = { ...oldDeposit };\n }\n }\n let reserve: KaminoReserve | undefined = undefined;\n for (const kaminoReserve of reserves.values()) {\n if (kaminoReserve.getLiquidityMint().equals(mint)) {\n reserve = kaminoReserve;\n }\n }\n if (!reserve) {\n throw new Error(`No reserve found for mint ${mint}`);\n }\n\n if (!depositPosition) {\n depositPosition = {\n reserveAddress: reserve!.address,\n mintAddress: mint,\n amount: new Decimal(0),\n marketValueRefreshed: new Decimal(0),\n };\n }\n\n if (!reserve.state.config.elevationGroups.includes(this.state.elevationGroup)) {\n throw new Error(\n `User would have to downgrade the elevation group in order to be able to deposit in this reserve`\n );\n }\n const { maxLtv, liquidationLtv } = this.getLtvForReserve(market, reserve);\n\n const supplyAmount = amount; //.mul(reserve.getCollateralExchangeRate()).floor();\n const supplyAmountMultiplierUSD = supplyAmount\n .mul(reserve.getOracleMarketPrice())\n .dividedBy('1'.concat(Array(reserve.stats.decimals + 1).join('0')));\n\n newStats.userTotalDeposit = positiveOrZero(newStats.userTotalDeposit.plus(supplyAmountMultiplierUSD));\n newStats.borrowLimit = positiveOrZero(newStats.borrowLimit.plus(supplyAmountMultiplierUSD.mul(maxLtv)));\n newStats.borrowLiquidationLimit = positiveOrZero(\n newStats.borrowLiquidationLimit.plus(supplyAmountMultiplierUSD.mul(liquidationLtv))\n );\n newStats.liquidationLtv = valueOrZero(newStats.borrowLiquidationLimit.div(newStats.userTotalDeposit));\n\n depositPosition.amount = positiveOrZero(depositPosition.amount.plus(amount));\n depositPosition.mintAddress = mint;\n depositPosition.marketValueRefreshed = positiveOrZero(\n depositPosition.marketValueRefreshed.plus(\n supplyAmount.mul(reserve.getOracleMarketPrice()).dividedBy(reserve.getMintFactor())\n )\n );\n\n newDeposits.set(depositPosition.reserveAddress, depositPosition);\n\n return {\n deposits: newDeposits,\n stats: newStats,\n };\n }\n\n /**\n * Calculate the newly modified stats of the obligation\n */\n // TODO: Elevation group problems\n // TODO: Shall we set up position limits?\n getSimulatedObligationStats(params: {\n amountCollateral?: Decimal;\n amountDebt?: Decimal;\n action: ActionType;\n mintCollateral?: PublicKey;\n mintDebt?: PublicKey;\n market: KaminoMarket;\n reserves: Map<PublicKey, KaminoReserve>;\n }): {\n stats: ObligationStats;\n deposits: Map<PublicKey, Position>;\n borrows: Map<PublicKey, Position>;\n } {\n const { amountCollateral, amountDebt, action, mintCollateral, mintDebt, market, reserves } = params;\n let newStats = { ...this.refreshedStats };\n let newDeposits: Map<PublicKey, Position> = new PubkeyHashMap<PublicKey, Position>([...this.deposits.entries()]);\n let newBorrows: Map<PublicKey, Position> = new PubkeyHashMap<PublicKey, Position>([...this.borrows.entries()]);\n\n switch (action) {\n case 'deposit': {\n if (amountCollateral === undefined || mintCollateral === undefined) {\n throw Error('amountCollateral & mintCollateral are required for deposit action');\n }\n const { stats, deposits } = this.calculateSimulatedDeposit(\n this.refreshedStats,\n this.deposits,\n amountCollateral,\n mintCollateral,\n reserves,\n market\n );\n\n newStats = stats;\n newDeposits = deposits;\n\n break;\n }\n case 'borrow': {\n if (amountDebt === undefined || mintDebt === undefined) {\n throw Error('amountDebt & mintDebt are required for borrow action');\n }\n const { stats, borrows } = this.calculateSimulatedBorrow(\n this.refreshedStats,\n this.borrows,\n amountDebt,\n mintDebt,\n reserves\n );\n newStats = stats;\n newBorrows = borrows;\n break;\n }\n case 'repay': {\n if (amountDebt === undefined || mintDebt === undefined) {\n throw Error('amountDebt & mintDebt are required for repay action');\n }\n const { stats, borrows } = this.calculateSimulatedBorrow(\n this.refreshedStats,\n this.borrows,\n new Decimal(amountDebt).neg(),\n mintDebt,\n reserves\n );\n newStats = stats;\n newBorrows = borrows;\n break;\n }\n\n case 'withdraw': {\n if (amountCollateral === undefined || mintCollateral === undefined) {\n throw Error('amountCollateral & mintCollateral are required for withdraw action');\n }\n const { stats, deposits } = this.calculateSimulatedDeposit(\n this.refreshedStats,\n this.deposits,\n new Decimal(amountCollateral).neg(),\n mintCollateral,\n reserves,\n market\n );\n newStats = stats;\n newDeposits = deposits;\n break;\n }\n case 'depositAndBorrow': {\n if (\n amountCollateral === undefined ||\n amountDebt === undefined ||\n mintCollateral === undefined ||\n mintDebt === undefined\n ) {\n throw Error('amountColl & amountDebt & mintCollateral & mintDebt are required for depositAndBorrow action');\n }\n const { stats: statsAfterDeposit, deposits } = this.calculateSimulatedDeposit(\n this.refreshedStats,\n this.deposits,\n amountCollateral,\n mintCollateral,\n reserves,\n market\n );\n const { stats, borrows } = this.calculateSimulatedBorrow(\n statsAfterDeposit,\n this.borrows,\n amountDebt,\n mintDebt,\n reserves\n );\n\n newStats = stats;\n newDeposits = deposits;\n newBorrows = borrows;\n break;\n }\n case 'repayAndWithdraw': {\n if (\n amountCollateral === undefined ||\n amountDebt === undefined ||\n mintCollateral === undefined ||\n mintDebt === undefined\n ) {\n throw Error('amountColl & amountDebt & mintCollateral & mintDebt are required for repayAndWithdraw action');\n }\n const { stats: statsAfterRepay, borrows } = this.calculateSimulatedBorrow(\n this.refreshedStats,\n this.borrows,\n new Decimal(amountDebt).neg(),\n mintDebt,\n reserves\n );\n const { stats: statsAfterWithdraw, deposits } = this.calculateSimulatedDeposit(\n statsAfterRepay,\n this.deposits,\n new Decimal(amountCollateral).neg(),\n mintCollateral,\n reserves,\n market\n );\n newStats = statsAfterWithdraw;\n newDeposits = deposits;\n newBorrows = borrows;\n break;\n }\n default: {\n throw Error(`Invalid action type ${action} for getSimulatedObligationStats`);\n }\n }\n newStats.netAccountValue = newStats.userTotalDeposit.minus(newStats.userTotalBorrow);\n newStats.loanToValue = valueOrZero(\n newStats.userTotalBorrowBorrowFactorAdjusted.dividedBy(newStats.userTotalDeposit)\n );\n newStats.leverage = valueOrZero(newStats.userTotalDeposit.dividedBy(newStats.netAccountValue));\n\n return {\n stats: newStats,\n deposits: newDeposits,\n borrows: newBorrows,\n };\n }\n\n estimateObligationInterestRate = (\n market: KaminoMarket,\n reserve: KaminoReserve,\n borrow: ObligationLiquidity,\n currentSlot: number\n ): Decimal => {\n const estimatedCumulativeBorrowRate = reserve.getEstimatedCumulativeBorrowRate(\n currentSlot,\n market.state.referralFeeBps\n );\n\n const currentCumulativeBorrowRate = KaminoObligation.getCumulativeBorrowRate(borrow);\n\n if (estimatedCumulativeBorrowRate.gt(currentCumulativeBorrowRate)) {\n return estimatedCumulativeBorrowRate.div(currentCumulativeBorrowRate);\n }\n\n return new Decimal(0);\n };\n\n private calculateDeposits(\n market: KaminoMarket,\n obligation: Obligation,\n collateralExchangeRates: Map<PublicKey, Decimal>,\n getPx: (reserve: KaminoReserve) => Decimal\n ): {\n deposits: Map<PublicKey, Position>;\n userTotalDeposit: Decimal;\n borrowLimit: Decimal;\n liquidationLtv: Decimal;\n borrowLiquidationLimit: Decimal;\n } {\n return KaminoObligation.calculateObligationDeposits(\n market,\n obligation,\n collateralExchangeRates,\n obligation.elevationGroup,\n getPx\n );\n }\n\n private calculateBorrows(\n market: KaminoMarket,\n obligation: Obligation,\n cumulativeBorrowRates: Map<PublicKey, Decimal>,\n getPx: (reserve: KaminoReserve) => Decimal\n ): BorrowStats {\n return KaminoObligation.calculateObligationBorrows(\n market,\n obligation,\n cumulativeBorrowRates,\n obligation.elevationGroup,\n getPx\n );\n }\n\n private calculatePositions(\n market: KaminoMarket,\n obligation: Obligation,\n collateralExchangeRates: Map<PublicKey, Decimal>,\n cumulativeBorrowRates: Map<PublicKey, Decimal>\n ): {\n borrows: Map<PublicKey, Position>;\n deposits: Map<PublicKey, Position>;\n refreshedStats: ObligationStats;\n } {\n const getOraclePx = (reserve: KaminoReserve) => reserve.getOracleMarketPrice();\n const depositStatsOraclePrice = this.calculateDeposits(market, obligation, collateralExchangeRates, getOraclePx);\n const borrowStatsOraclePrice = this.calculateBorrows(market, obligation, cumulativeBorrowRates, getOraclePx);\n\n const netAccountValueScopeRefreshed = depositStatsOraclePrice.userTotalDeposit.minus(\n borrowStatsOraclePrice.userTotalBorrow\n );\n\n const potentialElevationGroupUpdate = 0;\n\n return {\n deposits: depositStatsOraclePrice.deposits,\n borrows: borrowStatsOraclePrice.borrows,\n refreshedStats: {\n borrowLimit: depositStatsOraclePrice.borrowLimit,\n borrowLiquidationLimit: depositStatsOraclePrice.borrowLiquidationLimit,\n userTotalBorrow: borrowStatsOraclePrice.userTotalBorrow,\n userTotalBorrowBorrowFactorAdjusted: borrowStatsOraclePrice.userTotalBorrowBorrowFactorAdjusted,\n userTotalDeposit: depositStatsOraclePrice.userTotalDeposit,\n liquidationLtv: depositStatsOraclePrice.liquidationLtv,\n borrowUtilization: borrowStatsOraclePrice.userTotalBorrowBorrowFactorAdjusted.dividedBy(\n depositStatsOraclePrice.borrowLimit\n ),\n netAccountValue: netAccountValueScopeRefreshed,\n leverage: depositStatsOraclePrice.userTotalDeposit.dividedBy(netAccountValueScopeRefreshed),\n loanToValue: borrowStatsOraclePrice.userTotalBorrowBorrowFactorAdjusted.dividedBy(\n depositStatsOraclePrice.userTotalDeposit\n ),\n potentialElevationGroupUpdate,\n },\n };\n }\n\n public static calculateObligationDeposits(\n market: KaminoMarket,\n obligation: Obligation,\n collateralExchangeRates: Map<PublicKey, Decimal> | null,\n elevationGroup: number,\n getPx: (reserve: KaminoReserve) => Decimal\n ): {\n deposits: Map<PublicKey, Position>;\n userTotalDeposit: Decimal;\n userTotalCollateralDeposit: Decimal;\n borrowLimit: Decimal;\n liquidationLtv: Decimal;\n borrowLiquidationLimit: Decimal;\n } {\n let userTotalDeposit = new Decimal(0);\n let userTotalCollateralDeposit = new Decimal(0);\n let borrowLimit = new Decimal(0);\n let borrowLiquidationLimit = new Decimal(0);\n\n const deposits = new PubkeyHashMap<PublicKey, Position>();\n for (let i = 0; i < obligation.deposits.length; i++) {\n if (!isNotNullPubkey(obligation.deposits[i].depositReserve)) {\n continue;\n }\n const deposit = obligation.deposits[i];\n const reserve = market.getReserveByAddress(deposit.depositReserve);\n if (!reserve) {\n throw new Error(\n `Obligation contains a deposit belonging to reserve: ${deposit.depositReserve} but the reserve was not found on the market. Deposit amount: ${deposit.depositedAmount}`\n );\n }\n const { maxLtv, liquidationLtv } = KaminoObligation.getLtvForReserve(market, reserve, elevationGroup);\n\n let exchangeRate: Decimal;\n if (collateralExchangeRates !== null) {\n exchangeRate = collateralExchangeRates.get(reserve.address)!;\n } else {\n exchangeRate = reserve.getCollateralExchangeRate();\n }\n const supplyAmount = new Decimal(deposit.depositedAmount.toString()).div(exchangeRate);\n\n const depositValueUsd = supplyAmount.mul(getPx(reserve)).div(reserve.getMintFactor());\n\n userTotalDeposit = userTotalDeposit.add(depositValueUsd);\n\n if (!maxLtv.eq('0')) {\n userTotalCollateralDeposit = userTotalCollateralDeposit.add(depositValueUsd);\n }\n\n borrowLimit = borrowLimit.add(depositValueUsd.mul(maxLtv));\n borrowLiquidationLimit = borrowLiquidationLimit.add(depositValueUsd.mul(liquidationLtv));\n\n const position: Position = {\n reserveAddress: reserve.address,\n mintAddress: reserve.getLiquidityMint(),\n amount: supplyAmount,\n marketValueRefreshed: depositValueUsd,\n };\n deposits.set(reserve.address, position);\n }\n\n return {\n deposits,\n userTotalDeposit,\n userTotalCollateralDeposit,\n borrowLimit,\n liquidationLtv: valueOrZero(borrowLiquidationLimit.div(userTotalDeposit)),\n borrowLiquidationLimit,\n };\n }\n\n public static calculateObligationBorrows(\n market: KaminoMarket,\n obligation: Obligation,\n cumulativeBorrowRates: Map<PublicKey, Decimal> | null,\n elevationGroup: number,\n getPx: (reserve: KaminoReserve) => Decimal\n ): BorrowStats {\n let userTotalBorrow = new Decimal(0);\n let userTotalBorrowBorrowFactorAdjusted = new Decimal(0);\n let positions = 0;\n\n const borrows = new PubkeyHashMap<PublicKey, Position>();\n for (let i = 0; i < obligation.borrows.length; i++) {\n if (!isNotNullPubkey(obligation.borrows[i].borrowReserve)) {\n continue;\n }\n const borrow = obligation.borrows[i];\n const reserve = market.getReserveByAddress(borrow.borrowReserve);\n if (!reserve) {\n throw new Error(\n `Obligation contains a borrow belonging to reserve: ${\n borrow.borrowReserve\n } but the reserve was not found on the market. Borrow amount: ${KaminoObligation.getBorrowAmount(borrow)}`\n );\n }\n\n const obligationCumulativeBorrowRate = KaminoObligation.getCumulativeBorrowRate(borrow);\n let cumulativeBorrowRate;\n if (cumulativeBorrowRates !== null) {\n cumulativeBorrowRate = cumulativeBorrowRates.get(reserve.address)!;\n } else {\n cumulativeBorrowRate = reserve.getCumulativeBorrowRate();\n }\n\n const borrowAmount = KaminoObligation.getBorrowAmount(borrow)\n .mul(cumulativeBorrowRate)\n .dividedBy(obligationCumulativeBorrowRate);\n\n const borrowValueUsd = borrowAmount.mul(getPx(reserve)).dividedBy(reserve.getMintFactor());\n\n const borrowFactor = KaminoObligation.getBorrowFactorForReserve(reserve, elevationGroup);\n const borrowValueBorrowFactorAdjustedUsd = borrowValueUsd.mul(borrowFactor);\n\n if (!borrowAmount.eq(new Decimal('0'))) {\n positions += 1;\n }\n\n userTotalBorrow = userTotalBorrow.plus(borrowValueUsd);\n userTotalBorrowBorrowFactorAdjusted = userTotalBorrowBorrowFactorAdjusted.plus(\n borrowValueBorrowFactorAdjustedUsd\n );\n\n const position: Position = {\n reserveAddress: reserve.address,\n mintAddress: reserve.getLiquidityMint(),\n amount: borrowAmount,\n marketValueRefreshed: borrowValueUsd,\n };\n borrows.set(reserve.address, position);\n }\n\n return {\n borrows,\n userTotalBorrow,\n userTotalBorrowBorrowFactorAdjusted,\n positions,\n };\n }\n\n /* \n How much of a given token can a user borrow extra given an elevation group, \n regardless of caps and liquidity or assuming infinite liquidity and infinite caps,\n until it hits max LTV.\n\n This is purely a function about the borrow power of an obligation, \n not a reserve-specific, caps-specific, liquidity-specific function.\n\n * @param market - The KaminoMarket instance.\n * @param liquidityMint - The liquidity mint PublicKey.\n * @param slot - The slot number.\n * @param elevationGroup - The elevation group number (default: this.state.elevationGroup).\n * @returns The borrow power as a Decimal.\n * @throws Error if the reserve is not found.\n */\n getBorrowPower(\n market: KaminoMarket,\n liquidityMint: PublicKey,\n slot: number,\n elevationGroup: number = this.state.elevationGroup\n ): Decimal {\n const reserve = market.getReserveByMint(liquidityMint);\n if (!reserve) {\n throw new Error('Reserve not found');\n }\n\n const elevationGroupActivated =\n reserve.state.config.elevationGroups.includes(elevationGroup) && elevationGroup !== 0;\n\n const borrowFactor = KaminoObligation.getBorrowFactorForReserve(reserve, elevationGroup);\n\n const getOraclePx = (reserve: KaminoReserve) => reserve.getOracleMarketPrice();\n const { collateralExchangeRates, cumulativeBorrowRates } = KaminoObligation.getRatesForObligation(\n market,\n this.state,\n slot\n );\n\n const { borrowLimit } = KaminoObligation.calculateObligationDeposits(\n market,\n this.state,\n collateralExchangeRates,\n elevationGroup,\n getOraclePx\n );\n\n const { userTotalBorrowBorrowFactorAdjusted } = KaminoObligation.calculateObligationBorrows(\n market,\n this.state,\n cumulativeBorrowRates,\n elevationGroup,\n getOraclePx\n );\n\n const maxObligationBorrowPower = borrowLimit // adjusted available amount\n .minus(userTotalBorrowBorrowFactorAdjusted)\n .div(borrowFactor)\n .div(reserve.getOracleMarketPrice())\n .mul(reserve.getMintFactor());\n\n // If it has any collateral outside emode, then return 0\n for (const [_, value] of this.deposits.entries()) {\n const depositReserve = market.getReserveByAddress(value.reserveAddress);\n if (!depositReserve) {\n throw new Error('Reserve not found');\n }\n if (depositReserve.state.config.disableUsageAsCollOutsideEmode && !elevationGroupActivated) {\n return new Decimal(0);\n }\n }\n\n // This is not amazing because it assumes max borrow, which is not true\n let originationFeeRate = reserve.getBorrowFee();\n\n // Inclusive fee rate\n originationFeeRate = originationFeeRate.div(originationFeeRate.add(new Decimal(1)));\n const borrowFee = maxObligationBorrowPower.mul(originationFeeRate);\n\n const maxBorrowAmount = maxObligationBorrowPower.sub(borrowFee);\n\n return Decimal.max(new Decimal(0), maxBorrowAmount);\n }\n\n /* \n How much of a given token can a user borrow extra given an elevation group,\n and a specific reserve, until it hits max LTV and given available liquidity and caps.\n\n * @param market - The KaminoMarket instance.\n * @param liquidityMint - The liquidity mint PublicKey.\n * @param slot - The slot number.\n * @param elevationGroup - The elevation group number (default: this.state.elevationGroup).\n * @returns The maximum borrow amount as a Decimal.\n * @throws Error if the reserve is not found.\n */\n getMaxBorrowAmountV2(\n market: KaminoMarket,\n liquidityMint: PublicKey,\n slot: number,\n elevationGroup: number = this.state.elevationGroup\n ): Decimal {\n const reserve = market.getReserveByMint(liquidityMint);\n if (!reserve) {\n throw new Error('Reserve not found');\n }\n\n const liquidityAvailable = reserve.getLiquidityAvailableForDebtReserveGivenCaps(market, [elevationGroup])[0];\n const maxBorrowAmount = this.getBorrowPower(market, liquidityMint, slot, elevationGroup);\n\n if (elevationGroup === this.state.elevationGroup) {\n return Decimal.min(maxBorrowAmount, liquidityAvailable);\n } else {\n const { amount: debtThisReserve } = this.borrows.get(reserve.address) || { amount: new Decimal(0) };\n const liquidityAvailablePostMigration = Decimal.max(0, liquidityAvailable.minus(debtThisReserve));\n return Decimal.min(maxBorrowAmount, liquidityAvailablePostMigration);\n }\n }\n\n /* \n Returns true if the loan is eligible for the elevation group, including for the default one.\n * @param market - The KaminoMarket object representing the market.\n * @param slot - The slot number of the loan.\n * @param elevationGroup - The elevation group number.\n * @returns A boolean indicating whether the loan is eligible for elevation.\n */\n isLoanEligibleForElevationGroup(market: KaminoMarket, slot: number, elevationGroup: number): boolean {\n // - isLoanEligibleForEmode(obligation, emode: 0 | number): <boolean, ErrorMessage>\n // - essentially checks if a loan can be migrated or not\n // - [x] due to collateral / debt reserves combination\n // - [x] due to LTV, etc\n\n const reserveDeposits: string[] = Array.from(this.deposits.keys()).map((x) => x.toString());\n const reserveBorrows: string[] = Array.from(this.borrows.keys()).map((x) => x.toString());\n\n if (reserveBorrows.length > 1) {\n return false;\n }\n\n if (elevationGroup > 0) {\n // Elevation group 0 doesn't need to do reserve checks, as all are included by default\n const allElevationGroups = market.getMarketElevationGroupDescriptions();\n const elevationGroupDescription = allElevationGroups[elevationGroup - 1];\n\n // Has to be a subset\n const allCollsIncluded = reserveDeposits.every((reserve) =>\n elevationGroupDescription.collateralReserves.includes(reserve)\n );\n const allDebtsIncluded =\n reserveBorrows.length === 0 ||\n (reserveBorrows.length === 1 && elevationGroupDescription.debtReserve === reserveBorrows[0]);\n\n if (!allCollsIncluded || !allDebtsIncluded) {\n return false;\n }\n }\n\n // Check if the loan can be migrated based on LTV\n const getOraclePx = (reserve: KaminoReserve) => reserve.getOracleMarketPrice();\n const { collateralExchangeRates } = KaminoObligation.getRatesForObligation(market, this.state, slot);\n\n const { borrowLimit } = KaminoObligation.calculateObligationDeposits(\n market,\n this.state,\n collateralExchangeRates,\n elevationGroup,\n getOraclePx\n );\n\n const isEligibleBasedOnLtv = this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.lte(borrowLimit);\n\n return isEligibleBasedOnLtv;\n }\n\n /* \n Returns all elevation groups for a given obligation, except the default one\n * @param market - The KaminoMarket instance.\n * @returns An array of ElevationGroupDescription objects representing the elevation groups for the obligation.\n */\n getElevationGroupsForObligation(market: KaminoMarket): ElevationGroupDescription[] {\n if (this.borrows.size > 1) {\n return [];\n }\n\n const collReserves = Array.from(this.deposits.keys());\n if (this.borrows.size === 0) {\n return market.getElevationGroupsForReservesCombination(collReserves);\n } else {\n const debtReserve = Array.from(this.borrows.keys())[0];\n return market.getElevationGroupsForReservesCombination(collReserves, debtReserve);\n }\n }\n\n /* Deprecated function, also broken */\n getMaxBorrowAmount(\n market: KaminoMarket,\n liquidityMint: PublicKey,\n slot: number,\n requestElevationGroup: boolean\n ): Decimal {\n const reserve = market.getReserveByMint(liquidityMint);\n\n if (!reserve) {\n throw new Error('Reserve not found');\n }\n\n const groups = market.state.elevationGroups;\n const emodeGroupsDebtReserve = reserve.state.config.elevationGroups;\n let commonElevationGroups = [...emodeGroupsDebtReserve].filter(\n (item) => item !== 0 && groups[item - 1].debtReserve.equals(reserve.address)\n );\n\n for (const [_, value] of this.deposits.entries()) {\n const depositReserve = market.getReserveByAddress(value.reserveAddress);\n\n if (!depositReserve) {\n throw new Error('Reserve not found');\n }\n\n const depositReserveEmodeGroups = depositReserve.state.config.elevationGroups;\n\n commonElevationGroups = commonElevationGroups.filter((item) => depositReserveEmodeGroups.includes(item));\n }\n\n let elevationGroup = this.state.elevationGroup;\n if (commonElevationGroups.length != 0) {\n const eModeGroupWithMaxLtvAndDebtReserve = commonElevationGroups.reduce((prev, curr) => {\n const prevGroup = groups.find((group) => group.id === prev);\n const currGroup = groups.find((group) => group.id === curr);\n return prevGroup!.ltvPct > currGroup!.ltvPct ? prev : curr;\n });\n\n if (requestElevationGroup) {\n elevationGroup = eModeGroupWithMaxLtvAndDebtReserve;\n }\n }\n\n const elevationGroupActivated =\n reserve.state.config.elevationGroups.includes(elevationGroup) && elevationGroup !== 0;\n\n const borrowFactor = this.getBorrowFactorForReserve(reserve);\n\n const maxObligationBorrowPower = this.refreshedStats.borrowLimit // adjusted available amount\n .minus(this.refreshedStats.userTotalBorrowBorrowFactorAdjusted)\n .div(borrowFactor)\n .div(reserve.getOracleMarketPrice())\n .mul(reserve.getMintFactor());\n const reserveAvailableAmount = reserve.getLiquidityAvailableAmount();\n let reserveBorrowCapRemained = reserve.stats.reserveBorrowLimit.sub(reserve.getBorrowedAmount());\n\n this.deposits.forEach((deposit) => {\n const depositReserve = market.getReserveByAddress(deposit.reserveAddress);\n if (!depositReserve) {\n throw new Error('Reserve not found');\n }\n if (depositReserve.state.config.disableUsageAsCollOutsideEmode && !elevationGroupActivated) {\n reserveBorrowCapRemained = new Decimal(0);\n }\n });\n\n let maxBorrowAmount = Decimal.min(maxObligationBorrowPower, reserveAvailableAmount, reserveBorrowCapRemained);\n\n const debtWithdrawalCap = reserve.getDebtWithdrawalCapCapacity().sub(reserve.getDebtWithdrawalCapCurrent(slot));\n maxBorrowAmount = reserve.getDebtWithdrawalCapCapacity().gt(0)\n ? Decimal.min(maxBorrowAmount, debtWithdrawalCap)\n : maxBorrowAmount;\n\n let originationFeeRate = reserve.getBorrowFee();\n\n // Inclusive fee rate\n originationFeeRate = originationFeeRate.div(originationFeeRate.add(new Decimal(1)));\n const borrowFee = maxBorrowAmount.mul(originationFeeRate);\n\n maxBorrowAmount = maxBorrowAmount.sub(borrowFee);\n\n const utilizationRatioLimit = reserve.state.config.utilizationLimitBlockBorrowingAbove / 100;\n const currentUtilizationRatio = reserve.calculateUtilizationRatio();\n\n if (utilizationRatioLimit > 0 && currentUtilizationRatio > utilizationRatioLimit) {\n return new Decimal(0);\n } else if (utilizationRatioLimit > 0 && currentUtilizationRatio < utilizationRatioLimit) {\n const maxBorrowBasedOnUtilization = new Decimal(utilizationRatioLimit - currentUtilizationRatio).mul(\n reserve.getTotalSupply()\n );\n maxBorrowAmount = Decimal.min(maxBorrowAmount, maxBorrowBasedOnUtilization);\n }\n\n let borrowLimitDependentOnElevationGroup = new Decimal(U64_MAX);\n\n if (!elevationGroupActivated) {\n borrowLimitDependentOnElevationGroup = reserve\n .getBorrowLimitOutsideElevationGroup()\n .sub(reserve.getBorrowedAmountOutsideElevationGroup());\n } else {\n let maxDebtTakenAgainstCollaterals = new Decimal(U64_MAX);\n for (const [_, value] of this.deposits.entries()) {\n const depositReserve = market.getReserveByAddress(value.reserveAddress);\n\n if (!depositReserve) {\n throw new Error('Reserve not found');\n }\n\n const maxDebtAllowedAgainstCollateral = depositReserve\n .getBorrowLimitAgainstCollateralInElevationGroup(elevationGroup - 1)\n .sub(depositReserve.getBorrowedAmountAgainstCollateralInElevationGroup(elevationGroup - 1));\n\n maxDebtTakenAgainstCollaterals = Decimal.max(\n new Decimal(0),\n Decimal.min(maxDebtAllowedAgainstCollateral, maxDebtTakenAgainstCollaterals)\n );\n }\n borrowLimitDependentOnElevationGroup = maxDebtTakenAgainstCollaterals;\n }\n\n maxBorrowAmount = Decimal.min(maxBorrowAmount, borrowLimitDependentOnElevationGroup);\n\n return Decimal.max(new Decimal(0), maxBorrowAmount);\n }\n\n getMaxWithdrawAmount(market: KaminoMarket, tokenMint: PublicKey, slot: number): Decimal {\n const depositReserve = market.getReserveByMint(tokenMint);\n\n if (!depositReserve) {\n throw new Error('Reserve not found');\n }\n\n const userDepositPosition = this.getDepositByReserve(depositReserve.address);\n\n if (!userDepositPosition) {\n throw new Error('Deposit reserve not found');\n }\n\n const userDepositPositionAmount = userDepositPosition.amount;\n\n if (this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.equals(new Decimal(0))) {\n return new Decimal(userDepositPositionAmount);\n }\n\n const { maxLtv: reserveMaxLtv } = this.getLtvForReserve(market, depositReserve);\n // bf adjusted debt value > allowed_borrow_value\n if (this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.gte(this.refreshedStats.borrowLimit)) {\n return new Decimal(0);\n }\n\n let maxWithdrawValue: Decimal;\n if (reserveMaxLtv.eq(0)) {\n maxWithdrawValue = userDepositPositionAmount;\n } else {\n // borrowLimit / userTotalDeposit = maxLtv\n // maxWithdrawValue = userTotalDeposit - userTotalBorrow / maxLtv\n maxWithdrawValue = this.refreshedStats.borrowLimit\n .sub(this.refreshedStats.userTotalBorrowBorrowFactorAdjusted)\n .div(reserveMaxLtv)\n .mul(0.999); // remove 0.1% to prevent going over max ltv\n }\n\n const maxWithdrawAmount = maxWithdrawValue\n .div(depositReserve.getOracleMarketPrice())\n .mul(depositReserve.getMintFactor());\n const reserveAvailableLiquidity = depositReserve.getLiquidityAvailableAmount();\n\n const withdrawalCapRemained = depositReserve\n .getDepositWithdrawalCapCapacity()\n .sub(depositReserve.getDepositWithdrawalCapCurrent(slot));\n return Decimal.max(\n 0,\n Decimal.min(userDepositPositionAmount, maxWithdrawAmount, reserveAvailableLiquidity, withdrawalCapRemained)\n );\n }\n\n /**\n *\n * @returns Total borrowed amount for the specified obligation liquidity/borrow asset\n */\n static getBorrowAmount(borrow: ObligationLiquidity): Decimal {\n return new Fraction(borrow.borrowedAmountSf).toDecimal();\n }\n\n /**\n *\n * @returns Cumulative borrow rate for the specified obligation liquidity/borrow asset\n */\n static getCumulativeBorrowRate(borrow: ObligationLiquidity): Decimal {\n let accSf = new BN(0);\n for (const value of borrow.cumulativeBorrowRateBsf.value.reverse()) {\n accSf = accSf.add(value);\n accSf.shrn(64);\n }\n return new Fraction(accSf).toDecimal();\n }\n\n public static getRatesForObligation(\n kaminoMarket: KaminoMarket,\n obligation: Obligation,\n slot: number\n ): {\n collateralExchangeRates: Map<PublicKey, Decimal>;\n cumulativeBorrowRates: Map<PublicKey, Decimal>;\n } {\n const collateralExchangeRates = KaminoObligation.getCollateralExchangeRatesForObligation(\n kaminoMarket,\n obligation,\n slot\n );\n const cumulativeBorrowRates = KaminoObligation.getCumulativeBorrowRatesForObligation(\n kaminoMarket,\n obligation,\n slot\n );\n\n return {\n collateralExchangeRates,\n cumulativeBorrowRates,\n };\n }\n\n public static addRatesForObligation(\n kaminoMarket: KaminoMarket,\n obligation: Obligation,\n collateralExchangeRates: Map<PublicKey, Decimal>,\n cumulativeBorrowRates: Map<PublicKey, Decimal>,\n slot: number\n ): void {\n KaminoObligation.addCollateralExchangeRatesForObligation(kaminoMarket, collateralExchangeRates, obligation, slot);\n KaminoObligation.addCumulativeBorrowRatesForObligation(kaminoMarket, cumulativeBorrowRates, obligation, slot);\n }\n\n static getCollateralExchangeRatesForObligation(\n kaminoMarket: KaminoMarket,\n obligation: Obligation,\n slot: number\n ): Map<PublicKey, Decimal> {\n const collateralExchangeRates = new PubkeyHashMap<PublicKey, Decimal>();\n for (let i = 0; i < obligation.deposits.length; i++) {\n const deposit = obligation.deposits[i];\n if (isNotNullPubkey(deposit.depositReserve) && !collateralExchangeRates.has(deposit.depositReserve)) {\n const reserve = kaminoMarket.getReserveByAddress(deposit.depositReserve)!;\n const collateralExchangeRate = reserve.getEstimatedCollateralExchangeRate(\n slot,\n kaminoMarket.state.referralFeeBps\n );\n collateralExchangeRates.set(reserve.address, collateralExchangeRate);\n }\n }\n return collateralExchangeRates;\n }\n\n static addCollateralExchangeRatesForObligation(\n kaminoMarket: KaminoMarket,\n collateralExchangeRates: Map<PublicKey, Decimal>,\n obligation: Obligation,\n slot: number\n ) {\n for (let i = 0; i < obligation.deposits.length; i++) {\n const deposit = obligation.deposits[i];\n if (isNotNullPubkey(deposit.depositReserve) && !collateralExchangeRates.has(deposit.depositReserve)) {\n const reserve = kaminoMarket.getReserveByAddress(deposit.depositReserve)!;\n const collateralExchangeRate = reserve.getEstimatedCollateralExchangeRate(\n slot,\n kaminoMarket.state.referralFeeBps\n );\n collateralExchangeRates.set(reserve.address, collateralExchangeRate);\n }\n }\n }\n\n static getCumulativeBorrowRatesForObligation(kaminoMarket: KaminoMarket, obligation: Obligation, slot: number) {\n const cumulativeBorrowRates = new PubkeyHashMap<PublicKey, Decimal>();\n for (let i = 0; i < obligation.borrows.length; i++) {\n const borrow = obligation.borrows[i];\n if (isNotNullPubkey(borrow.borrowReserve) && !cumulativeBorrowRates.has(borrow.borrowReserve)) {\n const reserve = kaminoMarket.getReserveByAddress(borrow.borrowReserve)!;\n const cumulativeBorrowRate = reserve.getEstimatedCumulativeBorrowRate(slot, kaminoMarket.state.referralFeeBps);\n cumulativeBorrowRates.set(reserve.address, cumulativeBorrowRate);\n }\n }\n return cumulativeBorrowRates;\n }\n\n static addCumulativeBorrowRatesForObligation(\n kaminoMarket: KaminoMarket,\n cumulativeBorrowRates: Map<PublicKey, Decimal>,\n obligation: Obligation,\n slot: number\n ) {\n for (let i = 0; i < obligation.borrows.length; i++) {\n const borrow = obligation.borrows[i];\n if (isNotNullPubkey(borrow.borrowReserve) && !cumulativeBorrowRates.has(borrow.borrowReserve)) {\n const reserve = kaminoMarket.getReserveByAddress(borrow.borrowReserve)!;\n const cumulativeBorrowRate = reserve.getEstimatedCumulativeBorrowRate(slot, kaminoMarket.state.referralFeeBps);\n cumulativeBorrowRates.set(reserve.address, cumulativeBorrowRate);\n }\n }\n }\n\n /**\n * Get the borrow factor for a borrow reserve, accounting for the obligation elevation group if it is active\n * @param reserve\n * @param elevationGroup\n */\n public static getBorrowFactorForReserve(reserve: KaminoReserve, elevationGroup: number): Decimal {\n const elevationGroupActivated =\n reserve.state.config.elevationGroups.includes(elevationGroup) && elevationGroup !== 0;\n if (elevationGroupActivated) {\n return new Decimal('1');\n }\n return new Decimal(reserve.stats.borrowFactor).div('100');\n }\n\n /**\n * Get the loan to value and liquidation loan to value for a collateral reserve as ratios, accounting for the obligation elevation group if it is active\n * @param market\n * @param reserve\n * @param elevationGroup\n */\n public static getLtvForReserve(\n market: KaminoMarket,\n reserve: KaminoReserve,\n elevationGroup: number\n ): { maxLtv: Decimal; liquidationLtv: Decimal } {\n const elevationGroupActivated =\n elevationGroup !== 0 && reserve.state.config.elevationGroups.includes(elevationGroup);\n if (elevationGroupActivated) {\n const { ltvPct, liquidationThresholdPct } = market.getElevationGroup(elevationGroup);\n return {\n maxLtv: new Decimal(ltvPct).div('100'),\n liquidationLtv: new Decimal(liquidationThresholdPct).div('100'),\n };\n } else {\n const { loanToValue, liquidationThreshold } = reserve.stats;\n return {\n maxLtv: new Decimal(loanToValue),\n liquidationLtv: new Decimal(liquidationThreshold),\n };\n }\n }\n}\n"]}
|