hedge-web3 0.2.3 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
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