@kamino-finance/klend-sdk 5.11.12-beta.0 → 5.11.13

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 (68) hide show
  1. package/README_KAMINO_MANAGER.md +2 -2
  2. package/dist/classes/manager.d.ts +7 -0
  3. package/dist/classes/manager.d.ts.map +1 -1
  4. package/dist/classes/manager.js +9 -0
  5. package/dist/classes/manager.js.map +1 -1
  6. package/dist/classes/reserve.d.ts +1 -7
  7. package/dist/classes/reserve.d.ts.map +1 -1
  8. package/dist/classes/reserve.js +255 -145
  9. package/dist/classes/reserve.js.map +1 -1
  10. package/dist/classes/utils.d.ts +1 -1
  11. package/dist/classes/utils.d.ts.map +1 -1
  12. package/dist/classes/utils.js +2 -8
  13. package/dist/classes/utils.js.map +1 -1
  14. package/dist/classes/vault.d.ts +7 -0
  15. package/dist/classes/vault.d.ts.map +1 -1
  16. package/dist/classes/vault.js +21 -2
  17. package/dist/classes/vault.js.map +1 -1
  18. package/dist/client_kamino_manager.d.ts.map +1 -1
  19. package/dist/client_kamino_manager.js +130 -57
  20. package/dist/client_kamino_manager.js.map +1 -1
  21. package/dist/idl_codegen_kamino_vault/accounts/VaultState.d.ts +9 -6
  22. package/dist/idl_codegen_kamino_vault/accounts/VaultState.d.ts.map +1 -1
  23. package/dist/idl_codegen_kamino_vault/accounts/VaultState.js +19 -13
  24. package/dist/idl_codegen_kamino_vault/accounts/VaultState.js.map +1 -1
  25. package/dist/idl_codegen_kamino_vault/errors/custom.d.ts +9 -1
  26. package/dist/idl_codegen_kamino_vault/errors/custom.d.ts.map +1 -1
  27. package/dist/idl_codegen_kamino_vault/errors/custom.js +15 -1
  28. package/dist/idl_codegen_kamino_vault/errors/custom.js.map +1 -1
  29. package/dist/idl_codegen_kamino_vault/instructions/index.d.ts +2 -0
  30. package/dist/idl_codegen_kamino_vault/instructions/index.d.ts.map +1 -1
  31. package/dist/idl_codegen_kamino_vault/instructions/index.js +3 -1
  32. package/dist/idl_codegen_kamino_vault/instructions/index.js.map +1 -1
  33. package/dist/idl_codegen_kamino_vault/instructions/removeAllocation.d.ts +8 -0
  34. package/dist/idl_codegen_kamino_vault/instructions/removeAllocation.d.ts.map +1 -0
  35. package/dist/idl_codegen_kamino_vault/instructions/removeAllocation.js +17 -0
  36. package/dist/idl_codegen_kamino_vault/instructions/removeAllocation.js.map +1 -0
  37. package/dist/idl_codegen_kamino_vault/programId.d.ts.map +1 -1
  38. package/dist/idl_codegen_kamino_vault/programId.js +1 -1
  39. package/dist/idl_codegen_kamino_vault/programId.js.map +1 -1
  40. package/dist/lending_operations/repay_with_collateral_operations.d.ts +3 -1
  41. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  42. package/dist/lending_operations/repay_with_collateral_operations.js +13 -3
  43. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  44. package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
  45. package/dist/lending_operations/swap_collateral_operations.js +4 -0
  46. package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
  47. package/dist/leverage/operations.d.ts +5 -2
  48. package/dist/leverage/operations.d.ts.map +1 -1
  49. package/dist/leverage/operations.js +83 -44
  50. package/dist/leverage/operations.js.map +1 -1
  51. package/dist/leverage/types.d.ts +11 -0
  52. package/dist/leverage/types.d.ts.map +1 -1
  53. package/package.json +2 -2
  54. package/src/classes/manager.ts +13 -0
  55. package/src/classes/reserve.ts +319 -177
  56. package/src/classes/utils.ts +3 -9
  57. package/src/classes/vault.ts +33 -2
  58. package/src/client_kamino_manager.ts +164 -57
  59. package/src/idl_codegen_kamino_vault/accounts/VaultState.ts +25 -17
  60. package/src/idl_codegen_kamino_vault/errors/custom.ts +17 -0
  61. package/src/idl_codegen_kamino_vault/instructions/index.ts +2 -0
  62. package/src/idl_codegen_kamino_vault/instructions/removeAllocation.ts +26 -0
  63. package/src/idl_codegen_kamino_vault/programId.ts +1 -2
  64. package/src/idl_kamino_vault.json +38 -3
  65. package/src/lending_operations/repay_with_collateral_operations.ts +22 -6
  66. package/src/lending_operations/swap_collateral_operations.ts +12 -1
  67. package/src/leverage/operations.ts +101 -55
  68. package/src/leverage/types.ts +13 -0
@@ -222,17 +222,11 @@ export function calculateAPRFromAPY(apy: Decimal.Value) {
222
222
  .times(SLOTS_PER_YEAR);
223
223
  }
224
224
 
225
- export function sameLengthArrayEquals<T>(left: Array<T>, right: Array<T>): boolean {
225
+ export function sameLengthArrayEquals(left: Array<number>, right: Array<number>): boolean {
226
226
  if (left.length != right.length) {
227
- throw new Error(`Not same length: ${left.length} != ${right.length}`);
227
+ throw new Error(`Not same length: ${left.length} != ${left.length}`);
228
228
  }
229
- return left.every((value, index) => {
230
- const other = right[index];
231
- if (value != null && typeof (value as any).eq === 'function') {
232
- return (value as any).eq(other);
233
- }
234
- return value === other;
235
- });
229
+ return left.every((value, index) => value === right[index]);
236
230
  }
237
231
 
238
232
  export function getTokenBalanceFromAccountInfoLamports(accountInfo: AccountInfo<Buffer>): Decimal {
@@ -33,6 +33,8 @@ import {
33
33
  InitVaultAccounts,
34
34
  invest,
35
35
  InvestAccounts,
36
+ removeAllocation,
37
+ RemoveAllocationAccounts,
36
38
  updateAdmin,
37
39
  UpdateAdminAccounts,
38
40
  updateReserveAllocation,
@@ -92,8 +94,8 @@ import {
92
94
  } from './farm_utils';
93
95
  import { printHoldings } from './types_utils';
94
96
 
95
- export const kaminoVaultId = new PublicKey('kvauTFR8qm1dhniz6pYuBZkuene3Hfrs1VQhVRgCNrr');
96
- export const kaminoVaultStagingId = new PublicKey('STkvh7ostar39Fwr4uZKASs1RNNuYMFMTsE77FiRsL2');
97
+ export const kaminoVaultId = new PublicKey('KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd');
98
+ export const kaminoVaultStagingId = new PublicKey('stKvQfwRsQiKnLtMNVLHKS3exFJmZFsgfzBPWHECUYK');
97
99
 
98
100
  const TOKEN_VAULT_SEED = 'token_vault';
99
101
  const CTOKEN_VAULT_SEED = 'ctoken_vault';
@@ -338,6 +340,35 @@ export class KaminoVaultClient {
338
340
  return updateReserveAllocationIxs;
339
341
  }
340
342
 
343
+ /**
344
+ * This method removes a reserve from the vault allocation strategy if already part of the allocation strategy
345
+ * @param vault - vault to remove the reserve from
346
+ * @param reserve - reserve to remove from the vault allocation strategy
347
+ * @returns - an instruction to remove the reserve from the vault allocation strategy or undefined if the reserve is not part of the allocation strategy
348
+ */
349
+ async removeReserveFromAllocationIx(
350
+ vault: KaminoVault,
351
+ reserve: PublicKey
352
+ ): Promise<TransactionInstruction | undefined> {
353
+ const vaultState = await vault.getState(this.getConnection());
354
+
355
+ const reserveIsPartOfAllocation = vaultState.vaultAllocationStrategy.some((allocation) =>
356
+ allocation.reserve.equals(reserve)
357
+ );
358
+
359
+ if (!reserveIsPartOfAllocation) {
360
+ return undefined;
361
+ }
362
+
363
+ const accounts: RemoveAllocationAccounts = {
364
+ vaultAdminAuthority: vaultState.vaultAdminAuthority,
365
+ vaultState: vault.address,
366
+ reserve,
367
+ };
368
+
369
+ return removeAllocation(accounts);
370
+ }
371
+
341
372
  /**
342
373
  * Update a field of the vault. If the field is a pubkey it will return an extra instruction to add that account into the lookup table
343
374
  * @param vault the vault to update
@@ -16,12 +16,14 @@ import {
16
16
  Chain,
17
17
  DEFAULT_RECENT_SLOT_DURATION_MS,
18
18
  encodeTokenName,
19
+ initLookupTableIx,
19
20
  KaminoManager,
20
21
  KaminoMarket,
21
22
  KaminoVault,
22
23
  KaminoVaultConfig,
23
24
  LendingMarket,
24
25
  MAINNET_BETA_CHAIN_ID,
26
+ parseZeroPaddedUtf8,
25
27
  Reserve,
26
28
  ReserveAllocationConfig,
27
29
  ReserveWithAddress,
@@ -408,6 +410,14 @@ async function main() {
408
410
  mode === 'execute' && console.log('Management fee updated:', updateVaultConfigSig);
409
411
  });
410
412
 
413
+ commands.command('create-lut').action(async () => {
414
+ const env = initializeClient(false, false);
415
+ const initLutIx = initLookupTableIx(env.payer.publicKey, await env.connection.getSlot());
416
+
417
+ const updateVaultConfigSig = await processTxn(env.client, env.payer, [initLutIx[0]], 'execute', 2500, []);
418
+ console.log(`LUT created: ${initLutIx[1].toString()} tx id: ${updateVaultConfigSig}`);
419
+ });
420
+
411
421
  commands
412
422
  .command('sync-vault-lut')
413
423
  .requiredOption('--vault <string>', 'The vault address to sync')
@@ -1142,9 +1152,6 @@ async function main() {
1142
1152
  address: lendingMarketAddress,
1143
1153
  state: lendingMarketState,
1144
1154
  };
1145
- if (!lendingMarketState) {
1146
- throw new Error('Lending Market not found');
1147
- }
1148
1155
 
1149
1156
  if (mode === 'multisig') {
1150
1157
  throw new Error('If using multisig mode, multisig is required');
@@ -1163,6 +1170,106 @@ async function main() {
1163
1170
  );
1164
1171
  });
1165
1172
 
1173
+ commands
1174
+ .command('update-lending-market-name')
1175
+ .requiredOption('--lending-market <string>', 'Lending Market address')
1176
+ .requiredOption('--new-name <string>', 'Lending Market address')
1177
+ .requiredOption(
1178
+ `--mode <string>`,
1179
+ 'simulate - to print txn simulation, inspect - to get txn simulation in explorer, execute - execute txn, multisig - to get bs58 txn for multisig usage'
1180
+ )
1181
+ .option(`--staging`, 'If true, will use the staging programs')
1182
+ .action(async ({ lendingMarket, newName, mode, staging }) => {
1183
+ const env = initializeClient(mode === 'multisig', staging);
1184
+ const lendingMarketAddress = new PublicKey(lendingMarket);
1185
+ const lendingMarketState = await LendingMarket.fetch(env.connection, lendingMarketAddress, env.kLendProgramId);
1186
+ if (!lendingMarketState) {
1187
+ throw new Error('Lending Market not found');
1188
+ }
1189
+ const marketWithAddress = {
1190
+ address: lendingMarketAddress,
1191
+ state: lendingMarketState,
1192
+ };
1193
+
1194
+ if (mode === 'multisig') {
1195
+ throw new Error('If using multisig mode, multisig is required');
1196
+ }
1197
+
1198
+ const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
1199
+
1200
+ const currentName = parseZeroPaddedUtf8(lendingMarketState.name);
1201
+ const newNameEncoded = encodeTokenName(newName);
1202
+
1203
+ console.log('Current name: ', currentName, ' encoded: ', lendingMarketState.name);
1204
+ console.log('New name: ', newName, ' encoded: ', newNameEncoded);
1205
+
1206
+ // @ts-ignore
1207
+ const newLendingMarket: LendingMarket = {
1208
+ ...lendingMarketState,
1209
+ name: newNameEncoded,
1210
+ };
1211
+
1212
+ const ixns = kaminoManager.updateLendingMarketIxs(marketWithAddress, newLendingMarket);
1213
+
1214
+ const _updateLendingMarketSig = await processTxn(env.client, env.payer, ixns, mode, 2500, [], 400_000);
1215
+
1216
+ mode === 'execute' &&
1217
+ console.log(
1218
+ 'Lending market name updated to -> ',
1219
+ JSON.parse(JSON.stringify(lendingMarketState.lendingMarketOwnerCached))
1220
+ );
1221
+ });
1222
+
1223
+ commands
1224
+ .command('update-reserve-config-debt-cap')
1225
+ .requiredOption('--reserve <string>', 'Lending Market address')
1226
+ .requiredOption(
1227
+ `--mode <string>`,
1228
+ 'simulate - to print txn simulation, inspect - to get txn simulation in explorer, execute - execute txn, multisig - to get bs58 txn for multisig usage'
1229
+ )
1230
+ .option(`--staging`, 'If true, will use the staging programs')
1231
+ .action(async ({ reserve, mode, staging }) => {
1232
+ const env = initializeClient(mode === 'multisig', staging);
1233
+ const reserveAddress = new PublicKey(reserve);
1234
+ const reserveState = await Reserve.fetch(env.connection, reserveAddress, env.kLendProgramId);
1235
+ if (!reserveState) {
1236
+ throw new Error('Reserve not found');
1237
+ }
1238
+
1239
+ const lendingMarketAddress = reserveState.lendingMarket;
1240
+ const lendingMarketState = await LendingMarket.fetch(env.connection, lendingMarketAddress, env.kLendProgramId);
1241
+ if (!lendingMarketState) {
1242
+ throw new Error('Lending Market not found');
1243
+ }
1244
+
1245
+ const marketWithAddress = {
1246
+ address: lendingMarketAddress,
1247
+ state: lendingMarketState,
1248
+ };
1249
+
1250
+ if (mode === 'multisig') {
1251
+ throw new Error('If using multisig mode, multisig is required');
1252
+ }
1253
+
1254
+ const kaminoManager = new KaminoManager(env.connection, env.kLendProgramId, env.kVaultProgramId);
1255
+
1256
+ const newReserveConfigFields: ReserveConfigFields = {
1257
+ ...reserveState.config,
1258
+ borrowLimit: new BN(1000),
1259
+ };
1260
+ const newReserveConfig: ReserveConfig = new ReserveConfig(newReserveConfigFields);
1261
+
1262
+ const ixns = await kaminoManager.updateReserveIxs(marketWithAddress, reserveAddress, newReserveConfig);
1263
+
1264
+ const _updateLendingMarketSig = await processTxn(env.client, env.payer, ixns, mode, 2500, [], 400_000);
1265
+
1266
+ mode === 'execute' &&
1267
+ console.log(
1268
+ 'Lending market name updated to -> ',
1269
+ JSON.parse(JSON.stringify(lendingMarketState.lendingMarketOwnerCached))
1270
+ );
1271
+ });
1272
+
1166
1273
  await commands.parseAsync();
1167
1274
  }
1168
1275
 
@@ -1320,64 +1427,64 @@ function createAddExtraComputeUnitFeeTransaction(units: number, microLamports: n
1320
1427
  return ixns;
1321
1428
  }
1322
1429
 
1323
- function parseReserveConfigFromFile(reserveConfigFromFile: any): ReserveConfig {
1430
+ function parseReserveConfigFromFile(farmConfigFromFile: any): ReserveConfig {
1324
1431
  const reserveConfigFields: ReserveConfigFields = {
1325
- status: reserveConfigFromFile.status,
1326
- loanToValuePct: reserveConfigFromFile.loanToValuePct,
1327
- liquidationThresholdPct: reserveConfigFromFile.liquidationThresholdPct,
1328
- minLiquidationBonusBps: reserveConfigFromFile.minLiquidationBonusBps,
1329
- protocolLiquidationFeePct: reserveConfigFromFile.protocolLiquidationFeePct,
1330
- protocolTakeRatePct: reserveConfigFromFile.protocolLiquidationFeePct,
1331
- assetTier: reserveConfigFromFile.assetTier,
1332
- maxLiquidationBonusBps: reserveConfigFromFile.maxLiquidationBonusBps,
1333
- badDebtLiquidationBonusBps: reserveConfigFromFile.badDebtLiquidationBonusBps,
1432
+ status: farmConfigFromFile.status,
1433
+ loanToValuePct: farmConfigFromFile.loanToValuePct,
1434
+ liquidationThresholdPct: farmConfigFromFile.liquidationThresholdPct,
1435
+ minLiquidationBonusBps: farmConfigFromFile.minLiquidationBonusBps,
1436
+ protocolLiquidationFeePct: farmConfigFromFile.protocolLiquidationFeePct,
1437
+ protocolTakeRatePct: farmConfigFromFile.protocolLiquidationFeePct,
1438
+ assetTier: farmConfigFromFile.assetTier,
1439
+ maxLiquidationBonusBps: farmConfigFromFile.maxLiquidationBonusBps,
1440
+ badDebtLiquidationBonusBps: farmConfigFromFile.badDebtLiquidationBonusBps,
1334
1441
  fees: {
1335
- borrowFeeSf: Fraction.fromDecimal(new Decimal(reserveConfigFromFile.fees.borrowFee)).valueSf,
1336
- flashLoanFeeSf: Fraction.fromDecimal(new Decimal(reserveConfigFromFile.fees.flashLoanFee)).valueSf,
1442
+ borrowFeeSf: Fraction.fromDecimal(new Decimal(farmConfigFromFile.fees.borrowFee)).valueSf,
1443
+ flashLoanFeeSf: Fraction.fromDecimal(new Decimal(farmConfigFromFile.fees.flashLoanFee)).valueSf,
1337
1444
  padding: Array(8).fill(0),
1338
1445
  },
1339
- depositLimit: new BN(reserveConfigFromFile.depositLimit),
1340
- borrowLimit: new BN(reserveConfigFromFile.borrowLimit),
1446
+ depositLimit: new BN(farmConfigFromFile.depositLimit),
1447
+ borrowLimit: new BN(farmConfigFromFile.borrowLimit),
1341
1448
  tokenInfo: {
1342
- name: encodeTokenName(reserveConfigFromFile.tokenInfo.name),
1449
+ name: encodeTokenName(farmConfigFromFile.tokenInfo.name),
1343
1450
  heuristic: new PriceHeuristic({
1344
- lower: new BN(reserveConfigFromFile.tokenInfo.heuristic.lower),
1345
- upper: new BN(reserveConfigFromFile.tokenInfo.heuristic.upper),
1346
- exp: new BN(reserveConfigFromFile.tokenInfo.heuristic.exp),
1451
+ lower: new BN(farmConfigFromFile.tokenInfo.heuristic.lower),
1452
+ upper: new BN(farmConfigFromFile.tokenInfo.heuristic.upper),
1453
+ exp: new BN(farmConfigFromFile.tokenInfo.heuristic.exp),
1347
1454
  }),
1348
- maxTwapDivergenceBps: new BN(reserveConfigFromFile.tokenInfo.maxTwapDivergenceBps),
1349
- maxAgePriceSeconds: new BN(reserveConfigFromFile.tokenInfo.maxAgePriceSeconds),
1350
- maxAgeTwapSeconds: new BN(reserveConfigFromFile.tokenInfo.maxAgeTwapSeconds),
1351
- ...parseOracleConfiguration(reserveConfigFromFile),
1352
- blockPriceUsage: reserveConfigFromFile.tokenInfo.blockPriceUsage,
1455
+ maxTwapDivergenceBps: new BN(farmConfigFromFile.tokenInfo.maxTwapDivergenceBps),
1456
+ maxAgePriceSeconds: new BN(farmConfigFromFile.tokenInfo.maxAgePriceSeconds),
1457
+ maxAgeTwapSeconds: new BN(farmConfigFromFile.tokenInfo.maxAgeTwapSeconds),
1458
+ ...parseOracleConfiguration(farmConfigFromFile),
1459
+ blockPriceUsage: farmConfigFromFile.tokenInfo.blockPriceUsage,
1353
1460
  reserved: Array(7).fill(0),
1354
1461
  padding: Array(19).fill(new BN(0)),
1355
1462
  } as TokenInfo,
1356
- borrowRateCurve: parseBorrowRateCurve(reserveConfigFromFile),
1463
+ borrowRateCurve: parseBorrowRateCurve(farmConfigFromFile),
1357
1464
  depositWithdrawalCap: new WithdrawalCaps({
1358
- configCapacity: new BN(reserveConfigFromFile.depositWithdrawalCap.configCapacity),
1465
+ configCapacity: new BN(farmConfigFromFile.depositWithdrawalCap.configCapacity),
1359
1466
  currentTotal: new BN(0),
1360
1467
  lastIntervalStartTimestamp: new BN(0),
1361
- configIntervalLengthSeconds: new BN(reserveConfigFromFile.depositWithdrawalCap.configIntervalLengthSeconds),
1468
+ configIntervalLengthSeconds: new BN(farmConfigFromFile.depositWithdrawalCap.configIntervalLengthSeconds),
1362
1469
  }),
1363
1470
  debtWithdrawalCap: new WithdrawalCaps({
1364
- configCapacity: new BN(reserveConfigFromFile.debtWithdrawalCap.configCapacity),
1471
+ configCapacity: new BN(farmConfigFromFile.debtWithdrawalCap.configCapacity),
1365
1472
  currentTotal: new BN(0),
1366
1473
  lastIntervalStartTimestamp: new BN(0),
1367
- configIntervalLengthSeconds: new BN(reserveConfigFromFile.debtWithdrawalCap.configIntervalLengthSeconds),
1474
+ configIntervalLengthSeconds: new BN(farmConfigFromFile.debtWithdrawalCap.configIntervalLengthSeconds),
1368
1475
  }),
1369
- deleveragingMarginCallPeriodSecs: new BN(reserveConfigFromFile.deleveragingMarginCallPeriodSecs),
1370
- borrowFactorPct: new BN(reserveConfigFromFile.borrowFactorPct),
1371
- elevationGroups: reserveConfigFromFile.elevationGroups,
1372
- deleveragingThresholdDecreaseBpsPerDay: new BN(reserveConfigFromFile.deleveragingThresholdDecreaseBpsPerDay),
1373
- disableUsageAsCollOutsideEmode: reserveConfigFromFile.disableUsageAsCollOutsideEmode,
1374
- utilizationLimitBlockBorrowingAbovePct: reserveConfigFromFile.utilizationLimitBlockBorrowingAbovePct,
1375
- hostFixedInterestRateBps: reserveConfigFromFile.hostFixedInterestRateBps,
1376
- autodeleverageEnabled: reserveConfigFromFile.autodeleverageEnabled,
1377
- borrowLimitOutsideElevationGroup: new BN(reserveConfigFromFile.borrowLimitOutsideElevationGroup),
1378
- borrowLimitAgainstThisCollateralInElevationGroup: parseReserveBorrowLimitAgainstCollInEmode(reserveConfigFromFile),
1379
- deleveragingBonusIncreaseBpsPerDay: new BN(reserveConfigFromFile.deleveragingBonusIncreaseBpsPerDay),
1380
- reserved1: Array(1).fill(0),
1476
+ deleveragingMarginCallPeriodSecs: new BN(farmConfigFromFile.deleveragingMarginCallPeriodSecs),
1477
+ borrowFactorPct: new BN(farmConfigFromFile.borrowFactorPct),
1478
+ elevationGroups: farmConfigFromFile.elevationGroups,
1479
+ deleveragingThresholdDecreaseBpsPerDay: new BN(farmConfigFromFile.deleveragingThresholdDecreaseBpsPerDay),
1480
+ disableUsageAsCollOutsideEmode: farmConfigFromFile.disableUsageAsCollOutsideEmode,
1481
+ utilizationLimitBlockBorrowingAbovePct: farmConfigFromFile.utilizationLimitBlockBorrowingAbovePct,
1482
+ hostFixedInterestRateBps: farmConfigFromFile.hostFixedInterestRateBps,
1483
+ autodeleverageEnabled: farmConfigFromFile.autodeleverageEnabled,
1484
+ borrowLimitOutsideElevationGroup: new BN(farmConfigFromFile.borrowLimitOutsideElevationGroup),
1485
+ borrowLimitAgainstThisCollateralInElevationGroup: parseReserveBorrowLimitAgainstCollInEmode(farmConfigFromFile),
1486
+ deleveragingBonusIncreaseBpsPerDay: new BN(farmConfigFromFile.deleveragingBonusIncreaseBpsPerDay),
1487
+ reserved1: Array(2).fill(0),
1381
1488
  reserved2: Array(2).fill(0),
1382
1489
  reserved3: Array(8).fill(0),
1383
1490
  };
@@ -1385,29 +1492,29 @@ function parseReserveConfigFromFile(reserveConfigFromFile: any): ReserveConfig {
1385
1492
  return new ReserveConfig(reserveConfigFields);
1386
1493
  }
1387
1494
 
1388
- function parseOracleConfiguration(reserveConfigFromFile: any): {
1495
+ function parseOracleConfiguration(farmConfigFromFile: any): {
1389
1496
  pythConfiguration: PythConfiguration;
1390
1497
  switchboardConfiguration: SwitchboardConfiguration;
1391
1498
  scopeConfiguration: ScopeConfiguration;
1392
1499
  } {
1393
1500
  const pythConfiguration = new PythConfiguration({
1394
- price: new PublicKey(reserveConfigFromFile.tokenInfo.pythConfiguration.price),
1501
+ price: new PublicKey(farmConfigFromFile.tokenInfo.pythConfiguration.price),
1395
1502
  });
1396
1503
  const switchboardConfiguration = new SwitchboardConfiguration({
1397
- priceAggregator: new PublicKey(reserveConfigFromFile.tokenInfo.switchboardConfiguration.priceAggregator),
1398
- twapAggregator: new PublicKey(reserveConfigFromFile.tokenInfo.switchboardConfiguration.twapAggregator),
1504
+ priceAggregator: new PublicKey(farmConfigFromFile.tokenInfo.switchboardConfiguration.priceAggregator),
1505
+ twapAggregator: new PublicKey(farmConfigFromFile.tokenInfo.switchboardConfiguration.twapAggregator),
1399
1506
  });
1400
1507
  const priceChain = [65535, 65535, 65535, 65535];
1401
1508
  const twapChain = [65535, 65535, 65535, 65535];
1402
1509
 
1403
- const priceChainFromFile: number[] = reserveConfigFromFile.tokenInfo.scopeConfiguration.priceChain;
1404
- const twapChainFromFile: number[] = reserveConfigFromFile.tokenInfo.scopeConfiguration.twapChain;
1510
+ const priceChainFromFile: number[] = farmConfigFromFile.tokenInfo.scopeConfiguration.priceChain;
1511
+ const twapChainFromFile: number[] = farmConfigFromFile.tokenInfo.scopeConfiguration.twapChain;
1405
1512
 
1406
1513
  priceChainFromFile.forEach((value, index) => (priceChain[index] = value));
1407
1514
  twapChainFromFile.forEach((value, index) => (twapChain[index] = value));
1408
1515
 
1409
1516
  const scopeConfiguration = new ScopeConfiguration({
1410
- priceFeed: new PublicKey(reserveConfigFromFile.tokenInfo.scopeConfiguration.priceFeed),
1517
+ priceFeed: new PublicKey(farmConfigFromFile.tokenInfo.scopeConfiguration.priceFeed),
1411
1518
  priceChain: priceChain,
1412
1519
  twapChain: twapChain,
1413
1520
  });
@@ -1419,29 +1526,29 @@ function parseOracleConfiguration(reserveConfigFromFile: any): {
1419
1526
  };
1420
1527
  }
1421
1528
 
1422
- function parseBorrowRateCurve(reserveConfigFromFile: any): BorrowRateCurve {
1529
+ function parseBorrowRateCurve(farmConfigFromFile: any): BorrowRateCurve {
1423
1530
  const curvePoints: CurvePointFields[] = [];
1424
1531
 
1425
- reserveConfigFromFile.borrowRateCurve.points.forEach((curvePoint: { utilizationRateBps: any; borrowRateBps: any }) =>
1532
+ farmConfigFromFile.borrowRateCurve.points.forEach((curvePoint: { utilizationRateBps: any; borrowRateBps: any }) =>
1426
1533
  curvePoints.push({
1427
1534
  utilizationRateBps: curvePoint.utilizationRateBps,
1428
1535
  borrowRateBps: curvePoint.borrowRateBps,
1429
1536
  })
1430
1537
  );
1431
1538
 
1432
- const finalCurvePoints: CurvePointFields[] = Array(11).fill(curvePoints[curvePoints.length - 1]);
1539
+ const finalCruvePoints: CurvePointFields[] = Array(11).fill(curvePoints[curvePoints.length - 1]);
1433
1540
 
1434
- curvePoints.forEach((curvePoint, index) => (finalCurvePoints[index] = curvePoint));
1541
+ curvePoints.forEach((curvePoint, index) => (finalCruvePoints[index] = curvePoint));
1435
1542
 
1436
- const borrowRateCurve = new BorrowRateCurve({ points: finalCurvePoints });
1543
+ const borrowRateCurve = new BorrowRateCurve({ points: finalCruvePoints });
1437
1544
 
1438
1545
  return borrowRateCurve;
1439
1546
  }
1440
1547
 
1441
- function parseReserveBorrowLimitAgainstCollInEmode(reserveConfigFromFile: any): BN[] {
1548
+ function parseReserveBorrowLimitAgainstCollInEmode(farmConfigFromFile: any): BN[] {
1442
1549
  const reserveBorrowLimitAgainstCollInEmode: BN[] = Array(32).fill(new BN(0));
1443
1550
 
1444
- reserveConfigFromFile.borrowLimitAgainstThisCollateralInElevationGroup.forEach(
1551
+ farmConfigFromFile.borrowLimitAgainstThisCollateralInElevationGroup.forEach(
1445
1552
  (limit: any, index: number) => (reserveBorrowLimitAgainstCollInEmode[index] = new BN(limit))
1446
1553
  );
1447
1554
 
@@ -24,6 +24,7 @@ export interface VaultStateFields {
24
24
  prevAumSf: BN
25
25
  pendingFeesSf: BN
26
26
  vaultAllocationStrategy: Array<types.VaultAllocationFields>
27
+ padding1: Array<BN>
27
28
  minDepositAmount: BN
28
29
  minWithdrawAmount: BN
29
30
  minInvestAmount: BN
@@ -37,9 +38,9 @@ export interface VaultStateFields {
37
38
  vaultLookupTable: PublicKey
38
39
  vaultFarm: PublicKey
39
40
  creationTimestamp: BN
40
- padding1: BN
41
+ padding2: BN
41
42
  allocationAdmin: PublicKey
42
- padding2: Array<BN>
43
+ padding3: Array<BN>
43
44
  }
44
45
 
45
46
  export interface VaultStateJSON {
@@ -62,6 +63,7 @@ export interface VaultStateJSON {
62
63
  prevAumSf: string
63
64
  pendingFeesSf: string
64
65
  vaultAllocationStrategy: Array<types.VaultAllocationJSON>
66
+ padding1: Array<string>
65
67
  minDepositAmount: string
66
68
  minWithdrawAmount: string
67
69
  minInvestAmount: string
@@ -75,9 +77,9 @@ export interface VaultStateJSON {
75
77
  vaultLookupTable: string
76
78
  vaultFarm: string
77
79
  creationTimestamp: string
78
- padding1: string
80
+ padding2: string
79
81
  allocationAdmin: string
80
- padding2: Array<string>
82
+ padding3: Array<string>
81
83
  }
82
84
 
83
85
  export class VaultState {
@@ -100,6 +102,7 @@ export class VaultState {
100
102
  readonly prevAumSf: BN
101
103
  readonly pendingFeesSf: BN
102
104
  readonly vaultAllocationStrategy: Array<types.VaultAllocation>
105
+ readonly padding1: Array<BN>
103
106
  readonly minDepositAmount: BN
104
107
  readonly minWithdrawAmount: BN
105
108
  readonly minInvestAmount: BN
@@ -113,9 +116,9 @@ export class VaultState {
113
116
  readonly vaultLookupTable: PublicKey
114
117
  readonly vaultFarm: PublicKey
115
118
  readonly creationTimestamp: BN
116
- readonly padding1: BN
119
+ readonly padding2: BN
117
120
  readonly allocationAdmin: PublicKey
118
- readonly padding2: Array<BN>
121
+ readonly padding3: Array<BN>
119
122
 
120
123
  static readonly discriminator = Buffer.from([
121
124
  228, 196, 82, 165, 98, 210, 235, 152,
@@ -140,7 +143,8 @@ export class VaultState {
140
143
  borsh.u64("lastFeeChargeTimestamp"),
141
144
  borsh.u128("prevAumSf"),
142
145
  borsh.u128("pendingFeesSf"),
143
- borsh.array(types.VaultAllocation.layout(), 10, "vaultAllocationStrategy"),
146
+ borsh.array(types.VaultAllocation.layout(), 25, "vaultAllocationStrategy"),
147
+ borsh.array(borsh.u128(), 256, "padding1"),
144
148
  borsh.u64("minDepositAmount"),
145
149
  borsh.u64("minWithdrawAmount"),
146
150
  borsh.u64("minInvestAmount"),
@@ -154,9 +158,9 @@ export class VaultState {
154
158
  borsh.publicKey("vaultLookupTable"),
155
159
  borsh.publicKey("vaultFarm"),
156
160
  borsh.u64("creationTimestamp"),
157
- borsh.u64("padding1"),
161
+ borsh.u64("padding2"),
158
162
  borsh.publicKey("allocationAdmin"),
159
- borsh.array(borsh.u128(), 242, "padding2"),
163
+ borsh.array(borsh.u128(), 242, "padding3"),
160
164
  ])
161
165
 
162
166
  constructor(fields: VaultStateFields) {
@@ -181,6 +185,7 @@ export class VaultState {
181
185
  this.vaultAllocationStrategy = fields.vaultAllocationStrategy.map(
182
186
  (item) => new types.VaultAllocation({ ...item })
183
187
  )
188
+ this.padding1 = fields.padding1
184
189
  this.minDepositAmount = fields.minDepositAmount
185
190
  this.minWithdrawAmount = fields.minWithdrawAmount
186
191
  this.minInvestAmount = fields.minInvestAmount
@@ -194,9 +199,9 @@ export class VaultState {
194
199
  this.vaultLookupTable = fields.vaultLookupTable
195
200
  this.vaultFarm = fields.vaultFarm
196
201
  this.creationTimestamp = fields.creationTimestamp
197
- this.padding1 = fields.padding1
198
- this.allocationAdmin = fields.allocationAdmin
199
202
  this.padding2 = fields.padding2
203
+ this.allocationAdmin = fields.allocationAdmin
204
+ this.padding3 = fields.padding3
200
205
  }
201
206
 
202
207
  static async fetch(
@@ -266,6 +271,7 @@ export class VaultState {
266
271
  item: any /* eslint-disable-line @typescript-eslint/no-explicit-any */
267
272
  ) => types.VaultAllocation.fromDecoded(item)
268
273
  ),
274
+ padding1: dec.padding1,
269
275
  minDepositAmount: dec.minDepositAmount,
270
276
  minWithdrawAmount: dec.minWithdrawAmount,
271
277
  minInvestAmount: dec.minInvestAmount,
@@ -279,9 +285,9 @@ export class VaultState {
279
285
  vaultLookupTable: dec.vaultLookupTable,
280
286
  vaultFarm: dec.vaultFarm,
281
287
  creationTimestamp: dec.creationTimestamp,
282
- padding1: dec.padding1,
283
- allocationAdmin: dec.allocationAdmin,
284
288
  padding2: dec.padding2,
289
+ allocationAdmin: dec.allocationAdmin,
290
+ padding3: dec.padding3,
285
291
  })
286
292
  }
287
293
 
@@ -308,6 +314,7 @@ export class VaultState {
308
314
  vaultAllocationStrategy: this.vaultAllocationStrategy.map((item) =>
309
315
  item.toJSON()
310
316
  ),
317
+ padding1: this.padding1.map((item) => item.toString()),
311
318
  minDepositAmount: this.minDepositAmount.toString(),
312
319
  minWithdrawAmount: this.minWithdrawAmount.toString(),
313
320
  minInvestAmount: this.minInvestAmount.toString(),
@@ -321,9 +328,9 @@ export class VaultState {
321
328
  vaultLookupTable: this.vaultLookupTable.toString(),
322
329
  vaultFarm: this.vaultFarm.toString(),
323
330
  creationTimestamp: this.creationTimestamp.toString(),
324
- padding1: this.padding1.toString(),
331
+ padding2: this.padding2.toString(),
325
332
  allocationAdmin: this.allocationAdmin.toString(),
326
- padding2: this.padding2.map((item) => item.toString()),
333
+ padding3: this.padding3.map((item) => item.toString()),
327
334
  }
328
335
  }
329
336
 
@@ -350,6 +357,7 @@ export class VaultState {
350
357
  vaultAllocationStrategy: obj.vaultAllocationStrategy.map((item) =>
351
358
  types.VaultAllocation.fromJSON(item)
352
359
  ),
360
+ padding1: obj.padding1.map((item) => new BN(item)),
353
361
  minDepositAmount: new BN(obj.minDepositAmount),
354
362
  minWithdrawAmount: new BN(obj.minWithdrawAmount),
355
363
  minInvestAmount: new BN(obj.minInvestAmount),
@@ -363,9 +371,9 @@ export class VaultState {
363
371
  vaultLookupTable: new PublicKey(obj.vaultLookupTable),
364
372
  vaultFarm: new PublicKey(obj.vaultFarm),
365
373
  creationTimestamp: new BN(obj.creationTimestamp),
366
- padding1: new BN(obj.padding1),
374
+ padding2: new BN(obj.padding2),
367
375
  allocationAdmin: new PublicKey(obj.allocationAdmin),
368
- padding2: obj.padding2.map((item) => new BN(item)),
376
+ padding3: obj.padding3.map((item) => new BN(item)),
369
377
  })
370
378
  }
371
379
  }
@@ -46,6 +46,7 @@ export type CustomError =
46
46
  | MinWithdrawAmountTooBig
47
47
  | InvestTooSoon
48
48
  | WrongAdminOrAllocationAdmin
49
+ | ReserveHasNonZeroAllocationOrCTokens
49
50
 
50
51
  export class DepositAmountsZero extends Error {
51
52
  static readonly code = 7000
@@ -564,6 +565,20 @@ export class WrongAdminOrAllocationAdmin extends Error {
564
565
  }
565
566
  }
566
567
 
568
+ export class ReserveHasNonZeroAllocationOrCTokens extends Error {
569
+ static readonly code = 7047
570
+ readonly code = 7047
571
+ readonly name = "ReserveHasNonZeroAllocationOrCTokens"
572
+ readonly msg =
573
+ "Reserve has non-zero allocation or ctokens so cannot be removed"
574
+
575
+ constructor(readonly logs?: string[]) {
576
+ super(
577
+ "7047: Reserve has non-zero allocation or ctokens so cannot be removed"
578
+ )
579
+ }
580
+ }
581
+
567
582
  export function fromCode(code: number, logs?: string[]): CustomError | null {
568
583
  switch (code) {
569
584
  case 7000:
@@ -660,6 +675,8 @@ export function fromCode(code: number, logs?: string[]): CustomError | null {
660
675
  return new InvestTooSoon(logs)
661
676
  case 7046:
662
677
  return new WrongAdminOrAllocationAdmin(logs)
678
+ case 7047:
679
+ return new ReserveHasNonZeroAllocationOrCTokens(logs)
663
680
  }
664
681
 
665
682
  return null
@@ -40,3 +40,5 @@ export type {
40
40
  WithdrawFromAvailableArgs,
41
41
  WithdrawFromAvailableAccounts,
42
42
  } from "./withdrawFromAvailable"
43
+ export { removeAllocation } from "./removeAllocation"
44
+ export type { RemoveAllocationAccounts } from "./removeAllocation"
@@ -0,0 +1,26 @@
1
+ import { TransactionInstruction, PublicKey, AccountMeta } from "@solana/web3.js" // eslint-disable-line @typescript-eslint/no-unused-vars
2
+ import BN from "bn.js" // eslint-disable-line @typescript-eslint/no-unused-vars
3
+ import * as borsh from "@coral-xyz/borsh" // eslint-disable-line @typescript-eslint/no-unused-vars
4
+ import * as types from "../types" // eslint-disable-line @typescript-eslint/no-unused-vars
5
+ import { PROGRAM_ID } from "../programId"
6
+
7
+ export interface RemoveAllocationAccounts {
8
+ vaultAdminAuthority: PublicKey
9
+ vaultState: PublicKey
10
+ reserve: PublicKey
11
+ }
12
+
13
+ export function removeAllocation(
14
+ accounts: RemoveAllocationAccounts,
15
+ programId: PublicKey = PROGRAM_ID
16
+ ) {
17
+ const keys: Array<AccountMeta> = [
18
+ { pubkey: accounts.vaultAdminAuthority, isSigner: true, isWritable: true },
19
+ { pubkey: accounts.vaultState, isSigner: false, isWritable: true },
20
+ { pubkey: accounts.reserve, isSigner: false, isWritable: false },
21
+ ]
22
+ const identifier = Buffer.from([32, 220, 211, 141, 209, 231, 73, 76])
23
+ const data = identifier
24
+ const ix = new TransactionInstruction({ keys, programId, data })
25
+ return ix
26
+ }
@@ -2,13 +2,12 @@ import { PublicKey } from "@solana/web3.js"
2
2
 
3
3
  // Program ID passed with the cli --program-id flag when running the code generator. Do not edit, it will get overwritten.
4
4
  export const KVAULTS_PROGRAM_ID_CLI = new PublicKey(
5
- "kvauTFR8qm1dhniz6pYuBZkuene3Hfrs1VQhVRgCNrr"
5
+ "KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd"
6
6
  )
7
7
 
8
8
  // This constant will not get overwritten on subsequent code generations and it's safe to modify it's value.
9
9
  export let KVAULTS_PROGRAM_ID: PublicKey = KVAULTS_PROGRAM_ID_CLI
10
10
  export let PROGRAM_ID: PublicKey = KVAULTS_PROGRAM_ID_CLI
11
-
12
11
  export const setKVaultsProgramId = (programId: PublicKey) => {
13
12
  KVAULTS_PROGRAM_ID = programId;
14
13
  PROGRAM_ID = programId;