@voltr/vault-sdk 0.2.0 → 1.0.1
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.
- package/README.md +97 -9
- package/dist/client.d.ts +193 -39
- package/dist/client.js +254 -54
- package/dist/constants.d.ts +6 -2
- package/dist/constants.js +8 -3
- package/dist/decimals.d.ts +3 -0
- package/dist/decimals.js +10 -0
- package/dist/idl/voltr_vault.json +772 -63
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/types/vault.d.ts +4 -4
- package/dist/types/voltr_vault.d.ts +771 -62
- package/package.json +5 -2
package/dist/client.js
CHANGED
|
@@ -32,14 +32,19 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
35
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
39
|
exports.VoltrClient = void 0;
|
|
37
40
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
41
|
+
const bn_js_1 = __importDefault(require("bn.js"));
|
|
38
42
|
const web3_js_1 = require("@solana/web3.js");
|
|
39
43
|
const spl_token_1 = require("@solana/spl-token");
|
|
40
44
|
const constants_1 = require("./constants");
|
|
41
45
|
// Import IDL files
|
|
42
46
|
const vaultIdl = __importStar(require("./idl/voltr_vault.json"));
|
|
47
|
+
const decimals_1 = require("./decimals");
|
|
43
48
|
class CustomWallet {
|
|
44
49
|
constructor(payer) {
|
|
45
50
|
this.payer = payer;
|
|
@@ -227,6 +232,21 @@ class VoltrClient extends AccountUtils {
|
|
|
227
232
|
directWithdrawInitReceipt,
|
|
228
233
|
};
|
|
229
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* Finds the request withdraw vault receipt address
|
|
237
|
+
* @param vault - Public key of the vault
|
|
238
|
+
* @param user - Public key of the user
|
|
239
|
+
* @returns The PDA for the request withdraw vault receipt
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```typescript
|
|
243
|
+
* const requestWithdrawVaultReceipt = client.findRequestWithdrawVaultReceipt(vaultPubkey, userPubkey);
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
findRequestWithdrawVaultReceipt(vault, user) {
|
|
247
|
+
const [requestWithdrawVaultReceipt] = web3_js_1.PublicKey.findProgramAddressSync([constants_1.SEEDS.REQUEST_WITHDRAW_VAULT_RECEIPT, vault.toBuffer(), user.toBuffer()], this.vaultProgram.programId);
|
|
248
|
+
return requestWithdrawVaultReceipt;
|
|
249
|
+
}
|
|
230
250
|
// --------------------------------------- Vault Instructions
|
|
231
251
|
/**
|
|
232
252
|
* Creates an instruction to initialize a new vault
|
|
@@ -235,10 +255,14 @@ class VoltrClient extends AccountUtils {
|
|
|
235
255
|
* @param {VaultConfig} vaultParams.config - Vault configuration settings
|
|
236
256
|
* @param {BN} vaultParams.config.maxCap - Maximum capacity of the vault
|
|
237
257
|
* @param {BN} vaultParams.config.startAtTs - Vault start timestamp in seconds
|
|
258
|
+
* @param {BN} vaultParams.config.lockedProfitDegradationDuration - Locked profit degradation duration in seconds
|
|
238
259
|
* @param {number} vaultParams.config.managerManagementFee - Manager's management fee in basis points (e.g., 50 = 0.5%)
|
|
239
260
|
* @param {number} vaultParams.config.managerPerformanceFee - Manager's performance fee in basis points (e.g., 1000 = 10%)
|
|
240
261
|
* @param {number} vaultParams.config.adminManagementFee - Admin's management fee in basis points (e.g., 50 = 0.5%)
|
|
241
262
|
* @param {number} vaultParams.config.adminPerformanceFee - Admin's performance fee in basis points (e.g., 1000 = 10%)
|
|
263
|
+
* @param {number} vaultParams.config.redemptionFee - Redemption fee in basis points (e.g., 10 = 0.1%)
|
|
264
|
+
* @param {number} vaultParams.config.issuanceFee - Issuance fee in basis points (e.g., 10 = 0.1%)
|
|
265
|
+
* @param {BN} vaultParams.config.withdrawalWaitingPeriod - Withdrawal waiting period in seconds
|
|
242
266
|
* @param {string} vaultParams.name - Name of the vault
|
|
243
267
|
* @param {string} vaultParams.description - Description of the vault
|
|
244
268
|
* @param {Object} params - Additional parameters for initializing the vault
|
|
@@ -256,6 +280,10 @@ class VoltrClient extends AccountUtils {
|
|
|
256
280
|
* config: {
|
|
257
281
|
* maxCap: new BN('1000000000'),
|
|
258
282
|
* startAtTs: new BN(Math.floor(Date.now() / 1000)),
|
|
283
|
+
* lockedProfitDegradationDuration: new BN(3600), // 1 hour
|
|
284
|
+
* redemptionFee: 10,
|
|
285
|
+
* issuanceFee: 10,
|
|
286
|
+
* withdrawalWaitingPeriod: new BN(3600), // 1 hour
|
|
259
287
|
* managerManagementFee: 50, // 0.5%
|
|
260
288
|
* managerPerformanceFee: 1000, // 10%
|
|
261
289
|
* adminManagementFee: 50, // 0.5%
|
|
@@ -333,7 +361,7 @@ class VoltrClient extends AccountUtils {
|
|
|
333
361
|
*
|
|
334
362
|
* @param {BN} amount - Amount of tokens to deposit
|
|
335
363
|
* @param {Object} params - Deposit parameters
|
|
336
|
-
* @param {PublicKey} params.
|
|
364
|
+
* @param {PublicKey} params.userTransferAuthority - Public key of the user's transfer authority
|
|
337
365
|
* @param {PublicKey} params.vault - Public key of the vault
|
|
338
366
|
* @param {PublicKey} params.vaultAssetMint - Public key of the vault asset mint
|
|
339
367
|
* @param {PublicKey} params.assetTokenProgram - Public key of the asset token program
|
|
@@ -345,7 +373,7 @@ class VoltrClient extends AccountUtils {
|
|
|
345
373
|
* const ix = await client.createDepositVaultIx(
|
|
346
374
|
* new BN('1000000000'),
|
|
347
375
|
* {
|
|
348
|
-
*
|
|
376
|
+
* userTransferAuthority: userPubkey,
|
|
349
377
|
* vault: vaultPubkey,
|
|
350
378
|
* vaultAssetMint: mintPubkey,
|
|
351
379
|
* assetTokenProgram: tokenProgramPubkey
|
|
@@ -353,11 +381,11 @@ class VoltrClient extends AccountUtils {
|
|
|
353
381
|
* );
|
|
354
382
|
* ```
|
|
355
383
|
*/
|
|
356
|
-
async createDepositVaultIx(amount, {
|
|
384
|
+
async createDepositVaultIx(amount, { userTransferAuthority, vault, vaultAssetMint, assetTokenProgram, }) {
|
|
357
385
|
return await this.vaultProgram.methods
|
|
358
386
|
.depositVault(amount)
|
|
359
387
|
.accounts({
|
|
360
|
-
userTransferAuthority
|
|
388
|
+
userTransferAuthority,
|
|
361
389
|
vault,
|
|
362
390
|
vaultAssetMint,
|
|
363
391
|
assetTokenProgram,
|
|
@@ -365,41 +393,98 @@ class VoltrClient extends AccountUtils {
|
|
|
365
393
|
.instruction();
|
|
366
394
|
}
|
|
367
395
|
/**
|
|
368
|
-
* Creates a withdraw instruction for a vault
|
|
396
|
+
* Creates a request withdraw instruction for a vault
|
|
369
397
|
*
|
|
370
|
-
* @param {
|
|
371
|
-
* @param {BN}
|
|
372
|
-
* @param {boolean}
|
|
373
|
-
* @param {boolean}
|
|
374
|
-
* @param {Object} params -
|
|
375
|
-
* @param {PublicKey} params.
|
|
398
|
+
* @param {RequestWithdrawVaultArgs} requestWithdrawArgs - Arguments for withdrawing from the vault
|
|
399
|
+
* @param {BN} requestWithdrawArgs.amount - Amount of LP tokens to withdraw
|
|
400
|
+
* @param {boolean} requestWithdrawArgs.isAmountInLp - Whether the amount is in LP tokens
|
|
401
|
+
* @param {boolean} requestWithdrawArgs.isWithdrawAll - Whether to withdraw all assets
|
|
402
|
+
* @param {Object} params - Request withdraw parameters
|
|
403
|
+
* @param {PublicKey} params.payer - Public key of the payer
|
|
404
|
+
* @param {PublicKey} params.userTransferAuthority - Public key of the user authority
|
|
376
405
|
* @param {PublicKey} params.vault - Public key of the vault
|
|
377
|
-
* @param {PublicKey} params.vaultAssetMint - Public key of the vault asset mint
|
|
378
|
-
* @param {PublicKey} params.assetTokenProgram - Public key of the asset token program
|
|
379
406
|
* @returns {Promise<TransactionInstruction>} Transaction instruction for withdrawal
|
|
380
407
|
*
|
|
381
408
|
* @throws {Error} If the instruction creation fails
|
|
382
409
|
*
|
|
383
410
|
* @example
|
|
384
|
-
* const ix = await client.
|
|
411
|
+
* const ix = await client.createRequestWithdrawVaultIx(
|
|
385
412
|
* {
|
|
386
413
|
* amount: new BN('1000000000'),
|
|
387
414
|
* isAmountInLp: true,
|
|
388
415
|
* isWithdrawAll: false,
|
|
389
416
|
* },
|
|
390
417
|
* {
|
|
391
|
-
*
|
|
418
|
+
* payer: payerPubkey,
|
|
419
|
+
* userTransferAuthority: userPubkey,
|
|
420
|
+
* vault: vaultPubkey,
|
|
421
|
+
* }
|
|
422
|
+
* );
|
|
423
|
+
*/
|
|
424
|
+
async createRequestWithdrawVaultIx({ amount, isAmountInLp, isWithdrawAll }, { payer, userTransferAuthority, vault, }) {
|
|
425
|
+
return await this.vaultProgram.methods
|
|
426
|
+
.requestWithdrawVault(amount, isAmountInLp, isWithdrawAll)
|
|
427
|
+
.accounts({
|
|
428
|
+
payer,
|
|
429
|
+
userTransferAuthority,
|
|
430
|
+
vault,
|
|
431
|
+
})
|
|
432
|
+
.instruction();
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Creates a cancel withdraw instruction for a vault
|
|
436
|
+
*
|
|
437
|
+
* @param {Object} params - Cancel withdraw request parameters
|
|
438
|
+
* @param {PublicKey} params.userTransferAuthority - Public key of the user authority
|
|
439
|
+
* @param {PublicKey} params.vault - Public key of the vault
|
|
440
|
+
* @returns {Promise<TransactionInstruction>} Transaction instruction for withdrawal
|
|
441
|
+
*
|
|
442
|
+
* @throws {Error} If the instruction creation fails
|
|
443
|
+
*
|
|
444
|
+
* @example
|
|
445
|
+
* const ix = await client.createCancelRequestWithdrawVaultIx(
|
|
446
|
+
* {
|
|
447
|
+
* userTransferAuthority: userPubkey,
|
|
448
|
+
* vault: vaultPubkey,
|
|
449
|
+
* }
|
|
450
|
+
* );
|
|
451
|
+
*/
|
|
452
|
+
async createCancelRequestWithdrawVaultIx({ userTransferAuthority, vault, }) {
|
|
453
|
+
return await this.vaultProgram.methods
|
|
454
|
+
.cancelRequestWithdrawVault()
|
|
455
|
+
.accounts({
|
|
456
|
+
userTransferAuthority,
|
|
457
|
+
vault,
|
|
458
|
+
})
|
|
459
|
+
.instruction();
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Creates a withdraw instruction for a vault
|
|
463
|
+
*
|
|
464
|
+
* @param {Object} params - Withdraw parameters
|
|
465
|
+
* @param {PublicKey} params.userTransferAuthority - Public key of the user authority
|
|
466
|
+
* @param {PublicKey} params.vault - Public key of the vault
|
|
467
|
+
* @param {PublicKey} params.vaultAssetMint - Public key of the vault asset mint
|
|
468
|
+
* @param {PublicKey} params.assetTokenProgram - Public key of the asset token program
|
|
469
|
+
* @returns {Promise<TransactionInstruction>} Transaction instruction for withdrawal
|
|
470
|
+
*
|
|
471
|
+
* @throws {Error} If the instruction creation fails
|
|
472
|
+
*
|
|
473
|
+
* @example
|
|
474
|
+
* const ix = await client.createWithdrawVaultIx(
|
|
475
|
+
* {
|
|
476
|
+
* userTransferAuthority: userPubkey,
|
|
392
477
|
* vault: vaultPubkey,
|
|
393
478
|
* vaultAssetMint: mintPubkey,
|
|
394
479
|
* assetTokenProgram: tokenProgramPubkey
|
|
395
480
|
* }
|
|
396
481
|
* );
|
|
397
482
|
*/
|
|
398
|
-
async createWithdrawVaultIx({
|
|
483
|
+
async createWithdrawVaultIx({ userTransferAuthority, vault, vaultAssetMint, assetTokenProgram, }) {
|
|
399
484
|
return await this.vaultProgram.methods
|
|
400
|
-
.withdrawVault(
|
|
485
|
+
.withdrawVault()
|
|
401
486
|
.accounts({
|
|
402
|
-
userTransferAuthority
|
|
487
|
+
userTransferAuthority,
|
|
403
488
|
vault,
|
|
404
489
|
vaultAssetMint,
|
|
405
490
|
assetTokenProgram,
|
|
@@ -662,10 +747,7 @@ class VoltrClient extends AccountUtils {
|
|
|
662
747
|
}
|
|
663
748
|
/**
|
|
664
749
|
* Creates an instruction to withdraw assets from a direct withdraw strategy
|
|
665
|
-
* @param {
|
|
666
|
-
* @param {BN} directWithdrawArgs.amount - Amount of assets to withdraw
|
|
667
|
-
* @param {boolean} directWithdrawArgs.isAmountInLp - Whether the amount is in LP tokens
|
|
668
|
-
* @param {boolean} directWithdrawArgs.isWithdrawAll - Whether to withdraw all assets
|
|
750
|
+
* @param {Object} directWithdrawArgs - Withdrawal arguments
|
|
669
751
|
* @param {Buffer | null} [directWithdrawArgs.userArgs] - Optional user arguments for the instruction
|
|
670
752
|
* @param {Object} params - Parameters for withdrawing assets from direct withdraw strategy
|
|
671
753
|
* @param {PublicKey} params.user - Public key of the user
|
|
@@ -682,9 +764,6 @@ class VoltrClient extends AccountUtils {
|
|
|
682
764
|
* ```typescript
|
|
683
765
|
* const ix = await client.createDirectWithdrawStrategyIx(
|
|
684
766
|
* {
|
|
685
|
-
* amount: new BN('1000000000'),
|
|
686
|
-
* isAmountInLp: true,
|
|
687
|
-
* isWithdrawAll: false,
|
|
688
767
|
* userArgs: Buffer.from('...')
|
|
689
768
|
* },
|
|
690
769
|
* {
|
|
@@ -699,9 +778,9 @@ class VoltrClient extends AccountUtils {
|
|
|
699
778
|
* );
|
|
700
779
|
* ```
|
|
701
780
|
*/
|
|
702
|
-
async createDirectWithdrawStrategyIx({
|
|
781
|
+
async createDirectWithdrawStrategyIx({ userArgs = null }, { user, vault, strategy, vaultAssetMint, assetTokenProgram, adaptorProgram = constants_1.LENDING_ADAPTOR_PROGRAM_ID, remainingAccounts, }) {
|
|
703
782
|
return await this.vaultProgram.methods
|
|
704
|
-
.directWithdrawStrategy(
|
|
783
|
+
.directWithdrawStrategy(userArgs)
|
|
705
784
|
.accounts({
|
|
706
785
|
userTransferAuthority: user,
|
|
707
786
|
strategy,
|
|
@@ -746,6 +825,26 @@ class VoltrClient extends AccountUtils {
|
|
|
746
825
|
},
|
|
747
826
|
]);
|
|
748
827
|
}
|
|
828
|
+
/**
|
|
829
|
+
* Fetches all request withdraw vault receipt accounts of a vault
|
|
830
|
+
* @param vault - Public key of the vault
|
|
831
|
+
* @returns Promise resolving to an array of request withdraw vault receipt accounts
|
|
832
|
+
*
|
|
833
|
+
* @example
|
|
834
|
+
* ```typescript
|
|
835
|
+
* const requestWithdrawVaultReceiptAccounts = await client.fetchAllRequestWithdrawVaultReceiptsOfVault(vaultPubkey);
|
|
836
|
+
* ```
|
|
837
|
+
*/
|
|
838
|
+
async fetchAllRequestWithdrawVaultReceiptsOfVault(vault) {
|
|
839
|
+
return await this.vaultProgram.account.requestWithdrawVaultReceipt.all([
|
|
840
|
+
{
|
|
841
|
+
memcmp: {
|
|
842
|
+
offset: 8, // 8 for discriminator
|
|
843
|
+
bytes: vault.toBase58(),
|
|
844
|
+
},
|
|
845
|
+
},
|
|
846
|
+
]);
|
|
847
|
+
}
|
|
749
848
|
/**
|
|
750
849
|
* Fetches all adaptor add receipt accounts of a vault
|
|
751
850
|
* @param vault - Public key of the vault
|
|
@@ -815,6 +914,39 @@ class VoltrClient extends AccountUtils {
|
|
|
815
914
|
return await this.vaultProgram.account.adaptorAddReceipt.fetch(adaptorAddReceipt, "confirmed");
|
|
816
915
|
}
|
|
817
916
|
// --------------------------------------- Helpers
|
|
917
|
+
/**
|
|
918
|
+
* Fetches all pending withdrawals for a vault
|
|
919
|
+
* @param vault - Public key of the vault
|
|
920
|
+
* @returns Promise resolving to an array of pending withdrawals
|
|
921
|
+
*
|
|
922
|
+
* @example
|
|
923
|
+
* ```typescript
|
|
924
|
+
* const pendingWithdrawals = await client.getAllPendingWithdrawalsForVault(vaultPubkey);
|
|
925
|
+
* ```
|
|
926
|
+
*/
|
|
927
|
+
async getAllPendingWithdrawalsForVault(vault) {
|
|
928
|
+
const requestWithdrawVaultReceipts = await this.fetchAllRequestWithdrawVaultReceiptsOfVault(vault);
|
|
929
|
+
return requestWithdrawVaultReceipts.map((receipt) => {
|
|
930
|
+
const amountAssetToWithdrawDecimal = (0, decimals_1.convertDecimalBitsToDecimal)(receipt.account.amountAssetToWithdrawDecimalBits);
|
|
931
|
+
const amountAssetToWithdraw = amountAssetToWithdrawDecimal.toNumber();
|
|
932
|
+
return {
|
|
933
|
+
amountAssetToWithdraw,
|
|
934
|
+
withdrawableFromTs: receipt.account.withdrawableFromTs,
|
|
935
|
+
};
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
calculateLockedProfit(lastUpdatedLockedProfit, lockedProfitDegradationDuration, currentTime) {
|
|
939
|
+
if (lockedProfitDegradationDuration.eq(new bn_js_1.default(0)))
|
|
940
|
+
return new bn_js_1.default(0);
|
|
941
|
+
const duration = currentTime.sub(lastUpdatedLockedProfit);
|
|
942
|
+
const lockedProfit = lastUpdatedLockedProfit
|
|
943
|
+
.mul(lockedProfitDegradationDuration.sub(duration))
|
|
944
|
+
.div(lockedProfitDegradationDuration);
|
|
945
|
+
if (duration.gt(lockedProfitDegradationDuration))
|
|
946
|
+
return new bn_js_1.default(0);
|
|
947
|
+
else
|
|
948
|
+
return lockedProfit;
|
|
949
|
+
}
|
|
818
950
|
/**
|
|
819
951
|
* Calculates the amount of assets that would be received for a given LP token amount
|
|
820
952
|
*
|
|
@@ -834,33 +966,90 @@ class VoltrClient extends AccountUtils {
|
|
|
834
966
|
* ```
|
|
835
967
|
*/
|
|
836
968
|
async calculateAssetsForWithdraw(vaultPk, lpAmount) {
|
|
837
|
-
const vault = await this.fetchVaultAccount(vaultPk);
|
|
838
|
-
const totalValue = vault.asset.totalValue;
|
|
839
|
-
const lpMint = this.findVaultLpMint(vaultPk);
|
|
840
|
-
const lp = await (0, spl_token_1.getMint)(this.conn, lpMint);
|
|
841
|
-
const lpSupply = new anchor_1.BN(lp.supply.toString());
|
|
842
|
-
// Validate inputs
|
|
843
|
-
if (lpSupply <= new anchor_1.BN(0))
|
|
844
|
-
throw new Error("Invalid LP supply");
|
|
845
|
-
if (totalValue <= new anchor_1.BN(0))
|
|
846
|
-
throw new Error("Invalid total assets");
|
|
847
|
-
const amountPreRedemption = lpAmount.mul(totalValue).div(lpSupply);
|
|
848
|
-
const amount = amountPreRedemption
|
|
849
|
-
.mul(new anchor_1.BN(10000 - constants_1.REDEMPTION_FEE_PERCENTAGE_BPS))
|
|
850
|
-
.div(new anchor_1.BN(10000));
|
|
851
|
-
// Calculate: (lpAmount * totalValue) / totalLpSupply
|
|
852
969
|
try {
|
|
970
|
+
const vault = await this.fetchVaultAccount(vaultPk);
|
|
971
|
+
const totalValue = vault.asset.totalValue;
|
|
972
|
+
const lockedProfit = this.calculateLockedProfit(vault.lockedProfitState.lastUpdatedLockedProfit, vault.vaultConfiguration.lockedProfitDegradationDuration, new bn_js_1.default(Date.now() / 1000));
|
|
973
|
+
const totalUnlockedValue = totalValue.sub(lockedProfit);
|
|
974
|
+
const lpMint = this.findVaultLpMint(vaultPk);
|
|
975
|
+
const lp = await (0, spl_token_1.getMint)(this.conn, lpMint);
|
|
976
|
+
const lpSupply = new bn_js_1.default(lp.supply.toString());
|
|
977
|
+
// Validate inputs
|
|
978
|
+
if (lpSupply <= new bn_js_1.default(0))
|
|
979
|
+
throw new Error("Invalid LP supply");
|
|
980
|
+
if (totalValue <= new bn_js_1.default(0))
|
|
981
|
+
throw new Error("Invalid total assets");
|
|
982
|
+
const unharvestedFeesLp = vault.feeState.accumulatedLpAdminFees
|
|
983
|
+
.add(vault.feeState.accumulatedLpManagerFees)
|
|
984
|
+
.add(vault.feeState.accumulatedLpProtocolFees);
|
|
985
|
+
const lpSupplyInclFees = lpSupply.add(unharvestedFeesLp);
|
|
986
|
+
// asset_to_redeem_pre_fee = amount * (total_asset_pre_withdraw / total_lp_supply_pre_withdraw)
|
|
987
|
+
// asset_to_redeem_post_fee = asset_to_redeem_pre_fee * (10000 - redemption_fee_bps) / 10000
|
|
988
|
+
const assetToRedeemNumerator = lpAmount
|
|
989
|
+
.mul(totalUnlockedValue)
|
|
990
|
+
.mul(new bn_js_1.default(10000 - vault.feeConfiguration.redemptionFee));
|
|
991
|
+
const assetToRedeemDenominator = lpSupplyInclFees.mul(new bn_js_1.default(10000));
|
|
992
|
+
const amount = assetToRedeemNumerator.div(assetToRedeemDenominator);
|
|
853
993
|
return amount;
|
|
854
994
|
}
|
|
855
995
|
catch (e) {
|
|
856
|
-
throw new Error("Math overflow in asset calculation");
|
|
996
|
+
throw new Error("Math overflow in asset calculation for withdraw");
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* Calculates the amount of LP tokens that would be burned for a given asset amount
|
|
1001
|
+
*
|
|
1002
|
+
* @param vaultPk - Public key of the vault
|
|
1003
|
+
* @param assetAmount - Amount of assets to calculate for
|
|
1004
|
+
* @returns Promise resolving to the amount of LP tokens that would be burned
|
|
1005
|
+
*
|
|
1006
|
+
* @throws {Error} If LP supply or total assets are invalid
|
|
1007
|
+
* @throws {Error} If math overflow occurs during calculation
|
|
1008
|
+
*
|
|
1009
|
+
* @example
|
|
1010
|
+
* ```typescript
|
|
1011
|
+
* const lpTokensToBurn = await client.calculateLpForWithdraw(
|
|
1012
|
+
* vaultPubkey,
|
|
1013
|
+
* new BN('1000000000')
|
|
1014
|
+
* );
|
|
1015
|
+
* ```
|
|
1016
|
+
*/
|
|
1017
|
+
async calculateLpForWithdraw(vaultPk, assetAmount) {
|
|
1018
|
+
try {
|
|
1019
|
+
const vault = await this.fetchVaultAccount(vaultPk);
|
|
1020
|
+
const totalValue = vault.asset.totalValue;
|
|
1021
|
+
const lockedProfit = this.calculateLockedProfit(vault.lockedProfitState.lastUpdatedLockedProfit, vault.vaultConfiguration.lockedProfitDegradationDuration, new bn_js_1.default(Date.now() / 1000));
|
|
1022
|
+
const totalUnlockedValue = totalValue.sub(lockedProfit);
|
|
1023
|
+
const lpMint = this.findVaultLpMint(vaultPk);
|
|
1024
|
+
const lp = await (0, spl_token_1.getMint)(this.conn, lpMint);
|
|
1025
|
+
const lpSupply = new bn_js_1.default(lp.supply.toString());
|
|
1026
|
+
// Validate inputs
|
|
1027
|
+
if (lpSupply <= new bn_js_1.default(0))
|
|
1028
|
+
throw new Error("Invalid LP supply");
|
|
1029
|
+
if (totalValue <= new bn_js_1.default(0))
|
|
1030
|
+
throw new Error("Invalid total assets");
|
|
1031
|
+
const unharvestedFeesLp = vault.feeState.accumulatedLpAdminFees
|
|
1032
|
+
.add(vault.feeState.accumulatedLpManagerFees)
|
|
1033
|
+
.add(vault.feeState.accumulatedLpProtocolFees);
|
|
1034
|
+
const lpSupplyInclFees = lpSupply.add(unharvestedFeesLp);
|
|
1035
|
+
// lp_to_burn_pre_fee = redeem_amount * (total_lp_supply_pre_withdraw / total_asset_pre_withdraw)
|
|
1036
|
+
// lp_to_burn_post_fee = lp_to_burn_pre_fee * (10000 / (10000 - redemption_fee_bps))
|
|
1037
|
+
const lpToBurnNumerator = assetAmount
|
|
1038
|
+
.mul(lpSupplyInclFees)
|
|
1039
|
+
.mul(new bn_js_1.default(10000));
|
|
1040
|
+
const lpToBurnDenominator = totalUnlockedValue.mul(new bn_js_1.default(10000 - vault.feeConfiguration.redemptionFee));
|
|
1041
|
+
const lpToBurn = lpToBurnNumerator.div(lpToBurnDenominator);
|
|
1042
|
+
return lpToBurn;
|
|
1043
|
+
}
|
|
1044
|
+
catch (e) {
|
|
1045
|
+
throw new Error("Math overflow in LP token calculation for withdraw");
|
|
857
1046
|
}
|
|
858
1047
|
}
|
|
859
1048
|
/**
|
|
860
1049
|
* Calculates the amount of LP tokens that would be received for a given asset deposit
|
|
861
1050
|
*
|
|
862
|
-
* @param depositAmount - Amount of assets to deposit
|
|
863
1051
|
* @param vaultPk - Public key of the vault
|
|
1052
|
+
* @param assetAmount - Amount of assets to deposit
|
|
864
1053
|
* @returns Promise resolving to the amount of LP tokens that would be received
|
|
865
1054
|
*
|
|
866
1055
|
* @throws {Error} If math overflow occurs during calculation
|
|
@@ -868,32 +1057,43 @@ class VoltrClient extends AccountUtils {
|
|
|
868
1057
|
* @example
|
|
869
1058
|
* ```typescript
|
|
870
1059
|
* const lpTokens = await client.calculateLpTokensForDeposit(
|
|
871
|
-
* new BN('1000000000'),
|
|
872
1060
|
* vaultPubkey
|
|
1061
|
+
* new BN('1000000000'),
|
|
873
1062
|
* );
|
|
874
1063
|
* ```
|
|
875
1064
|
*/
|
|
876
|
-
async
|
|
1065
|
+
async calculateLpForDeposit(vaultPk, assetAmount) {
|
|
877
1066
|
const vault = await this.fetchVaultAccount(vaultPk);
|
|
878
1067
|
const totalValue = vault.asset.totalValue;
|
|
879
1068
|
const lpMint = this.findVaultLpMint(vaultPk);
|
|
880
1069
|
const lp = await (0, spl_token_1.getMint)(this.conn, lpMint);
|
|
881
|
-
const lpSupply = new
|
|
1070
|
+
const lpSupply = new bn_js_1.default(lp.supply.toString());
|
|
1071
|
+
const unharvestedFeesLp = vault.feeState.accumulatedLpAdminFees
|
|
1072
|
+
.add(vault.feeState.accumulatedLpManagerFees)
|
|
1073
|
+
.add(vault.feeState.accumulatedLpProtocolFees);
|
|
1074
|
+
const lpSupplyInclFees = lpSupply.add(unharvestedFeesLp);
|
|
882
1075
|
// If the pool is empty, mint LP tokens 1:1 with deposit
|
|
883
|
-
if (
|
|
1076
|
+
if (lpSupplyInclFees.eq(new bn_js_1.default(0))) {
|
|
884
1077
|
const assetMint = await (0, spl_token_1.getMint)(this.conn, vault.asset.mint);
|
|
885
1078
|
const assetDecimals = assetMint.decimals;
|
|
886
1079
|
const lpDecimals = lp.decimals;
|
|
887
|
-
return
|
|
888
|
-
.mul(new
|
|
889
|
-
.div(new
|
|
1080
|
+
return assetAmount
|
|
1081
|
+
.mul(new bn_js_1.default(10 ** lpDecimals))
|
|
1082
|
+
.div(new bn_js_1.default(10 ** assetDecimals));
|
|
890
1083
|
}
|
|
891
|
-
// Calculate: (depositAmount * totalLpSupply) / totalValue
|
|
892
1084
|
try {
|
|
893
|
-
|
|
1085
|
+
const lpToMintNumerator = assetAmount
|
|
1086
|
+
.mul(lpSupplyInclFees)
|
|
1087
|
+
.mul(new bn_js_1.default(10000 - vault.feeConfiguration.issuanceFee));
|
|
1088
|
+
const totalAssetPostDeposit = totalValue.add(assetAmount);
|
|
1089
|
+
const lpToMintDenominator = totalAssetPostDeposit
|
|
1090
|
+
.mul(new bn_js_1.default(10000))
|
|
1091
|
+
.sub(assetAmount.mul(new bn_js_1.default(10000 - vault.feeConfiguration.issuanceFee)));
|
|
1092
|
+
const lpToMint = lpToMintNumerator.div(lpToMintDenominator);
|
|
1093
|
+
return lpToMint;
|
|
894
1094
|
}
|
|
895
1095
|
catch (e) {
|
|
896
|
-
throw new Error("Math overflow in LP token calculation");
|
|
1096
|
+
throw new Error("Math overflow in LP token calculation for deposit");
|
|
897
1097
|
}
|
|
898
1098
|
}
|
|
899
1099
|
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -2,12 +2,16 @@ import { PublicKey } from "@solana/web3.js";
|
|
|
2
2
|
export declare const VAULT_PROGRAM_ID: PublicKey;
|
|
3
3
|
export declare const LENDING_ADAPTOR_PROGRAM_ID: PublicKey;
|
|
4
4
|
export declare const DRIFT_ADAPTOR_PROGRAM_ID: PublicKey;
|
|
5
|
-
export declare const REDEMPTION_FEE_PERCENTAGE_BPS = 10;
|
|
6
5
|
export declare const SEEDS: {
|
|
6
|
+
PROTOCOL: Buffer<ArrayBuffer>;
|
|
7
7
|
VAULT_LP_MINT: Buffer<ArrayBuffer>;
|
|
8
|
+
VAULT_LP_MINT_AUTH: Buffer<ArrayBuffer>;
|
|
8
9
|
VAULT_ASSET_IDLE_AUTH: Buffer<ArrayBuffer>;
|
|
9
|
-
|
|
10
|
+
ADAPTOR_ADD_RECEIPT: Buffer<ArrayBuffer>;
|
|
10
11
|
STRATEGY_INIT_RECEIPT: Buffer<ArrayBuffer>;
|
|
11
12
|
VAULT_STRATEGY_AUTH: Buffer<ArrayBuffer>;
|
|
13
|
+
VAULT_STRATEGY: Buffer<ArrayBuffer>;
|
|
12
14
|
DIRECT_WITHDRAW_INIT_RECEIPT_SEED: Buffer<ArrayBuffer>;
|
|
15
|
+
REQUEST_WITHDRAW_VAULT_RECEIPT: Buffer<ArrayBuffer>;
|
|
16
|
+
STRATEGY: Buffer<ArrayBuffer>;
|
|
13
17
|
};
|
package/dist/constants.js
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SEEDS = exports.
|
|
3
|
+
exports.SEEDS = exports.DRIFT_ADAPTOR_PROGRAM_ID = exports.LENDING_ADAPTOR_PROGRAM_ID = exports.VAULT_PROGRAM_ID = void 0;
|
|
4
4
|
const web3_js_1 = require("@solana/web3.js");
|
|
5
5
|
exports.VAULT_PROGRAM_ID = new web3_js_1.PublicKey("vVoLTRjQmtFpiYoegx285Ze4gsLJ8ZxgFKVcuvmG1a8");
|
|
6
6
|
exports.LENDING_ADAPTOR_PROGRAM_ID = new web3_js_1.PublicKey("aVoLTRCRt3NnnchvLYH6rMYehJHwM5m45RmLBZq7PGz");
|
|
7
7
|
exports.DRIFT_ADAPTOR_PROGRAM_ID = new web3_js_1.PublicKey("EBN93eXs5fHGBABuajQqdsKRkCgaqtJa8vEFD6vKXiP");
|
|
8
|
-
exports.REDEMPTION_FEE_PERCENTAGE_BPS = 10;
|
|
9
8
|
exports.SEEDS = {
|
|
9
|
+
PROTOCOL: Buffer.from("protocol"),
|
|
10
10
|
VAULT_LP_MINT: Buffer.from("vault_lp_mint"),
|
|
11
|
+
VAULT_LP_MINT_AUTH: Buffer.from("vault_lp_mint_auth"),
|
|
11
12
|
VAULT_ASSET_IDLE_AUTH: Buffer.from("vault_asset_idle_auth"),
|
|
12
|
-
|
|
13
|
+
ADAPTOR_ADD_RECEIPT: Buffer.from("adaptor_add_receipt"),
|
|
13
14
|
STRATEGY_INIT_RECEIPT: Buffer.from("strategy_init_receipt"),
|
|
14
15
|
VAULT_STRATEGY_AUTH: Buffer.from("vault_strategy_auth"),
|
|
16
|
+
VAULT_STRATEGY: Buffer.from("vault_strategy"),
|
|
15
17
|
DIRECT_WITHDRAW_INIT_RECEIPT_SEED: Buffer.from("direct_withdraw_init_receipt"),
|
|
18
|
+
REQUEST_WITHDRAW_VAULT_RECEIPT: Buffer.from("request_withdraw_vault_receipt"),
|
|
19
|
+
// TODO: Remove this
|
|
20
|
+
STRATEGY: Buffer.from("strategy"),
|
|
16
21
|
};
|
package/dist/decimals.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertDecimalBitsToDecimal = convertDecimalBitsToDecimal;
|
|
4
|
+
const decimal_js_1 = require("decimal.js");
|
|
5
|
+
const DECIMAL_FRACTIONAL_BYTES = 6;
|
|
6
|
+
const DECIMAL_DIVISOR = new decimal_js_1.Decimal(2).pow(8 * DECIMAL_FRACTIONAL_BYTES);
|
|
7
|
+
function convertDecimalBitsToDecimal(value) {
|
|
8
|
+
let decimalValue = new decimal_js_1.Decimal(value.toString());
|
|
9
|
+
return decimalValue.div(DECIMAL_DIVISOR);
|
|
10
|
+
}
|