@kamino-finance/klend-sdk 5.13.21-beta.0 → 5.13.21

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.
Files changed (128) hide show
  1. package/dist/classes/farm_utils.d.ts.map +1 -1
  2. package/dist/classes/farm_utils.js +10 -3
  3. package/dist/classes/farm_utils.js.map +1 -1
  4. package/dist/classes/manager.d.ts +12 -5
  5. package/dist/classes/manager.d.ts.map +1 -1
  6. package/dist/classes/manager.js +300 -39
  7. package/dist/classes/manager.js.map +1 -1
  8. package/dist/classes/obligation.d.ts.map +1 -1
  9. package/dist/classes/obligation.js +0 -14
  10. package/dist/classes/obligation.js.map +1 -1
  11. package/dist/classes/reserve.d.ts +14 -5
  12. package/dist/classes/reserve.d.ts.map +1 -1
  13. package/dist/classes/reserve.js +463 -91
  14. package/dist/classes/reserve.js.map +1 -1
  15. package/dist/classes/utils.d.ts +0 -1
  16. package/dist/classes/utils.d.ts.map +1 -1
  17. package/dist/classes/utils.js +0 -12
  18. package/dist/classes/utils.js.map +1 -1
  19. package/dist/classes/vault.d.ts +2 -1
  20. package/dist/classes/vault.d.ts.map +1 -1
  21. package/dist/classes/vault.js +9 -5
  22. package/dist/classes/vault.js.map +1 -1
  23. package/dist/client_kamino_manager.d.ts.map +1 -1
  24. package/dist/client_kamino_manager.js +26 -27
  25. package/dist/client_kamino_manager.js.map +1 -1
  26. package/dist/idl.json +9 -186
  27. package/dist/idl_codegen/accounts/LendingMarket.d.ts +3 -24
  28. package/dist/idl_codegen/accounts/LendingMarket.d.ts.map +1 -1
  29. package/dist/idl_codegen/accounts/LendingMarket.js +7 -25
  30. package/dist/idl_codegen/accounts/LendingMarket.js.map +1 -1
  31. package/dist/idl_codegen/accounts/index.d.ts +0 -2
  32. package/dist/idl_codegen/accounts/index.d.ts.map +1 -1
  33. package/dist/idl_codegen/accounts/index.js +1 -3
  34. package/dist/idl_codegen/accounts/index.js.map +1 -1
  35. package/dist/idl_codegen/errors/custom.d.ts +1 -25
  36. package/dist/idl_codegen/errors/custom.d.ts.map +1 -1
  37. package/dist/idl_codegen/errors/custom.js +1 -43
  38. package/dist/idl_codegen/errors/custom.js.map +1 -1
  39. package/dist/idl_codegen/instructions/idlMissingTypes.d.ts +1 -2
  40. package/dist/idl_codegen/instructions/idlMissingTypes.d.ts.map +1 -1
  41. package/dist/idl_codegen/instructions/idlMissingTypes.js +1 -2
  42. package/dist/idl_codegen/instructions/idlMissingTypes.js.map +1 -1
  43. package/dist/idl_codegen/instructions/index.d.ts +0 -6
  44. package/dist/idl_codegen/instructions/index.d.ts.map +1 -1
  45. package/dist/idl_codegen/instructions/index.js +1 -7
  46. package/dist/idl_codegen/instructions/index.js.map +1 -1
  47. package/dist/idl_codegen/instructions/updateReserveConfig.d.ts +3 -4
  48. package/dist/idl_codegen/instructions/updateReserveConfig.d.ts.map +1 -1
  49. package/dist/idl_codegen/instructions/updateReserveConfig.js +3 -5
  50. package/dist/idl_codegen/instructions/updateReserveConfig.js.map +1 -1
  51. package/dist/idl_codegen/instructions/withdrawProtocolFee.d.ts +2 -2
  52. package/dist/idl_codegen/instructions/withdrawProtocolFee.d.ts.map +1 -1
  53. package/dist/idl_codegen/instructions/withdrawProtocolFee.js +6 -2
  54. package/dist/idl_codegen/instructions/withdrawProtocolFee.js.map +1 -1
  55. package/dist/idl_codegen/types/UpdateLendingMarketMode.d.ts +7 -33
  56. package/dist/idl_codegen/types/UpdateLendingMarketMode.d.ts.map +1 -1
  57. package/dist/idl_codegen/types/UpdateLendingMarketMode.js +12 -60
  58. package/dist/idl_codegen/types/UpdateLendingMarketMode.js.map +1 -1
  59. package/dist/idl_codegen/types/index.d.ts +2 -6
  60. package/dist/idl_codegen/types/index.d.ts.map +1 -1
  61. package/dist/idl_codegen/types/index.js +1 -3
  62. package/dist/idl_codegen/types/index.js.map +1 -1
  63. package/dist/utils/accountListing.d.ts +1 -1
  64. package/dist/utils/accountListing.d.ts.map +1 -1
  65. package/dist/utils/accountListing.js +2 -2
  66. package/dist/utils/accountListing.js.map +1 -1
  67. package/dist/utils/lookupTable.d.ts.map +1 -1
  68. package/dist/utils/lookupTable.js +6 -1
  69. package/dist/utils/lookupTable.js.map +1 -1
  70. package/dist/utils/managerTypes.d.ts.map +1 -1
  71. package/dist/utils/managerTypes.js +4 -10
  72. package/dist/utils/managerTypes.js.map +1 -1
  73. package/dist/utils/seeds.d.ts +0 -16
  74. package/dist/utils/seeds.d.ts.map +1 -1
  75. package/dist/utils/seeds.js +1 -23
  76. package/dist/utils/seeds.js.map +1 -1
  77. package/package.json +1 -1
  78. package/src/classes/farm_utils.ts +11 -3
  79. package/src/classes/manager.ts +401 -51
  80. package/src/classes/obligation.ts +0 -16
  81. package/src/classes/reserve.ts +783 -119
  82. package/src/classes/utils.ts +0 -12
  83. package/src/classes/vault.ts +18 -7
  84. package/src/client_kamino_manager.ts +34 -42
  85. package/src/idl.json +9 -186
  86. package/src/idl_codegen/accounts/LendingMarket.ts +9 -41
  87. package/src/idl_codegen/accounts/index.ts +0 -2
  88. package/src/idl_codegen/errors/custom.ts +0 -45
  89. package/src/idl_codegen/instructions/idlMissingTypes.ts +2 -4
  90. package/src/idl_codegen/instructions/index.ts +0 -9
  91. package/src/idl_codegen/instructions/updateReserveConfig.ts +5 -7
  92. package/src/idl_codegen/instructions/withdrawProtocolFee.ts +8 -4
  93. package/src/idl_codegen/types/UpdateLendingMarketMode.ts +13 -73
  94. package/src/idl_codegen/types/index.ts +2 -16
  95. package/src/utils/accountListing.ts +3 -2
  96. package/src/utils/lookupTable.ts +7 -1
  97. package/src/utils/managerTypes.ts +4 -10
  98. package/src/utils/seeds.ts +0 -25
  99. package/dist/classes/configItems.d.ts +0 -166
  100. package/dist/classes/configItems.d.ts.map +0 -1
  101. package/dist/classes/configItems.js +0 -202
  102. package/dist/classes/configItems.js.map +0 -1
  103. package/dist/idl_codegen/accounts/GlobalConfig.d.ts +0 -40
  104. package/dist/idl_codegen/accounts/GlobalConfig.d.ts.map +0 -1
  105. package/dist/idl_codegen/accounts/GlobalConfig.js +0 -116
  106. package/dist/idl_codegen/accounts/GlobalConfig.js.map +0 -1
  107. package/dist/idl_codegen/instructions/initGlobalConfig.d.ts +0 -10
  108. package/dist/idl_codegen/instructions/initGlobalConfig.d.ts.map +0 -1
  109. package/dist/idl_codegen/instructions/initGlobalConfig.js +0 -19
  110. package/dist/idl_codegen/instructions/initGlobalConfig.js.map +0 -1
  111. package/dist/idl_codegen/instructions/updateGlobalConfig.d.ts +0 -13
  112. package/dist/idl_codegen/instructions/updateGlobalConfig.d.ts.map +0 -1
  113. package/dist/idl_codegen/instructions/updateGlobalConfig.js +0 -61
  114. package/dist/idl_codegen/instructions/updateGlobalConfig.js.map +0 -1
  115. package/dist/idl_codegen/instructions/updateGlobalConfigAdmin.d.ts +0 -7
  116. package/dist/idl_codegen/instructions/updateGlobalConfigAdmin.d.ts.map +0 -1
  117. package/dist/idl_codegen/instructions/updateGlobalConfigAdmin.js +0 -16
  118. package/dist/idl_codegen/instructions/updateGlobalConfigAdmin.js.map +0 -1
  119. package/dist/idl_codegen/types/UpdateGlobalConfigMode.d.ts +0 -32
  120. package/dist/idl_codegen/types/UpdateGlobalConfigMode.d.ts.map +0 -1
  121. package/dist/idl_codegen/types/UpdateGlobalConfigMode.js +0 -108
  122. package/dist/idl_codegen/types/UpdateGlobalConfigMode.js.map +0 -1
  123. package/src/classes/configItems.ts +0 -295
  124. package/src/idl_codegen/accounts/GlobalConfig.ts +0 -125
  125. package/src/idl_codegen/instructions/initGlobalConfig.ts +0 -30
  126. package/src/idl_codegen/instructions/updateGlobalConfig.ts +0 -47
  127. package/src/idl_codegen/instructions/updateGlobalConfigAdmin.ts +0 -24
  128. package/src/idl_codegen/types/UpdateGlobalConfigMode.ts +0 -90
@@ -1,3 +1,4 @@
1
+ import { BN } from '@coral-xyz/anchor';
1
2
  import {
2
3
  Farms,
3
4
  FarmState,
@@ -74,9 +75,8 @@ export async function getFarmUnstakeIx(
74
75
  throw new Error(`User state not found for ${user}`);
75
76
  }
76
77
 
77
- const x = new Decimal(lamportsToUnstake.toString()).mul(WAD);
78
- console.log('lamportsToUnstake', lamportsToUnstake.toString());
79
- return farmClient.unstakeIx(user, farmAddress, x.toString(), scopePricesArg);
78
+ const scaledLamportsToUnstake = new BN(lamportsToUnstake.floor().toString()).mul(new BN(WAD.toString()));
79
+ return farmClient.unstakeIx(user, farmAddress, scaledLamportsToUnstake.toString(), scopePricesArg);
80
80
  }
81
81
 
82
82
  // withdrawing from a farm is a 2 step operation: first we unstake the tokens from the farm, then we withdraw them
@@ -127,6 +127,14 @@ export async function getUserSharesInFarm(
127
127
  farmTokenDecimals: number
128
128
  ): Promise<Decimal> {
129
129
  const farmClient = new Farms(connection);
130
+ const userStatePDA = getUserStatePDA(farmClient.getProgramID(), farm, user);
131
+ // if the user state does not exist, return 0
132
+ const userState = await connection.getAccountInfo(userStatePDA);
133
+ if (!userState) {
134
+ return new Decimal(0);
135
+ }
136
+
137
+ // if the user state exists, return the user shares
130
138
  return farmClient.getUserTokensInUndelegatedFarm(user, farm, farmTokenDecimals);
131
139
  }
132
140
 
@@ -28,6 +28,7 @@ import {
28
28
  } from './vault';
29
29
  import {
30
30
  AddAssetToMarketParams,
31
+ assertNever,
31
32
  CreateKaminoMarketParams,
32
33
  createReserveIxs,
33
34
  ENV,
@@ -44,6 +45,7 @@ import {
44
45
  KaminoReserve,
45
46
  LendingMarket,
46
47
  lendingMarketAuthPda,
48
+ LendingMarketFields,
47
49
  MarketWithAddress,
48
50
  parseForChangesReserveConfigAndGetIxs,
49
51
  parseOracleType,
@@ -51,6 +53,7 @@ import {
51
53
  PubkeyHashMap,
52
54
  Reserve,
53
55
  ReserveWithAddress,
56
+ sameLengthArrayEquals,
54
57
  ScopeOracleConfig,
55
58
  updateEntireReserveConfigIx,
56
59
  updateLendingMarket,
@@ -62,7 +65,12 @@ import {
62
65
  import { PROGRAM_ID } from '../idl_codegen/programId';
63
66
  import { Scope, TokenMetadatas, U16_MAX } from '@kamino-finance/scope-sdk';
64
67
  import BN from 'bn.js';
65
- import { ReserveConfig, UpdateLendingMarketMode, UpdateLendingMarketModeKind } from '../idl_codegen/types';
68
+ import {
69
+ ElevationGroup,
70
+ ReserveConfig,
71
+ UpdateLendingMarketMode,
72
+ UpdateLendingMarketModeKind,
73
+ } from '../idl_codegen/types';
66
74
  import Decimal from 'decimal.js';
67
75
  import * as anchor from '@coral-xyz/anchor';
68
76
  import { VaultState } from '../idl_codegen_kamino_vault/accounts';
@@ -88,7 +96,6 @@ import { FarmState } from '@kamino-finance/farms-sdk/dist';
88
96
  import SwitchboardProgram from '@switchboard-xyz/sbv2-lite';
89
97
  import { getSquadsMultisigAdminsAndThreshold, walletIsSquadsMultisig, WalletType } from '../utils/multisig';
90
98
  import { decodeVaultState } from '../utils/vault';
91
- import { arrayElementConfigItems, ConfigUpdater } from './configItems';
92
99
 
93
100
  /**
94
101
  * KaminoManager is a class that provides a high-level interface to interact with the Kamino Lend and Kamino Vault programs, in order to create and manage a market, as well as vaults
@@ -384,15 +391,7 @@ export class KaminoManager {
384
391
  const ixs: TransactionInstruction[] = [];
385
392
 
386
393
  if (!reserveState || updateEntireConfig) {
387
- ixs.push(
388
- updateEntireReserveConfigIx(
389
- marketWithAddress.state.lendingMarketOwner,
390
- marketWithAddress.address,
391
- reserve,
392
- config,
393
- this._kaminoLendProgramId
394
- )
395
- );
394
+ ixs.push(updateEntireReserveConfigIx(marketWithAddress, reserve, config, this._kaminoLendProgramId));
396
395
  } else {
397
396
  ixs.push(
398
397
  ...parseForChangesReserveConfigAndGetIxs(
@@ -658,9 +657,9 @@ export class KaminoManager {
658
657
  * Get all lending markets
659
658
  * @returns an array of all lending markets
660
659
  */
661
- async getAllMarkets(): Promise<KaminoMarket[]> {
660
+ async getAllMarkets(programId: PublicKey = PROGRAM_ID): Promise<KaminoMarket[]> {
662
661
  // Get all lending markets
663
- const marketGenerator = getAllLendingMarketAccounts(this.getConnection());
662
+ const marketGenerator = getAllLendingMarketAccounts(this.getConnection(), programId);
664
663
  const slotDuration = await getMedianSlotDurationInMsFromLastEpochs();
665
664
 
666
665
  const lendingMarketPairs: [PublicKey, LendingMarket][] = [];
@@ -1014,6 +1013,13 @@ export class KaminoManager {
1014
1013
  return this._vaultClient.calculateSimulatedFees(vaultState, simulatedCurrentHoldingsWithInterest, currentTimestamp);
1015
1014
  }
1016
1015
 
1016
+ /**
1017
+ * This will compute the PDA that is used as delegatee in Farms program to compute the user state PDA
1018
+ */
1019
+ computeUserFarmStateForUserInVault(farmProgramID: PublicKey, vault: PublicKey, user: PublicKey) {
1020
+ return this._vaultClient.computeUserFarmStateDelegateePDAForUserInVault(farmProgramID, vault, user);
1021
+ }
1022
+
1017
1023
  /**
1018
1024
  * This will load the onchain state for all the reserves that the vault has allocations for
1019
1025
  * @param vaultState - the vault state to load reserves for
@@ -1248,51 +1254,383 @@ export class KaminoManager {
1248
1254
  };
1249
1255
  }
1250
1256
  } // KaminoManager
1257
+ export type BaseLendingMarketKey = keyof LendingMarketFields;
1258
+ const EXCLUDED_LENDING_MARKET_KEYS = [
1259
+ 'version',
1260
+ 'bumpSeed',
1261
+ 'reserved0',
1262
+ 'reserved1',
1263
+ 'padding1',
1264
+ 'padding2',
1265
+ 'elevationGroupPadding',
1266
+ 'quoteCurrency',
1267
+ ] as const;
1268
+ export type ExcludedLendingMarketKey = (typeof EXCLUDED_LENDING_MARKET_KEYS)[number];
1269
+
1270
+ function isExcludedLendingMarketKey(value: unknown): value is ExcludedLendingMarketKey {
1271
+ return EXCLUDED_LENDING_MARKET_KEYS.includes(value as ExcludedLendingMarketKey);
1272
+ }
1251
1273
 
1252
- export const MARKET_UPDATER = new ConfigUpdater(UpdateLendingMarketMode.fromDecoded, LendingMarket, (config) => ({
1253
- [UpdateLendingMarketMode.UpdateOwner.kind]: config.lendingMarketOwnerCached,
1254
- [UpdateLendingMarketMode.UpdateImmutableFlag.kind]: config.immutable,
1255
- [UpdateLendingMarketMode.UpdateEmergencyMode.kind]: config.emergencyMode,
1256
- [UpdateLendingMarketMode.UpdateLiquidationCloseFactor.kind]: config.liquidationMaxDebtCloseFactorPct,
1257
- [UpdateLendingMarketMode.UpdateLiquidationMaxValue.kind]: config.maxLiquidatableDebtMarketValueAtOnce,
1258
- [UpdateLendingMarketMode.DeprecatedUpdateGlobalUnhealthyBorrow.kind]: [], // deprecated
1259
- [UpdateLendingMarketMode.UpdateGlobalAllowedBorrow.kind]: config.globalAllowedBorrowValue,
1260
- [UpdateLendingMarketMode.UpdateRiskCouncil.kind]: config.riskCouncil,
1261
- [UpdateLendingMarketMode.UpdateMinFullLiquidationThreshold.kind]: config.minFullLiquidationValueThreshold,
1262
- [UpdateLendingMarketMode.UpdateInsolvencyRiskLtv.kind]: config.insolvencyRiskUnhealthyLtvPct,
1263
- [UpdateLendingMarketMode.UpdateElevationGroup.kind]: arrayElementConfigItems(config.elevationGroups),
1264
- [UpdateLendingMarketMode.UpdateReferralFeeBps.kind]: config.referralFeeBps,
1265
- [UpdateLendingMarketMode.DeprecatedUpdateMultiplierPoints.kind]: [], // deprecated
1266
- [UpdateLendingMarketMode.UpdatePriceRefreshTriggerToMaxAgePct.kind]: config.priceRefreshTriggerToMaxAgePct,
1267
- [UpdateLendingMarketMode.UpdateAutodeleverageEnabled.kind]: config.autodeleverageEnabled,
1268
- [UpdateLendingMarketMode.UpdateBorrowingDisabled.kind]: config.borrowDisabled,
1269
- [UpdateLendingMarketMode.UpdateMinNetValueObligationPostAction.kind]: config.minNetValueInObligationSf,
1270
- [UpdateLendingMarketMode.UpdateMinValueLtvSkipPriorityLiqCheck.kind]: config.minValueSkipLiquidationLtvChecks,
1271
- [UpdateLendingMarketMode.UpdateMinValueBfSkipPriorityLiqCheck.kind]: config.minValueSkipLiquidationBfChecks,
1272
- [UpdateLendingMarketMode.UpdatePaddingFields.kind]: [], // we do not update padding this way
1273
- [UpdateLendingMarketMode.UpdateName.kind]: config.name,
1274
- [UpdateLendingMarketMode.UpdateIndividualAutodeleverageMarginCallPeriodSecs.kind]:
1275
- config.individualAutodeleverageMarginCallPeriodSecs,
1276
- [UpdateLendingMarketMode.UpdateInitialDepositAmount.kind]: config.minInitialDepositAmount,
1277
- [UpdateLendingMarketMode.UpdateObligationOrderCreationEnabled.kind]: config.obligationOrderCreationEnabled,
1278
- [UpdateLendingMarketMode.UpdateObligationOrderExecutionEnabled.kind]: config.obligationOrderExecutionEnabled,
1279
- }));
1274
+ export type LendingMarketKey = Exclude<BaseLendingMarketKey, ExcludedLendingMarketKey>;
1275
+
1276
+ const updateLendingMarketConfig = (
1277
+ key: LendingMarketKey,
1278
+ market: LendingMarket,
1279
+ newMarket: LendingMarket
1280
+ ): { mode: number; value: Buffer }[] => {
1281
+ const updateLendingMarketIxsArgs: { mode: number; value: Buffer }[] = [];
1282
+ switch (key) {
1283
+ case 'lendingMarketOwner': {
1284
+ if (!market.lendingMarketOwner.equals(newMarket.lendingMarketOwner)) {
1285
+ updateLendingMarketIxsArgs.push({
1286
+ mode: UpdateLendingMarketMode.UpdateOwner.discriminator,
1287
+ value: updateMarketConfigEncodedValue(
1288
+ UpdateLendingMarketMode.UpdateOwner.discriminator,
1289
+ newMarket.lendingMarketOwner
1290
+ ),
1291
+ });
1292
+ }
1293
+ break;
1294
+ }
1295
+ case 'lendingMarketOwnerCached':
1296
+ if (!market.lendingMarketOwnerCached.equals(newMarket.lendingMarketOwnerCached)) {
1297
+ updateLendingMarketIxsArgs.push({
1298
+ mode: UpdateLendingMarketMode.UpdateOwner.discriminator,
1299
+ value: updateMarketConfigEncodedValue(
1300
+ UpdateLendingMarketMode.UpdateOwner.discriminator,
1301
+ newMarket.lendingMarketOwnerCached
1302
+ ),
1303
+ });
1304
+ }
1305
+ break;
1306
+ case 'referralFeeBps':
1307
+ if (market.referralFeeBps !== newMarket.referralFeeBps) {
1308
+ updateLendingMarketIxsArgs.push({
1309
+ mode: UpdateLendingMarketMode.UpdateReferralFeeBps.discriminator,
1310
+ value: updateMarketConfigEncodedValue(
1311
+ UpdateLendingMarketMode.UpdateReferralFeeBps.discriminator,
1312
+ newMarket.referralFeeBps
1313
+ ),
1314
+ });
1315
+ }
1316
+ break;
1317
+ case 'emergencyMode':
1318
+ if (market.emergencyMode !== newMarket.emergencyMode) {
1319
+ updateLendingMarketIxsArgs.push({
1320
+ mode: UpdateLendingMarketMode.UpdateEmergencyMode.discriminator,
1321
+ value: updateMarketConfigEncodedValue(
1322
+ UpdateLendingMarketMode.UpdateEmergencyMode.discriminator,
1323
+ newMarket.emergencyMode
1324
+ ),
1325
+ });
1326
+ }
1327
+ break;
1328
+ case 'autodeleverageEnabled':
1329
+ if (market.autodeleverageEnabled !== newMarket.autodeleverageEnabled) {
1330
+ updateLendingMarketIxsArgs.push({
1331
+ mode: UpdateLendingMarketMode.UpdateAutodeleverageEnabled.discriminator,
1332
+ value: updateMarketConfigEncodedValue(
1333
+ UpdateLendingMarketMode.UpdateAutodeleverageEnabled.discriminator,
1334
+ newMarket.autodeleverageEnabled
1335
+ ),
1336
+ });
1337
+ }
1338
+ break;
1339
+ case 'borrowDisabled':
1340
+ if (market.borrowDisabled !== newMarket.borrowDisabled) {
1341
+ updateLendingMarketIxsArgs.push({
1342
+ mode: UpdateLendingMarketMode.UpdateBorrowingDisabled.discriminator,
1343
+ value: updateMarketConfigEncodedValue(
1344
+ UpdateLendingMarketMode.UpdateBorrowingDisabled.discriminator,
1345
+ newMarket.borrowDisabled
1346
+ ),
1347
+ });
1348
+ }
1349
+ break;
1350
+ case 'priceRefreshTriggerToMaxAgePct':
1351
+ if (market.priceRefreshTriggerToMaxAgePct !== newMarket.priceRefreshTriggerToMaxAgePct) {
1352
+ updateLendingMarketIxsArgs.push({
1353
+ mode: UpdateLendingMarketMode.UpdatePriceRefreshTriggerToMaxAgePct.discriminator,
1354
+ value: updateMarketConfigEncodedValue(
1355
+ UpdateLendingMarketMode.UpdatePriceRefreshTriggerToMaxAgePct.discriminator,
1356
+ newMarket.priceRefreshTriggerToMaxAgePct
1357
+ ),
1358
+ });
1359
+ }
1360
+ break;
1361
+ case 'liquidationMaxDebtCloseFactorPct':
1362
+ if (market.liquidationMaxDebtCloseFactorPct !== newMarket.liquidationMaxDebtCloseFactorPct) {
1363
+ updateLendingMarketIxsArgs.push({
1364
+ mode: UpdateLendingMarketMode.UpdateLiquidationCloseFactor.discriminator,
1365
+ value: updateMarketConfigEncodedValue(
1366
+ UpdateLendingMarketMode.UpdateLiquidationCloseFactor.discriminator,
1367
+ newMarket.liquidationMaxDebtCloseFactorPct
1368
+ ),
1369
+ });
1370
+ }
1371
+ break;
1372
+ case 'insolvencyRiskUnhealthyLtvPct':
1373
+ if (market.insolvencyRiskUnhealthyLtvPct !== newMarket.insolvencyRiskUnhealthyLtvPct) {
1374
+ updateLendingMarketIxsArgs.push({
1375
+ mode: UpdateLendingMarketMode.UpdateInsolvencyRiskLtv.discriminator,
1376
+ value: updateMarketConfigEncodedValue(
1377
+ UpdateLendingMarketMode.UpdateInsolvencyRiskLtv.discriminator,
1378
+ newMarket.insolvencyRiskUnhealthyLtvPct
1379
+ ),
1380
+ });
1381
+ }
1382
+ break;
1383
+ case 'minFullLiquidationValueThreshold':
1384
+ if (!market.minFullLiquidationValueThreshold.eq(newMarket.minFullLiquidationValueThreshold)) {
1385
+ updateLendingMarketIxsArgs.push({
1386
+ mode: UpdateLendingMarketMode.UpdateMinFullLiquidationThreshold.discriminator,
1387
+ value: updateMarketConfigEncodedValue(
1388
+ UpdateLendingMarketMode.UpdateMinFullLiquidationThreshold.discriminator,
1389
+ newMarket.minFullLiquidationValueThreshold.toNumber()
1390
+ ),
1391
+ });
1392
+ }
1393
+ break;
1394
+ case 'maxLiquidatableDebtMarketValueAtOnce':
1395
+ if (!market.maxLiquidatableDebtMarketValueAtOnce.eq(newMarket.maxLiquidatableDebtMarketValueAtOnce)) {
1396
+ updateLendingMarketIxsArgs.push({
1397
+ mode: UpdateLendingMarketMode.UpdateLiquidationMaxValue.discriminator,
1398
+ value: updateMarketConfigEncodedValue(
1399
+ UpdateLendingMarketMode.UpdateLiquidationMaxValue.discriminator,
1400
+ newMarket.maxLiquidatableDebtMarketValueAtOnce.toNumber()
1401
+ ),
1402
+ });
1403
+ }
1404
+ break;
1405
+ case 'globalAllowedBorrowValue':
1406
+ if (!market.globalAllowedBorrowValue.eq(newMarket.globalAllowedBorrowValue)) {
1407
+ updateLendingMarketIxsArgs.push({
1408
+ mode: UpdateLendingMarketMode.UpdateGlobalAllowedBorrow.discriminator,
1409
+ value: updateMarketConfigEncodedValue(
1410
+ UpdateLendingMarketMode.UpdateGlobalAllowedBorrow.discriminator,
1411
+ newMarket.globalAllowedBorrowValue.toNumber()
1412
+ ),
1413
+ });
1414
+ }
1415
+ break;
1416
+ case 'riskCouncil':
1417
+ if (!market.riskCouncil.equals(newMarket.riskCouncil)) {
1418
+ updateLendingMarketIxsArgs.push({
1419
+ mode: UpdateLendingMarketMode.UpdateRiskCouncil.discriminator,
1420
+ value: updateMarketConfigEncodedValue(
1421
+ UpdateLendingMarketMode.UpdateRiskCouncil.discriminator,
1422
+ newMarket.riskCouncil
1423
+ ),
1424
+ });
1425
+ }
1426
+ break;
1427
+ case 'elevationGroups':
1428
+ let elevationGroupsDiffs = 0;
1429
+ for (let i = 0; i < market.elevationGroups.length; i++) {
1430
+ if (
1431
+ market.elevationGroups[i].id !== newMarket.elevationGroups[i].id ||
1432
+ market.elevationGroups[i].maxLiquidationBonusBps !== newMarket.elevationGroups[i].maxLiquidationBonusBps ||
1433
+ market.elevationGroups[i].ltvPct !== newMarket.elevationGroups[i].ltvPct ||
1434
+ market.elevationGroups[i].liquidationThresholdPct !== newMarket.elevationGroups[i].liquidationThresholdPct ||
1435
+ market.elevationGroups[i].allowNewLoans !== newMarket.elevationGroups[i].allowNewLoans ||
1436
+ market.elevationGroups[i].maxReservesAsCollateral !== newMarket.elevationGroups[i].maxReservesAsCollateral ||
1437
+ !market.elevationGroups[i].debtReserve.equals(newMarket.elevationGroups[i].debtReserve)
1438
+ ) {
1439
+ updateLendingMarketIxsArgs.push({
1440
+ mode: UpdateLendingMarketMode.UpdateElevationGroup.discriminator,
1441
+ value: updateMarketConfigEncodedValue(
1442
+ UpdateLendingMarketMode.UpdateElevationGroup.discriminator,
1443
+ newMarket.elevationGroups[i]
1444
+ ),
1445
+ });
1446
+ elevationGroupsDiffs++;
1447
+ }
1448
+ }
1449
+ if (elevationGroupsDiffs > 1) {
1450
+ throw new Error('Can only update 1 elevation group at a time');
1451
+ }
1452
+ break;
1453
+ case 'minNetValueInObligationSf':
1454
+ if (!market.minNetValueInObligationSf.eq(newMarket.minNetValueInObligationSf)) {
1455
+ updateLendingMarketIxsArgs.push({
1456
+ mode: UpdateLendingMarketMode.UpdateMinNetValueObligationPostAction.discriminator,
1457
+ value: updateMarketConfigEncodedValue(
1458
+ UpdateLendingMarketMode.UpdateMinNetValueObligationPostAction.discriminator,
1459
+ newMarket.minNetValueInObligationSf.toString()
1460
+ ),
1461
+ });
1462
+ }
1463
+ break;
1464
+ case 'minValueSkipLiquidationBfChecks':
1465
+ if (!market.minValueSkipLiquidationBfChecks.eq(newMarket.minValueSkipLiquidationBfChecks)) {
1466
+ updateLendingMarketIxsArgs.push({
1467
+ mode: UpdateLendingMarketMode.UpdateMinValueBfSkipPriorityLiqCheck.discriminator,
1468
+ value: updateMarketConfigEncodedValue(
1469
+ UpdateLendingMarketMode.UpdateMinValueBfSkipPriorityLiqCheck.discriminator,
1470
+ newMarket.minValueSkipLiquidationBfChecks.toNumber()
1471
+ ),
1472
+ });
1473
+ }
1474
+ break;
1475
+ case 'minValueSkipLiquidationLtvChecks':
1476
+ if (!market.minValueSkipLiquidationLtvChecks.eq(newMarket.minValueSkipLiquidationLtvChecks)) {
1477
+ updateLendingMarketIxsArgs.push({
1478
+ mode: UpdateLendingMarketMode.UpdateMinValueLtvSkipPriorityLiqCheck.discriminator,
1479
+ value: updateMarketConfigEncodedValue(
1480
+ UpdateLendingMarketMode.UpdateMinValueLtvSkipPriorityLiqCheck.discriminator,
1481
+ newMarket.minValueSkipLiquidationLtvChecks.toNumber()
1482
+ ),
1483
+ });
1484
+ }
1485
+ break;
1486
+ case 'individualAutodeleverageMarginCallPeriodSecs':
1487
+ if (
1488
+ market.individualAutodeleverageMarginCallPeriodSecs !== newMarket.individualAutodeleverageMarginCallPeriodSecs
1489
+ ) {
1490
+ updateLendingMarketIxsArgs.push({
1491
+ mode: UpdateLendingMarketMode.UpdateIndividualAutodeleverageMarginCallPeriodSecs.discriminator,
1492
+ value: updateMarketConfigEncodedValue(
1493
+ UpdateLendingMarketMode.UpdateIndividualAutodeleverageMarginCallPeriodSecs.discriminator,
1494
+ newMarket.individualAutodeleverageMarginCallPeriodSecs.toNumber()
1495
+ ),
1496
+ });
1497
+ }
1498
+ break;
1499
+ case 'name':
1500
+ if (!sameLengthArrayEquals(market.name, newMarket.name)) {
1501
+ updateLendingMarketIxsArgs.push({
1502
+ mode: UpdateLendingMarketMode.UpdateName.discriminator,
1503
+ value: updateMarketConfigEncodedValue(UpdateLendingMarketMode.UpdateName.discriminator, newMarket.name),
1504
+ });
1505
+ }
1506
+ break;
1507
+ case 'minInitialDepositAmount':
1508
+ if (!market.minInitialDepositAmount.eq(newMarket.minInitialDepositAmount)) {
1509
+ updateLendingMarketIxsArgs.push({
1510
+ mode: UpdateLendingMarketMode.UpdateInitialDepositAmount.discriminator,
1511
+ value: updateMarketConfigEncodedValue(
1512
+ UpdateLendingMarketMode.UpdateInitialDepositAmount.discriminator,
1513
+ newMarket.minInitialDepositAmount.toNumber()
1514
+ ),
1515
+ });
1516
+ }
1517
+ break;
1518
+ case 'obligationOrdersEnabled':
1519
+ if (market.obligationOrdersEnabled !== newMarket.obligationOrdersEnabled) {
1520
+ updateLendingMarketIxsArgs.push({
1521
+ mode: UpdateLendingMarketMode.UpdateObligationOrdersEnabled.discriminator,
1522
+ value: updateMarketConfigEncodedValue(
1523
+ UpdateLendingMarketMode.UpdateObligationOrdersEnabled.discriminator,
1524
+ newMarket.obligationOrdersEnabled
1525
+ ),
1526
+ });
1527
+ }
1528
+ break;
1529
+ default:
1530
+ assertNever(key);
1531
+ }
1532
+ return updateLendingMarketIxsArgs;
1533
+ };
1280
1534
 
1281
1535
  function parseForChangesMarketConfigAndGetIxs(
1282
1536
  marketWithAddress: MarketWithAddress,
1283
1537
  newMarket: LendingMarket,
1284
1538
  programId: PublicKey
1285
1539
  ): TransactionInstruction[] {
1286
- const encodedMarketUpdates = MARKET_UPDATER.encodeAllUpdates(marketWithAddress.state, newMarket);
1287
- return encodedMarketUpdates.map((encodedMarketUpdate) =>
1288
- updateMarketConfigIx(marketWithAddress, encodedMarketUpdate.mode, encodedMarketUpdate.value, programId)
1289
- );
1540
+ const market = marketWithAddress.state;
1541
+ const updateLendingMarketIxsArgs: { mode: number; value: Buffer }[] = [];
1542
+
1543
+ for (const key in market.toJSON()) {
1544
+ if (isExcludedLendingMarketKey(key)) {
1545
+ continue;
1546
+ }
1547
+ updateLendingMarketIxsArgs.push(...updateLendingMarketConfig(key as LendingMarketKey, market, newMarket));
1548
+ }
1549
+
1550
+ const ixs: TransactionInstruction[] = [];
1551
+
1552
+ updateLendingMarketIxsArgs.forEach((updateLendingMarketConfigArgs) => {
1553
+ ixs.push(
1554
+ updateMarketConfigIx(
1555
+ marketWithAddress,
1556
+ updateLendingMarketConfigArgs.mode,
1557
+ updateLendingMarketConfigArgs.value,
1558
+ programId
1559
+ )
1560
+ );
1561
+ });
1562
+
1563
+ return ixs;
1564
+ }
1565
+
1566
+ function updateMarketConfigEncodedValue(
1567
+ discriminator: UpdateLendingMarketModeKind['discriminator'],
1568
+ value: number | number[] | PublicKey | ElevationGroup | string
1569
+ ): Buffer {
1570
+ let buffer: Buffer = Buffer.alloc(72);
1571
+ let pkBuffer: Buffer;
1572
+ let valueBigInt: bigint;
1573
+ let valueArray: number[];
1574
+
1575
+ switch (discriminator) {
1576
+ case UpdateLendingMarketMode.UpdateEmergencyMode.discriminator:
1577
+ case UpdateLendingMarketMode.UpdateLiquidationCloseFactor.discriminator:
1578
+ case UpdateLendingMarketMode.UpdateInsolvencyRiskLtv.discriminator:
1579
+ case UpdateLendingMarketMode.UpdatePriceRefreshTriggerToMaxAgePct.discriminator:
1580
+ case UpdateLendingMarketMode.UpdateAutodeleverageEnabled.discriminator:
1581
+ case UpdateLendingMarketMode.UpdateObligationOrdersEnabled.discriminator:
1582
+ case UpdateLendingMarketMode.UpdateBorrowingDisabled.discriminator:
1583
+ buffer.writeUIntLE(value as number, 0, 1);
1584
+ break;
1585
+ case UpdateLendingMarketMode.UpdateReferralFeeBps.discriminator:
1586
+ buffer.writeUInt16LE(value as number, 0);
1587
+ break;
1588
+ case UpdateLendingMarketMode.UpdateLiquidationMaxValue.discriminator:
1589
+ case UpdateLendingMarketMode.UpdateGlobalAllowedBorrow.discriminator:
1590
+ case UpdateLendingMarketMode.UpdateMinFullLiquidationThreshold.discriminator:
1591
+ case UpdateLendingMarketMode.UpdateMinValueBfSkipPriorityLiqCheck.discriminator:
1592
+ case UpdateLendingMarketMode.UpdateMinValueLtvSkipPriorityLiqCheck.discriminator:
1593
+ case UpdateLendingMarketMode.UpdateIndividualAutodeleverageMarginCallPeriodSecs.discriminator:
1594
+ case UpdateLendingMarketMode.UpdateInitialDepositAmount.discriminator:
1595
+ value = value as number;
1596
+ buffer.writeBigUint64LE(BigInt(value), 0);
1597
+ break;
1598
+ case UpdateLendingMarketMode.UpdateOwner.discriminator:
1599
+ case UpdateLendingMarketMode.UpdateRiskCouncil.discriminator:
1600
+ pkBuffer = (value as PublicKey).toBuffer();
1601
+ pkBuffer.copy(buffer, 0);
1602
+ break;
1603
+ case UpdateLendingMarketMode.UpdateElevationGroup.discriminator:
1604
+ buffer = serializeElevationGroup(value as ElevationGroup);
1605
+ break;
1606
+ case UpdateLendingMarketMode.UpdateMinNetValueObligationPostAction.discriminator:
1607
+ valueBigInt = BigInt(value as string);
1608
+ for (let i = 0; i < 16; i++) {
1609
+ buffer[15 - i] = Number((valueBigInt >> BigInt(i * 8)) & BigInt(0xff));
1610
+ }
1611
+ break;
1612
+ case UpdateLendingMarketMode.UpdateName.discriminator:
1613
+ valueArray = value as number[];
1614
+ for (let i = 0; i < valueArray.length; i++) {
1615
+ buffer.writeUIntLE(valueArray[i], i, 1);
1616
+ }
1617
+ break;
1618
+ case UpdateLendingMarketMode.UpdatePaddingFields.discriminator:
1619
+ case UpdateLendingMarketMode.DeprecatedUpdateGlobalUnhealthyBorrow.discriminator:
1620
+ case UpdateLendingMarketMode.DeprecatedUpdateMultiplierPoints.discriminator:
1621
+ // Deliberately skipped - we are not updating padding or deprecated fields using this method
1622
+ break;
1623
+ default:
1624
+ assertNever(discriminator);
1625
+ }
1626
+
1627
+ return buffer;
1290
1628
  }
1291
1629
 
1292
1630
  function updateMarketConfigIx(
1293
1631
  marketWithAddress: MarketWithAddress,
1294
- mode: UpdateLendingMarketModeKind,
1295
- value: Uint8Array,
1632
+ modeDiscriminator: number,
1633
+ value: Buffer,
1296
1634
  programId: PublicKey
1297
1635
  ): TransactionInstruction {
1298
1636
  const accounts: UpdateLendingMarketAccounts = {
@@ -1301,13 +1639,25 @@ function updateMarketConfigIx(
1301
1639
  };
1302
1640
 
1303
1641
  const args: UpdateLendingMarketArgs = {
1304
- mode: new anchor.BN(mode.discriminator),
1305
- // NOTE: the Market's update handler expects a `[u8; 72]` (contrary to e.g. the Reserve's update handler accepting
1306
- // `Vec<u8>`). Hence, we need to add explicit padding here:
1307
- value: [...value, ...Array(72 - value.length).fill(0)],
1642
+ mode: new anchor.BN(modeDiscriminator),
1643
+ value: [...value],
1308
1644
  };
1309
1645
 
1310
1646
  const ix = updateLendingMarket(args, accounts, programId);
1311
1647
 
1312
1648
  return ix;
1313
1649
  }
1650
+
1651
+ function serializeElevationGroup(elevationGroup: ElevationGroup): Buffer {
1652
+ const buffer = Buffer.alloc(72);
1653
+ buffer.writeUInt16LE(elevationGroup.maxLiquidationBonusBps, 0);
1654
+ buffer.writeUIntLE(elevationGroup.id, 2, 1);
1655
+ buffer.writeUIntLE(elevationGroup.ltvPct, 3, 1);
1656
+ buffer.writeUIntLE(elevationGroup.liquidationThresholdPct, 4, 1);
1657
+ buffer.writeUIntLE(elevationGroup.allowNewLoans, 5, 1);
1658
+ buffer.writeUIntLE(elevationGroup.maxReservesAsCollateral, 6, 1);
1659
+ buffer.writeUIntLE(elevationGroup.padding0, 7, 1);
1660
+ const debtReserveBuffer = elevationGroup.debtReserve.toBuffer();
1661
+ debtReserveBuffer.copy(buffer, 8);
1662
+ return buffer;
1663
+ }
@@ -636,14 +636,6 @@ export class KaminoObligation {
636
636
  let newObligationDeposits = this.state.deposits;
637
637
  let newObligationBorrows = this.state.borrows;
638
638
 
639
- // Print deposits and borrows before
640
- for (const deposit of this.state.deposits) {
641
- console.log(`Before Deposit: ${deposit.depositReserve.toBase58()} - ${deposit.depositedAmount}`);
642
- }
643
- for (const borrow of this.state.borrows) {
644
- console.log(`Before Borrow: ${borrow.borrowReserve.toBase58()} - ${borrow.borrowedAmountSf}`);
645
- }
646
-
647
639
  switch (action) {
648
640
  case 'deposit': {
649
641
  if (amountCollateral === undefined || mintCollateral === undefined) {
@@ -758,14 +750,6 @@ export class KaminoObligation {
758
750
  null
759
751
  );
760
752
 
761
- // Print deposits and borrows after
762
- for (const deposit of newObligationDeposits) {
763
- console.log(`After Deposit: ${deposit.depositReserve.toBase58()} - ${deposit.depositedAmount}`);
764
- }
765
- for (const borrow of newObligationBorrows) {
766
- console.log(`After Borrow: ${borrow.borrowReserve.toBase58()} - ${borrow.borrowedAmountSf}`);
767
- }
768
-
769
753
  newStats = refreshedStats;
770
754
  newDeposits = deposits;
771
755
  newBorrows = borrows;