hedge-web3 0.2.8 → 0.2.9

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.
@@ -1,6 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { PublicKey } from '@solana/web3.js';
3
3
  import Decimal from 'decimal.js';
4
+ import BN from 'bn.js';
4
5
  import VaultType from './VaultType';
5
6
  /**
6
7
  * A class that represents an on-chian vault.
@@ -13,9 +14,9 @@ export declare class VaultAccount {
13
14
  /** The public key of the vault owner. */
14
15
  pdaSalt: string;
15
16
  /** The deposited collateral of the vault (in SOL Lamports). */
16
- deposited: number;
17
+ deposited: BN;
17
18
  /** The outstanding debt of the vault (in USH Lamports). Denormalized to time 0. */
18
- denormalizedDebt: number;
19
+ denormalizedDebt: BN;
19
20
  /** The ordered number of when this vault was created. */
20
21
  vaultNumber: number;
21
22
  /** Debt redistribution snapshot */
@@ -38,12 +39,6 @@ export declare class VaultAccount {
38
39
  * @returns true if publicKey matches the owner publicKey
39
40
  */
40
41
  isOwnedBy(publicKey: PublicKey): boolean;
41
- /**
42
- * Get the collateral value in SOL
43
- *
44
- * @returns collateral value in SOL
45
- */
46
- inSol(): number;
47
42
  /**
48
43
  * Get the debt value in USH
49
44
  *
@@ -56,8 +51,36 @@ export declare class VaultAccount {
56
51
  * @returns example: `1b6ca...azy71s`
57
52
  */
58
53
  toDisplayString(): string;
59
- addDebt(additionalDebt: Decimal, vaultTypeAccount: VaultType): void;
60
- addDeposit(depositAmount: number): void;
54
+ /**
55
+ * Add additional debt to the vault.
56
+ *
57
+ * @param {BN} additionalDebt - Additional normalized debt to add in (USH) lamports.
58
+ * @param {VaultType} vaultTypeAccount - Vault's vaultType
59
+ *
60
+ */
61
+ addDebt(additionalDebt: BN, vaultTypeAccount: VaultType): void;
62
+ /**
63
+ * Repay debt on a vault
64
+ *
65
+ * @param {BN} repayAmount - Normalized debt to repay in (USH) lamports.
66
+ * @param {VaultType} vaultTypeAccount - Vault's vaultType
67
+ *
68
+ */
69
+ repayDebt(repayAmount: BN, vaultTypeAccount: VaultType): void;
70
+ /**
71
+ * Deposit Collateral
72
+ *
73
+ * @param {BN} depositAmount - Amount to deposit in (CollateralMint) lamports
74
+ *
75
+ */
76
+ depositCollateral(depositAmount: BN): void;
77
+ /**
78
+ * Withdraw Collateral
79
+ *
80
+ * @param {BN} withdrawAmount - Amount to withdraw in (CollateralMint) lamports
81
+ *
82
+ */
83
+ withdrawCollateral(withdrawAmount: BN): void;
61
84
  redeem(): void;
62
85
  liquidate(): void;
63
86
  updateDebtAndCollateral(vaultTypeAccountData: VaultType): void;
@@ -1,5 +1,20 @@
1
- import { Program, Provider } from '@project-serum/anchor';
1
+ /// <reference types="bn.js" />
2
+ import { Program, BN } from '@project-serum/anchor';
2
3
  import { PublicKey } from '@solana/web3.js';
3
4
  import { VaultAccount } from '../state/VaultAccount';
4
5
  import { Vault } from '../idl/vault';
5
- export declare function getLinkedListAccounts(program: Program<Vault>, provider: Provider, vaultTypeAccountPublicKey: PublicKey, vaultPublicKey: PublicKey, depositAmount: number, loanAmount: number, redeem: boolean, liquidate: boolean, cachedVaults?: VaultAccount[]): Promise<[PublicKey, PublicKey, PublicKey, VaultAccount[]]>;
6
+ /**
7
+ * Get the accounts the left and right for re-inserting in the linked list
8
+ *
9
+ * @param {Program<Vault>} program - Anchor program <Vault ILD>
10
+ * @param {PublicKey} vaultTypeAccountPublicKey - Vault Type Account PublicKey
11
+ * @param {PublicKey} vaultPublicKey - Vault Account PublicKey
12
+ * @param {BN} depositAmount - Amount that will be deposited into vault with instruction
13
+ * @param {BN} withdrawAmount - Amount that will be withdrawn from vault with instruction
14
+ * @param {BN} loanAmount - Amount that will be deposited into vault with transaction (sans fees)
15
+ * @param {BN} repayAmount - Amount that will be repaid into vault with transaction
16
+ * @param {boolean} redeem - True if vault is going to be redeemed fully
17
+ * @param {boolean} liquidate - True if vault is going to be liquidated fully
18
+ * @param {VaultAccount[]} cachedVaults - Optional list of cached vaults. Saves a request to the on-chain data.
19
+ */
20
+ export declare function getLinkedListAccounts(program: Program<Vault>, vaultTypeAccountPublicKey: PublicKey, vaultPublicKey: PublicKey, depositAmount: BN, withdrawAmount: BN, loanAmount: BN, repayAmount: BN, redeem: boolean, liquidate: boolean, cachedVaults?: VaultAccount[]): Promise<[PublicKey, PublicKey, PublicKey, VaultAccount[]]>;
@@ -38,7 +38,7 @@ function depositVault(program, provider, payer, vaultPublicKey, depositAmount, o
38
38
  const hedgeStakingPoolAssociatedUshTokenAccount = yield (0, Constants_1.findAssociatedTokenAddress)(hedgeStakingPoolPublicKey, ushMintPublickey);
39
39
  const transaction = new web3_js_1.Transaction();
40
40
  const signers = [payer, history];
41
- const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = yield (0, getLinkedListAccounts_1.getLinkedListAccounts)(program, provider, vaultAccount.vaultType, vaultPublicKey, depositAmount, 0, false, false);
41
+ const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = yield (0, getLinkedListAccounts_1.getLinkedListAccounts)(program, vaultAccount.vaultType, vaultPublicKey, new anchor_1.BN(depositAmount), new anchor_1.BN(0), new anchor_1.BN(0), new anchor_1.BN(0), false, false);
42
42
  if (vaultTypeAccountInfo.collateralMint.toString() === token_instructions_1.WRAPPED_SOL_MINT.toString()) {
43
43
  transaction.add(web3_js_1.SystemProgram.createAccount({
44
44
  fromPubkey: payer.publicKey,
@@ -35,7 +35,7 @@ function liquidateVault(program, provider, payer, vaultPublicKey, overrideTime)
35
35
  const poolAssociatedTokenAccount = yield (0, spl_token_1.getOrCreateAssociatedTokenAccount)(provider.connection, payer, collateralMint, liquidationPoolStatePublicKey, true);
36
36
  const vaultTypeAssociatedTokenAccount = yield (0, spl_token_1.getOrCreateAssociatedTokenAccount)(provider.connection, payer, collateralMint, vaultAccount.vaultType, true);
37
37
  const hedgeStakingPoolAssociatedUshTokenAccount = yield (0, spl_token_1.getOrCreateAssociatedTokenAccount)(provider.connection, payer, ushMintPublickey, hedgeStakingPoolPublicKey, true);
38
- const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = yield (0, getLinkedListAccounts_1.getLinkedListAccounts)(program, provider, vaultAccount.vaultType, vaultPublicKey, 0, 0, false, true);
38
+ const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = yield (0, getLinkedListAccounts_1.getLinkedListAccounts)(program, vaultAccount.vaultType, vaultPublicKey, new anchor_1.BN(0), new anchor_1.BN(0), new anchor_1.BN(0), new anchor_1.BN(0), false, true);
39
39
  const history = web3_js_1.Keypair.generate();
40
40
  const newEra = web3_js_1.Keypair.generate();
41
41
  const transaction = new web3_js_1.Transaction();
@@ -27,7 +27,7 @@ function loanVault(program, provider, payer, vaultPublicKey, loanAmount, overrid
27
27
  const vaultTypeAccount = yield program.account.vaultType.fetch(vaultAccount.vaultType);
28
28
  const vaultTypeAssociatedTokenAccount = yield (0, spl_token_1.getOrCreateAssociatedTokenAccount)(provider.connection, payer, vaultTypeAccount.collateralMint, vaultAccount.vaultType, true);
29
29
  const vaultAssociatedTokenAccount = yield (0, spl_token_1.getOrCreateAssociatedTokenAccount)(provider.connection, payer, vaultTypeAccount.collateralMint, vaultPublicKey, true);
30
- const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = yield (0, getLinkedListAccounts_1.getLinkedListAccounts)(program, provider, vaultAccount.vaultType, vaultPublicKey, 0, loanAmount, false, false);
30
+ const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = yield (0, getLinkedListAccounts_1.getLinkedListAccounts)(program, vaultAccount.vaultType, vaultPublicKey, new anchor_1.BN(0), new anchor_1.BN(0), new anchor_1.BN(loanAmount), new anchor_1.BN(0), false, false);
31
31
  const history = web3_js_1.Keypair.generate();
32
32
  const transaction = new web3_js_1.Transaction().add(yield loanVaultInstruction(program, payer.publicKey, payerUshAccount.address, vaultPublicKey, vaultAssociatedTokenAccount.address, history.publicKey, vaultAccount.vaultType, vaultTypeAssociatedTokenAccount.address, oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey, new anchor_1.BN(loanAmount), overrideTime));
33
33
  yield (0, sendAndConfirmWithDebug_1.default)(provider.connection, transaction, [payer, history]);
@@ -30,7 +30,7 @@ function redeemVault(program, provider, payer, vaultPublicKey, redeemAmount, tra
30
30
  const vaultTypeAssociatedTokenAccount = yield (0, spl_token_1.getOrCreateAssociatedTokenAccount)(provider.connection, payer, vaultTypeAccountInfo.collateralMint, vaultAccount.vaultType, true);
31
31
  const vaultAssociatedTokenAccount = yield (0, spl_token_1.getOrCreateAssociatedTokenAccount)(provider.connection, payer, vaultTypeAccountInfo.collateralMint, vaultPublicKey, true);
32
32
  const payerTokenAccount = yield (0, spl_token_1.getOrCreateAssociatedTokenAccount)(provider.connection, payer, vaultTypeAccountInfo.collateralMint, payer.publicKey);
33
- const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = yield (0, getLinkedListAccounts_1.getLinkedListAccounts)(program, provider, vaultAccount.vaultType, vaultPublicKey, 0, 0, true, false);
33
+ const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = yield (0, getLinkedListAccounts_1.getLinkedListAccounts)(program, vaultAccount.vaultType, vaultPublicKey, new anchor_1.BN(0), new anchor_1.BN(0), new anchor_1.BN(0), new anchor_1.BN(0), true, false);
34
34
  const history = web3_js_1.Keypair.generate();
35
35
  const transaction = new web3_js_1.Transaction().add(yield redeemVaultInstruction(program, payer.publicKey, payerUshAccount.address, payerTokenAccount.address, vaultPublicKey, vaultAssociatedTokenAccount.address, history.publicKey, vaultAccount.vaultType, vaultTypeAssociatedTokenAccount.address, oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey, new anchor_1.BN(redeemAmount), transactionOverrideTime));
36
36
  yield (0, sendAndConfirmWithDebug_1.default)(provider.connection, transaction, [payer, history]);
@@ -59,12 +59,12 @@ const pythAccounts = {
59
59
  };
60
60
  const chainlinkAccounts = {
61
61
  Testing: web3_js_1.SystemProgram.programId,
62
- Devnet: new web3_js_1.PublicKey('FmAmfoyPXiA8Vhhe6MZTr3U6rZfEZ1ctEHay1ysqCqcf'),
62
+ Devnet: new web3_js_1.PublicKey('HgTtcbcmp5BeThax5AU8vg4VwK79qAvAKKFMs8txMLW6'),
63
63
  MainnetBeta: web3_js_1.SystemProgram.programId, // CHAINLINK NOT ON MAINNET YET
64
64
  };
65
65
  const switchboardAccounts = {
66
66
  Testing: web3_js_1.SystemProgram.programId,
67
67
  // Devnet: new PublicKey('GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR'),
68
- Devnet: new web3_js_1.PublicKey('DpoK8Zz69APV9ntjuY9C4LZCxANYMV56M2cbXEdkjxME'),
68
+ Devnet: new web3_js_1.PublicKey('GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR'),
69
69
  MainnetBeta: web3_js_1.SystemProgram.programId, // Switchboard V2 NOT ON MAINNET YET
70
70
  };
@@ -28,7 +28,7 @@ function repayVault(program, provider, payer, vaultPublicKey, repayAmount, overr
28
28
  const vaultTypeAccount = yield program.account.vaultType.fetch(vaultAccount.vaultType);
29
29
  const vaultTypeAssociatedTokenAccount = yield (0, Constants_1.findAssociatedTokenAddress)(vaultAccount.vaultType, vaultTypeAccount.collateralMint);
30
30
  const vaultAssociatedTokenAccount = yield (0, Constants_1.findAssociatedTokenAddress)(vaultPublicKey, vaultTypeAccount.collateralMint);
31
- const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = yield (0, getLinkedListAccounts_1.getLinkedListAccounts)(program, provider, vaultAccount.vaultType, vaultPublicKey, 0, repayAmount * -1, false, false);
31
+ const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = yield (0, getLinkedListAccounts_1.getLinkedListAccounts)(program, vaultAccount.vaultType, vaultPublicKey, new anchor_1.BN(0), new anchor_1.BN(0), new anchor_1.BN(0), new anchor_1.BN(Math.abs(repayAmount)), false, false);
32
32
  const history = web3_js_1.Keypair.generate();
33
33
  const transaction = new web3_js_1.Transaction().add(yield repayVaultInstruction(program, payer.publicKey, payerUshAccount.address, vaultPublicKey, vaultAssociatedTokenAccount, history.publicKey, vaultAccount.vaultType, vaultTypeAssociatedTokenAccount, oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey, new anchor_1.BN(repayAmount), overrideTime));
34
34
  yield (0, sendAndConfirmWithDebug_1.default)(provider.connection, transaction, [payer, history]);
@@ -34,7 +34,7 @@ function withdrawVault(program, provider, payer, vaultPublicKey, withdrawAmount,
34
34
  const destinationTokenAccount = yield (0, spl_token_1.getOrCreateAssociatedTokenAccount)(provider.connection, payer, vaultTypeAccountInfo.collateralMint, payer.publicKey);
35
35
  const [hedgeStakingPoolPublicKey] = yield (0, Constants_1.getPoolPublicKeyForMint)(yield (0, Constants_1.getHedgeMintPublicKey)());
36
36
  const hedgeStakingPoolAssociatedUshTokenAccount = yield (0, Constants_1.findAssociatedTokenAddress)(hedgeStakingPoolPublicKey, ushMintPublickey);
37
- const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = yield (0, getLinkedListAccounts_1.getLinkedListAccounts)(program, provider, vaultAccount.vaultType, vaultPublicKey, withdrawAmount * -1, 0, false, false);
37
+ const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = yield (0, getLinkedListAccounts_1.getLinkedListAccounts)(program, vaultAccount.vaultType, vaultPublicKey, new anchor_1.BN(0), new anchor_1.BN(Math.abs(withdrawAmount)), new anchor_1.BN(0), new anchor_1.BN(0), false, false);
38
38
  const transaction = new web3_js_1.Transaction().add(yield withdrawVaultInstruction(program, vaultSystemStatePublicKey, payer.publicKey, destinationTokenAccount.address, vaultPublicKey, vaultAssociatedCollateralAccount.address, vaultAccount.vaultType, vaultTypeAssociatedTokenAccount.address, hedgeStakingPoolPublicKey, hedgeStakingPoolAssociatedUshTokenAccount, ushMintPublickey, history.publicKey, oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey, new anchor_1.BN(withdrawAmount), overrideTime));
39
39
  yield (0, sendAndConfirmWithDebug_1.default)(provider.connection, transaction, [payer, history]);
40
40
  return vaultPublicKey;
@@ -27,12 +27,16 @@ const web3_js_1 = require("@solana/web3.js");
27
27
  const decimal_js_1 = __importDefault(require("decimal.js"));
28
28
  const HedgeDecimal_1 = require("../HedgeDecimal");
29
29
  const borsh = __importStar(require("@project-serum/borsh"));
30
+ const bn_js_1 = __importDefault(require("bn.js"));
30
31
  /**
31
32
  * A class that represents an on-chian vault.
32
33
  */
33
34
  class VaultAccount {
34
35
  constructor(vault, publicKey) {
35
- var _a, _b;
36
+ /** The deposited collateral of the vault (in SOL Lamports). */
37
+ this.deposited = new bn_js_1.default(0);
38
+ /** The outstanding debt of the vault (in USH Lamports). Denormalized to time 0. */
39
+ this.denormalizedDebt = new bn_js_1.default(0);
36
40
  /** The ordered number of when this vault was created. */
37
41
  this.vaultNumber = 0;
38
42
  /** Debt redistribution snapshot */
@@ -44,8 +48,8 @@ class VaultAccount {
44
48
  this.publicKey = publicKey;
45
49
  this.vaultOwner = vault.vaultOwner;
46
50
  this.pdaSalt = vault.pdaSalt;
47
- this.deposited = (_a = vault.deposited) === null || _a === void 0 ? void 0 : _a.toNumber();
48
- this.denormalizedDebt = (_b = vault.denormalizedDebt) === null || _b === void 0 ? void 0 : _b.toNumber();
51
+ this.deposited = vault.deposited;
52
+ this.denormalizedDebt = vault.denormalizedDebt;
49
53
  if (vault.vaultNumber) {
50
54
  this.vaultNumber = vault.vaultNumber.toNumber();
51
55
  }
@@ -71,21 +75,22 @@ class VaultAccount {
71
75
  isOwnedBy(publicKey) {
72
76
  return publicKey && publicKey.toString() === this.vaultOwner.toString();
73
77
  }
74
- /**
75
- * Get the collateral value in SOL
76
- *
77
- * @returns collateral value in SOL
78
- */
79
- inSol() {
80
- return this.deposited / web3_js_1.LAMPORTS_PER_SOL;
81
- }
78
+ // /**
79
+ // * Get the collateral value in SOL
80
+ // *
81
+ // * @returns collateral value in SOL
82
+ // */
83
+ // public inSol(): number {
84
+ // This should not be LAMPORTS_PER_SOL. Should be collateral units like Ray
85
+ // return new Decimal(this.deposited.toString()).div(LAMPORTS_PER_SOL).toNumber()
86
+ // }
82
87
  /**
83
88
  * Get the debt value in USH
84
89
  *
85
90
  * @returns debt value in USH
86
91
  */
87
92
  inUsd() {
88
- return this.denormalizedDebt / web3_js_1.LAMPORTS_PER_SOL;
93
+ return new decimal_js_1.default(this.denormalizedDebt.toString()).div(web3_js_1.LAMPORTS_PER_SOL).toNumber();
89
94
  }
90
95
  /**
91
96
  * Pretty print the vault publickey for easy display
@@ -97,35 +102,69 @@ class VaultAccount {
97
102
  .toString()
98
103
  .substring(this.publicKey.toString().length - 6)}`;
99
104
  }
105
+ /**
106
+ * Add additional debt to the vault.
107
+ *
108
+ * @param {BN} additionalDebt - Additional normalized debt to add in (USH) lamports.
109
+ * @param {VaultType} vaultTypeAccount - Vault's vaultType
110
+ *
111
+ */
100
112
  addDebt(additionalDebt, vaultTypeAccount) {
101
- let loanFee = new decimal_js_1.default(0);
102
- if (additionalDebt.isPositive()) {
103
- loanFee = vaultTypeAccount.loanInitFee.mul(additionalDebt);
104
- }
105
- const totalNormalizedLoan = additionalDebt.add(loanFee);
106
- const denormalizedNewDebt = totalNormalizedLoan.div(new decimal_js_1.default(vaultTypeAccount.cumulativeRate.toString()));
107
- this.denormalizedDebt = denormalizedNewDebt.add(new decimal_js_1.default(this.denormalizedDebt)).floor().toNumber();
113
+ const additionalDebtAsDecimal = new decimal_js_1.default(additionalDebt.toString());
114
+ // Calculate the fee on the loan
115
+ const loanFee = vaultTypeAccount.loanInitFee.mul(additionalDebtAsDecimal);
116
+ // TODO: There's a chance this needs to be .Floor()
117
+ const totalNormalizedLoan = additionalDebtAsDecimal.add(loanFee);
118
+ const denormalizedNewDebt = new bn_js_1.default(totalNormalizedLoan.div(vaultTypeAccount.cumulativeRate).floor().toString());
119
+ this.denormalizedDebt = this.denormalizedDebt.add(denormalizedNewDebt);
108
120
  }
109
- addDeposit(depositAmount) {
110
- this.deposited += depositAmount;
121
+ /**
122
+ * Repay debt on a vault
123
+ *
124
+ * @param {BN} repayAmount - Normalized debt to repay in (USH) lamports.
125
+ * @param {VaultType} vaultTypeAccount - Vault's vaultType
126
+ *
127
+ */
128
+ repayDebt(repayAmount, vaultTypeAccount) {
129
+ const denormalizedRepayment = new decimal_js_1.default(repayAmount.toString()).div(vaultTypeAccount.cumulativeRate).floor();
130
+ this.denormalizedDebt = this.denormalizedDebt.sub(new bn_js_1.default(denormalizedRepayment.toString()));
131
+ }
132
+ /**
133
+ * Deposit Collateral
134
+ *
135
+ * @param {BN} depositAmount - Amount to deposit in (CollateralMint) lamports
136
+ *
137
+ */
138
+ depositCollateral(depositAmount) {
139
+ this.deposited = this.deposited.add(depositAmount);
140
+ }
141
+ /**
142
+ * Withdraw Collateral
143
+ *
144
+ * @param {BN} withdrawAmount - Amount to withdraw in (CollateralMint) lamports
145
+ *
146
+ */
147
+ withdrawCollateral(withdrawAmount) {
148
+ this.deposited = this.deposited.sub(withdrawAmount);
111
149
  }
112
150
  redeem() {
113
151
  // TODO - Calculate actual redeem amount and adust correctly
114
- this.denormalizedDebt = 0;
152
+ this.denormalizedDebt = new bn_js_1.default(0);
115
153
  this.vaultStatus = 'initialized';
116
154
  }
117
155
  liquidate() {
118
156
  // TODO - Calculate actual liquidate amount and adust correctly
119
- this.denormalizedDebt = 0;
157
+ this.denormalizedDebt = new bn_js_1.default(0);
120
158
  this.vaultStatus = 'liquidated';
121
159
  }
122
160
  updateDebtAndCollateral(vaultTypeAccountData) {
123
- this.denormalizedDebt = vaultTypeAccountData.debtRedistributionProduct
161
+ this.denormalizedDebt = new bn_js_1.default(vaultTypeAccountData.debtRedistributionProduct
124
162
  .div(this.debtProductSnapshotBytes)
125
- .mul(new decimal_js_1.default(this.denormalizedDebt))
126
- .toNumber();
127
- const extraCollateralDeposited = this.denormalizedDebt * vaultTypeAccountData.collateralRedistributionAccumulator.sub(this.collateralAccumulatorSnapshotBytes).toNumber();
128
- this.deposited += extraCollateralDeposited;
163
+ .mul(new decimal_js_1.default(this.denormalizedDebt.toString()))
164
+ .floor()
165
+ .toString());
166
+ const extraCollateralDeposited = new decimal_js_1.default(this.denormalizedDebt.toString()).mul(vaultTypeAccountData.collateralRedistributionAccumulator.sub(this.collateralAccumulatorSnapshotBytes).toNumber()).floor();
167
+ this.deposited = this.deposited.add(new bn_js_1.default(extraCollateralDeposited.toString()));
129
168
  this.collateralAccumulatorSnapshotBytes = vaultTypeAccountData.collateralRedistributionAccumulator;
130
169
  this.debtProductSnapshotBytes = vaultTypeAccountData.debtRedistributionProduct;
131
170
  }
@@ -135,8 +174,8 @@ class VaultAccount {
135
174
  arrow = ' <----!!';
136
175
  }
137
176
  let collateralRatio = 'Infinite';
138
- if (this.denormalizedDebt > 0) {
139
- collateralRatio = new decimal_js_1.default(this.deposited).div(new decimal_js_1.default(this.denormalizedDebt)).toString();
177
+ if (this.denormalizedDebt.gt(new bn_js_1.default(0))) {
178
+ collateralRatio = new decimal_js_1.default(this.deposited.toString()).div(new decimal_js_1.default(this.denormalizedDebt.toString())).toString();
140
179
  }
141
180
  let nextVault = 'None';
142
181
  if (this.nextVaultToRedeem) {
@@ -13,13 +13,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.getLinkedListAccounts = void 0;
16
+ const anchor_1 = require("@project-serum/anchor");
16
17
  const underscore_1 = __importDefault(require("underscore"));
17
18
  const Constants_1 = require("../Constants");
18
19
  const VaultAccount_1 = require("../state/VaultAccount");
19
20
  const decimal_js_1 = __importDefault(require("decimal.js"));
20
21
  const bs58_1 = __importDefault(require("bs58"));
21
22
  const VaultType_1 = __importDefault(require("../state/VaultType"));
22
- function getLinkedListAccounts(program, provider, vaultTypeAccountPublicKey, vaultPublicKey, depositAmount, loanAmount, redeem, liquidate, cachedVaults) {
23
+ /**
24
+ * Get the accounts the left and right for re-inserting in the linked list
25
+ *
26
+ * @param {Program<Vault>} program - Anchor program <Vault ILD>
27
+ * @param {PublicKey} vaultTypeAccountPublicKey - Vault Type Account PublicKey
28
+ * @param {PublicKey} vaultPublicKey - Vault Account PublicKey
29
+ * @param {BN} depositAmount - Amount that will be deposited into vault with instruction
30
+ * @param {BN} withdrawAmount - Amount that will be withdrawn from vault with instruction
31
+ * @param {BN} loanAmount - Amount that will be deposited into vault with transaction (sans fees)
32
+ * @param {BN} repayAmount - Amount that will be repaid into vault with transaction
33
+ * @param {boolean} redeem - True if vault is going to be redeemed fully
34
+ * @param {boolean} liquidate - True if vault is going to be liquidated fully
35
+ * @param {VaultAccount[]} cachedVaults - Optional list of cached vaults. Saves a request to the on-chain data.
36
+ */
37
+ function getLinkedListAccounts(program, vaultTypeAccountPublicKey, vaultPublicKey, depositAmount, withdrawAmount, loanAmount, repayAmount, redeem, liquidate, cachedVaults) {
23
38
  return __awaiter(this, void 0, void 0, function* () {
24
39
  const vaultTypeRaw = yield program.account.vaultType.fetch(vaultTypeAccountPublicKey);
25
40
  const vaultType = new VaultType_1.default(vaultTypeRaw, vaultTypeAccountPublicKey);
@@ -50,7 +65,7 @@ function getLinkedListAccounts(program, provider, vaultTypeAccountPublicKey, vau
50
65
  // })
51
66
  // Remove any vaults with no debt or collateral
52
67
  vaults = underscore_1.default.filter(vaults, (vault) => {
53
- return vault.denormalizedDebt > 0 && vault.deposited > 0;
68
+ return vault.denormalizedDebt.gt(new anchor_1.BN(0)) && vault.deposited.gt(new anchor_1.BN(0));
54
69
  });
55
70
  // Sort them
56
71
  vaults.sort(sortVaults);
@@ -101,17 +116,18 @@ function getLinkedListAccounts(program, provider, vaultTypeAccountPublicKey, vau
101
116
  }
102
117
  // Now that we know it's def in the list, iterate the list and update
103
118
  // this vault with the operation we're going to apply
104
- const newNormalizedDebt = new decimal_js_1.default(loanAmount);
105
119
  vaults[indexBefore].updateDebtAndCollateral(vaultType);
106
- vaults[indexBefore].addDebt(newNormalizedDebt, vaultType);
107
- vaults[indexBefore].addDeposit(depositAmount);
120
+ vaults[indexBefore].addDebt(loanAmount, vaultType);
121
+ vaults[indexBefore].repayDebt(repayAmount, vaultType);
122
+ vaults[indexBefore].depositCollateral(depositAmount);
123
+ vaults[indexBefore].withdrawCollateral(withdrawAmount);
108
124
  if (liquidate) {
109
125
  vaults[indexBefore].liquidate();
110
126
  }
111
127
  if (redeem) {
112
128
  vaults[indexBefore].redeem();
113
129
  }
114
- if (vaults[indexBefore].denormalizedDebt === 0) {
130
+ if (vaults[indexBefore].denormalizedDebt.isZero()) {
115
131
  vaults.splice(indexBefore, 1);
116
132
  }
117
133
  // Sort it again since we've changed one vault
@@ -154,12 +170,12 @@ exports.getLinkedListAccounts = getLinkedListAccounts;
154
170
  // Sort function we can use to sort the vaults
155
171
  // Sorted by collateral ratio. If two are the same, newer vault first
156
172
  function sortVaults(a, b) {
157
- const aRatio = a.deposited / a.denormalizedDebt;
158
- const bRatio = b.deposited / b.denormalizedDebt;
159
- if (aRatio === bRatio) {
173
+ const aRatio = new decimal_js_1.default(a.deposited.toString()).div(new decimal_js_1.default(a.denormalizedDebt.toString()));
174
+ const bRatio = new decimal_js_1.default(b.deposited.toString()).div(new decimal_js_1.default(b.denormalizedDebt.toString()));
175
+ if (aRatio.equals(bRatio)) {
160
176
  return a.publicKey.toString() > b.publicKey.toString() ? 1 : -1;
161
177
  }
162
- return aRatio - bRatio;
178
+ return aRatio.greaterThan(bRatio) ? 1 : -1;
163
179
  }
164
180
  function getMiniVaults(program, vaultTypePublicKey) {
165
181
  return __awaiter(this, void 0, void 0, function* () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedge-web3",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "Hedge Javascript Web3 API",
5
5
  "main": "lib/index.js",
6
6
  "types": "declarations/index.d.ts",
@@ -67,11 +67,12 @@ export async function depositVault(
67
67
  const signers = [payer, history]
68
68
  const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = await getLinkedListAccounts(
69
69
  program,
70
- provider,
71
70
  vaultAccount.vaultType,
72
71
  vaultPublicKey,
73
- depositAmount,
74
- 0,
72
+ new BN(depositAmount),
73
+ new BN(0),
74
+ new BN(0),
75
+ new BN(0),
75
76
  false,
76
77
  false
77
78
  )
@@ -87,11 +87,12 @@ export async function liquidateVault(
87
87
 
88
88
  const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = await getLinkedListAccounts(
89
89
  program,
90
- provider,
91
90
  vaultAccount.vaultType,
92
91
  vaultPublicKey,
93
- 0,
94
- 0,
92
+ new BN(0),
93
+ new BN(0),
94
+ new BN(0),
95
+ new BN(0),
95
96
  false,
96
97
  true
97
98
  )
@@ -59,11 +59,12 @@ export async function loanVault(
59
59
  )
60
60
  const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = await getLinkedListAccounts(
61
61
  program,
62
- provider,
63
62
  vaultAccount.vaultType,
64
63
  vaultPublicKey,
65
- 0,
66
- loanAmount,
64
+ new BN(0),
65
+ new BN(0),
66
+ new BN(loanAmount),
67
+ new BN(0),
67
68
  false,
68
69
  false
69
70
  )
@@ -67,11 +67,12 @@ export async function redeemVault(
67
67
 
68
68
  const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = await getLinkedListAccounts(
69
69
  program,
70
- provider,
71
70
  vaultAccount.vaultType,
72
71
  vaultPublicKey,
73
- 0,
74
- 0,
72
+ new BN(0),
73
+ new BN(0),
74
+ new BN(0),
75
+ new BN(0),
75
76
  true,
76
77
  false
77
78
  )
@@ -75,12 +75,12 @@ const pythAccounts = {
75
75
  }
76
76
  const chainlinkAccounts = {
77
77
  Testing: SystemProgram.programId,
78
- Devnet: new PublicKey('FmAmfoyPXiA8Vhhe6MZTr3U6rZfEZ1ctEHay1ysqCqcf'),
78
+ Devnet: new PublicKey('HgTtcbcmp5BeThax5AU8vg4VwK79qAvAKKFMs8txMLW6'),
79
79
  MainnetBeta: SystemProgram.programId, // CHAINLINK NOT ON MAINNET YET
80
80
  }
81
81
  const switchboardAccounts = {
82
82
  Testing: SystemProgram.programId,
83
83
  // Devnet: new PublicKey('GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR'),
84
- Devnet: new PublicKey('DpoK8Zz69APV9ntjuY9C4LZCxANYMV56M2cbXEdkjxME'),
84
+ Devnet: new PublicKey('GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR'),
85
85
  MainnetBeta: SystemProgram.programId, // Switchboard V2 NOT ON MAINNET YET
86
86
  }
@@ -49,11 +49,12 @@ export async function repayVault(
49
49
 
50
50
  const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = await getLinkedListAccounts(
51
51
  program,
52
- provider,
53
52
  vaultAccount.vaultType,
54
53
  vaultPublicKey,
55
- 0,
56
- repayAmount * -1,
54
+ new BN(0),
55
+ new BN(0),
56
+ new BN(0),
57
+ new BN(Math.abs(repayAmount)),
57
58
  false,
58
59
  false
59
60
  )
@@ -69,11 +69,12 @@ export async function withdrawVault(
69
69
 
70
70
  const [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey] = await getLinkedListAccounts(
71
71
  program,
72
- provider,
73
72
  vaultAccount.vaultType,
74
73
  vaultPublicKey,
75
- withdrawAmount * -1,
76
- 0,
74
+ new BN(0),
75
+ new BN(Math.abs(withdrawAmount)),
76
+ new BN(0),
77
+ new BN(0),
77
78
  false,
78
79
  false
79
80
  )
@@ -20,10 +20,10 @@ export class VaultAccount {
20
20
  pdaSalt: string
21
21
 
22
22
  /** The deposited collateral of the vault (in SOL Lamports). */
23
- deposited: number
23
+ deposited = new BN(0)
24
24
 
25
25
  /** The outstanding debt of the vault (in USH Lamports). Denormalized to time 0. */
26
- denormalizedDebt: number
26
+ denormalizedDebt = new BN(0)
27
27
 
28
28
  /** The ordered number of when this vault was created. */
29
29
  vaultNumber = 0
@@ -50,8 +50,10 @@ export class VaultAccount {
50
50
  this.publicKey = publicKey
51
51
  this.vaultOwner = vault.vaultOwner
52
52
  this.pdaSalt = vault.pdaSalt
53
- this.deposited = vault.deposited?.toNumber()
54
- this.denormalizedDebt = vault.denormalizedDebt?.toNumber()
53
+
54
+ this.deposited = vault.deposited
55
+ this.denormalizedDebt = vault.denormalizedDebt
56
+
55
57
  if (vault.vaultNumber) {
56
58
  this.vaultNumber = vault.vaultNumber.toNumber()
57
59
  }
@@ -80,14 +82,15 @@ export class VaultAccount {
80
82
  return publicKey && publicKey.toString() === this.vaultOwner.toString()
81
83
  }
82
84
 
83
- /**
84
- * Get the collateral value in SOL
85
- *
86
- * @returns collateral value in SOL
87
- */
88
- public inSol(): number {
89
- return this.deposited / LAMPORTS_PER_SOL
90
- }
85
+ // /**
86
+ // * Get the collateral value in SOL
87
+ // *
88
+ // * @returns collateral value in SOL
89
+ // */
90
+ // public inSol(): number {
91
+ // This should not be LAMPORTS_PER_SOL. Should be collateral units like Ray
92
+ // return new Decimal(this.deposited.toString()).div(LAMPORTS_PER_SOL).toNumber()
93
+ // }
91
94
 
92
95
  /**
93
96
  * Get the debt value in USH
@@ -95,7 +98,7 @@ export class VaultAccount {
95
98
  * @returns debt value in USH
96
99
  */
97
100
  public inUsd(): number {
98
- return this.denormalizedDebt / LAMPORTS_PER_SOL
101
+ return new Decimal(this.denormalizedDebt.toString()).div(LAMPORTS_PER_SOL).toNumber()
99
102
  }
100
103
 
101
104
  /**
@@ -109,42 +112,82 @@ export class VaultAccount {
109
112
  .substring(this.publicKey.toString().length - 6)}`
110
113
  }
111
114
 
112
- public addDebt(additionalDebt: Decimal, vaultTypeAccount: VaultType) {
113
- let loanFee = new Decimal(0)
114
- if (additionalDebt.isPositive()){
115
- loanFee = vaultTypeAccount.loanInitFee.mul(additionalDebt)
116
- }
115
+ /**
116
+ * Add additional debt to the vault.
117
+ *
118
+ * @param {BN} additionalDebt - Additional normalized debt to add in (USH) lamports.
119
+ * @param {VaultType} vaultTypeAccount - Vault's vaultType
120
+ *
121
+ */
122
+ public addDebt(additionalDebt: BN, vaultTypeAccount: VaultType) {
123
+ const additionalDebtAsDecimal = new Decimal(additionalDebt.toString())
124
+ // Calculate the fee on the loan
125
+ const loanFee = vaultTypeAccount.loanInitFee.mul(additionalDebtAsDecimal)
117
126
 
118
- const totalNormalizedLoan = additionalDebt.add(loanFee)
119
- const denormalizedNewDebt = totalNormalizedLoan.div(new Decimal(vaultTypeAccount.cumulativeRate.toString()))
120
- this.denormalizedDebt = denormalizedNewDebt.add(new Decimal(this.denormalizedDebt)).floor().toNumber()
127
+ // TODO: There's a chance this needs to be .Floor()
128
+ const totalNormalizedLoan = additionalDebtAsDecimal.add(loanFee)
129
+
130
+ const denormalizedNewDebt = new BN(totalNormalizedLoan.div(vaultTypeAccount.cumulativeRate).floor().toString())
131
+ this.denormalizedDebt = this.denormalizedDebt.add(denormalizedNewDebt)
121
132
  }
122
133
 
123
- public addDeposit(depositAmount: number) {
124
- this.deposited += depositAmount
134
+ /**
135
+ * Repay debt on a vault
136
+ *
137
+ * @param {BN} repayAmount - Normalized debt to repay in (USH) lamports.
138
+ * @param {VaultType} vaultTypeAccount - Vault's vaultType
139
+ *
140
+ */
141
+ public repayDebt(repayAmount: BN, vaultTypeAccount: VaultType) {
142
+ const denormalizedRepayment = new Decimal(repayAmount.toString()).div(vaultTypeAccount.cumulativeRate).floor()
143
+
144
+ this.denormalizedDebt = this.denormalizedDebt.sub(new BN(denormalizedRepayment.toString()))
145
+ }
146
+
147
+ /**
148
+ * Deposit Collateral
149
+ *
150
+ * @param {BN} depositAmount - Amount to deposit in (CollateralMint) lamports
151
+ *
152
+ */
153
+ public depositCollateral(depositAmount: BN) {
154
+ this.deposited = this.deposited.add(depositAmount)
155
+ }
156
+ /**
157
+ * Withdraw Collateral
158
+ *
159
+ * @param {BN} withdrawAmount - Amount to withdraw in (CollateralMint) lamports
160
+ *
161
+ */
162
+ public withdrawCollateral(withdrawAmount: BN) {
163
+ this.deposited = this.deposited.sub(withdrawAmount)
125
164
  }
126
165
 
127
166
  public redeem() {
128
167
  // TODO - Calculate actual redeem amount and adust correctly
129
- this.denormalizedDebt = 0
168
+ this.denormalizedDebt = new BN(0)
130
169
  this.vaultStatus = 'initialized'
131
170
  }
132
171
  public liquidate() {
133
172
  // TODO - Calculate actual liquidate amount and adust correctly
134
- this.denormalizedDebt = 0
173
+ this.denormalizedDebt = new BN(0)
135
174
  this.vaultStatus = 'liquidated'
136
175
  }
137
176
 
138
177
  public updateDebtAndCollateral(vaultTypeAccountData: VaultType) {
139
-
140
- this.denormalizedDebt = vaultTypeAccountData.debtRedistributionProduct
178
+ this.denormalizedDebt = new BN(
179
+ vaultTypeAccountData.debtRedistributionProduct
141
180
  .div(this.debtProductSnapshotBytes)
142
- .mul(new Decimal(this.denormalizedDebt))
143
- .toNumber()
181
+ .mul(new Decimal(this.denormalizedDebt.toString()))
182
+ .floor()
183
+ .toString()
184
+ )
144
185
 
145
186
  const extraCollateralDeposited =
146
- this.denormalizedDebt * vaultTypeAccountData.collateralRedistributionAccumulator.sub(this.collateralAccumulatorSnapshotBytes).toNumber()
147
- this.deposited += extraCollateralDeposited
187
+ new Decimal(this.denormalizedDebt.toString()).mul(
188
+ vaultTypeAccountData.collateralRedistributionAccumulator.sub(this.collateralAccumulatorSnapshotBytes).toNumber()
189
+ ).floor()
190
+ this.deposited = this.deposited.add(new BN(extraCollateralDeposited.toString()))
148
191
 
149
192
  this.collateralAccumulatorSnapshotBytes = vaultTypeAccountData.collateralRedistributionAccumulator
150
193
  this.debtProductSnapshotBytes = vaultTypeAccountData.debtRedistributionProduct
@@ -156,8 +199,8 @@ export class VaultAccount {
156
199
  arrow = ' <----!!'
157
200
  }
158
201
  let collateralRatio = 'Infinite'
159
- if (this.denormalizedDebt > 0) {
160
- collateralRatio = new Decimal(this.deposited).div(new Decimal(this.denormalizedDebt)).toString()
202
+ if (this.denormalizedDebt.gt(new BN(0))) {
203
+ collateralRatio = new Decimal(this.deposited.toString()).div(new Decimal(this.denormalizedDebt.toString())).toString()
161
204
  }
162
205
 
163
206
  let nextVault = 'None'
@@ -165,9 +208,9 @@ export class VaultAccount {
165
208
  nextVault = this.nextVaultToRedeem.toString().substring(0, 6)
166
209
  }
167
210
 
168
- return `${this.publicKey.toString().substring(0, 6)}. Debt: ${
169
- this.denormalizedDebt
170
- } Collat: ${this.deposited} Ratio: ${collateralRatio} ${arrow} `
211
+ return `${this.publicKey.toString().substring(0, 6)}. Debt: ${this.denormalizedDebt} Collat: ${
212
+ this.deposited
213
+ } Ratio: ${collateralRatio} ${arrow} `
171
214
  }
172
215
  /**
173
216
  * Creates a VaultAccount from a slice of data
@@ -1,4 +1,4 @@
1
- import { Program, Provider } from '@project-serum/anchor'
1
+ import { Program, Provider, BN } from '@project-serum/anchor'
2
2
  import { PublicKey, Signer } from '@solana/web3.js'
3
3
  import _ from 'underscore'
4
4
  import { getVaultSystemStatePublicKey, getVaultTypeOracleAccountPublicKey, HEDGE_PROGRAM_PUBLICKEY } from '../Constants'
@@ -12,13 +12,28 @@ import * as borsh from '@project-serum/borsh'
12
12
  import base58 from 'bs58'
13
13
  import VaultType from '../state/VaultType'
14
14
 
15
+ /**
16
+ * Get the accounts the left and right for re-inserting in the linked list
17
+ *
18
+ * @param {Program<Vault>} program - Anchor program <Vault ILD>
19
+ * @param {PublicKey} vaultTypeAccountPublicKey - Vault Type Account PublicKey
20
+ * @param {PublicKey} vaultPublicKey - Vault Account PublicKey
21
+ * @param {BN} depositAmount - Amount that will be deposited into vault with instruction
22
+ * @param {BN} withdrawAmount - Amount that will be withdrawn from vault with instruction
23
+ * @param {BN} loanAmount - Amount that will be deposited into vault with transaction (sans fees)
24
+ * @param {BN} repayAmount - Amount that will be repaid into vault with transaction
25
+ * @param {boolean} redeem - True if vault is going to be redeemed fully
26
+ * @param {boolean} liquidate - True if vault is going to be liquidated fully
27
+ * @param {VaultAccount[]} cachedVaults - Optional list of cached vaults. Saves a request to the on-chain data.
28
+ */
15
29
  export async function getLinkedListAccounts(
16
30
  program: Program<Vault>,
17
- provider: Provider,
18
31
  vaultTypeAccountPublicKey: PublicKey,
19
32
  vaultPublicKey: PublicKey,
20
- depositAmount: number,
21
- loanAmount: number,
33
+ depositAmount: BN,
34
+ withdrawAmount: BN,
35
+ loanAmount: BN,
36
+ repayAmount: BN,
22
37
  redeem: boolean,
23
38
  liquidate: boolean,
24
39
  cachedVaults?: VaultAccount[]
@@ -58,7 +73,7 @@ export async function getLinkedListAccounts(
58
73
 
59
74
  // Remove any vaults with no debt or collateral
60
75
  vaults = _.filter(vaults, (vault) => {
61
- return vault.denormalizedDebt > 0 && vault.deposited > 0
76
+ return vault.denormalizedDebt.gt(new BN(0)) && vault.deposited.gt(new BN(0))
62
77
  })
63
78
 
64
79
  // Sort them
@@ -117,10 +132,13 @@ export async function getLinkedListAccounts(
117
132
 
118
133
  // Now that we know it's def in the list, iterate the list and update
119
134
  // this vault with the operation we're going to apply
120
- const newNormalizedDebt = new Decimal(loanAmount)
121
135
  vaults[indexBefore].updateDebtAndCollateral(vaultType)
122
- vaults[indexBefore].addDebt(newNormalizedDebt, vaultType)
123
- vaults[indexBefore].addDeposit(depositAmount)
136
+
137
+ vaults[indexBefore].addDebt(loanAmount, vaultType)
138
+ vaults[indexBefore].repayDebt(repayAmount, vaultType)
139
+
140
+ vaults[indexBefore].depositCollateral(depositAmount)
141
+ vaults[indexBefore].withdrawCollateral(withdrawAmount)
124
142
 
125
143
  if (liquidate) {
126
144
  vaults[indexBefore].liquidate()
@@ -129,7 +147,7 @@ export async function getLinkedListAccounts(
129
147
  vaults[indexBefore].redeem()
130
148
  }
131
149
 
132
- if (vaults[indexBefore].denormalizedDebt === 0) {
150
+ if (vaults[indexBefore].denormalizedDebt.isZero()) {
133
151
  vaults.splice(indexBefore, 1)
134
152
  }
135
153
 
@@ -180,12 +198,12 @@ export async function getLinkedListAccounts(
180
198
  // Sort function we can use to sort the vaults
181
199
  // Sorted by collateral ratio. If two are the same, newer vault first
182
200
  function sortVaults(a: VaultAccount, b: VaultAccount) {
183
- const aRatio = a.deposited / a.denormalizedDebt
184
- const bRatio = b.deposited / b.denormalizedDebt
185
- if (aRatio === bRatio) {
201
+ const aRatio = new Decimal(a.deposited.toString()).div(new Decimal(a.denormalizedDebt.toString()))
202
+ const bRatio = new Decimal(b.deposited.toString()).div(new Decimal(b.denormalizedDebt.toString()))
203
+ if (aRatio.equals(bRatio)) {
186
204
  return a.publicKey.toString() > b.publicKey.toString() ? 1 : -1
187
205
  }
188
- return aRatio - bRatio
206
+ return aRatio.greaterThan(bRatio) ? 1 : -1
189
207
  }
190
208
 
191
209
  async function getMiniVaults(program: Program<Vault>, vaultTypePublicKey: PublicKey) {