@kamino-finance/klend-sdk 3.2.24 → 3.2.26

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.
@@ -37,6 +37,14 @@ interface BorrowStats {
37
37
  userTotalBorrowBorrowFactorAdjusted: Decimal;
38
38
  positions: number;
39
39
  }
40
+ interface DepositStats {
41
+ deposits: Map<PublicKey, Position>;
42
+ userTotalDeposit: Decimal;
43
+ userTotalCollateralDeposit: Decimal;
44
+ borrowLimit: Decimal;
45
+ liquidationLtv: Decimal;
46
+ borrowLiquidationLimit: Decimal;
47
+ }
40
48
  export declare class KaminoObligation {
41
49
  obligationAddress: PublicKey;
42
50
  state: Obligation;
@@ -118,33 +126,13 @@ export declare class KaminoObligation {
118
126
  */
119
127
  getNumberOfPositions(): number;
120
128
  getNetAccountValue(): Decimal;
121
- /**
122
- * 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
123
- * @param market
124
- * @param reserve
125
- */
126
- getLtvForReserve(market: KaminoMarket, reserve: KaminoReserve): {
127
- maxLtv: Decimal;
128
- liquidationLtv: Decimal;
129
- };
130
- /**
131
- * Get the borrow factor for a borrow reserve, accounting for the obligation elevation group if it is active
132
- * @param reserve
133
- */
134
- getBorrowFactorForReserve(reserve: KaminoReserve): Decimal;
135
129
  /**
136
130
  * @returns the potential elevation groups the obligation qualifies for
137
131
  */
138
132
  getElevationGroups(kaminoMarket: KaminoMarket): Array<number>;
139
133
  static getElevationGroupsForReserves(reserves: Array<KaminoReserve>): Array<number>;
140
- calculateSimulatedBorrow(oldStats: ObligationStats, oldBorrows: Map<PublicKey, Position>, borrowAmount: Decimal, mint: PublicKey, reserves: Map<PublicKey, KaminoReserve>): {
141
- stats: ObligationStats;
142
- borrows: Map<PublicKey, Position>;
143
- };
144
- calculateSimulatedDeposit(oldStats: ObligationStats, oldDeposits: Map<PublicKey, Position>, amount: Decimal, mint: PublicKey, reserves: Map<PublicKey, KaminoReserve>, market: KaminoMarket): {
145
- stats: ObligationStats;
146
- deposits: Map<PublicKey, Position>;
147
- };
134
+ simulateDepositChange(obligationDeposits: ObligationCollateral[], changeInLamports: number, changeReserve: PublicKey, collateralExchangeRates: Map<PublicKey, Decimal>): ObligationCollateral[];
135
+ simulateBorrowChange(obligationBorrows: ObligationLiquidity[], changeInLamports: number, changeReserve: PublicKey): ObligationLiquidity[];
148
136
  /**
149
137
  * Calculate the newly modified stats of the obligation
150
138
  */
@@ -156,24 +144,17 @@ export declare class KaminoObligation {
156
144
  mintDebt?: PublicKey;
157
145
  market: KaminoMarket;
158
146
  reserves: Map<PublicKey, KaminoReserve>;
147
+ slot: number;
148
+ elevationGroupOverride?: number;
159
149
  }): {
160
150
  stats: ObligationStats;
161
151
  deposits: Map<PublicKey, Position>;
162
152
  borrows: Map<PublicKey, Position>;
163
153
  };
164
154
  estimateObligationInterestRate: (market: KaminoMarket, reserve: KaminoReserve, borrow: ObligationLiquidity, currentSlot: number) => Decimal;
165
- private calculateDeposits;
166
- private calculateBorrows;
167
155
  private calculatePositions;
168
- static calculateObligationDeposits(market: KaminoMarket, obligation: Obligation, collateralExchangeRates: Map<PublicKey, Decimal> | null, elevationGroup: number, getPx: (reserve: KaminoReserve) => Decimal): {
169
- deposits: Map<PublicKey, Position>;
170
- userTotalDeposit: Decimal;
171
- userTotalCollateralDeposit: Decimal;
172
- borrowLimit: Decimal;
173
- liquidationLtv: Decimal;
174
- borrowLiquidationLimit: Decimal;
175
- };
176
- static calculateObligationBorrows(market: KaminoMarket, obligation: Obligation, cumulativeBorrowRates: Map<PublicKey, Decimal> | null, elevationGroup: number, getPx: (reserve: KaminoReserve) => Decimal): BorrowStats;
156
+ static calculateObligationDeposits(market: KaminoMarket, obligationDeposits: ObligationCollateral[], collateralExchangeRates: Map<PublicKey, Decimal> | null, elevationGroup: number, getPx: (reserve: KaminoReserve) => Decimal): DepositStats;
157
+ static calculateObligationBorrows(market: KaminoMarket, obligationBorrows: ObligationLiquidity[], cumulativeBorrowRates: Map<PublicKey, Decimal> | null, elevationGroup: number, getPx: (reserve: KaminoReserve) => Decimal): BorrowStats;
177
158
  getMaxLoanLtvGivenElevationGroup(market: KaminoMarket, elevationGroup: number, slot: number): Decimal;
178
159
  getBorrowPower(market: KaminoMarket, liquidityMint: PublicKey, slot: number, elevationGroup?: number): Decimal;
179
160
  getMaxBorrowAmountV2(market: KaminoMarket, liquidityMint: PublicKey, slot: number, elevationGroup?: number): Decimal;
@@ -17,6 +17,7 @@ const decimal_js_1 = __importDefault(require("decimal.js"));
17
17
  const accounts_1 = require("../idl_codegen/accounts");
18
18
  const bn_js_1 = __importDefault(require("bn.js"));
19
19
  const fraction_1 = require("./fraction");
20
+ const types_1 = require("../idl_codegen/types");
20
21
  const utils_1 = require("./utils");
21
22
  const utils_2 = require("../utils");
22
23
  class KaminoObligation {
@@ -39,7 +40,7 @@ class KaminoObligation {
39
40
  };
40
41
  this.obligationAddress = obligationAddress;
41
42
  this.state = obligation;
42
- const { borrows, deposits, refreshedStats } = this.calculatePositions(market, obligation, collateralExchangeRates, cumulativeBorrowRates);
43
+ const { borrows, deposits, refreshedStats } = this.calculatePositions(market, obligation.deposits, obligation.borrows, obligation.elevationGroup, collateralExchangeRates, cumulativeBorrowRates);
43
44
  this.deposits = deposits;
44
45
  this.borrows = borrows;
45
46
  this.refreshedStats = refreshedStats;
@@ -195,21 +196,6 @@ class KaminoObligation {
195
196
  getNetAccountValue() {
196
197
  return this.refreshedStats.netAccountValue;
197
198
  }
198
- /**
199
- * 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
200
- * @param market
201
- * @param reserve
202
- */
203
- getLtvForReserve(market, reserve) {
204
- return KaminoObligation.getLtvForReserve(market, reserve, this.state.elevationGroup);
205
- }
206
- /**
207
- * Get the borrow factor for a borrow reserve, accounting for the obligation elevation group if it is active
208
- * @param reserve
209
- */
210
- getBorrowFactorForReserve(reserve) {
211
- return KaminoObligation.getBorrowFactorForReserve(reserve, this.state.elevationGroup);
212
- }
213
199
  /**
214
200
  * @returns the potential elevation groups the obligation qualifies for
215
201
  */
@@ -250,141 +236,85 @@ class KaminoObligation {
250
236
  }
251
237
  return activeElevationGroups;
252
238
  }
253
- calculateSimulatedBorrow(oldStats, oldBorrows, borrowAmount, mint, reserves) {
254
- const newStats = Object.assign({}, oldStats);
255
- const newBorrows = new utils_2.PubkeyHashMap([...oldBorrows.entries()]);
256
- let borrowPosition = undefined;
257
- for (const oldBorrow of oldBorrows.values()) {
258
- if (oldBorrow.mintAddress.equals(mint)) {
259
- borrowPosition = Object.assign({}, oldBorrow);
239
+ simulateDepositChange(obligationDeposits, changeInLamports, changeReserve, collateralExchangeRates) {
240
+ const newDeposits = [];
241
+ for (let i = 0; i < obligationDeposits.length; i++) {
242
+ if (obligationDeposits[i].depositReserve.equals(changeReserve)) {
243
+ const coll = Object.assign({}, obligationDeposits[i]);
244
+ const exchangeRate = collateralExchangeRates.get(changeReserve);
245
+ const changeInCollateral = new decimal_js_1.default(changeInLamports).mul(exchangeRate);
246
+ const updatedDeposit = new decimal_js_1.default(obligationDeposits[i].depositedAmount.toNumber()).add(changeInCollateral);
247
+ coll.depositedAmount = new bn_js_1.default((0, utils_1.positiveOrZero)(updatedDeposit).toString());
248
+ newDeposits.push(new types_1.ObligationCollateral(coll));
260
249
  }
261
- }
262
- let reserve = undefined;
263
- for (const kaminoReserve of reserves.values()) {
264
- if (kaminoReserve.getLiquidityMint().equals(mint)) {
265
- reserve = kaminoReserve;
250
+ else {
251
+ newDeposits.push(obligationDeposits[i]);
266
252
  }
267
253
  }
268
- if (!reserve) {
269
- throw new Error(`No reserve found for mint ${mint}`);
270
- }
271
- if (!borrowPosition) {
272
- borrowPosition = {
273
- reserveAddress: reserve.address,
274
- mintAddress: mint,
275
- amount: new decimal_js_1.default(0),
276
- marketValueRefreshed: new decimal_js_1.default(0),
277
- };
278
- }
279
- if (!reserve.state.config.elevationGroups.includes(this.state.elevationGroup)) {
280
- throw new Error(`User would have to downgrade the elevation group in order to be able to borrow from this reserve`);
281
- }
282
- const borrowFactor = this.getBorrowFactorForReserve(reserve);
283
- const borrowValueUSD = borrowAmount.mul(reserve.getOracleMarketPrice()).dividedBy(reserve.getMintFactor());
284
- const borrowValueBorrowFactorAdjustedUSD = borrowValueUSD.mul(borrowFactor);
285
- newStats.userTotalBorrow = (0, utils_1.positiveOrZero)(newStats.userTotalBorrow.plus(borrowValueUSD));
286
- newStats.userTotalBorrowBorrowFactorAdjusted = (0, utils_1.positiveOrZero)(newStats.userTotalBorrowBorrowFactorAdjusted.plus(borrowValueBorrowFactorAdjustedUSD));
287
- borrowPosition.amount = (0, utils_1.positiveOrZero)(borrowPosition.amount.plus(borrowAmount));
288
- borrowPosition.mintAddress = mint;
289
- borrowPosition.marketValueRefreshed = (0, utils_1.positiveOrZero)(borrowPosition.marketValueRefreshed.plus(borrowValueUSD));
290
- newBorrows.set(borrowPosition.reserveAddress, borrowPosition);
291
- return {
292
- borrows: newBorrows,
293
- stats: newStats,
294
- };
254
+ return newDeposits;
295
255
  }
296
- calculateSimulatedDeposit(oldStats, oldDeposits, amount, mint, reserves, market) {
297
- const newStats = Object.assign({}, oldStats);
298
- const newDeposits = new utils_2.PubkeyHashMap([...oldDeposits.entries()]);
299
- let depositPosition = undefined;
300
- for (const oldDeposit of oldDeposits.values()) {
301
- if (oldDeposit.mintAddress.equals(mint)) {
302
- depositPosition = Object.assign({}, oldDeposit);
256
+ simulateBorrowChange(obligationBorrows, changeInLamports, changeReserve) {
257
+ const newBorrows = [];
258
+ for (let i = 0; i < obligationBorrows.length; i++) {
259
+ if (obligationBorrows[i].borrowReserve.equals(changeReserve)) {
260
+ const borrow = Object.assign({}, obligationBorrows[i]);
261
+ const newBorrowedAmount = new fraction_1.Fraction(borrow.borrowedAmountSf).toDecimal().add(changeInLamports);
262
+ const newBorrowedAmountSf = fraction_1.Fraction.fromDecimal((0, utils_1.positiveOrZero)(newBorrowedAmount)).getValue();
263
+ borrow.borrowedAmountSf = newBorrowedAmountSf;
264
+ newBorrows.push(new types_1.ObligationLiquidity(borrow));
303
265
  }
304
- }
305
- let reserve = undefined;
306
- for (const kaminoReserve of reserves.values()) {
307
- if (kaminoReserve.getLiquidityMint().equals(mint)) {
308
- reserve = kaminoReserve;
266
+ else {
267
+ newBorrows.push(obligationBorrows[i]);
309
268
  }
310
269
  }
311
- if (!reserve) {
312
- throw new Error(`No reserve found for mint ${mint}`);
313
- }
314
- if (!depositPosition) {
315
- depositPosition = {
316
- reserveAddress: reserve.address,
317
- mintAddress: mint,
318
- amount: new decimal_js_1.default(0),
319
- marketValueRefreshed: new decimal_js_1.default(0),
320
- };
321
- }
322
- if (!reserve.state.config.elevationGroups.includes(this.state.elevationGroup)) {
323
- throw new Error(`User would have to downgrade the elevation group in order to be able to deposit in this reserve`);
324
- }
325
- const { maxLtv, liquidationLtv } = this.getLtvForReserve(market, reserve);
326
- const supplyAmount = amount; //.mul(reserve.getCollateralExchangeRate()).floor();
327
- const supplyAmountMultiplierUSD = supplyAmount
328
- .mul(reserve.getOracleMarketPrice())
329
- .dividedBy('1'.concat(Array(reserve.stats.decimals + 1).join('0')));
330
- newStats.userTotalDeposit = (0, utils_1.positiveOrZero)(newStats.userTotalDeposit.plus(supplyAmountMultiplierUSD));
331
- newStats.borrowLimit = (0, utils_1.positiveOrZero)(newStats.borrowLimit.plus(supplyAmountMultiplierUSD.mul(maxLtv)));
332
- newStats.borrowLiquidationLimit = (0, utils_1.positiveOrZero)(newStats.borrowLiquidationLimit.plus(supplyAmountMultiplierUSD.mul(liquidationLtv)));
333
- newStats.liquidationLtv = (0, utils_1.valueOrZero)(newStats.borrowLiquidationLimit.div(newStats.userTotalDeposit));
334
- depositPosition.amount = (0, utils_1.positiveOrZero)(depositPosition.amount.plus(amount));
335
- depositPosition.mintAddress = mint;
336
- depositPosition.marketValueRefreshed = (0, utils_1.positiveOrZero)(depositPosition.marketValueRefreshed.plus(supplyAmount.mul(reserve.getOracleMarketPrice()).dividedBy(reserve.getMintFactor())));
337
- newDeposits.set(depositPosition.reserveAddress, depositPosition);
338
- return {
339
- deposits: newDeposits,
340
- stats: newStats,
341
- };
270
+ return newBorrows;
342
271
  }
343
272
  /**
344
273
  * Calculate the newly modified stats of the obligation
345
274
  */
346
- // TODO: Elevation group problems
347
275
  // TODO: Shall we set up position limits?
348
276
  getSimulatedObligationStats(params) {
349
- const { amountCollateral, amountDebt, action, mintCollateral, mintDebt, market, reserves } = params;
277
+ var _a;
278
+ const { amountCollateral, amountDebt, action, mintCollateral, mintDebt, market } = params;
350
279
  let newStats = Object.assign({}, this.refreshedStats);
280
+ const { collateralExchangeRates, cumulativeBorrowRates } = KaminoObligation.getRatesForObligation(market, this.state, params.slot);
281
+ const elevationGroup = (_a = params.elevationGroupOverride) !== null && _a !== void 0 ? _a : this.state.elevationGroup;
351
282
  let newDeposits = new utils_2.PubkeyHashMap([...this.deposits.entries()]);
352
283
  let newBorrows = new utils_2.PubkeyHashMap([...this.borrows.entries()]);
284
+ // Any action can impact both deposit stats and borrow stats if elevation group is changed
285
+ // so we have to recalculate the entire position, not just an updated deposit or borrow
286
+ // as both LTVs and borrow factors can change, affecting all calcs
287
+ const collateralReserve = mintCollateral ? market.getReserveByMint(mintCollateral).address : undefined;
288
+ const debtReserve = mintDebt ? market.getReserveByMint(mintDebt).address : undefined;
289
+ let newObligationDeposits = this.state.deposits;
290
+ let newObligationBorrows = this.state.borrows;
353
291
  switch (action) {
354
292
  case 'deposit': {
355
293
  if (amountCollateral === undefined || mintCollateral === undefined) {
356
294
  throw Error('amountCollateral & mintCollateral are required for deposit action');
357
295
  }
358
- const { stats, deposits } = this.calculateSimulatedDeposit(this.refreshedStats, this.deposits, amountCollateral, mintCollateral, reserves, market);
359
- newStats = stats;
360
- newDeposits = deposits;
296
+ newObligationDeposits = this.simulateDepositChange(this.state.deposits, amountCollateral.toNumber(), collateralReserve, collateralExchangeRates);
361
297
  break;
362
298
  }
363
299
  case 'borrow': {
364
300
  if (amountDebt === undefined || mintDebt === undefined) {
365
301
  throw Error('amountDebt & mintDebt are required for borrow action');
366
302
  }
367
- const { stats, borrows } = this.calculateSimulatedBorrow(this.refreshedStats, this.borrows, amountDebt, mintDebt, reserves);
368
- newStats = stats;
369
- newBorrows = borrows;
303
+ newObligationBorrows = this.simulateBorrowChange(this.state.borrows, amountDebt.toNumber(), debtReserve);
370
304
  break;
371
305
  }
372
306
  case 'repay': {
373
307
  if (amountDebt === undefined || mintDebt === undefined) {
374
308
  throw Error('amountDebt & mintDebt are required for repay action');
375
309
  }
376
- const { stats, borrows } = this.calculateSimulatedBorrow(this.refreshedStats, this.borrows, new decimal_js_1.default(amountDebt).neg(), mintDebt, reserves);
377
- newStats = stats;
378
- newBorrows = borrows;
310
+ newObligationBorrows = this.simulateBorrowChange(this.state.borrows, amountDebt.neg().toNumber(), debtReserve);
379
311
  break;
380
312
  }
381
313
  case 'withdraw': {
382
314
  if (amountCollateral === undefined || mintCollateral === undefined) {
383
315
  throw Error('amountCollateral & mintCollateral are required for withdraw action');
384
316
  }
385
- const { stats, deposits } = this.calculateSimulatedDeposit(this.refreshedStats, this.deposits, new decimal_js_1.default(amountCollateral).neg(), mintCollateral, reserves, market);
386
- newStats = stats;
387
- newDeposits = deposits;
317
+ newObligationDeposits = this.simulateDepositChange(this.state.deposits, amountCollateral.neg().toNumber(), collateralReserve, collateralExchangeRates);
388
318
  break;
389
319
  }
390
320
  case 'depositAndBorrow': {
@@ -394,11 +324,8 @@ class KaminoObligation {
394
324
  mintDebt === undefined) {
395
325
  throw Error('amountColl & amountDebt & mintCollateral & mintDebt are required for depositAndBorrow action');
396
326
  }
397
- const { stats: statsAfterDeposit, deposits } = this.calculateSimulatedDeposit(this.refreshedStats, this.deposits, amountCollateral, mintCollateral, reserves, market);
398
- const { stats, borrows } = this.calculateSimulatedBorrow(statsAfterDeposit, this.borrows, amountDebt, mintDebt, reserves);
399
- newStats = stats;
400
- newDeposits = deposits;
401
- newBorrows = borrows;
327
+ newObligationDeposits = this.simulateDepositChange(this.state.deposits, amountCollateral.toNumber(), collateralReserve, collateralExchangeRates);
328
+ newObligationBorrows = this.simulateBorrowChange(this.state.borrows, amountDebt.toNumber(), debtReserve);
402
329
  break;
403
330
  }
404
331
  case 'repayAndWithdraw': {
@@ -408,17 +335,18 @@ class KaminoObligation {
408
335
  mintDebt === undefined) {
409
336
  throw Error('amountColl & amountDebt & mintCollateral & mintDebt are required for repayAndWithdraw action');
410
337
  }
411
- const { stats: statsAfterRepay, borrows } = this.calculateSimulatedBorrow(this.refreshedStats, this.borrows, new decimal_js_1.default(amountDebt).neg(), mintDebt, reserves);
412
- const { stats: statsAfterWithdraw, deposits } = this.calculateSimulatedDeposit(statsAfterRepay, this.deposits, new decimal_js_1.default(amountCollateral).neg(), mintCollateral, reserves, market);
413
- newStats = statsAfterWithdraw;
414
- newDeposits = deposits;
415
- newBorrows = borrows;
338
+ newObligationDeposits = this.simulateDepositChange(this.state.deposits, amountCollateral.neg().toNumber(), collateralReserve, collateralExchangeRates);
339
+ newObligationBorrows = this.simulateBorrowChange(this.state.borrows, amountDebt.neg().toNumber(), debtReserve);
416
340
  break;
417
341
  }
418
342
  default: {
419
343
  throw Error(`Invalid action type ${action} for getSimulatedObligationStats`);
420
344
  }
421
345
  }
346
+ const { borrows, deposits, refreshedStats } = this.calculatePositions(market, newObligationDeposits, newObligationBorrows, elevationGroup, collateralExchangeRates, cumulativeBorrowRates);
347
+ newStats = refreshedStats;
348
+ newDeposits = deposits;
349
+ newBorrows = borrows;
422
350
  newStats.netAccountValue = newStats.userTotalDeposit.minus(newStats.userTotalBorrow);
423
351
  newStats.loanToValue = (0, utils_1.valueOrZero)(newStats.userTotalBorrowBorrowFactorAdjusted.dividedBy(newStats.userTotalDeposit));
424
352
  newStats.leverage = (0, utils_1.valueOrZero)(newStats.userTotalDeposit.dividedBy(newStats.netAccountValue));
@@ -428,17 +356,12 @@ class KaminoObligation {
428
356
  borrows: newBorrows,
429
357
  };
430
358
  }
431
- calculateDeposits(market, obligation, collateralExchangeRates, getPx) {
432
- return KaminoObligation.calculateObligationDeposits(market, obligation, collateralExchangeRates, obligation.elevationGroup, getPx);
433
- }
434
- calculateBorrows(market, obligation, cumulativeBorrowRates, getPx) {
435
- return KaminoObligation.calculateObligationBorrows(market, obligation, cumulativeBorrowRates, obligation.elevationGroup, getPx);
436
- }
437
- calculatePositions(market, obligation, collateralExchangeRates, cumulativeBorrowRates) {
359
+ calculatePositions(market, obligationDeposits, obligationBorrows, elevationGroup, collateralExchangeRates, cumulativeBorrowRates) {
438
360
  const getOraclePx = (reserve) => reserve.getOracleMarketPrice();
439
- const depositStatsOraclePrice = this.calculateDeposits(market, obligation, collateralExchangeRates, getOraclePx);
440
- const borrowStatsOraclePrice = this.calculateBorrows(market, obligation, cumulativeBorrowRates, getOraclePx);
361
+ const depositStatsOraclePrice = KaminoObligation.calculateObligationDeposits(market, obligationDeposits, collateralExchangeRates, elevationGroup, getOraclePx);
362
+ const borrowStatsOraclePrice = KaminoObligation.calculateObligationBorrows(market, obligationBorrows, cumulativeBorrowRates, elevationGroup, getOraclePx);
441
363
  const netAccountValueScopeRefreshed = depositStatsOraclePrice.userTotalDeposit.minus(borrowStatsOraclePrice.userTotalBorrow);
364
+ // TODO: Fix this?
442
365
  const potentialElevationGroupUpdate = 0;
443
366
  return {
444
367
  deposits: depositStatsOraclePrice.deposits,
@@ -458,17 +381,17 @@ class KaminoObligation {
458
381
  },
459
382
  };
460
383
  }
461
- static calculateObligationDeposits(market, obligation, collateralExchangeRates, elevationGroup, getPx) {
384
+ static calculateObligationDeposits(market, obligationDeposits, collateralExchangeRates, elevationGroup, getPx) {
462
385
  let userTotalDeposit = new decimal_js_1.default(0);
463
386
  let userTotalCollateralDeposit = new decimal_js_1.default(0);
464
387
  let borrowLimit = new decimal_js_1.default(0);
465
388
  let borrowLiquidationLimit = new decimal_js_1.default(0);
466
389
  const deposits = new utils_2.PubkeyHashMap();
467
- for (let i = 0; i < obligation.deposits.length; i++) {
468
- if (!(0, utils_2.isNotNullPubkey)(obligation.deposits[i].depositReserve)) {
390
+ for (let i = 0; i < obligationDeposits.length; i++) {
391
+ if (!(0, utils_2.isNotNullPubkey)(obligationDeposits[i].depositReserve)) {
469
392
  continue;
470
393
  }
471
- const deposit = obligation.deposits[i];
394
+ const deposit = obligationDeposits[i];
472
395
  const reserve = market.getReserveByAddress(deposit.depositReserve);
473
396
  if (!reserve) {
474
397
  throw new Error(`Obligation contains a deposit belonging to reserve: ${deposit.depositReserve} but the reserve was not found on the market. Deposit amount: ${deposit.depositedAmount}`);
@@ -506,16 +429,16 @@ class KaminoObligation {
506
429
  borrowLiquidationLimit,
507
430
  };
508
431
  }
509
- static calculateObligationBorrows(market, obligation, cumulativeBorrowRates, elevationGroup, getPx) {
432
+ static calculateObligationBorrows(market, obligationBorrows, cumulativeBorrowRates, elevationGroup, getPx) {
510
433
  let userTotalBorrow = new decimal_js_1.default(0);
511
434
  let userTotalBorrowBorrowFactorAdjusted = new decimal_js_1.default(0);
512
435
  let positions = 0;
513
436
  const borrows = new utils_2.PubkeyHashMap();
514
- for (let i = 0; i < obligation.borrows.length; i++) {
515
- if (!(0, utils_2.isNotNullPubkey)(obligation.borrows[i].borrowReserve)) {
437
+ for (let i = 0; i < obligationBorrows.length; i++) {
438
+ if (!(0, utils_2.isNotNullPubkey)(obligationBorrows[i].borrowReserve)) {
516
439
  continue;
517
440
  }
518
- const borrow = obligation.borrows[i];
441
+ const borrow = obligationBorrows[i];
519
442
  const reserve = market.getReserveByAddress(borrow.borrowReserve);
520
443
  if (!reserve) {
521
444
  throw new Error(`Obligation contains a borrow belonging to reserve: ${borrow.borrowReserve} but the reserve was not found on the market. Borrow amount: ${KaminoObligation.getBorrowAmount(borrow)}`);
@@ -557,7 +480,7 @@ class KaminoObligation {
557
480
  getMaxLoanLtvGivenElevationGroup(market, elevationGroup, slot) {
558
481
  const getOraclePx = (reserve) => reserve.getOracleMarketPrice();
559
482
  const { collateralExchangeRates } = KaminoObligation.getRatesForObligation(market, this.state, slot);
560
- const { borrowLimit, userTotalDeposit } = KaminoObligation.calculateObligationDeposits(market, this.state, collateralExchangeRates, elevationGroup, getOraclePx);
483
+ const { borrowLimit, userTotalDeposit } = KaminoObligation.calculateObligationDeposits(market, this.state.deposits, collateralExchangeRates, elevationGroup, getOraclePx);
561
484
  if (borrowLimit.eq(0) || userTotalDeposit.eq(0)) {
562
485
  return new decimal_js_1.default(0);
563
486
  }
@@ -587,8 +510,8 @@ class KaminoObligation {
587
510
  const borrowFactor = KaminoObligation.getBorrowFactorForReserve(reserve, elevationGroup);
588
511
  const getOraclePx = (reserve) => reserve.getOracleMarketPrice();
589
512
  const { collateralExchangeRates, cumulativeBorrowRates } = KaminoObligation.getRatesForObligation(market, this.state, slot);
590
- const { borrowLimit } = KaminoObligation.calculateObligationDeposits(market, this.state, collateralExchangeRates, elevationGroup, getOraclePx);
591
- const { userTotalBorrowBorrowFactorAdjusted } = KaminoObligation.calculateObligationBorrows(market, this.state, cumulativeBorrowRates, elevationGroup, getOraclePx);
513
+ const { borrowLimit } = KaminoObligation.calculateObligationDeposits(market, this.state.deposits, collateralExchangeRates, elevationGroup, getOraclePx);
514
+ const { userTotalBorrowBorrowFactorAdjusted } = KaminoObligation.calculateObligationBorrows(market, this.state.borrows, cumulativeBorrowRates, elevationGroup, getOraclePx);
592
515
  const maxObligationBorrowPower = borrowLimit // adjusted available amount
593
516
  .minus(userTotalBorrowBorrowFactorAdjusted)
594
517
  .div(borrowFactor)
@@ -671,7 +594,7 @@ class KaminoObligation {
671
594
  // Check if the loan can be migrated based on LTV
672
595
  const getOraclePx = (reserve) => reserve.getOracleMarketPrice();
673
596
  const { collateralExchangeRates } = KaminoObligation.getRatesForObligation(market, this.state, slot);
674
- const { borrowLimit } = KaminoObligation.calculateObligationDeposits(market, this.state, collateralExchangeRates, elevationGroup, getOraclePx);
597
+ const { borrowLimit } = KaminoObligation.calculateObligationDeposits(market, this.state.deposits, collateralExchangeRates, elevationGroup, getOraclePx);
675
598
  const isEligibleBasedOnLtv = this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.lte(borrowLimit);
676
599
  return isEligibleBasedOnLtv;
677
600
  }
@@ -722,7 +645,7 @@ class KaminoObligation {
722
645
  }
723
646
  }
724
647
  const elevationGroupActivated = reserve.state.config.elevationGroups.includes(elevationGroup) && elevationGroup !== 0;
725
- const borrowFactor = this.getBorrowFactorForReserve(reserve);
648
+ const borrowFactor = KaminoObligation.getBorrowFactorForReserve(reserve, elevationGroup);
726
649
  const maxObligationBorrowPower = this.refreshedStats.borrowLimit // adjusted available amount
727
650
  .minus(this.refreshedStats.userTotalBorrowBorrowFactorAdjusted)
728
651
  .div(borrowFactor)
@@ -794,7 +717,7 @@ class KaminoObligation {
794
717
  if (this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.equals(new decimal_js_1.default(0))) {
795
718
  return new decimal_js_1.default(userDepositPositionAmount);
796
719
  }
797
- const { maxLtv: reserveMaxLtv } = this.getLtvForReserve(market, depositReserve);
720
+ const { maxLtv: reserveMaxLtv } = KaminoObligation.getLtvForReserve(market, depositReserve, this.state.elevationGroup);
798
721
  // bf adjusted debt value > allowed_borrow_value
799
722
  if (this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.gte(this.refreshedStats.borrowLimit)) {
800
723
  return new decimal_js_1.default(0);