hedge-web3 0.1.27 → 0.1.28

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 (36) hide show
  1. package/declarations/Constants.d.ts +1 -1
  2. package/declarations/index.d.ts +2 -0
  3. package/declarations/instructions/depositVault.d.ts +1 -1
  4. package/declarations/instructions/liquidateVault.d.ts +1 -1
  5. package/declarations/instructions/loanVault.d.ts +1 -1
  6. package/declarations/instructions/redeemVault.d.ts +1 -1
  7. package/declarations/instructions/repayVault.d.ts +1 -1
  8. package/declarations/instructions/setVaultTypeStatus.d.ts +4 -0
  9. package/declarations/instructions/withdrawVault.d.ts +1 -1
  10. package/declarations/state/VaultAccount.d.ts +8 -0
  11. package/declarations/utils/getLinkedListAccounts.d.ts +3 -0
  12. package/lib/Constants.js +1 -1
  13. package/lib/index.js +2 -0
  14. package/lib/instructions/createStakingPool.js +2 -2
  15. package/lib/instructions/depositVault.js +14 -7
  16. package/lib/instructions/liquidateVault.js +9 -4
  17. package/lib/instructions/loanVault.js +9 -4
  18. package/lib/instructions/redeemVault.js +7 -2
  19. package/lib/instructions/repayVault.js +9 -4
  20. package/lib/instructions/setVaultTypeStatus.js +38 -0
  21. package/lib/instructions/withdrawVault.js +12 -7
  22. package/lib/state/VaultAccount.js +54 -1
  23. package/lib/utils/getLinkedListAccounts.js +131 -0
  24. package/package.json +3 -1
  25. package/src/Constants.ts +1 -1
  26. package/src/index.ts +3 -0
  27. package/src/instructions/createStakingPool.ts +1 -2
  28. package/src/instructions/depositVault.ts +97 -22
  29. package/src/instructions/liquidateVault.ts +118 -21
  30. package/src/instructions/loanVault.ts +91 -19
  31. package/src/instructions/redeemVault.ts +23 -0
  32. package/src/instructions/repayVault.ts +84 -19
  33. package/src/instructions/setVaultTypeStatus.ts +50 -0
  34. package/src/instructions/withdrawVault.ts +99 -21
  35. package/src/state/VaultAccount.ts +86 -10
  36. package/src/utils/getLinkedListAccounts.ts +156 -0
@@ -14,13 +14,16 @@ export class VaultAccount {
14
14
 
15
15
  /** The public key of the vault owner. */
16
16
  pdaSalt: string
17
-
17
+
18
18
  /** The deposited collateral of the vault (in SOL Lamports). */
19
19
  deposited: number
20
20
 
21
21
  /** The outstanding debt of the vault (in USH Lamports). Denormalized to time 0. */
22
22
  denormalizedDebt: number
23
23
 
24
+ /** The ordered number of when this vault was created. */
25
+ vaultNumber: number
26
+
24
27
  debtProductSnapshotBytes: Decimal
25
28
 
26
29
  collateralAccumulatorSnapshotBytes: Decimal
@@ -30,14 +33,19 @@ export class VaultAccount {
30
33
  /** Current State of the vautl ("Open", "Closed", "Liquidated") */
31
34
  vaultStatus: string
32
35
 
33
- constructor (vault: any, publicKey: PublicKey) {
36
+ constructor(vault: any, publicKey: PublicKey) {
34
37
  this.publicKey = publicKey
35
38
  this.vaultOwner = vault.vaultOwner
39
+ this.vaultNumber = vault.vaultNumber.toNumber()
36
40
  this.pdaSalt = vault.pdaSalt
37
41
  this.deposited = vault.deposited.toNumber()
38
42
  this.denormalizedDebt = vault.denormalizedDebt.toNumber()
39
- this.debtProductSnapshotBytes = DecimalFromU128(vault.debtProductSnapshotBytes.toString())
40
- this.collateralAccumulatorSnapshotBytes = DecimalFromU128(vault.collateralAccumulatorSnapshotBytes.toString())
43
+ this.debtProductSnapshotBytes = DecimalFromU128(
44
+ vault.debtProductSnapshotBytes.toString()
45
+ )
46
+ this.collateralAccumulatorSnapshotBytes = DecimalFromU128(
47
+ vault.collateralAccumulatorSnapshotBytes.toString()
48
+ )
41
49
  this.collateralType = vault.collateralType
42
50
 
43
51
  this.vaultStatus = Object.keys(vault.vaultStatus)[0]
@@ -49,8 +57,7 @@ export class VaultAccount {
49
57
  * @param publicKey the publicKey to check against the vault owner
50
58
  * @returns true if publicKey matches the owner publicKey
51
59
  */
52
- public isOwnedBy (publicKey: PublicKey): boolean {
53
-
60
+ public isOwnedBy(publicKey: PublicKey): boolean {
54
61
  return publicKey && publicKey.toString() === this.vaultOwner.toString()
55
62
  }
56
63
 
@@ -59,7 +66,7 @@ export class VaultAccount {
59
66
  *
60
67
  * @returns collateral value in SOL
61
68
  */
62
- public inSol (): number {
69
+ public inSol(): number {
63
70
  return this.deposited / LAMPORTS_PER_SOL
64
71
  }
65
72
 
@@ -68,7 +75,7 @@ export class VaultAccount {
68
75
  *
69
76
  * @returns debt value in USH
70
77
  */
71
- public inUsd (): number {
78
+ public inUsd(): number {
72
79
  return this.denormalizedDebt / LAMPORTS_PER_SOL
73
80
  }
74
81
 
@@ -77,7 +84,76 @@ export class VaultAccount {
77
84
  *
78
85
  * @returns example: `1b6ca...azy71s`
79
86
  */
80
- public toDisplayString (): string {
81
- return `${this.publicKey.toString().substring(0, 6)}...${this.publicKey.toString().substring(this.publicKey.toString().length - 6)}`
87
+ public toDisplayString(): string {
88
+ return `${this.publicKey.toString().substring(0, 6)}...${this.publicKey
89
+ .toString()
90
+ .substring(this.publicKey.toString().length - 6)}`
91
+ }
92
+
93
+ public addDebt(
94
+ newNormalizedDebt: Decimal,
95
+ vaultTypeCompoundedInterest: Decimal
96
+ ) {
97
+ const denormalizedNewDebt = newNormalizedDebt.div(
98
+ vaultTypeCompoundedInterest
99
+ )
100
+ this.denormalizedDebt += denormalizedNewDebt.toNumber()
101
+ }
102
+ public addDeposit(depositAmount: number) {
103
+ this.deposited += depositAmount
104
+ }
105
+
106
+ public redeem() {
107
+ // TODO - Calculate actual redeem amount and adust correctly
108
+ this.denormalizedDebt = 0
109
+ this.vaultStatus = 'initialized'
110
+ }
111
+ public liquidate() {
112
+ // TODO - Calculate actual liquidate amount and adust correctly
113
+ this.denormalizedDebt = 0
114
+ this.vaultStatus = 'liquidated'
115
+ }
116
+
117
+ public redistribution(vaultTypeAccuntData: any) {
118
+ const debtProductCurrent = DecimalFromU128(
119
+ vaultTypeAccuntData.debtRedistributionProduct
120
+ )
121
+
122
+ const collateralAccumulatorCurrent = DecimalFromU128(
123
+ vaultTypeAccuntData.collateralRedistributionAccumulator
124
+ )
125
+
126
+ this.denormalizedDebt = debtProductCurrent
127
+ .div(this.debtProductSnapshotBytes)
128
+ .mul(new Decimal(this.denormalizedDebt))
129
+ // .add(new Decimal(vaultTypeAccuntData.debtRedistributionError))
130
+ .toNumber()
131
+
132
+ const extraCollateralDeposited =
133
+ this.denormalizedDebt *
134
+ collateralAccumulatorCurrent
135
+ .sub(this.collateralAccumulatorSnapshotBytes)
136
+ .toNumber()
137
+ this.deposited += extraCollateralDeposited
138
+
139
+ this.collateralAccumulatorSnapshotBytes = collateralAccumulatorCurrent
140
+ this.debtProductSnapshotBytes = debtProductCurrent
141
+ }
142
+
143
+ public toString(highlight: PublicKey): string {
144
+ let arrow = ''
145
+ if (this.publicKey.toString() === highlight.toString()) {
146
+ arrow = ' <----'
147
+ }
148
+ let collateralRatio = 'Infinite'
149
+ if (this.denormalizedDebt > 0) {
150
+ collateralRatio = (this.deposited / this.denormalizedDebt).toFixed(8)
151
+ }
152
+ return `Vault(${this.vaultNumber}): ${this.publicKey
153
+ .toString()
154
+ .substring(
155
+ 0,
156
+ 6
157
+ )}. Debt: ${this.inUsd()} Collat: ${collateralRatio} ${arrow}`
82
158
  }
83
159
  }
@@ -0,0 +1,156 @@
1
+ import { Program, Provider } from '@project-serum/anchor'
2
+ import { PublicKey, Signer } from '@solana/web3.js'
3
+ import _ from 'underscore'
4
+ import {
5
+ getVaultSystemStatePublicKey,
6
+ getVaultTypeOracleAccountPublicKey,
7
+ } from '../Constants'
8
+
9
+ import { DecimalFromU128 } from '../HedgeDecimal'
10
+ import { VaultAccount } from '../state/VaultAccount'
11
+ import Decimal from 'decimal.js'
12
+ export async function getLinkedListAccounts(
13
+ program: Program,
14
+ provider: Provider,
15
+ vaultTypeAccountPublicKey: PublicKey,
16
+ vaultPublicKey: PublicKey,
17
+ depositAmount: number,
18
+ loanAmount: number,
19
+ redeem: boolean,
20
+ liquidate: boolean
21
+ ): Promise<[PublicKey, PublicKey, PublicKey]> {
22
+ const vaultTypeAccount = await program.account.vaultType.fetch(
23
+ vaultTypeAccountPublicKey
24
+ )
25
+
26
+ // Default for null is the vault itself, so set them all to this vault
27
+ let oldSmallerPublicKey = vaultPublicKey
28
+ let newSmallerPublicKey = vaultPublicKey
29
+ let newLargerPublicKey = vaultPublicKey
30
+
31
+ const thisVaultData = await program.account.vault.fetch(vaultPublicKey)
32
+ const thisVault = new VaultAccount(thisVaultData, vaultPublicKey)
33
+
34
+ // Load all the vaults
35
+ let allVaults =
36
+ (await program.account.vault
37
+ .all([
38
+ // {
39
+ // memcmp: { bytes: bs58.encode(inputCollateralType), offset: 8 + 32 + 8 },
40
+ // },
41
+ ])
42
+ .catch((error) => {
43
+ console.log('error', error)
44
+ })) || []
45
+
46
+ // Load them into our account objects
47
+ let vaults = allVaults.map((vault) => {
48
+ return new VaultAccount(vault.account, vault.publicKey)
49
+ })
50
+
51
+ // Filter out the account that are not the same vault type
52
+ vaults = _.filter(vaults, (vault) => {
53
+ return vault.collateralType === vaultTypeAccount.collateralType
54
+ })
55
+
56
+ // Filter out the accounts that are not open
57
+ vaults = _.filter(vaults, (vault) => {
58
+ return vault.vaultStatus === 'open'
59
+ })
60
+
61
+ // Sort them
62
+ vaults.sort(sortVaults)
63
+
64
+ // Find the location of the vault before the operation
65
+ let indexBefore = -1
66
+ vaults.forEach((vault, index) => {
67
+ if (vault.publicKey.toString() === vaultPublicKey.toString()) {
68
+ indexBefore = index
69
+ }
70
+ })
71
+
72
+ // If we found it before, set the old smaller vault the one to the left
73
+ if (indexBefore > 0) {
74
+ oldSmallerPublicKey = vaults[indexBefore - 1].publicKey
75
+ }
76
+
77
+ // Pretty print all the vaults before the operation
78
+ // console.log('Sorted open vaults before')
79
+ // vaults.forEach((vault) => {
80
+ // console.log(vault.toString(vaultPublicKey))
81
+ // })
82
+
83
+ // If it wasn't in the list, add it now
84
+ if (indexBefore < 0) {
85
+ vaults.push(thisVault)
86
+ indexBefore = vaults.length - 1
87
+ }
88
+
89
+ // Now that we know it's def in the list, iterate the list and update
90
+ // this vault with the opeation we're going to apply
91
+ const newNormalizedDebt = new Decimal(loanAmount)
92
+ const vaultTypeCompoundedInterest = DecimalFromU128(
93
+ vaultTypeAccount.cumulativeRate.toString()
94
+ )
95
+ vaults[indexBefore].addDebt(newNormalizedDebt, vaultTypeCompoundedInterest)
96
+ vaults[indexBefore].addDeposit(depositAmount)
97
+
98
+ if (liquidate) {
99
+ vaults[indexBefore].liquidate()
100
+ }
101
+ if (redeem) {
102
+ vaults[indexBefore].redeem()
103
+ }
104
+ vaults[indexBefore].redistribution(vaultTypeAccount)
105
+
106
+ if (vaults[indexBefore].denormalizedDebt === 0) {
107
+ vaults.splice(indexBefore, 1)
108
+ }
109
+
110
+ // Sort it again since we've changed one vault
111
+ vaults = vaults.sort(sortVaults)
112
+
113
+ // Pretty print the list again
114
+ // console.log('Sorted open vaults with new debt added')
115
+ // vaults.forEach((vault) => {
116
+ // console.log(vault.toString(vaultPublicKey))
117
+ // })
118
+
119
+ // Search for the vaults new position
120
+ let indexAfter = -1
121
+ vaults.forEach((vault, index) => {
122
+ if (vault.publicKey.toString() === vaultPublicKey.toString()) {
123
+ indexAfter = index
124
+ }
125
+ })
126
+
127
+ // Print where it moved from / to
128
+ // console.log('Index Before', indexBefore)
129
+ // console.log('Index After', indexAfter)
130
+
131
+ // Save references to the new left and right
132
+ if (indexAfter > 0) {
133
+ newSmallerPublicKey = vaults[indexAfter - 1].publicKey
134
+ }
135
+ if (indexAfter < vaults.length - 1 && indexAfter >= 0) {
136
+ newLargerPublicKey = vaults[indexAfter + 1].publicKey
137
+ }
138
+
139
+ // Print out the new left/right
140
+ // console.log('oldSmallerPublicKey', oldSmallerPublicKey.toString())
141
+ // console.log('newSmallerPublicKey', newSmallerPublicKey.toString())
142
+ // console.log('newLargerPublicKey', newLargerPublicKey.toString())
143
+
144
+ return [oldSmallerPublicKey, newSmallerPublicKey, newLargerPublicKey]
145
+ }
146
+
147
+ // Sort function we can use to sort the vaults
148
+ // Sorted by collateral ratio. If two are the same, newer vault first
149
+ function sortVaults(a: VaultAccount, b: VaultAccount) {
150
+ const aRatio = a.deposited / a.denormalizedDebt
151
+ const bRatio = b.deposited / b.denormalizedDebt
152
+ if (aRatio === bRatio) {
153
+ return b.vaultNumber - a.vaultNumber
154
+ }
155
+ return aRatio - bRatio
156
+ }