@velocity-exchange/vaults-sdk 0.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.
Files changed (65) hide show
  1. package/.env.example +3 -0
  2. package/README.md +152 -0
  3. package/cli/cli.ts +751 -0
  4. package/cli/commands/adminDeleteFeeUpdate.ts +73 -0
  5. package/cli/commands/adminInitFeeUpdate.ts +73 -0
  6. package/cli/commands/adminUpdateVaultClass.ts +49 -0
  7. package/cli/commands/applyProfitShare.ts +139 -0
  8. package/cli/commands/decodeLogs.ts +98 -0
  9. package/cli/commands/deposit.ts +98 -0
  10. package/cli/commands/deriveVaultAddress.ts +14 -0
  11. package/cli/commands/forceWithdraw.ts +56 -0
  12. package/cli/commands/forceWithdrawAll.ts +142 -0
  13. package/cli/commands/index.ts +28 -0
  14. package/cli/commands/initVault.ts +227 -0
  15. package/cli/commands/initVaultDepositor.ts +42 -0
  16. package/cli/commands/listDepositorsForVault.ts +32 -0
  17. package/cli/commands/managerApplyProfitShare.ts +32 -0
  18. package/cli/commands/managerBorrow.ts +77 -0
  19. package/cli/commands/managerCancelWithdraw.ts +30 -0
  20. package/cli/commands/managerDeposit.ts +45 -0
  21. package/cli/commands/managerRepay.ts +94 -0
  22. package/cli/commands/managerRequestWithdraw.ts +86 -0
  23. package/cli/commands/managerUpdateBorrow.ts +56 -0
  24. package/cli/commands/managerUpdateFees.ts +156 -0
  25. package/cli/commands/managerUpdateMarginTradingEnabled.ts +32 -0
  26. package/cli/commands/managerUpdatePoolId.ts +36 -0
  27. package/cli/commands/managerUpdateVault.ts +210 -0
  28. package/cli/commands/managerUpdateVaultDelegate.ts +43 -0
  29. package/cli/commands/managerUpdateVaultManager.ts +77 -0
  30. package/cli/commands/managerWithdraw.ts +30 -0
  31. package/cli/commands/requestWithdraw.ts +58 -0
  32. package/cli/commands/vaultDeposit.ts +42 -0
  33. package/cli/commands/vaultInvariantChecks.ts +407 -0
  34. package/cli/commands/vaultWithdraw.ts +42 -0
  35. package/cli/commands/viewVault.ts +50 -0
  36. package/cli/commands/viewVaultDepositor.ts +36 -0
  37. package/cli/commands/withdraw.ts +40 -0
  38. package/cli/ledgerWallet.test.ts +49 -0
  39. package/cli/ledgerWallet.ts +111 -0
  40. package/cli/utils.ts +389 -0
  41. package/package.json +48 -0
  42. package/src/accountSubscribers/index.ts +2 -0
  43. package/src/accountSubscribers/pollingVaultDepositorSubscriber.ts +69 -0
  44. package/src/accountSubscribers/pollingVaultSubscriber.ts +63 -0
  45. package/src/accountSubscribers/pollingVaultsProgramAccountSubscriber.ts +114 -0
  46. package/src/accounts/index.ts +2 -0
  47. package/src/accounts/vaultAccount.ts +255 -0
  48. package/src/accounts/vaultDepositorAccount.ts +77 -0
  49. package/src/accounts/vaultsProgramAccount.ts +38 -0
  50. package/src/addresses.ts +114 -0
  51. package/src/constants/index.ts +15 -0
  52. package/src/idl/drift_vaults.json +5698 -0
  53. package/src/index.ts +11 -0
  54. package/src/math/index.ts +2 -0
  55. package/src/math/vault.ts +71 -0
  56. package/src/math/vaultDepositor.ts +90 -0
  57. package/src/name.ts +18 -0
  58. package/src/parsers/index.ts +1 -0
  59. package/src/parsers/logParser.ts +28 -0
  60. package/src/types/drift_vaults.ts +6211 -0
  61. package/src/types/types.ts +336 -0
  62. package/src/utils.ts +74 -0
  63. package/src/vaultClient.ts +3666 -0
  64. package/tsconfig.json +24 -0
  65. package/velocity-exchange-vaults-sdk-0.0.1.tgz +0 -0
@@ -0,0 +1,43 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import {
3
+ OptionValues,
4
+ Command
5
+ } from "commander";
6
+ import { dumpTransactionMessage, getCommandContext } from "../utils";
7
+
8
+ export const managerUpdateVaultDelegate = async (program: Command, cmdOpts: OptionValues) => {
9
+
10
+ let vaultAddress: PublicKey;
11
+ try {
12
+ vaultAddress = new PublicKey(cmdOpts.vaultAddress as string);
13
+ } catch (err) {
14
+ console.error("Invalid vault address");
15
+ process.exit(1);
16
+ }
17
+
18
+ const {
19
+ driftVault,
20
+ driftClient
21
+ } = await getCommandContext(program, true);
22
+
23
+ let delegate = cmdOpts.delegate;
24
+ if (!delegate) {
25
+ throw new Error(`Must provide delegate address`);
26
+ } else {
27
+ try {
28
+ delegate = new PublicKey(delegate);
29
+ } catch (err) {
30
+ throw new Error(`Invalid delegate address: ${err}`);
31
+ }
32
+ }
33
+
34
+ if (cmdOpts.dumpTransactionMessage) {
35
+ const vaultAccount = await driftVault.program.account.vault.fetch(vaultAddress);
36
+ const tx = await driftVault.getUpdateDelegateIx(vaultAddress, delegate, vaultAccount.user, vaultAccount.manager);
37
+ console.log(dumpTransactionMessage(driftClient.wallet.publicKey, [tx]));
38
+ } else {
39
+ const tx = await driftVault.updateDelegate(vaultAddress, delegate);
40
+ console.log(`Updated vault delegate to ${delegate.toBase58()}: https://solana.fm/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet-solana" : ""}`);
41
+ }
42
+
43
+ };
@@ -0,0 +1,77 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import {
3
+ OptionValues,
4
+ Command
5
+ } from "commander";
6
+ import { dumpTransactionMessage, getCommandContext } from "../utils";
7
+
8
+ export const managerUpdateVaultManager = async (program: Command, cmdOpts: OptionValues) => {
9
+
10
+ let vaultAddress: PublicKey;
11
+ try {
12
+ vaultAddress = new PublicKey(cmdOpts.vaultAddress as string);
13
+ } catch (err) {
14
+ console.error("Invalid vault address");
15
+ process.exit(1);
16
+ }
17
+
18
+ let manager: PublicKey;
19
+ try {
20
+ manager = new PublicKey(cmdOpts.newManager as string);
21
+ } catch (err) {
22
+ console.error("Invalid manager address");
23
+ process.exit(1);
24
+ }
25
+
26
+ const {
27
+ driftVault,
28
+ driftClient,
29
+ } = await getCommandContext(program, true);
30
+
31
+ const vault = await driftVault.getVault(vaultAddress);
32
+
33
+ console.log(`Updating vault manager:`);
34
+ console.log(` Current manager: ${vault.manager.toString()}`);
35
+ console.log(` New manager: ${manager.toString()}`);
36
+
37
+ const readline = require('readline').createInterface({
38
+ input: process.stdin,
39
+ output: process.stdout
40
+ });
41
+ console.log('');
42
+ const answer = await new Promise(resolve => {
43
+ readline.question('Is the above information correct? (yes/no) ', (answer: string) => {
44
+ readline.close();
45
+ resolve(answer);
46
+ });
47
+ });
48
+ if ((answer as string).toLowerCase() !== 'yes') {
49
+ console.log('Vault manager update canceled.');
50
+ process.exit(0);
51
+ }
52
+ console.log('Updating vault manager...');
53
+
54
+ let done = false;
55
+ while (!done) {
56
+ try {
57
+ if (cmdOpts.dumpTransactionMessage) {
58
+ const tx = await driftVault.getManagerUpdateVaultManagerIx(vaultAddress, manager);
59
+ console.log(dumpTransactionMessage(driftClient.wallet.publicKey, [tx]));
60
+ } else {
61
+ const tx = await driftVault.managerUpdateVaultManager(vaultAddress, manager);
62
+ console.log(`Updated vault manager: https://solana.fm/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet-solana" : ""}`);
63
+ done = true;
64
+ }
65
+ break;
66
+ } catch (e) {
67
+ const err = e as Error;
68
+ if (err.message.includes('TransactionExpiredTimeoutError')) {
69
+ console.log(err.message);
70
+ console.log('Transaction timeout. Retrying...');
71
+ await new Promise(resolve => setTimeout(resolve, 5000));
72
+ } else {
73
+ throw err;
74
+ }
75
+ }
76
+ }
77
+ };
@@ -0,0 +1,30 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import {
3
+ OptionValues,
4
+ Command
5
+ } from "commander";
6
+ import { dumpTransactionMessage, getCommandContext } from "../utils";
7
+
8
+ export const managerWithdraw = async (program: Command, cmdOpts: OptionValues) => {
9
+
10
+ let vaultAddress: PublicKey;
11
+ try {
12
+ vaultAddress = new PublicKey(cmdOpts.vaultAddress as string);
13
+ } catch (err) {
14
+ console.error("Invalid vault address");
15
+ process.exit(1);
16
+ }
17
+
18
+ const {
19
+ driftVault,
20
+ driftClient
21
+ } = await getCommandContext(program, true);
22
+
23
+ if (cmdOpts.dumpTransactionMessage) {
24
+ const tx = await driftVault.getManagerWithdrawIx(vaultAddress);
25
+ console.log(dumpTransactionMessage(driftClient.wallet.publicKey, tx));
26
+ } else {
27
+ const tx = await driftVault.managerWithdraw(vaultAddress);
28
+ console.log(`Withrew as vault manager: https://solana.fm/tx/${tx}${driftClient.env === "devnet" ? "?cluster=devnet-solana" : ""}`);
29
+ }
30
+ };
@@ -0,0 +1,58 @@
1
+ import { BN } from '@velocity-exchange/sdk';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ import { OptionValues, Command } from 'commander';
4
+ import { getCommandContext } from '../utils';
5
+ import { WithdrawUnit } from '../../src/types/types';
6
+ import { getVaultDepositorAddressSync, VAULT_PROGRAM_ID } from '../../src';
7
+
8
+ export const requestWithdraw = async (
9
+ program: Command,
10
+ cmdOpts: OptionValues
11
+ ) => {
12
+ // verify correct args provided
13
+ if (!cmdOpts.vaultDepositorAddress) {
14
+ if (!cmdOpts.vaultAddress || !cmdOpts.authority) {
15
+ console.error(
16
+ 'Must provide --vault-address and --authority if not providing --vault-depositor-address'
17
+ );
18
+ process.exit(1);
19
+ }
20
+ }
21
+
22
+ const { driftVault, driftClient } = await getCommandContext(program, true);
23
+
24
+ let vaultDepositorAddress: PublicKey;
25
+ if (cmdOpts.vaultDepositorAddress) {
26
+ try {
27
+ vaultDepositorAddress = new PublicKey(
28
+ cmdOpts.vaultDepositorAddress as string
29
+ );
30
+ } catch (err) {
31
+ console.error('Invalid vault depositor address');
32
+ process.exit(1);
33
+ }
34
+ } else {
35
+ const vaultAddress = new PublicKey(cmdOpts.vaultAddress as string);
36
+ const authority = new PublicKey(cmdOpts.authority as string);
37
+ vaultDepositorAddress = getVaultDepositorAddressSync(
38
+ VAULT_PROGRAM_ID,
39
+ vaultAddress,
40
+ authority
41
+ );
42
+ }
43
+
44
+ const withdrawAmountBN = new BN(cmdOpts.amount);
45
+
46
+ const tx = await driftVault.requestWithdraw(
47
+ vaultDepositorAddress,
48
+ withdrawAmountBN,
49
+ WithdrawUnit.SHARES
50
+ );
51
+ console.log(
52
+ `Requested to withdraw ${
53
+ cmdOpts.amount
54
+ } shares from the vault: https://solana.fm/tx/${tx}${
55
+ driftClient.env === 'devnet' ? '?cluster=devnet-solana' : ''
56
+ }`
57
+ );
58
+ };
@@ -0,0 +1,42 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import {
3
+ getVaultDepositorAddressSync
4
+ } from "../../src/addresses";
5
+ import {
6
+ OptionValues,
7
+ Command
8
+ } from "commander";
9
+ import { getCommandContext } from "../utils";
10
+ import { VAULT_PROGRAM_ID } from "../../src/types/types";
11
+
12
+ export const vaultDeposit = async (program: Command, cmdOpts: OptionValues) => {
13
+
14
+ let vaultAddress: PublicKey;
15
+ try {
16
+ vaultAddress = new PublicKey(cmdOpts.vaultAddress as string);
17
+ } catch (err) {
18
+ console.error("Invalid vault address");
19
+ process.exit(1);
20
+ }
21
+
22
+ let depositAuthority: PublicKey;
23
+ try {
24
+ depositAuthority = new PublicKey(cmdOpts.depositAuthority as string);
25
+ } catch (err) {
26
+ console.error("Invalid deposit authority");
27
+ process.exit(1);
28
+ }
29
+
30
+ const {
31
+ driftVault
32
+ } = await getCommandContext(program, true);
33
+
34
+ const vaultDepositorAddress = getVaultDepositorAddressSync(
35
+ VAULT_PROGRAM_ID,
36
+ vaultAddress,
37
+ depositAuthority,
38
+ );
39
+ const tx = await driftVault.initializeVaultDepositor(vaultAddress, depositAuthority);
40
+ console.log(`VaultDepositor initialized for ${depositAuthority}: ${tx}`);
41
+ console.log(`VaultDepositor address: ${vaultDepositorAddress}`);
42
+ };
@@ -0,0 +1,407 @@
1
+ import { PublicKey } from '@solana/web3.js';
2
+ import { OptionValues, Command } from 'commander';
3
+ import { getCommandContext } from '../utils';
4
+ import {
5
+ BN,
6
+ PERCENTAGE_PRECISION,
7
+ PRICE_PRECISION,
8
+ QUOTE_PRECISION,
9
+ User,
10
+ ZERO,
11
+ convertToNumber,
12
+ decodeName,
13
+ } from '@velocity-exchange/sdk';
14
+ import { calculateApplyProfitShare } from '../../src/math';
15
+ import { VaultDepositor } from '../../src';
16
+
17
+ export const vaultInvariantChecks = async (
18
+ program: Command,
19
+ cmdOpts: OptionValues
20
+ ) => {
21
+ let vaultAddress: PublicKey;
22
+ try {
23
+ vaultAddress = new PublicKey(cmdOpts.vaultAddress as string);
24
+ } catch (err) {
25
+ console.error('Invalid vault address');
26
+ process.exit(1);
27
+ }
28
+
29
+ const { driftVault, driftClient } = await getCommandContext(program, true);
30
+
31
+ /*
32
+ Invariants:
33
+ * sum(vault_depositors.shares) == vault.user_shares
34
+ * sum(vault_depositors.profit_share_paid) == vault.manager_total_profit_share
35
+ */
36
+
37
+ const vault = await driftVault.getVault(vaultAddress);
38
+ const spotMarket = driftVault.driftClient.getSpotMarketAccount(
39
+ vault.spotMarketIndex
40
+ );
41
+ const spotPrecision = new BN(10).pow(new BN(spotMarket!.decimals));
42
+ const spotOracle = driftVault.driftClient.getOracleDataForSpotMarket(
43
+ vault.spotMarketIndex
44
+ );
45
+ const spotOraclePriceNum = convertToNumber(spotOracle.price, PRICE_PRECISION);
46
+ const spotSymbol = decodeName(spotMarket!.name);
47
+
48
+ const user = new User({
49
+ // accountSubscription,
50
+ driftClient,
51
+ userAccountPublicKey: vault.user,
52
+ });
53
+ await user.subscribe();
54
+
55
+ const vaultEquity = await driftVault.calculateVaultEquity({
56
+ vault,
57
+ });
58
+ const vaultEquitySpot = vaultEquity.mul(spotPrecision).div(spotOracle.price);
59
+
60
+ const allVaultDepositors = await driftVault.getAllVaultDepositors(
61
+ vaultAddress
62
+ );
63
+ const approxSlot = await driftVault.driftClient.connection.getSlot();
64
+ const now = Date.now();
65
+
66
+ // let nonZeroDepositors = allVaultDepositors.filter(vd => vd.account.vaultShares.gt(new BN(0)));
67
+ // nonZeroDepositors = nonZeroDepositors.sort((a, b) => b.account.vaultShares.cmp(a.account.vaultShares));
68
+
69
+ let totalUserShares = new BN(0);
70
+ let totalUserProfits = 0;
71
+ let totalUserCumProfits = 0;
72
+ let totalUserProfitSharePaid = new BN(0);
73
+ let totalUserProfitShareSharesPaid = new BN(0);
74
+ let totalPendingProfitShareAmount = new BN(0);
75
+ let totalPendingProfitShareShares = new BN(0);
76
+ let totalUserNetDeposits = new BN(0);
77
+
78
+ console.log(
79
+ `Vault ${vaultAddress} vd and invariant check at approx slot: ${approxSlot}, date: ${new Date(
80
+ now
81
+ ).toLocaleString()}`
82
+ );
83
+ let nonZero = 0;
84
+ let usersWithoutPendingProfitShare = 0;
85
+ let usersWithPendingProfitShare = 0;
86
+ const sortedVd = allVaultDepositors.sort((a, b) =>
87
+ b.account.vaultShares.cmp(a.account.vaultShares)
88
+ );
89
+ const checkAuths: Array<string> = [];
90
+ for (const vd of sortedVd) {
91
+ const vdAccount = vd.account as VaultDepositor;
92
+
93
+ if (vdAccount.vaultShares.gt(new BN(0))) {
94
+ nonZero++;
95
+ }
96
+ totalUserNetDeposits = totalUserNetDeposits.add(vdAccount.netDeposits);
97
+
98
+ totalUserShares = totalUserShares.add(vdAccount.vaultShares);
99
+ const vdAuth = vdAccount.authority.toBase58();
100
+ const vdPct =
101
+ vdAccount.vaultShares.toNumber() / vault.totalShares.toNumber();
102
+ console.log(
103
+ `- ${vdAuth} has ${vdAccount.vaultShares.toNumber()} shares (${
104
+ vdPct * 100.0
105
+ }% of vault)`
106
+ );
107
+
108
+ if (!vdAccount.lastWithdrawRequest.shares.eq(new BN(0))) {
109
+ const withdrawRequested = vdAccount.lastWithdrawRequest.ts.toNumber();
110
+ const secToWithdrawal =
111
+ withdrawRequested + vault.redeemPeriod.toNumber() - Date.now() / 1000;
112
+ const withdrawAvailable = secToWithdrawal < 0;
113
+ const pct =
114
+ vdAccount.lastWithdrawRequest.shares.toNumber() /
115
+ vd.account.vaultShares.toNumber();
116
+ const daysUntilWithdraw = Math.floor(secToWithdrawal / 86400);
117
+ const hoursUntilWithdraw = Math.floor((secToWithdrawal % 86400) / 3600);
118
+
119
+ console.log(
120
+ ` - pending withdrawal: ${vdAccount.lastWithdrawRequest.shares.toString()} ($${convertToNumber(
121
+ vd.account.lastWithdrawRequest.value,
122
+ spotPrecision
123
+ )}), ${(pct * 100.0).toFixed(2)}% of their deposit ${
124
+ withdrawAvailable ? '<--- WITHDRAWABLE' : ''
125
+ }`
126
+ );
127
+ console.log(
128
+ ` - requested at: ${new Date(
129
+ withdrawRequested * 1000
130
+ ).toISOString()}`
131
+ );
132
+ console.log(
133
+ ` - can withdraw in: ${daysUntilWithdraw} days and ${hoursUntilWithdraw} hours`
134
+ );
135
+ }
136
+
137
+ totalUserProfitSharePaid = totalUserProfitSharePaid.add(
138
+ vdAccount.profitShareFeePaid
139
+ );
140
+ totalUserProfitShareSharesPaid = totalUserProfitShareSharesPaid.add(
141
+ vdAccount.cumulativeProfitShareAmount
142
+ );
143
+
144
+ const pendingProfitShares = calculateApplyProfitShare(
145
+ vdAccount,
146
+ vaultEquitySpot,
147
+ vault
148
+ );
149
+ const pendingProfitShareAmtNum = convertToNumber(
150
+ pendingProfitShares.profitShareAmount,
151
+ spotPrecision
152
+ );
153
+ if (pendingProfitShares.profitShareAmount.gt(ZERO)) {
154
+ totalPendingProfitShareAmount = totalPendingProfitShareAmount.add(
155
+ pendingProfitShares.profitShareAmount
156
+ );
157
+ totalPendingProfitShareShares = totalPendingProfitShareShares.add(
158
+ pendingProfitShares.profitShareShares
159
+ );
160
+ console.log(
161
+ ` - pending profit share amount: ${convertToNumber(
162
+ pendingProfitShares.profitShareAmount,
163
+ spotPrecision
164
+ )}`
165
+ );
166
+ usersWithPendingProfitShare++;
167
+ } else {
168
+ console.log(` - no pending profit share`);
169
+ usersWithoutPendingProfitShare++;
170
+ }
171
+
172
+ const userShareValue = vaultEquitySpot
173
+ .mul(vdAccount.vaultShares)
174
+ .div(vault.totalShares);
175
+ const userShareValueNum = convertToNumber(userShareValue, spotPrecision);
176
+ const netDepositsNum = convertToNumber(
177
+ vdAccount.netDeposits,
178
+ spotPrecision
179
+ );
180
+ const vdProfits = userShareValueNum - netDepositsNum;
181
+ const profitSharePaid = convertToNumber(
182
+ vdAccount.profitShareFeePaid,
183
+ spotPrecision
184
+ );
185
+ const cumProfitShareNum = convertToNumber(
186
+ vdAccount.cumulativeProfitShareAmount,
187
+ spotPrecision
188
+ );
189
+ totalUserProfits += vdProfits;
190
+ totalUserCumProfits += cumProfitShareNum;
191
+ console.log(` - net deposits: ${netDepositsNum}`);
192
+ console.log(` - vd profit: ${vdProfits}`);
193
+ console.log(` - cumProfitshareAmt: ${cumProfitShareNum}`);
194
+ console.log(
195
+ ` - profitShareFeePaid: ${convertToNumber(
196
+ vdAccount.profitShareFeePaid,
197
+ spotPrecision
198
+ )}`
199
+ );
200
+ const inclProfitShare =
201
+ ((profitSharePaid + pendingProfitShareAmtNum) /
202
+ (cumProfitShareNum + pendingProfitShareAmtNum)) *
203
+ 100.0;
204
+ console.log(
205
+ ` - pftSharePaidPct (excl pend): ${(
206
+ (profitSharePaid / cumProfitShareNum) *
207
+ 100.0
208
+ ).toFixed(2)}%`
209
+ );
210
+ console.log(
211
+ ` - pftSharePaidPct (incl pend): ${inclProfitShare.toFixed(2)}% `
212
+ );
213
+ if (inclProfitShare < 29.9 && inclProfitShare > 0) {
214
+ console.log(` ^^^ weird: ${inclProfitShare}`);
215
+ checkAuths.push(vdAuth);
216
+ }
217
+
218
+ if (vdAccount.vaultSharesBase !== 0) {
219
+ console.log(
220
+ ` - Nonzero vault shares base: ${vdAccount.vaultSharesBase} `
221
+ );
222
+ }
223
+ }
224
+ console.log(`Check these auths:\n${checkAuths.join('\n')}`);
225
+ console.log(
226
+ `Depositors with 0 shares: ${allVaultDepositors.length - nonZero} /${
227
+ allVaultDepositors.length
228
+ }`
229
+ );
230
+ console.log(
231
+ `Depositors with pending profit share: ${usersWithPendingProfitShare}`
232
+ );
233
+ console.log(
234
+ `Depositors without pending profit share: ${usersWithoutPendingProfitShare}`
235
+ );
236
+
237
+ console.log(`==== Vault Depositor Shares == vault.user_shares ====`);
238
+ console.log(`total vd shares: ${totalUserShares.toString()}`);
239
+ console.log(`total vault usershares: ${vault.userShares.toString()}`);
240
+ console.log(`diff: ${vault.userShares.sub(totalUserShares)}`);
241
+
242
+ console.log(``);
243
+ console.log(
244
+ `==== Vault Depositor ProfitSharePaid == vault.manager_total_profit_share ====`
245
+ );
246
+ console.log(
247
+ `total vault d profitshares: ${totalUserProfitSharePaid.toString()}`
248
+ );
249
+ console.log(
250
+ `vault total profit shares: ${vault.managerTotalProfitShare.toString()}`
251
+ );
252
+ console.log(
253
+ `diff: ${vault.managerTotalProfitShare.sub(totalUserProfitSharePaid)}`
254
+ );
255
+
256
+ console.log(``);
257
+ console.log(`==== Pending profit shares to realize ====`);
258
+ const totalPendingProfitShareAmountNum = convertToNumber(
259
+ totalPendingProfitShareAmount,
260
+ spotPrecision
261
+ );
262
+ const totalUserProfitSharePaidNum = convertToNumber(
263
+ totalUserProfitSharePaid,
264
+ spotPrecision
265
+ );
266
+ console.log(`amount: ${totalPendingProfitShareAmountNum}`);
267
+ console.log(`shares: ${totalPendingProfitShareShares.toNumber()}`);
268
+ // console.log(`csv: ${cmdOpts.csv}`);
269
+
270
+ console.log(``);
271
+ console.log(`==== Agg user profit share paid ====`);
272
+ console.log(
273
+ `vd total profit (incl unrealized profit share): ${totalUserProfits}`
274
+ );
275
+ console.log(
276
+ `vd total cum profits (before pending profit share): ${totalUserCumProfits}`
277
+ );
278
+ console.log(
279
+ `vd total profit share paid): ${totalUserProfitSharePaidNum}`
280
+ );
281
+ console.log(
282
+ `vd total pending profit share: ${totalPendingProfitShareAmountNum}`
283
+ );
284
+ console.log(
285
+ `vd total net deposits: ${convertToNumber(
286
+ totalUserNetDeposits,
287
+ spotPrecision
288
+ )}`
289
+ );
290
+ const driftUserDeposits = user.getUserAccount().totalDeposits;
291
+ const driftUserWithdraws = user.getUserAccount().totalWithdraws;
292
+ const driftUserSocialLoss = user.getUserAccount().totalSocialLoss;
293
+ console.log(
294
+ `vd drift user net deposits: ${convertToNumber(
295
+ driftUserDeposits.sub(driftUserWithdraws).sub(driftUserSocialLoss),
296
+ spotPrecision
297
+ )}`
298
+ );
299
+ console.log(
300
+ ` vd drift user deps: ${convertToNumber(driftUserDeposits, spotPrecision)}`
301
+ );
302
+ console.log(
303
+ ` vd drift user with: ${convertToNumber(
304
+ driftUserWithdraws,
305
+ spotPrecision
306
+ )}`
307
+ );
308
+ console.log(
309
+ ` vd drift user scls: ${convertToNumber(
310
+ driftUserSocialLoss,
311
+ spotPrecision
312
+ )}`
313
+ );
314
+
315
+ console.log(``);
316
+ console.log(`==== Manager share ====`);
317
+ console.log(` Vault total shares: ${vault.totalShares.toNumber()}`);
318
+ const managerShares = vault.totalShares.sub(vault.userShares);
319
+ const managerSharePct =
320
+ managerShares.toNumber() / vault.totalShares.toNumber();
321
+ const managerShareWithPendingPct =
322
+ managerShares.add(totalPendingProfitShareShares).toNumber() /
323
+ vault.totalShares.toNumber();
324
+ console.log(
325
+ ` Manager shares: ${managerShares.toString()} (${(
326
+ managerSharePct * 100.0
327
+ ).toFixed(4)}%)`
328
+ );
329
+ const vaultEquityNum = convertToNumber(vaultEquity, spotPrecision);
330
+ const vaultEquitySpotNum = convertToNumber(vaultEquitySpot, spotPrecision);
331
+ const vaultPnlNum = convertToNumber(
332
+ user.getTotalAllTimePnl(),
333
+ QUOTE_PRECISION
334
+ );
335
+ console.log(`vaultEquity (USDC): $${vaultEquityNum}`);
336
+ console.log(`vaultEquity (deposit asset): ${vaultEquitySpotNum}`);
337
+ const managerValueWoPending = managerSharePct * vaultEquitySpotNum;
338
+ const managerValueWithPending =
339
+ managerShareWithPendingPct * vaultEquitySpotNum;
340
+ console.log(
341
+ `manager share (w/o pending) (deposit asset): ${managerValueWoPending} (share: ${
342
+ (managerValueWoPending / vaultPnlNum) * 100.0
343
+ }%)`
344
+ );
345
+ console.log(
346
+ `manager share (with pending) (deposit asset): ${managerValueWithPending} (share: ${
347
+ (managerValueWithPending / vaultPnlNum) * 100.0
348
+ }%)`
349
+ );
350
+
351
+ console.log(``);
352
+ const profitSharePct = vault.profitShare / PERCENTAGE_PRECISION.toNumber();
353
+ const vdPnlBeforeProfitShare =
354
+ convertToNumber(totalUserProfitSharePaid, spotPrecision) / profitSharePct;
355
+ console.log(
356
+ `back out vault pnl: (userPnl + managerShareValue): ${totalUserProfits} + ${
357
+ managerSharePct * vaultEquitySpotNum
358
+ } = ${totalUserProfits + managerSharePct * vaultEquitySpotNum}`
359
+ );
360
+ console.log(
361
+ `vaultDepositors pnl (before profit share): ${vdPnlBeforeProfitShare}`
362
+ );
363
+
364
+ console.log(
365
+ `vault PnL (spot): ${
366
+ vaultEquitySpotNum - convertToNumber(vault.netDeposits, spotPrecision)
367
+ }`
368
+ );
369
+ console.log(`vault PnL (USD) ${vaultPnlNum}`);
370
+ console.log(`vault PnL (spot) ${vaultPnlNum / spotOraclePriceNum}`);
371
+
372
+ console.log(``);
373
+ console.log(`==== ${decodeName(vault.name)} Profit Summary ====`);
374
+ console.log(
375
+ `Depositors' total PnL: ${totalUserProfits} ${spotSymbol}`
376
+ );
377
+ console.log(
378
+ `Depositors' profit share paid to date: ${totalUserProfitSharePaidNum} ${spotSymbol}`
379
+ );
380
+ console.log(
381
+ `Unrealized profit share: ${totalPendingProfitShareAmountNum} ${spotSymbol}`
382
+ );
383
+ console.log(
384
+ `Vault manager net deposits: ${convertToNumber(
385
+ vault.managerNetDeposits,
386
+ spotPrecision
387
+ )} ${spotSymbol}`
388
+ );
389
+ console.log(
390
+ `Vault manager profit share received: ${convertToNumber(
391
+ vault.managerTotalProfitShare,
392
+ spotPrecision
393
+ )} ${spotSymbol}`
394
+ );
395
+ console.log(
396
+ `Vault manager share value: ${managerValueWithPending} ${spotSymbol} (share of vault: ${
397
+ (managerValueWithPending / vaultPnlNum) * 100.0
398
+ }%)`
399
+ );
400
+ if (spotSymbol !== 'USDC') {
401
+ console.log(
402
+ `Vault manager share value: ${
403
+ managerValueWithPending * spotOraclePriceNum
404
+ } USDC`
405
+ );
406
+ }
407
+ };
@@ -0,0 +1,42 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import {
3
+ getVaultDepositorAddressSync
4
+ } from "../../src/addresses";
5
+ import {
6
+ OptionValues,
7
+ Command
8
+ } from "commander";
9
+ import { getCommandContext } from "../utils";
10
+ import { VAULT_PROGRAM_ID } from "../../src/types/types";
11
+
12
+ export const vaultWithdraw= async (program: Command, cmdOpts: OptionValues) => {
13
+
14
+ let vaultAddress: PublicKey;
15
+ try {
16
+ vaultAddress = new PublicKey(cmdOpts.vaultAddress as string);
17
+ } catch (err) {
18
+ console.error("Invalid vault address");
19
+ process.exit(1);
20
+ }
21
+
22
+ let depositAuthority: PublicKey;
23
+ try {
24
+ depositAuthority = new PublicKey(cmdOpts.depositAuthority as string);
25
+ } catch (err) {
26
+ console.error("Invalid deposit authority");
27
+ process.exit(1);
28
+ }
29
+
30
+ const {
31
+ driftVault
32
+ } = await getCommandContext(program, true);
33
+
34
+ const vaultDepositorAddress = getVaultDepositorAddressSync(
35
+ VAULT_PROGRAM_ID,
36
+ vaultAddress,
37
+ depositAuthority,
38
+ );
39
+ const tx = await driftVault.initializeVaultDepositor(vaultAddress, depositAuthority);
40
+ console.log(`VaultDepositor initialized for ${depositAuthority}: ${tx}`);
41
+ console.log(`VaultDepositor address: ${vaultDepositorAddress}`);
42
+ };