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.
- package/declarations/Constants.d.ts +1 -1
- package/declarations/index.d.ts +2 -0
- package/declarations/instructions/depositVault.d.ts +1 -1
- package/declarations/instructions/liquidateVault.d.ts +1 -1
- package/declarations/instructions/loanVault.d.ts +1 -1
- package/declarations/instructions/redeemVault.d.ts +1 -1
- package/declarations/instructions/repayVault.d.ts +1 -1
- package/declarations/instructions/setVaultTypeStatus.d.ts +4 -0
- package/declarations/instructions/withdrawVault.d.ts +1 -1
- package/declarations/state/VaultAccount.d.ts +8 -0
- package/declarations/utils/getLinkedListAccounts.d.ts +3 -0
- package/lib/Constants.js +1 -1
- package/lib/index.js +2 -0
- package/lib/instructions/createStakingPool.js +2 -2
- package/lib/instructions/depositVault.js +14 -7
- package/lib/instructions/liquidateVault.js +9 -4
- package/lib/instructions/loanVault.js +9 -4
- package/lib/instructions/redeemVault.js +7 -2
- package/lib/instructions/repayVault.js +9 -4
- package/lib/instructions/setVaultTypeStatus.js +38 -0
- package/lib/instructions/withdrawVault.js +12 -7
- package/lib/state/VaultAccount.js +54 -1
- package/lib/utils/getLinkedListAccounts.js +131 -0
- package/package.json +3 -1
- package/src/Constants.ts +1 -1
- package/src/index.ts +3 -0
- package/src/instructions/createStakingPool.ts +1 -2
- package/src/instructions/depositVault.ts +97 -22
- package/src/instructions/liquidateVault.ts +118 -21
- package/src/instructions/loanVault.ts +91 -19
- package/src/instructions/redeemVault.ts +23 -0
- package/src/instructions/repayVault.ts +84 -19
- package/src/instructions/setVaultTypeStatus.ts +50 -0
- package/src/instructions/withdrawVault.ts +99 -21
- package/src/state/VaultAccount.ts +86 -10
- 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
|
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(
|
40
|
-
|
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
|
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
|
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
|
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
|
81
|
-
return `${this.publicKey.toString().substring(0, 6)}...${this.publicKey
|
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
|
+
}
|