hedge-web3 0.2.3 → 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.
Files changed (37) hide show
  1. package/declarations/instructions/createVault.d.ts +3 -2
  2. package/declarations/instructions/depositLiquidationPool.d.ts +4 -3
  3. package/declarations/instructions/depositStakingPool.d.ts +3 -2
  4. package/declarations/instructions/depositVault.d.ts +3 -2
  5. package/declarations/instructions/loanVault.d.ts +3 -2
  6. package/declarations/instructions/redeemVault.d.ts +3 -2
  7. package/declarations/instructions/repayVault.d.ts +3 -2
  8. package/declarations/instructions/setVaultTypeStatus.d.ts +2 -3
  9. package/declarations/instructions/withdrawVault.d.ts +3 -2
  10. package/declarations/state/VaultAccount.d.ts +33 -10
  11. package/declarations/utils/getLinkedListAccounts.d.ts +17 -2
  12. package/lib/instructions/createVault.js +2 -2
  13. package/lib/instructions/depositLiquidationPool.js +2 -2
  14. package/lib/instructions/depositStakingPool.js +2 -2
  15. package/lib/instructions/depositVault.js +3 -3
  16. package/lib/instructions/liquidateVault.js +1 -1
  17. package/lib/instructions/loanVault.js +3 -3
  18. package/lib/instructions/redeemVault.js +3 -3
  19. package/lib/instructions/refreshOraclePrice.js +2 -2
  20. package/lib/instructions/repayVault.js +3 -3
  21. package/lib/instructions/setVaultTypeStatus.js +10 -9
  22. package/lib/instructions/withdrawVault.js +3 -3
  23. package/lib/state/VaultAccount.js +76 -33
  24. package/lib/utils/getLinkedListAccounts.js +29 -13
  25. package/package.json +1 -1
  26. package/src/instructions/createVault.ts +3 -3
  27. package/src/instructions/depositLiquidationPool.ts +4 -4
  28. package/src/instructions/depositStakingPool.ts +3 -3
  29. package/src/instructions/depositVault.ts +7 -6
  30. package/src/instructions/liquidateVault.ts +4 -3
  31. package/src/instructions/loanVault.ts +7 -6
  32. package/src/instructions/redeemVault.ts +7 -6
  33. package/src/instructions/refreshOraclePrice.ts +2 -2
  34. package/src/instructions/repayVault.ts +7 -6
  35. package/src/instructions/withdrawVault.ts +7 -6
  36. package/src/state/VaultAccount.ts +84 -39
  37. package/src/utils/getLinkedListAccounts.ts +34 -16
@@ -20,13 +20,13 @@ 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
- vaultNumber: number
29
+ vaultNumber = 0
30
30
 
31
31
  /** Debt redistribution snapshot */
32
32
  debtProductSnapshotBytes = new Decimal(0)
@@ -49,10 +49,14 @@ export class VaultAccount {
49
49
  constructor(vault: any, publicKey: PublicKey) {
50
50
  this.publicKey = publicKey
51
51
  this.vaultOwner = vault.vaultOwner
52
- this.vaultNumber = vault.vaultNumber?.toNumber()
53
52
  this.pdaSalt = vault.pdaSalt
54
- this.deposited = vault.deposited?.toNumber()
55
- this.denormalizedDebt = vault.denormalizedDebt?.toNumber()
53
+
54
+ this.deposited = vault.deposited
55
+ this.denormalizedDebt = vault.denormalizedDebt
56
+
57
+ if (vault.vaultNumber) {
58
+ this.vaultNumber = vault.vaultNumber.toNumber()
59
+ }
56
60
  if (vault.debtProductSnapshotBytes) {
57
61
  this.debtProductSnapshotBytes = DecimalFromU128(vault.debtProductSnapshotBytes.toString())
58
62
  }
@@ -78,14 +82,15 @@ export class VaultAccount {
78
82
  return publicKey && publicKey.toString() === this.vaultOwner.toString()
79
83
  }
80
84
 
81
- /**
82
- * Get the collateral value in SOL
83
- *
84
- * @returns collateral value in SOL
85
- */
86
- public inSol(): number {
87
- return this.deposited / LAMPORTS_PER_SOL
88
- }
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
+ // }
89
94
 
90
95
  /**
91
96
  * Get the debt value in USH
@@ -93,7 +98,7 @@ export class VaultAccount {
93
98
  * @returns debt value in USH
94
99
  */
95
100
  public inUsd(): number {
96
- return this.denormalizedDebt / LAMPORTS_PER_SOL
101
+ return new Decimal(this.denormalizedDebt.toString()).div(LAMPORTS_PER_SOL).toNumber()
97
102
  }
98
103
 
99
104
  /**
@@ -107,42 +112,82 @@ export class VaultAccount {
107
112
  .substring(this.publicKey.toString().length - 6)}`
108
113
  }
109
114
 
110
- public addDebt(additionalDebt: Decimal, vaultTypeAccount: VaultType) {
111
- let loanFee = new Decimal(0)
112
- if (additionalDebt.isPositive()){
113
- loanFee = vaultTypeAccount.loanInitFee.mul(additionalDebt)
114
- }
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)
126
+
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)
132
+ }
133
+
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()
115
143
 
116
- const totalNormalizedLoan = additionalDebt.add(loanFee)
117
- const denormalizedNewDebt = totalNormalizedLoan.div(new Decimal(vaultTypeAccount.cumulativeRate.toString()))
118
- this.denormalizedDebt = denormalizedNewDebt.add(new Decimal(this.denormalizedDebt)).floor().toNumber()
144
+ this.denormalizedDebt = this.denormalizedDebt.sub(new BN(denormalizedRepayment.toString()))
119
145
  }
120
146
 
121
- public addDeposit(depositAmount: number) {
122
- this.deposited += depositAmount
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)
123
164
  }
124
165
 
125
166
  public redeem() {
126
167
  // TODO - Calculate actual redeem amount and adust correctly
127
- this.denormalizedDebt = 0
168
+ this.denormalizedDebt = new BN(0)
128
169
  this.vaultStatus = 'initialized'
129
170
  }
130
171
  public liquidate() {
131
172
  // TODO - Calculate actual liquidate amount and adust correctly
132
- this.denormalizedDebt = 0
173
+ this.denormalizedDebt = new BN(0)
133
174
  this.vaultStatus = 'liquidated'
134
175
  }
135
176
 
136
177
  public updateDebtAndCollateral(vaultTypeAccountData: VaultType) {
137
-
138
- this.denormalizedDebt = vaultTypeAccountData.debtRedistributionProduct
178
+ this.denormalizedDebt = new BN(
179
+ vaultTypeAccountData.debtRedistributionProduct
139
180
  .div(this.debtProductSnapshotBytes)
140
- .mul(new Decimal(this.denormalizedDebt))
141
- .toNumber()
181
+ .mul(new Decimal(this.denormalizedDebt.toString()))
182
+ .floor()
183
+ .toString()
184
+ )
142
185
 
143
186
  const extraCollateralDeposited =
144
- this.denormalizedDebt * vaultTypeAccountData.collateralRedistributionAccumulator.sub(this.collateralAccumulatorSnapshotBytes).toNumber()
145
- 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()))
146
191
 
147
192
  this.collateralAccumulatorSnapshotBytes = vaultTypeAccountData.collateralRedistributionAccumulator
148
193
  this.debtProductSnapshotBytes = vaultTypeAccountData.debtRedistributionProduct
@@ -154,8 +199,8 @@ export class VaultAccount {
154
199
  arrow = ' <----!!'
155
200
  }
156
201
  let collateralRatio = 'Infinite'
157
- if (this.denormalizedDebt > 0) {
158
- 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()
159
204
  }
160
205
 
161
206
  let nextVault = 'None'
@@ -163,9 +208,9 @@ export class VaultAccount {
163
208
  nextVault = this.nextVaultToRedeem.toString().substring(0, 6)
164
209
  }
165
210
 
166
- return `Vault(${this.vaultNumber}): ${this.publicKey.toString().substring(0, 6)}. Debt: ${
167
- this.denormalizedDebt
168
- } 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} `
169
214
  }
170
215
  /**
171
216
  * Creates a VaultAccount from a slice of data
@@ -180,7 +225,7 @@ export class VaultAccount {
180
225
  * @returns a new VaultAccount
181
226
  */
182
227
  static FromMiniSlice(data: Buffer, pubkey: PublicKey) {
183
- const props = [borsh.u64('vaultNumber'), borsh.u64('deposited'), borsh.u64('denormalizedDebt')]
228
+ const props = [borsh.u64('deposited'), borsh.u64('denormalizedDebt')]
184
229
  const miniVaultLayout = borsh.struct(props, 'minVaultLayout')
185
230
  const decodedData: any = miniVaultLayout.decode(data)
186
231
 
@@ -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) {
186
- return b.vaultNumber - a.vaultNumber
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)) {
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) {
@@ -215,8 +233,8 @@ async function getMiniVaults(program: Program<Vault>, vaultTypePublicKey: Public
215
233
  // Slice the data only to grab the 3 u64's of size 8 bytes each
216
234
  dataSlice: {
217
235
  // See programs/hedge-vault/src/account_data/vault.rs for struct layout
218
- offset: 8 + 32,
219
- length: 24,
236
+ offset: 8 + 32 + 8,
237
+ length: 16,
220
238
  },
221
239
  })
222
240