@gearbox-protocol/sdk 0.0.98 → 0.0.101
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/lib/apy/convexAPY.d.ts +8 -0
- package/lib/apy/convexAPY.js +202 -0
- package/lib/apy/lidoAPY.d.ts +4 -0
- package/lib/apy/lidoAPY.js +97 -0
- package/lib/config.d.ts +1 -0
- package/lib/config.js +2 -1
- package/lib/contracts/contracts.d.ts +6 -1
- package/lib/contracts/contracts.js +52 -14
- package/lib/contracts/contractsRegister.js +3 -3
- package/lib/core/constants.d.ts +4 -0
- package/lib/core/constants.js +8 -4
- package/lib/core/creditAccount.d.ts +2 -0
- package/lib/core/creditAccount.js +31 -30
- package/lib/core/creditManager.d.ts +13 -2
- package/lib/core/creditManager.js +79 -29
- package/lib/core/errors.d.ts +10 -0
- package/lib/core/errors.js +16 -1
- package/lib/core/events.js +9 -9
- package/lib/core/multicall.d.ts +1 -1
- package/lib/core/pool.d.ts +1 -1
- package/lib/core/pool.js +7 -5
- package/lib/core/price.d.ts +4 -0
- package/lib/core/price.js +12 -0
- package/lib/core/strategy.d.ts +34 -0
- package/lib/core/strategy.js +57 -0
- package/lib/index.d.ts +7 -1
- package/lib/index.js +8 -3
- package/lib/pathfinder/path.js +1 -1
- package/lib/pathfinder/yVault.js +7 -4
- package/lib/payload/creditAccount.d.ts +4 -26
- package/lib/payload/creditManager.d.ts +12 -24
- package/lib/payload/pool.d.ts +2 -17
- package/lib/payload/pool.js +0 -1
- package/lib/tokens/token.js +4 -4
- package/lib/utils/formatter.d.ts +1 -0
- package/lib/utils/formatter.js +6 -1
- package/lib/utils/mappers.d.ts +2 -1
- package/lib/utils/mappers.js +13 -5
- package/lib/utils/multicall.js +4 -3
- package/lib/utils/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/apy/convexAPY.ts +249 -0
- package/src/apy/lidoAPY.ts +81 -0
- package/src/config.ts +2 -1
- package/src/contracts/contracts.ts +69 -16
- package/src/contracts/contractsRegister.ts +3 -3
- package/src/core/constants.ts +7 -3
- package/src/core/creditAccount.ts +39 -33
- package/src/core/creditManager.ts +230 -148
- package/src/core/errors.ts +24 -0
- package/src/core/events.ts +921 -915
- package/src/core/multicall.ts +1 -1
- package/src/core/pool.ts +56 -51
- package/src/core/price.ts +16 -0
- package/src/core/strategy.ts +123 -0
- package/src/index.ts +8 -1
- package/src/pathfinder/path.ts +154 -154
- package/src/pathfinder/yVault.ts +57 -56
- package/src/payload/creditAccount.ts +4 -26
- package/src/payload/creditManager.ts +13 -25
- package/src/payload/pool.ts +2 -19
- package/src/tokens/token.ts +10 -5
- package/src/utils/formatter.ts +5 -1
- package/src/utils/mappers.ts +12 -5
- package/src/utils/multicall.ts +4 -9
- package/src/utils/types.ts +6 -2
- package/lib/core/adapters.d.ts +0 -15
- package/lib/core/adapters.js +0 -19
- package/lib/core/contracts.d.ts +0 -67
- package/lib/core/contracts.js +0 -254
- package/lib/core/contractsRegister.d.ts +0 -2
- package/lib/core/contractsRegister.js +0 -58
- package/lib/core/creditCard.d.ts +0 -13
- package/lib/core/creditCard.js +0 -2
- package/lib/core/oracles.d.ts +0 -38
- package/lib/core/oracles.js +0 -12
- package/lib/core/priceFeeds.d.ts +0 -3
- package/lib/core/priceFeeds.js +0 -492
- package/lib/core/protocols.d.ts +0 -13
- package/lib/core/protocols.js +0 -39
- package/lib/core/swap.d.ts +0 -4
- package/lib/core/swap.js +0 -8
- package/lib/core/trade.d.ts +0 -35
- package/lib/core/trade.js +0 -62
- package/lib/core/tradeTypes.d.ts +0 -79
- package/lib/core/tradeTypes.js +0 -21
|
@@ -3,8 +3,9 @@ import {
|
|
|
3
3
|
CreditAccountDataExtendedPayload,
|
|
4
4
|
CreditAccountDataPayload
|
|
5
5
|
} from "../payload/creditAccount";
|
|
6
|
-
import { PERCENTAGE_FACTOR, RAY } from "./constants";
|
|
6
|
+
import { PERCENTAGE_FACTOR, RAY, PERCENTAGE_DECIMALS } from "./constants";
|
|
7
7
|
import { TokenData } from "../tokens/tokenData";
|
|
8
|
+
import { priceCalc } from "./price";
|
|
8
9
|
|
|
9
10
|
export type Balance = { address: string; balance: BigNumber };
|
|
10
11
|
|
|
@@ -33,7 +34,7 @@ export class CreditAccountData {
|
|
|
33
34
|
this.borrower = payload.borrower;
|
|
34
35
|
this.inUse = payload.inUse;
|
|
35
36
|
this.creditManager = payload.creditManager;
|
|
36
|
-
this.underlyingToken = payload.
|
|
37
|
+
this.underlyingToken = payload.underlying;
|
|
37
38
|
this.borrowedAmountPlusInterest = BigNumber.from(
|
|
38
39
|
payload.borrowedAmountPlusInterest
|
|
39
40
|
);
|
|
@@ -43,7 +44,7 @@ export class CreditAccountData {
|
|
|
43
44
|
this.borrowRate =
|
|
44
45
|
BigNumber.from(payload.borrowRate)
|
|
45
46
|
.mul(PERCENTAGE_FACTOR)
|
|
46
|
-
.mul(
|
|
47
|
+
.mul(PERCENTAGE_DECIMALS)
|
|
47
48
|
.div(RAY)
|
|
48
49
|
.toNumber() / PERCENTAGE_FACTOR;
|
|
49
50
|
|
|
@@ -64,40 +65,45 @@ export class CreditAccountData {
|
|
|
64
65
|
prices: Record<string, number>,
|
|
65
66
|
tokens: Record<string, TokenData>
|
|
66
67
|
): Array<Balance> {
|
|
67
|
-
const
|
|
68
|
-
const price = prices[addr] || 0;
|
|
69
|
-
const { decimals = 18 } = tokens[addr] || {};
|
|
70
|
-
|
|
71
|
-
return amount
|
|
72
|
-
.mul(Math.floor(1000 * price))
|
|
73
|
-
.div(BigNumber.from(10).pow(decimals));
|
|
74
|
-
};
|
|
68
|
+
const safeBalances = this.balances || [];
|
|
75
69
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
return sortBalances(safeBalances, prices, tokens).map(
|
|
71
|
+
([address, balance]) => ({ address, balance })
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
79
75
|
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
export function sortBalances(
|
|
77
|
+
balances: Record<string, BigNumber>,
|
|
78
|
+
prices: Record<string, number>,
|
|
79
|
+
tokens: Record<string, TokenData>
|
|
80
|
+
) {
|
|
81
|
+
return Object.entries(balances).sort(([addr1, amount1], [addr2, amount2]) => {
|
|
82
|
+
const addr1Lc = addr1.toLowerCase();
|
|
83
|
+
const addr2Lc = addr2.toLowerCase();
|
|
84
|
+
|
|
85
|
+
const token1 = tokens[addr1Lc];
|
|
86
|
+
const token2 = tokens[addr2Lc];
|
|
87
|
+
|
|
88
|
+
const price1 = prices[addr1Lc] || 1;
|
|
89
|
+
const price2 = prices[addr2Lc] || 1;
|
|
90
|
+
|
|
91
|
+
const assetValue1 = priceCalc(price1, amount1, token1);
|
|
92
|
+
const assetValue2 = priceCalc(price2, amount2, token2);
|
|
93
|
+
|
|
94
|
+
return assetValue1.eq(assetValue2)
|
|
95
|
+
? tokensAbcComparator(token1, token2)
|
|
96
|
+
: assetValue1.gt(assetValue2)
|
|
97
|
+
? -1
|
|
98
|
+
: 1;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
82
101
|
|
|
83
|
-
|
|
102
|
+
export function tokensAbcComparator(t1?: TokenData, t2?: TokenData) {
|
|
103
|
+
const { symbol: symbol1 = "" } = t1 || {};
|
|
104
|
+
const { symbol: symbol2 = "" } = t2 || {};
|
|
84
105
|
|
|
85
|
-
|
|
86
|
-
.sort(([addr1, amount1], [addr2, amount2]) => {
|
|
87
|
-
const addr1Lc = addr1.toLowerCase();
|
|
88
|
-
const addr2Lc = addr2.toLowerCase();
|
|
89
|
-
|
|
90
|
-
const price1 = priceCalc(addr1Lc, amount1);
|
|
91
|
-
const price2 = priceCalc(addr2Lc, amount2);
|
|
92
|
-
|
|
93
|
-
return price1.eq(price2)
|
|
94
|
-
? tokensAbcComparator(tokens[addr1Lc], tokens[addr2Lc])
|
|
95
|
-
: price1.gt(price2)
|
|
96
|
-
? -1
|
|
97
|
-
: 1;
|
|
98
|
-
})
|
|
99
|
-
.map(([address, balance]) => ({ address, balance }));
|
|
100
|
-
}
|
|
106
|
+
return symbol1 > symbol2 ? 1 : -1;
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
export class CreditAccountDataExtended extends CreditAccountData {
|
|
@@ -1,174 +1,256 @@
|
|
|
1
|
-
import {BigNumber, ethers, Signer} from "ethers";
|
|
2
|
-
import {formatBN} from "../utils/formatter";
|
|
1
|
+
import { BigNumber, ethers, Signer } from "ethers";
|
|
3
2
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
UNDERLYING_TOKEN_LIQUIDATION_THRESHOLD
|
|
7
|
-
} from "./constants";
|
|
8
|
-
import {
|
|
9
|
-
CreditManagerDataPayload,
|
|
10
|
-
CreditManagerStatPayload
|
|
3
|
+
CreditManagerDataPayload,
|
|
4
|
+
CreditManagerStatPayload
|
|
11
5
|
} from "../payload/creditManager";
|
|
12
|
-
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
ICreditManager,
|
|
9
|
+
ICreditManager__factory,
|
|
10
|
+
ICreditFacade__factory
|
|
11
|
+
} from "../types";
|
|
12
|
+
|
|
13
|
+
import { MultiCall } from "./multicall";
|
|
14
|
+
import {
|
|
15
|
+
PERCENTAGE_FACTOR,
|
|
16
|
+
RAY,
|
|
17
|
+
UNDERLYING_TOKEN_LIQUIDATION_THRESHOLD,
|
|
18
|
+
LEVERAGE_DECIMALS,
|
|
19
|
+
PERCENTAGE_DECIMALS
|
|
20
|
+
} from "./constants";
|
|
21
|
+
import { OpenAccountError } from "./errors";
|
|
13
22
|
|
|
14
23
|
export class CreditManagerData {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
24
|
+
public readonly id: string;
|
|
25
|
+
public readonly address: string;
|
|
26
|
+
public readonly underlyingToken: string;
|
|
27
|
+
public readonly isWETH: boolean;
|
|
28
|
+
public readonly canBorrow: boolean;
|
|
29
|
+
public readonly borrowRate: number;
|
|
30
|
+
public readonly minAmount: BigNumber;
|
|
31
|
+
public readonly maxAmount: BigNumber;
|
|
32
|
+
public readonly maxLeverageFactor: number; // for V1 only
|
|
33
|
+
public readonly availableLiquidity: BigNumber;
|
|
34
|
+
public readonly allowedTokens: Array<string>;
|
|
35
|
+
public readonly adapters: Record<string, string>;
|
|
36
|
+
|
|
37
|
+
public readonly liquidationThresholds: Record<string, BigNumber>;
|
|
38
|
+
public readonly version: number;
|
|
39
|
+
public readonly creditFacade: string; // V2 only: address of creditFacade
|
|
40
|
+
public readonly isDegenMode: boolean; // V2 only: true if contract is in Degen mode
|
|
41
|
+
public readonly degenNFT: string; // V2 only: degenNFT, address(0) if not in degen mode
|
|
42
|
+
public readonly isIncreaseDebtForbidden: boolean; // V2 only: true if increasing debt is forbidden
|
|
43
|
+
public readonly forbiddenTokenMask: BigNumber; // V2 only: mask which forbids some particular tokens
|
|
44
|
+
|
|
45
|
+
constructor(payload: CreditManagerDataPayload) {
|
|
46
|
+
this.id = payload.addr;
|
|
47
|
+
this.address = payload.addr;
|
|
48
|
+
|
|
49
|
+
this.underlyingToken = payload.underlying || "";
|
|
50
|
+
|
|
51
|
+
this.isWETH = payload.isWETH || false;
|
|
52
|
+
this.canBorrow = payload.canBorrow || false;
|
|
53
|
+
|
|
54
|
+
this.borrowRate =
|
|
55
|
+
BigNumber.from(payload.borrowRate || 0)
|
|
56
|
+
.mul(PERCENTAGE_FACTOR)
|
|
57
|
+
.mul(PERCENTAGE_DECIMALS)
|
|
58
|
+
.div(RAY)
|
|
59
|
+
.toNumber() / PERCENTAGE_FACTOR;
|
|
60
|
+
this.minAmount = BigNumber.from(payload.minAmount || 0);
|
|
61
|
+
this.maxAmount = BigNumber.from(payload.maxAmount || 0);
|
|
62
|
+
|
|
63
|
+
this.maxLeverageFactor = BigNumber.from(
|
|
64
|
+
payload.maxLeverageFactor || 0
|
|
65
|
+
).toNumber();
|
|
66
|
+
this.availableLiquidity = BigNumber.from(payload.availableLiquidity || 0);
|
|
67
|
+
|
|
68
|
+
this.allowedTokens = payload.collateralTokens || [];
|
|
69
|
+
this.adapters = (payload.adapters || []).reduce<Record<string, string>>(
|
|
70
|
+
(acc, { allowedContract, adapter }) => ({
|
|
71
|
+
...acc,
|
|
72
|
+
[allowedContract]: adapter
|
|
73
|
+
}),
|
|
74
|
+
{}
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
this.liquidationThresholds = payload.liquidationThresholds.reduce<
|
|
78
|
+
Record<string, BigNumber>
|
|
79
|
+
>((acc, threshold, index) => {
|
|
80
|
+
const address = payload.collateralTokens[index];
|
|
81
|
+
|
|
82
|
+
if (address) acc[address.toLowerCase()] = threshold;
|
|
83
|
+
|
|
84
|
+
return acc;
|
|
85
|
+
}, {});
|
|
86
|
+
this.version = payload.version || 1;
|
|
87
|
+
this.creditFacade = payload.creditFacade || "";
|
|
88
|
+
this.isDegenMode = payload.isDegenMode || false;
|
|
89
|
+
this.degenNFT = payload.degenNFT || "";
|
|
90
|
+
this.isIncreaseDebtForbidden = payload.isIncreaseDebtForbidden || false;
|
|
91
|
+
this.forbiddenTokenMask = BigNumber.from(payload.forbiddenTokenMask || 0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
get isPaused(): boolean {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
getContractETH(signer: Signer | ethers.providers.Provider): ICreditManager {
|
|
99
|
+
return ICreditManager__factory.connect(this.address, signer);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
contractToAdapter(contractAddress: string): string | undefined {
|
|
103
|
+
return this.adapters[contractAddress];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
encodeAddCollateral(
|
|
107
|
+
accountAddress: string,
|
|
108
|
+
tokenAddress: string,
|
|
109
|
+
amount: BigNumber
|
|
110
|
+
): MultiCall {
|
|
111
|
+
if (this.version !== 2)
|
|
112
|
+
throw new Error("Multicall is eligible only for version 2");
|
|
113
|
+
return {
|
|
114
|
+
target: this.creditFacade,
|
|
115
|
+
callData: ICreditFacade__factory.createInterface().encodeFunctionData(
|
|
116
|
+
"addCollateral",
|
|
117
|
+
[accountAddress, tokenAddress, amount]
|
|
118
|
+
)
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
encodeIncreaseDebt(amount: BigNumber): MultiCall {
|
|
123
|
+
if (this.version !== 2)
|
|
124
|
+
throw new Error("Multicall is eligible only for version 2");
|
|
125
|
+
return {
|
|
126
|
+
target: this.creditFacade,
|
|
127
|
+
callData: ICreditFacade__factory.createInterface().encodeFunctionData(
|
|
128
|
+
"increaseDebt",
|
|
129
|
+
[amount]
|
|
130
|
+
)
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
encodeDecreaseDebt(amount: BigNumber): MultiCall {
|
|
135
|
+
if (this.version !== 2)
|
|
136
|
+
throw new Error("Multicall is eligible only for version 2");
|
|
137
|
+
return {
|
|
138
|
+
target: this.creditFacade,
|
|
139
|
+
callData: ICreditFacade__factory.createInterface().encodeFunctionData(
|
|
140
|
+
"decreaseDebt",
|
|
141
|
+
[amount]
|
|
142
|
+
)
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
validateOpenAccount(totalAmount: BigNumber, leverage: number): true {
|
|
147
|
+
if (totalAmount.lt(this.minAmount))
|
|
148
|
+
throw new OpenAccountError("amountLessMin", this.minAmount);
|
|
149
|
+
|
|
150
|
+
if (totalAmount.gt(this.maxAmount))
|
|
151
|
+
throw new OpenAccountError("amountGreaterMax", this.maxAmount);
|
|
152
|
+
|
|
153
|
+
if (leverage > this.maxLeverageFactor)
|
|
154
|
+
throw new OpenAccountError(
|
|
155
|
+
"leverageGreaterMax",
|
|
156
|
+
BigNumber.from(this.maxLeverageFactor)
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
if (
|
|
160
|
+
totalAmount
|
|
161
|
+
.mul(leverage)
|
|
162
|
+
.div(LEVERAGE_DECIMALS)
|
|
163
|
+
.gt(this.availableLiquidity)
|
|
164
|
+
)
|
|
165
|
+
throw new OpenAccountError(
|
|
166
|
+
"insufficientPoolLiquidity",
|
|
167
|
+
BigNumber.from(this.availableLiquidity)
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
91
172
|
}
|
|
92
173
|
|
|
93
174
|
export function calcMaxIncreaseBorrow(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
175
|
+
healthFactor: number,
|
|
176
|
+
borrowAmountPlusInterest: BigNumber,
|
|
177
|
+
maxLeverageFactor: number
|
|
97
178
|
): BigNumber {
|
|
98
|
-
|
|
179
|
+
const healthFactorPercentage = Math.floor(healthFactor * PERCENTAGE_FACTOR);
|
|
99
180
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
181
|
+
const minHealthFactor = Math.floor(
|
|
182
|
+
(UNDERLYING_TOKEN_LIQUIDATION_THRESHOLD *
|
|
183
|
+
(maxLeverageFactor + LEVERAGE_DECIMALS)) /
|
|
184
|
+
maxLeverageFactor
|
|
185
|
+
);
|
|
104
186
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
187
|
+
const result = borrowAmountPlusInterest
|
|
188
|
+
.mul(healthFactorPercentage - minHealthFactor)
|
|
189
|
+
.div(minHealthFactor - UNDERLYING_TOKEN_LIQUIDATION_THRESHOLD);
|
|
190
|
+
return result.isNegative() ? BigNumber.from(0) : result;
|
|
109
191
|
}
|
|
110
192
|
|
|
111
193
|
export function calcHealthFactorAfterIncreasingBorrow(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
194
|
+
healthFactor: number | undefined,
|
|
195
|
+
borrowAmountPlusInterest: BigNumber | undefined,
|
|
196
|
+
additional: BigNumber
|
|
115
197
|
): number {
|
|
116
|
-
|
|
198
|
+
if (!healthFactor || !borrowAmountPlusInterest) return 0;
|
|
117
199
|
|
|
118
|
-
|
|
200
|
+
const healthFactorPercentage = Math.floor(healthFactor * PERCENTAGE_FACTOR);
|
|
119
201
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
202
|
+
return (
|
|
203
|
+
borrowAmountPlusInterest
|
|
204
|
+
.mul(healthFactorPercentage)
|
|
205
|
+
.add(additional.mul(UNDERLYING_TOKEN_LIQUIDATION_THRESHOLD))
|
|
206
|
+
.div(borrowAmountPlusInterest.add(additional))
|
|
207
|
+
.toNumber() / PERCENTAGE_FACTOR
|
|
208
|
+
);
|
|
127
209
|
}
|
|
128
210
|
|
|
129
211
|
export function calcHealthFactorAfterAddingCollateral(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
212
|
+
healthFactor: number | undefined,
|
|
213
|
+
borrowAmountPlusInterest: BigNumber | undefined,
|
|
214
|
+
additionalCollateral: BigNumber
|
|
133
215
|
): number {
|
|
134
|
-
|
|
216
|
+
if (!healthFactor || !borrowAmountPlusInterest) return 0;
|
|
135
217
|
|
|
136
|
-
|
|
218
|
+
const healthFactorPercentage = Math.floor(healthFactor * PERCENTAGE_FACTOR);
|
|
137
219
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
220
|
+
return (
|
|
221
|
+
borrowAmountPlusInterest
|
|
222
|
+
.mul(healthFactorPercentage)
|
|
223
|
+
.add(additionalCollateral.mul(UNDERLYING_TOKEN_LIQUIDATION_THRESHOLD))
|
|
224
|
+
.div(borrowAmountPlusInterest)
|
|
225
|
+
.toNumber() / PERCENTAGE_FACTOR
|
|
226
|
+
);
|
|
145
227
|
}
|
|
146
228
|
|
|
147
229
|
export class CreditManagerStat extends CreditManagerData {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
230
|
+
public readonly uniqueUsers: number;
|
|
231
|
+
public readonly openedAccountsCount: number;
|
|
232
|
+
public readonly totalOpenedAccounts: number;
|
|
233
|
+
public readonly totalClosedAccounts: number;
|
|
234
|
+
public readonly totalRepaidAccounts: number;
|
|
235
|
+
public readonly totalLiquidatedAccounts: number;
|
|
236
|
+
public readonly totalBorrowed: BigNumber;
|
|
237
|
+
public readonly cumulativeBorrowed: BigNumber;
|
|
238
|
+
public readonly totalRepaid: BigNumber;
|
|
239
|
+
public readonly totalProfit: BigNumber;
|
|
240
|
+
public readonly totalLosses: BigNumber;
|
|
241
|
+
|
|
242
|
+
constructor(payload: CreditManagerStatPayload) {
|
|
243
|
+
super(payload);
|
|
244
|
+
this.uniqueUsers = payload.uniqueUsers;
|
|
245
|
+
this.openedAccountsCount = payload.openedAccountsCount || 0;
|
|
246
|
+
this.totalOpenedAccounts = payload.totalOpenedAccounts || 0;
|
|
247
|
+
this.totalClosedAccounts = payload.totalClosedAccounts || 0;
|
|
248
|
+
this.totalRepaidAccounts = payload.totalRepaidAccounts || 0;
|
|
249
|
+
this.totalLiquidatedAccounts = payload.totalLiquidatedAccounts || 0;
|
|
250
|
+
this.totalBorrowed = BigNumber.from(payload.totalBorrowed || 0);
|
|
251
|
+
this.cumulativeBorrowed = BigNumber.from(payload.cumulativeBorrowed || 0);
|
|
252
|
+
this.totalRepaid = BigNumber.from(payload.totalRepaid || 0);
|
|
253
|
+
this.totalProfit = BigNumber.from(payload.totalProfit || 0);
|
|
254
|
+
this.totalLosses = BigNumber.from(payload.totalLosses || 0);
|
|
255
|
+
}
|
|
174
256
|
}
|
package/src/core/errors.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { BigNumber } from "ethers";
|
|
2
|
+
|
|
1
3
|
export interface MetamaskError {
|
|
2
4
|
code: number;
|
|
3
5
|
message: string;
|
|
@@ -43,3 +45,25 @@ export class AccountsInAlllCreditManagersError extends Error {
|
|
|
43
45
|
super("errors.youOpenedAccountsInAllCreditManagersError");
|
|
44
46
|
}
|
|
45
47
|
}
|
|
48
|
+
|
|
49
|
+
export type OpenAccountErrorTypes =
|
|
50
|
+
| "insufficientPoolLiquidity"
|
|
51
|
+
| "leverageGreaterMax"
|
|
52
|
+
| "amountGreaterMax"
|
|
53
|
+
| "amountLessMin";
|
|
54
|
+
|
|
55
|
+
export class OpenAccountError extends Error {
|
|
56
|
+
message: OpenAccountErrorTypes;
|
|
57
|
+
payload: { amount: BigNumber };
|
|
58
|
+
|
|
59
|
+
constructor(errorType: OpenAccountErrorTypes, amount: BigNumber) {
|
|
60
|
+
super();
|
|
61
|
+
Object.setPrototypeOf(this, OpenAccountError.prototype);
|
|
62
|
+
this.message = errorType;
|
|
63
|
+
this.payload = { amount };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static isOpenAccountError(e: unknown): e is OpenAccountError {
|
|
67
|
+
return e instanceof OpenAccountError;
|
|
68
|
+
}
|
|
69
|
+
}
|