@kamino-finance/klend-sdk 4.0.1 → 4.0.2

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.
@@ -372,19 +372,31 @@ export class KaminoObligation {
372
372
  simulateBorrowChange(
373
373
  obligationBorrows: ObligationLiquidity[],
374
374
  changeInLamports: number,
375
- changeReserve: PublicKey
375
+ changeReserve: PublicKey,
376
+ cumulativeBorrowRate: Decimal
376
377
  ): ObligationLiquidity[] {
377
378
  const newBorrows: ObligationLiquidity[] = [];
378
- for (let i = 0; i < obligationBorrows.length; i++) {
379
- if (obligationBorrows[i].borrowReserve.equals(changeReserve)) {
380
- const borrow: ObligationLiquidityFields = { ...obligationBorrows[i] };
381
- const newBorrowedAmount: Decimal = new Fraction(borrow.borrowedAmountSf).toDecimal().add(changeInLamports);
382
- const newBorrowedAmountSf = Fraction.fromDecimal(positiveOrZero(newBorrowedAmount)).getValue();
383
- borrow.borrowedAmountSf = newBorrowedAmountSf;
384
- newBorrows.push(new ObligationLiquidity(borrow));
385
- } else {
386
- newBorrows.push(obligationBorrows[i]);
387
- }
379
+ const borrowIndex = obligationBorrows.findIndex((borrow) => borrow.borrowReserve.equals(changeReserve));
380
+
381
+ if (borrowIndex !== -1) {
382
+ const borrow: ObligationLiquidityFields = { ...obligationBorrows[borrowIndex] };
383
+ const newBorrowedAmount: Decimal = new Fraction(borrow.borrowedAmountSf).toDecimal().add(changeInLamports);
384
+ const newBorrowedAmountSf = Fraction.fromDecimal(positiveOrZero(newBorrowedAmount)).getValue();
385
+ borrow.borrowedAmountSf = newBorrowedAmountSf;
386
+ newBorrows.push(new ObligationLiquidity(borrow));
387
+ } else {
388
+ const firstBorrowIndexAvailable = obligationBorrows.findIndex((borrow) =>
389
+ borrow.borrowReserve.equals(PublicKey.default)
390
+ );
391
+
392
+ const borrow: ObligationLiquidityFields = { ...obligationBorrows[firstBorrowIndexAvailable] };
393
+ borrow.borrowedAmountSf = Fraction.fromDecimal(new Decimal(changeInLamports)).getValue();
394
+ borrow.borrowReserve = changeReserve;
395
+ borrow.cumulativeBorrowRateBsf = {
396
+ padding: [],
397
+ value: [Fraction.fromDecimal(cumulativeBorrowRate).getValue(), new BN(0), new BN(0), new BN(0)],
398
+ };
399
+ newBorrows.push(new ObligationLiquidity(borrow));
388
400
  }
389
401
 
390
402
  return newBorrows;
@@ -412,11 +424,7 @@ export class KaminoObligation {
412
424
  const { amountCollateral, amountDebt, action, mintCollateral, mintDebt, market } = params;
413
425
  let newStats = { ...this.refreshedStats };
414
426
 
415
- const { collateralExchangeRates, cumulativeBorrowRates } = KaminoObligation.getRatesForObligation(
416
- market,
417
- this.state,
418
- params.slot
419
- );
427
+ const { collateralExchangeRates } = KaminoObligation.getRatesForObligation(market, this.state, params.slot);
420
428
 
421
429
  const elevationGroup = params.elevationGroupOverride ?? this.state.elevationGroup;
422
430
 
@@ -427,8 +435,11 @@ export class KaminoObligation {
427
435
  // so we have to recalculate the entire position, not just an updated deposit or borrow
428
436
  // as both LTVs and borrow factors can change, affecting all calcs
429
437
 
430
- const collateralReserve = mintCollateral ? market.getReserveByMint(mintCollateral)!.address : undefined;
431
- const debtReserve = mintDebt ? market.getReserveByMint(mintDebt)!.address : undefined;
438
+ const collateralReservePk = mintCollateral ? market.getReserveByMint(mintCollateral)!.address : undefined;
439
+ const debtReservePk = mintDebt ? market.getReserveByMint(mintDebt)!.address : undefined;
440
+ const debtReserveCumulativeBorrowRate = mintDebt
441
+ ? market.getReserveByMint(mintDebt)!.getCumulativeBorrowRate()
442
+ : undefined;
432
443
 
433
444
  let newObligationDeposits = this.state.deposits;
434
445
  let newObligationBorrows = this.state.borrows;
@@ -441,7 +452,7 @@ export class KaminoObligation {
441
452
  newObligationDeposits = this.simulateDepositChange(
442
453
  this.state.deposits,
443
454
  amountCollateral.toNumber(),
444
- collateralReserve!,
455
+ collateralReservePk!,
445
456
  collateralExchangeRates
446
457
  );
447
458
  break;
@@ -451,14 +462,25 @@ export class KaminoObligation {
451
462
  throw Error('amountDebt & mintDebt are required for borrow action');
452
463
  }
453
464
 
454
- newObligationBorrows = this.simulateBorrowChange(this.state.borrows, amountDebt.toNumber(), debtReserve!);
465
+ newObligationBorrows = this.simulateBorrowChange(
466
+ this.state.borrows,
467
+ amountDebt.toNumber(),
468
+ debtReservePk!,
469
+ debtReserveCumulativeBorrowRate!
470
+ );
455
471
  break;
456
472
  }
457
473
  case 'repay': {
458
474
  if (amountDebt === undefined || mintDebt === undefined) {
459
475
  throw Error('amountDebt & mintDebt are required for repay action');
460
476
  }
461
- newObligationBorrows = this.simulateBorrowChange(this.state.borrows, amountDebt.neg().toNumber(), debtReserve!);
477
+
478
+ newObligationBorrows = this.simulateBorrowChange(
479
+ this.state.borrows,
480
+ amountDebt.neg().toNumber(),
481
+ debtReservePk!,
482
+ debtReserveCumulativeBorrowRate!
483
+ );
462
484
 
463
485
  break;
464
486
  }
@@ -470,7 +492,7 @@ export class KaminoObligation {
470
492
  newObligationDeposits = this.simulateDepositChange(
471
493
  this.state.deposits,
472
494
  amountCollateral.neg().toNumber(),
473
- collateralReserve!,
495
+ collateralReservePk!,
474
496
  collateralExchangeRates
475
497
  );
476
498
  break;
@@ -487,10 +509,16 @@ export class KaminoObligation {
487
509
  newObligationDeposits = this.simulateDepositChange(
488
510
  this.state.deposits,
489
511
  amountCollateral.toNumber(),
490
- collateralReserve!,
512
+ collateralReservePk!,
491
513
  collateralExchangeRates
492
514
  );
493
- newObligationBorrows = this.simulateBorrowChange(this.state.borrows, amountDebt.toNumber(), debtReserve!);
515
+
516
+ newObligationBorrows = this.simulateBorrowChange(
517
+ this.state.borrows,
518
+ amountDebt.toNumber(),
519
+ debtReservePk!,
520
+ debtReserveCumulativeBorrowRate!
521
+ );
494
522
  break;
495
523
  }
496
524
  case 'repayAndWithdraw': {
@@ -505,10 +533,15 @@ export class KaminoObligation {
505
533
  newObligationDeposits = this.simulateDepositChange(
506
534
  this.state.deposits,
507
535
  amountCollateral.neg().toNumber(),
508
- collateralReserve!,
536
+ collateralReservePk!,
509
537
  collateralExchangeRates
510
538
  );
511
- newObligationBorrows = this.simulateBorrowChange(this.state.borrows, amountDebt.neg().toNumber(), debtReserve!);
539
+ newObligationBorrows = this.simulateBorrowChange(
540
+ this.state.borrows,
541
+ amountDebt.neg().toNumber(),
542
+ debtReservePk!,
543
+ debtReserveCumulativeBorrowRate!
544
+ );
512
545
  break;
513
546
  }
514
547
  default: {
@@ -522,7 +555,7 @@ export class KaminoObligation {
522
555
  newObligationBorrows,
523
556
  elevationGroup,
524
557
  collateralExchangeRates,
525
- cumulativeBorrowRates
558
+ null
526
559
  );
527
560
 
528
561
  newStats = refreshedStats;
@@ -568,7 +601,7 @@ export class KaminoObligation {
568
601
  obligationBorrows: ObligationLiquidity[],
569
602
  elevationGroup: number,
570
603
  collateralExchangeRates: Map<PublicKey, Decimal>,
571
- cumulativeBorrowRates: Map<PublicKey, Decimal>
604
+ cumulativeBorrowRates: Map<PublicKey, Decimal> | null
572
605
  ): {
573
606
  borrows: Map<PublicKey, Position>;
574
607
  deposits: Map<PublicKey, Position>;
@@ -904,8 +937,8 @@ export class KaminoObligation {
904
937
  // - [x] due to collateral / debt reserves combination
905
938
  // - [x] due to LTV, etc
906
939
 
907
- const reserveDeposits: string[] = Array.from(this.deposits.keys()).map((x) => x.toString());
908
- const reserveBorrows: string[] = Array.from(this.borrows.keys()).map((x) => x.toString());
940
+ const reserveDeposits: PublicKey[] = Array.from(this.deposits.keys());
941
+ const reserveBorrows: PublicKey[] = Array.from(this.borrows.keys());
909
942
 
910
943
  if (reserveBorrows.length > 1) {
911
944
  return false;
@@ -918,11 +951,11 @@ export class KaminoObligation {
918
951
 
919
952
  // Has to be a subset
920
953
  const allCollsIncluded = reserveDeposits.every((reserve) =>
921
- elevationGroupDescription.collateralReserves.includes(reserve)
954
+ elevationGroupDescription.collateralReserves.contains(reserve)
922
955
  );
923
956
  const allDebtsIncluded =
924
957
  reserveBorrows.length === 0 ||
925
- (reserveBorrows.length === 1 && elevationGroupDescription.debtReserve === reserveBorrows[0]);
958
+ (reserveBorrows.length === 1 && elevationGroupDescription.debtReserve.equals(reserveBorrows[0]));
926
959
 
927
960
  if (!allCollsIncluded || !allDebtsIncluded) {
928
961
  return false;
@@ -935,9 +935,9 @@ export class KaminoReserve {
935
935
  currentValue: Decimal;
936
936
  }[] = market
937
937
  .getMarketElevationGroupDescriptions()
938
- .filter((x) => x.debtReserve === this.address.toString())
938
+ .filter((x) => x.debtReserve.equals(this.address))
939
939
  .map((elevationGroupDescription: ElevationGroupDescription) =>
940
- elevationGroupDescription.collateralReserves.map((collateralReserveAddress) => {
940
+ elevationGroupDescription.collateralReserves.toArray().map((collateralReserveAddress) => {
941
941
  const collRes = market.reserves.get(new PublicKey(collateralReserveAddress))!;
942
942
 
943
943
  const debtLimitAgainstThisCollInGroup =
@@ -1015,14 +1015,15 @@ export class KaminoReserve {
1015
1015
  positiveOrZero(remainingGlobalCap),
1016
1016
  positiveOrZero(liquidityGivenUtilizationCap)
1017
1017
  );
1018
-
1019
1018
  return availableInCrossMode;
1020
1019
  } else {
1021
- const remainingInsideEmodeCaps = Decimal.min(
1022
- ...caps.debtAgainstCollateralReserveCaps
1023
- .filter((x) => x.elevationGroup === elevationGroup)
1024
- .map((x) => x.maxDebt.minus(x.currentValue))
1020
+ let remainingInsideEmodeCaps = new Decimal(0);
1021
+ const capsGivenEgroup = caps.debtAgainstCollateralReserveCaps.filter(
1022
+ (x) => x.elevationGroup === elevationGroup
1025
1023
  );
1024
+ if (capsGivenEgroup.length > 0) {
1025
+ remainingInsideEmodeCaps = Decimal.min(...capsGivenEgroup.map((x) => x.maxDebt.minus(x.currentValue)));
1026
+ }
1026
1027
  return Decimal.min(
1027
1028
  positiveOrZero(liquidityAvailable),
1028
1029
  positiveOrZero(remainingInsideEmodeCaps),