@drift-labs/vaults-sdk 0.1.106 → 0.1.108
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/cli/cli.ts +6 -0
- package/cli/commands/applyProfitShare.ts +31 -13
- package/cli/commands/index.ts +3 -1
- package/cli/commands/vaultInvariantChecks.ts +72 -0
- package/cli/commands/viewVault.ts +28 -4
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/index.d.ts +1 -0
- package/lib/math/index.js +17 -0
- package/lib/math/vaultDepositor.d.ts +15 -0
- package/lib/math/vaultDepositor.js +32 -0
- package/lib/vaultClient.d.ts +1 -0
- package/lib/vaultClient.js +24 -4
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/math/index.ts +1 -0
- package/src/math/vaultDepositor.ts +58 -0
- package/src/vaultClient.ts +31 -4
package/cli/cli.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
listDepositorsForVault,
|
|
18
18
|
managerUpdateMarginTradingEnabled,
|
|
19
19
|
decodeLogs,
|
|
20
|
+
vaultInvariantChecks,
|
|
20
21
|
} from "./commands";
|
|
21
22
|
|
|
22
23
|
import { Command, Option } from 'commander';
|
|
@@ -147,6 +148,11 @@ program
|
|
|
147
148
|
.description("Decode program logs from a txid")
|
|
148
149
|
.addOption(new Option("--tx <tx>", "Transaction hash").makeOptionMandatory(true))
|
|
149
150
|
.action((opts) => decodeLogs(program, opts));
|
|
151
|
+
program
|
|
152
|
+
.command("check-invariants")
|
|
153
|
+
.description("Perform sanity checks on vault/depositor invariants")
|
|
154
|
+
.addOption(new Option("--vault-address <address>", "Vault address").makeOptionMandatory(true))
|
|
155
|
+
.action((opts) => vaultInvariantChecks(program, opts));
|
|
150
156
|
|
|
151
157
|
program.parseAsync().then(() => {
|
|
152
158
|
process.exit(0);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PublicKey, TransactionInstruction } from "@solana/web3.js";
|
|
1
|
+
import { ComputeBudgetProgram, PublicKey, Transaction, TransactionInstruction } from "@solana/web3.js";
|
|
2
2
|
import {
|
|
3
3
|
OptionValues,
|
|
4
4
|
Command
|
|
@@ -19,27 +19,45 @@ export const applyProfitShare = async (program: Command, cmdOpts: OptionValues)
|
|
|
19
19
|
driftVault
|
|
20
20
|
} = await getCommandContext(program, true);
|
|
21
21
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
console.log(`Cranking profit share for ${allVaultDepositors.length} depositors...`);
|
|
22
|
+
const vdToRealizeProfit = await driftVault.getAllVaultDepositorsWithNoWithdrawRequest(vaultAddress);
|
|
23
|
+
console.log(`Applying profit share for ${vdToRealizeProfit.length} depositors...`);
|
|
26
24
|
|
|
27
25
|
const chunkSize = 10;
|
|
28
26
|
const ixChunks: Array<Array<TransactionInstruction>> = [];
|
|
29
|
-
for (let i = 0; i <
|
|
30
|
-
const chunk =
|
|
27
|
+
for (let i = 0; i < vdToRealizeProfit.length; i += chunkSize) {
|
|
28
|
+
const chunk = vdToRealizeProfit.slice(i, i + chunkSize);
|
|
31
29
|
const ixs = await Promise.all(chunk.map((vaultDepositor) => {
|
|
32
30
|
return driftVault.getApplyProfitShareIx(vaultAddress, vaultDepositor.publicKey);
|
|
33
31
|
}));
|
|
34
32
|
|
|
35
33
|
ixChunks.push(ixs);
|
|
36
34
|
}
|
|
37
|
-
console.log(`
|
|
35
|
+
console.log(`Sending ${ixChunks.length} transactions...`);
|
|
36
|
+
|
|
37
|
+
for (let i = 0; i < ixChunks.length; i++) {
|
|
38
|
+
const ixs = ixChunks[i];
|
|
39
|
+
try {
|
|
40
|
+
ixs.unshift(ComputeBudgetProgram.setComputeUnitLimit({
|
|
41
|
+
units: 1_400_000,
|
|
42
|
+
}));
|
|
43
|
+
ixs.unshift(ComputeBudgetProgram.setComputeUnitPrice({
|
|
44
|
+
microLamports: 100,
|
|
45
|
+
}));
|
|
46
|
+
|
|
47
|
+
const tx = new Transaction();
|
|
48
|
+
tx.add(...ixs);
|
|
49
|
+
const { txSig } = await driftVault.driftClient.sendTransaction(
|
|
50
|
+
tx,
|
|
51
|
+
[],
|
|
52
|
+
driftVault.driftClient.opts
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
console.log(`[${i}]: https://solscan.io/tx/${txSig}`);
|
|
56
|
+
|
|
57
|
+
} catch (e) {
|
|
58
|
+
console.error(e);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
38
61
|
|
|
39
|
-
const txs = await Promise.all(ixChunks.map((ixs) => driftVault.createAndSendTxn(ixs, {
|
|
40
|
-
units: 2_000_000
|
|
41
|
-
})));
|
|
42
|
-
for (const tx of txs) {
|
|
43
|
-
console.log(`Crank tx: https://solscan.io/tx/${tx}`);
|
|
44
62
|
}
|
|
45
63
|
};
|
package/cli/commands/index.ts
CHANGED
|
@@ -15,4 +15,6 @@ export * from './forceWithdraw';
|
|
|
15
15
|
export * from './withdraw';
|
|
16
16
|
export * from './listDepositorsForVault';
|
|
17
17
|
export * from './managerUpdateMarginTradingEnabled';
|
|
18
|
-
export * from './decodeLogs';
|
|
18
|
+
export * from './decodeLogs';
|
|
19
|
+
export * from './vaultInvariantChecks';
|
|
20
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
|
2
|
+
import {
|
|
3
|
+
OptionValues,
|
|
4
|
+
Command
|
|
5
|
+
} from "commander";
|
|
6
|
+
import { getCommandContext } from "../utils";
|
|
7
|
+
import { BN, convertToNumber } from "@drift-labs/sdk";
|
|
8
|
+
import {
|
|
9
|
+
calculateApplyProfitShare,
|
|
10
|
+
} from "../../src/math";
|
|
11
|
+
|
|
12
|
+
export const vaultInvariantChecks = 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
|
+
const {
|
|
23
|
+
driftVault
|
|
24
|
+
} = await getCommandContext(program, true);
|
|
25
|
+
|
|
26
|
+
/*
|
|
27
|
+
Invariants:
|
|
28
|
+
* sum(vault_depositors.shares) == vault.user_shares
|
|
29
|
+
* sum(vault_depositors.profit_share_paid) == vault.manager_total_profit_share
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
const vault = await driftVault.getVault(vaultAddress);
|
|
34
|
+
const vaultEquity = await driftVault.calculateVaultEquity({
|
|
35
|
+
vault,
|
|
36
|
+
});
|
|
37
|
+
const spotMarket = driftVault.driftClient.getSpotMarketAccount(vault.spotMarketIndex);
|
|
38
|
+
const spotPrecision = new BN(10).pow(new BN(spotMarket!.decimals));
|
|
39
|
+
|
|
40
|
+
const allVaultDepositors = await driftVault.getAllVaultDepositors(vaultAddress);
|
|
41
|
+
|
|
42
|
+
let totalUserShares = new BN(0);
|
|
43
|
+
let totalUserProfitSharePaid = new BN(0);
|
|
44
|
+
|
|
45
|
+
for (const vd of allVaultDepositors) {
|
|
46
|
+
totalUserShares = totalUserShares.add(vd.account.vaultShares);
|
|
47
|
+
if (!vd.account.lastWithdrawRequest.shares.eq(new BN(0))) {
|
|
48
|
+
const pct = vd.account.lastWithdrawRequest.shares.toNumber() / vd.account.vaultShares.toNumber();
|
|
49
|
+
console.log(`Vd has withdrawal ${vd.publicKey.toBase58()} (auth: ${vd.account.authority.toBase58()}): ${vd.account.lastWithdrawRequest.shares.toString()} ($${convertToNumber(vd.account.lastWithdrawRequest.value, spotPrecision)}), ${(pct * 100.00).toFixed(2)}%`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!vd.account.cumulativeProfitShareAmount.eq(new BN(0))) {
|
|
53
|
+
// const profitSharePaid = vd.account.profitShareFeePaid.toNumber() / vd.account.cumulativeProfitShareAmount.toNumber();
|
|
54
|
+
// console.log(`Profit share paid: ${vd.publicKey.toBase58()} (auth: ${vd.account.authority.toBase58()}): ${Math.ceil(profitSharePaid * 100.0)}%`);
|
|
55
|
+
}
|
|
56
|
+
totalUserProfitSharePaid = totalUserProfitSharePaid.add(vd.account.profitShareFeePaid);
|
|
57
|
+
|
|
58
|
+
const pendingProfitShares = calculateApplyProfitShare(vd.account, vaultEquity, vault);
|
|
59
|
+
console.log(`Pending profit shares: ${vd.publicKey.toBase58()} (auth: ${vd.account.authority.toBase58()}): $${convertToNumber(pendingProfitShares.profitShareAmount, spotPrecision)}`);
|
|
60
|
+
console.log(` . ${pendingProfitShares.profitShareShares}, ${pendingProfitShares.profitShareAmount}`);
|
|
61
|
+
}
|
|
62
|
+
console.log(`==== Vault Depositor Shares == vault.user_shares ====`);
|
|
63
|
+
console.log(`total vd shares: ${totalUserShares.toString()}`);
|
|
64
|
+
console.log(`total vault usershares: ${vault.userShares.toString()}`);
|
|
65
|
+
console.log(`diff: ${vault.userShares.sub(totalUserShares)}`);
|
|
66
|
+
|
|
67
|
+
console.log(``);
|
|
68
|
+
console.log(`==== Vault Depositor ProfitSharePaid == vault.manager_total_profit_share ====`);
|
|
69
|
+
console.log(`total vault d profitshares: ${totalUserProfitSharePaid.toString()}`);
|
|
70
|
+
console.log(`vault total profit shares: ${vault.managerTotalProfitShare.toString()}`);
|
|
71
|
+
console.log(`diff: ${vault.managerTotalProfitShare.sub(totalUserProfitSharePaid)}`);
|
|
72
|
+
};
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
Command
|
|
5
5
|
} from "commander";
|
|
6
6
|
import { getCommandContext, printVault } from "../utils";
|
|
7
|
-
import { QUOTE_PRECISION, convertToNumber } from "@drift-labs/sdk";
|
|
7
|
+
import { BN, PRICE_PRECISION, QUOTE_PRECISION, TEN, convertToNumber, decodeName } from "@drift-labs/sdk";
|
|
8
8
|
|
|
9
9
|
export const viewVault = async (program: Command, cmdOpts: OptionValues) => {
|
|
10
10
|
|
|
@@ -17,14 +17,38 @@ export const viewVault = async (program: Command, cmdOpts: OptionValues) => {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const {
|
|
20
|
-
driftVault
|
|
20
|
+
driftVault,
|
|
21
|
+
driftClient,
|
|
21
22
|
} = await getCommandContext(program, false);
|
|
22
23
|
|
|
24
|
+
|
|
23
25
|
const vault = await driftVault.getVault(address);
|
|
24
26
|
const { managerSharePct } = printVault(vault);
|
|
25
27
|
const vaultEquity = await driftVault.calculateVaultEquity({
|
|
26
28
|
vault,
|
|
27
29
|
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
|
|
31
|
+
const spotMarket = driftClient.getSpotMarketAccount(vault.spotMarketIndex);
|
|
32
|
+
if (!spotMarket) {
|
|
33
|
+
throw new Error(`Spot market ${vault.spotMarketIndex} not found`);
|
|
34
|
+
}
|
|
35
|
+
const spotOracle = driftClient.getOracleDataForSpotMarket(vault.spotMarketIndex);
|
|
36
|
+
if (!spotOracle) {
|
|
37
|
+
throw new Error(`Spot oracle ${vault.spotMarketIndex} not found`);
|
|
38
|
+
}
|
|
39
|
+
const oraclePriceNum = convertToNumber(spotOracle.price, PRICE_PRECISION);
|
|
40
|
+
const spotPrecision = TEN.pow(new BN(spotMarket.decimals));
|
|
41
|
+
const spotSymbol = decodeName(spotMarket.name);
|
|
42
|
+
|
|
43
|
+
const vaultEquityNum = convertToNumber(vaultEquity, QUOTE_PRECISION);
|
|
44
|
+
const netDepositsNum = convertToNumber(vault.netDeposits, spotPrecision);
|
|
45
|
+
console.log(`vaultEquity (USDC): $${vaultEquityNum}`);
|
|
46
|
+
console.log(`manager share (USDC): $${managerSharePct * vaultEquityNum}`);
|
|
47
|
+
console.log(`vault PnL (USDC): $${vaultEquityNum - netDepositsNum}`);
|
|
48
|
+
|
|
49
|
+
const vaultEquitySpot = vaultEquityNum / oraclePriceNum;
|
|
50
|
+
|
|
51
|
+
console.log(`vaultEquity (${spotSymbol}): ${vaultEquitySpot}`);
|
|
52
|
+
console.log(`manager share (${spotSymbol}): ${managerSharePct * vaultEquitySpot}`);
|
|
53
|
+
console.log(`vault PnL (${spotSymbol}): ${vaultEquitySpot - netDepositsNum}`);
|
|
30
54
|
};
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './vaultDepositor';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./vaultDepositor"), exports);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { BN } from '@drift-labs/sdk';
|
|
3
|
+
import { Vault, VaultDepositor } from '../types/types';
|
|
4
|
+
/**
|
|
5
|
+
* Calculates the unrealized profitShare for a vaultDepositor
|
|
6
|
+
* @param vaultDepositor
|
|
7
|
+
* @param vaultEquity
|
|
8
|
+
* @param vault
|
|
9
|
+
* @returns
|
|
10
|
+
*/
|
|
11
|
+
export declare function calculateApplyProfitShare(vaultDepositor: VaultDepositor, vaultEquity: BN, vault: Vault): {
|
|
12
|
+
profitShareAmount: BN;
|
|
13
|
+
profitShareShares: BN;
|
|
14
|
+
};
|
|
15
|
+
export declare function calculateProfitShare(vaultDepositor: VaultDepositor, totalAmount: BN, vault: Vault): BN;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateProfitShare = exports.calculateApplyProfitShare = void 0;
|
|
4
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
5
|
+
/**
|
|
6
|
+
* Calculates the unrealized profitShare for a vaultDepositor
|
|
7
|
+
* @param vaultDepositor
|
|
8
|
+
* @param vaultEquity
|
|
9
|
+
* @param vault
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
function calculateApplyProfitShare(vaultDepositor, vaultEquity, vault) {
|
|
13
|
+
const amount = (0, sdk_1.unstakeSharesToAmount)(vaultDepositor.vaultShares, vault.totalShares, vaultEquity);
|
|
14
|
+
const profitShareAmount = calculateProfitShare(vaultDepositor, amount, vault);
|
|
15
|
+
const profitShareShares = (0, sdk_1.stakeAmountToShares)(profitShareAmount, vault.totalShares, vaultEquity);
|
|
16
|
+
return {
|
|
17
|
+
profitShareAmount,
|
|
18
|
+
profitShareShares,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
exports.calculateApplyProfitShare = calculateApplyProfitShare;
|
|
22
|
+
function calculateProfitShare(vaultDepositor, totalAmount, vault) {
|
|
23
|
+
const profit = totalAmount.sub(vaultDepositor.netDeposits.add(vaultDepositor.cumulativeProfitShareAmount));
|
|
24
|
+
if (profit.gt(sdk_1.ZERO)) {
|
|
25
|
+
const profitShareAmount = profit
|
|
26
|
+
.mul(new sdk_1.BN(vault.profitShare))
|
|
27
|
+
.div(sdk_1.PERCENTAGE_PRECISION);
|
|
28
|
+
return profitShareAmount;
|
|
29
|
+
}
|
|
30
|
+
return sdk_1.ZERO;
|
|
31
|
+
}
|
|
32
|
+
exports.calculateProfitShare = calculateProfitShare;
|
package/lib/vaultClient.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export declare class VaultClient {
|
|
|
18
18
|
});
|
|
19
19
|
getVault(vault: PublicKey): Promise<Vault>;
|
|
20
20
|
getVaultDepositor(vaultDepositor: PublicKey): Promise<any>;
|
|
21
|
+
getAllVaultDepositorsWithNoWithdrawRequest(vault: PublicKey): Promise<ProgramAccount<VaultDepositor>[]>;
|
|
21
22
|
getAllVaultDepositors(vault: PublicKey): Promise<ProgramAccount<VaultDepositor>[]>;
|
|
22
23
|
/**
|
|
23
24
|
*
|
package/lib/vaultClient.js
CHANGED
|
@@ -21,7 +21,7 @@ class VaultClient {
|
|
|
21
21
|
async getVaultDepositor(vaultDepositor) {
|
|
22
22
|
return await this.program.account.vaultDepositor.fetch(vaultDepositor);
|
|
23
23
|
}
|
|
24
|
-
async
|
|
24
|
+
async getAllVaultDepositorsWithNoWithdrawRequest(vault) {
|
|
25
25
|
const filters = [
|
|
26
26
|
{
|
|
27
27
|
// discriminator = VaultDepositor
|
|
@@ -38,10 +38,30 @@ class VaultClient {
|
|
|
38
38
|
},
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
|
-
//
|
|
41
|
+
// last_withdraw_request.shares (u128) = 0
|
|
42
42
|
memcmp: {
|
|
43
|
-
offset:
|
|
44
|
-
bytes: bytes_1.bs58.encode(Uint8Array.
|
|
43
|
+
offset: 112,
|
|
44
|
+
bytes: bytes_1.bs58.encode(new Uint8Array(16).fill(0)),
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
// @ts-ignore
|
|
49
|
+
return (await this.program.account.vaultDepositor.all(filters));
|
|
50
|
+
}
|
|
51
|
+
async getAllVaultDepositors(vault) {
|
|
52
|
+
const filters = [
|
|
53
|
+
{
|
|
54
|
+
// discriminator = VaultDepositor
|
|
55
|
+
memcmp: {
|
|
56
|
+
offset: 0,
|
|
57
|
+
bytes: bytes_1.bs58.encode(anchor_1.BorshAccountsCoder.accountDiscriminator('VaultDepositor')),
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
// vault = vault
|
|
62
|
+
memcmp: {
|
|
63
|
+
offset: 8,
|
|
64
|
+
bytes: vault.toBase58(),
|
|
45
65
|
},
|
|
46
66
|
},
|
|
47
67
|
];
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './vaultDepositor';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BN,
|
|
3
|
+
PERCENTAGE_PRECISION,
|
|
4
|
+
ZERO,
|
|
5
|
+
unstakeSharesToAmount as depositSharesToVaultAmount,
|
|
6
|
+
stakeAmountToShares as vaultAmountToDepositorShares,
|
|
7
|
+
} from '@drift-labs/sdk';
|
|
8
|
+
import { Vault, VaultDepositor } from '../types/types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Calculates the unrealized profitShare for a vaultDepositor
|
|
12
|
+
* @param vaultDepositor
|
|
13
|
+
* @param vaultEquity
|
|
14
|
+
* @param vault
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
export function calculateApplyProfitShare(
|
|
18
|
+
vaultDepositor: VaultDepositor,
|
|
19
|
+
vaultEquity: BN,
|
|
20
|
+
vault: Vault
|
|
21
|
+
): {
|
|
22
|
+
profitShareAmount: BN;
|
|
23
|
+
profitShareShares: BN;
|
|
24
|
+
} {
|
|
25
|
+
const amount = depositSharesToVaultAmount(
|
|
26
|
+
vaultDepositor.vaultShares,
|
|
27
|
+
vault.totalShares,
|
|
28
|
+
vaultEquity
|
|
29
|
+
);
|
|
30
|
+
const profitShareAmount = calculateProfitShare(vaultDepositor, amount, vault);
|
|
31
|
+
const profitShareShares = vaultAmountToDepositorShares(
|
|
32
|
+
profitShareAmount,
|
|
33
|
+
vault.totalShares,
|
|
34
|
+
vaultEquity
|
|
35
|
+
);
|
|
36
|
+
return {
|
|
37
|
+
profitShareAmount,
|
|
38
|
+
profitShareShares,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function calculateProfitShare(
|
|
43
|
+
vaultDepositor: VaultDepositor,
|
|
44
|
+
totalAmount: BN,
|
|
45
|
+
vault: Vault
|
|
46
|
+
) {
|
|
47
|
+
const profit = totalAmount.sub(
|
|
48
|
+
vaultDepositor.netDeposits.add(vaultDepositor.cumulativeProfitShareAmount)
|
|
49
|
+
);
|
|
50
|
+
if (profit.gt(ZERO)) {
|
|
51
|
+
const profitShareAmount = profit
|
|
52
|
+
.mul(new BN(vault.profitShare))
|
|
53
|
+
.div(PERCENTAGE_PRECISION);
|
|
54
|
+
return profitShareAmount;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return ZERO;
|
|
58
|
+
}
|
package/src/vaultClient.ts
CHANGED
|
@@ -65,7 +65,7 @@ export class VaultClient {
|
|
|
65
65
|
return await this.program.account.vaultDepositor.fetch(vaultDepositor);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
public async
|
|
68
|
+
public async getAllVaultDepositorsWithNoWithdrawRequest(
|
|
69
69
|
vault: PublicKey
|
|
70
70
|
): Promise<ProgramAccount<VaultDepositor>[]> {
|
|
71
71
|
const filters = [
|
|
@@ -86,10 +86,37 @@ export class VaultClient {
|
|
|
86
86
|
},
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
|
-
//
|
|
89
|
+
// last_withdraw_request.shares (u128) = 0
|
|
90
|
+
memcmp: {
|
|
91
|
+
offset: 112,
|
|
92
|
+
bytes: bs58.encode(new Uint8Array(16).fill(0)),
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
return (await this.program.account.vaultDepositor.all(
|
|
98
|
+
filters
|
|
99
|
+
)) as ProgramAccount<VaultDepositor>[];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public async getAllVaultDepositors(
|
|
103
|
+
vault: PublicKey
|
|
104
|
+
): Promise<ProgramAccount<VaultDepositor>[]> {
|
|
105
|
+
const filters = [
|
|
106
|
+
{
|
|
107
|
+
// discriminator = VaultDepositor
|
|
108
|
+
memcmp: {
|
|
109
|
+
offset: 0,
|
|
110
|
+
bytes: bs58.encode(
|
|
111
|
+
BorshAccountsCoder.accountDiscriminator('VaultDepositor')
|
|
112
|
+
),
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
// vault = vault
|
|
90
117
|
memcmp: {
|
|
91
|
-
offset:
|
|
92
|
-
bytes:
|
|
118
|
+
offset: 8,
|
|
119
|
+
bytes: vault.toBase58(),
|
|
93
120
|
},
|
|
94
121
|
},
|
|
95
122
|
];
|