@curvefi/llamalend-api 1.1.10 → 2.0.0

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 (138) hide show
  1. package/docs/MIGRATION.md +325 -0
  2. package/docs/SUPPORT_LLv2.md +409 -0
  3. package/lib/constants/abis/OneWayLendingFactoryV2ABI.json +543 -0
  4. package/lib/constants/aliases.d.ts +0 -11
  5. package/lib/constants/aliases.js +1 -86
  6. package/lib/constants/coins.d.ts +0 -11
  7. package/lib/constants/coins.js +0 -14
  8. package/lib/constants/utils.d.ts +2 -0
  9. package/lib/constants/utils.js +2 -0
  10. package/lib/index.d.ts +10 -4
  11. package/lib/interfaces.d.ts +3 -2
  12. package/lib/lendMarkets/LendMarketTemplate.d.ts +13 -502
  13. package/lib/lendMarkets/LendMarketTemplate.js +237 -2860
  14. package/lib/lendMarkets/fetch/fetchFactoryData.d.ts +13 -0
  15. package/lib/lendMarkets/fetch/fetchFactoryData.js +101 -0
  16. package/lib/lendMarkets/fetch/fetchLendMarkets.d.ts +3 -0
  17. package/lib/lendMarkets/fetch/fetchLendMarkets.js +94 -0
  18. package/lib/lendMarkets/interfaces/common/amm.d.ts +10 -0
  19. package/lib/lendMarkets/interfaces/common/amm.js +1 -0
  20. package/lib/lendMarkets/interfaces/common/index.d.ts +5 -0
  21. package/lib/lendMarkets/interfaces/common/index.js +5 -0
  22. package/lib/lendMarkets/interfaces/common/prices.d.ts +13 -0
  23. package/lib/lendMarkets/interfaces/common/prices.js +1 -0
  24. package/lib/lendMarkets/interfaces/common/userPosition.d.ts +39 -0
  25. package/lib/lendMarkets/interfaces/common/userPosition.js +1 -0
  26. package/lib/lendMarkets/interfaces/common/vault.d.ts +55 -0
  27. package/lib/lendMarkets/interfaces/common/vault.js +1 -0
  28. package/lib/lendMarkets/interfaces/common/wallet.d.ts +8 -0
  29. package/lib/lendMarkets/interfaces/common/wallet.js +1 -0
  30. package/lib/lendMarkets/interfaces/v1/index.d.ts +4 -0
  31. package/lib/lendMarkets/interfaces/v1/index.js +4 -0
  32. package/lib/lendMarkets/interfaces/v1/leverageV1.d.ts +90 -0
  33. package/lib/lendMarkets/interfaces/v1/leverageV1.js +1 -0
  34. package/lib/lendMarkets/interfaces/v1/loanV1.d.ts +73 -0
  35. package/lib/lendMarkets/interfaces/v1/loanV1.js +1 -0
  36. package/lib/lendMarkets/interfaces/v1/statsV1.d.ts +49 -0
  37. package/lib/lendMarkets/interfaces/v1/statsV1.js +1 -0
  38. package/lib/lendMarkets/interfaces/v2/index.d.ts +3 -0
  39. package/lib/lendMarkets/interfaces/v2/index.js +3 -0
  40. package/lib/lendMarkets/interfaces/v2/leverageV2.d.ts +90 -0
  41. package/lib/lendMarkets/interfaces/v2/leverageV2.js +1 -0
  42. package/lib/lendMarkets/interfaces/v2/loanV2.d.ts +73 -0
  43. package/lib/lendMarkets/interfaces/v2/loanV2.js +1 -0
  44. package/lib/lendMarkets/interfaces/v2/statsV2.d.ts +49 -0
  45. package/lib/lendMarkets/interfaces/v2/statsV2.js +1 -0
  46. package/lib/lendMarkets/lendMarketConstructor.js +1 -1
  47. package/lib/lendMarkets/modules/common/amm.d.ts +19 -0
  48. package/lib/lendMarkets/modules/common/amm.js +137 -0
  49. package/lib/lendMarkets/modules/common/index.d.ts +9 -0
  50. package/lib/lendMarkets/modules/common/index.js +9 -0
  51. package/lib/lendMarkets/modules/common/leverageZapV1Base.d.ts +118 -0
  52. package/lib/lendMarkets/modules/common/leverageZapV1Base.js +770 -0
  53. package/lib/lendMarkets/modules/{leverageZapV2.d.ts → common/leverageZapV2Base.d.ts} +10 -5
  54. package/lib/lendMarkets/modules/{leverageZapV2.js → common/leverageZapV2Base.js} +36 -32
  55. package/lib/lendMarkets/modules/common/loanBase.d.ts +115 -0
  56. package/lib/lendMarkets/modules/common/loanBase.js +793 -0
  57. package/lib/lendMarkets/modules/common/prices.d.ts +19 -0
  58. package/lib/lendMarkets/modules/common/prices.js +104 -0
  59. package/lib/lendMarkets/modules/common/statsBase.d.ts +69 -0
  60. package/lib/lendMarkets/modules/common/statsBase.js +291 -0
  61. package/lib/lendMarkets/modules/common/userPosition.d.ts +46 -0
  62. package/lib/lendMarkets/modules/common/userPosition.js +223 -0
  63. package/lib/lendMarkets/modules/common/vault.d.ts +69 -0
  64. package/lib/lendMarkets/modules/common/vault.js +535 -0
  65. package/lib/lendMarkets/modules/common/wallet.d.ts +13 -0
  66. package/lib/lendMarkets/modules/common/wallet.js +28 -0
  67. package/lib/lendMarkets/modules/index.d.ts +1 -1
  68. package/lib/lendMarkets/modules/index.js +1 -1
  69. package/lib/lendMarkets/modules/v1/index.d.ts +4 -0
  70. package/lib/lendMarkets/modules/v1/index.js +4 -0
  71. package/lib/lendMarkets/modules/v1/leverageV1ZapV1.d.ts +3 -0
  72. package/lib/lendMarkets/modules/v1/leverageV1ZapV1.js +3 -0
  73. package/lib/lendMarkets/modules/v1/leverageV1ZapV2.d.ts +3 -0
  74. package/lib/lendMarkets/modules/v1/leverageV1ZapV2.js +3 -0
  75. package/lib/lendMarkets/modules/v1/loanV1.d.ts +4 -0
  76. package/lib/lendMarkets/modules/v1/loanV1.js +3 -0
  77. package/lib/lendMarkets/modules/v1/statsV1.d.ts +3 -0
  78. package/lib/lendMarkets/modules/v1/statsV1.js +3 -0
  79. package/lib/lendMarkets/modules/v2/index.d.ts +4 -0
  80. package/lib/lendMarkets/modules/v2/index.js +4 -0
  81. package/lib/lendMarkets/modules/v2/leverageV2ZapV1.d.ts +3 -0
  82. package/lib/lendMarkets/modules/v2/leverageV2ZapV1.js +3 -0
  83. package/lib/lendMarkets/modules/v2/leverageV2ZapV2.d.ts +3 -0
  84. package/lib/lendMarkets/modules/v2/leverageV2ZapV2.js +3 -0
  85. package/lib/lendMarkets/modules/v2/loanV2.d.ts +4 -0
  86. package/lib/lendMarkets/modules/v2/loanV2.js +3 -0
  87. package/lib/lendMarkets/modules/v2/statsV2.d.ts +3 -0
  88. package/lib/lendMarkets/modules/v2/statsV2.js +3 -0
  89. package/lib/llamalend.d.ts +6 -6
  90. package/lib/llamalend.js +46 -210
  91. package/lib/utils.js +2 -33
  92. package/package.json +1 -1
  93. package/src/constants/abis/OneWayLendingFactoryV2ABI.json +543 -0
  94. package/src/constants/aliases.ts +1 -97
  95. package/src/constants/coins.ts +0 -25
  96. package/src/constants/utils.ts +4 -0
  97. package/src/interfaces.ts +3 -2
  98. package/src/lendMarkets/LendMarketTemplate.ts +318 -3222
  99. package/src/lendMarkets/fetch/fetchFactoryData.ts +113 -0
  100. package/src/lendMarkets/fetch/fetchLendMarkets.ts +108 -0
  101. package/src/lendMarkets/interfaces/common/amm.ts +11 -0
  102. package/src/lendMarkets/interfaces/common/index.ts +5 -0
  103. package/src/lendMarkets/interfaces/common/prices.ts +13 -0
  104. package/src/lendMarkets/interfaces/common/userPosition.ts +24 -0
  105. package/src/lendMarkets/interfaces/common/vault.ts +48 -0
  106. package/src/lendMarkets/interfaces/common/wallet.ts +3 -0
  107. package/src/lendMarkets/interfaces/v1/index.ts +4 -0
  108. package/src/lendMarkets/interfaces/v1/leverageV1.ts +84 -0
  109. package/src/lendMarkets/interfaces/v1/loanV1.ts +77 -0
  110. package/src/lendMarkets/interfaces/v1/statsV1.ts +21 -0
  111. package/src/lendMarkets/interfaces/v2/index.ts +3 -0
  112. package/src/lendMarkets/interfaces/v2/leverageV2.ts +84 -0
  113. package/src/lendMarkets/interfaces/v2/loanV2.ts +77 -0
  114. package/src/lendMarkets/interfaces/v2/statsV2.ts +21 -0
  115. package/src/lendMarkets/lendMarketConstructor.ts +1 -1
  116. package/src/lendMarkets/modules/common/amm.ts +132 -0
  117. package/src/lendMarkets/modules/common/index.ts +9 -0
  118. package/src/lendMarkets/modules/common/leverageZapV1Base.ts +912 -0
  119. package/src/lendMarkets/modules/{leverageZapV2.ts → common/leverageZapV2Base.ts} +41 -37
  120. package/src/lendMarkets/modules/common/loanBase.ts +773 -0
  121. package/src/lendMarkets/modules/common/prices.ts +111 -0
  122. package/src/lendMarkets/modules/common/statsBase.ts +313 -0
  123. package/src/lendMarkets/modules/common/userPosition.ts +243 -0
  124. package/src/lendMarkets/modules/common/vault.ts +551 -0
  125. package/src/lendMarkets/modules/common/wallet.ts +29 -0
  126. package/src/lendMarkets/modules/index.ts +1 -1
  127. package/src/lendMarkets/modules/v1/index.ts +4 -0
  128. package/src/lendMarkets/modules/v1/leverageV1ZapV1.ts +3 -0
  129. package/src/lendMarkets/modules/v1/leverageV1ZapV2.ts +3 -0
  130. package/src/lendMarkets/modules/v1/loanV1.ts +4 -0
  131. package/src/lendMarkets/modules/v1/statsV1.ts +3 -0
  132. package/src/lendMarkets/modules/v2/index.ts +4 -0
  133. package/src/lendMarkets/modules/v2/leverageV2ZapV1.ts +3 -0
  134. package/src/lendMarkets/modules/v2/leverageV2ZapV2.ts +3 -0
  135. package/src/lendMarkets/modules/v2/loanV2.ts +4 -0
  136. package/src/lendMarkets/modules/v2/statsV2.ts +3 -0
  137. package/src/llamalend.ts +47 -244
  138. package/src/utils.ts +2 -35
@@ -1,492 +1,35 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
1
+ import { LeverageV1ZapV1Module, LeverageV1ZapV2Module, StatsV1Module, LoanV1Module, } from "./modules/v1";
2
+ import { LeverageV2ZapV1Module, LeverageV2ZapV2Module, StatsV2Module, LoanV2Module, } from "./modules/v2";
3
+ import { UserPositionModule, WalletModule, PricesModule, AmmModule, VaultModule, } from "./modules/common";
4
+ const versionModules = {
5
+ v1: {
6
+ UserPosition: UserPositionModule,
7
+ Wallet: WalletModule,
8
+ Prices: PricesModule,
9
+ Amm: AmmModule,
10
+ Vault: VaultModule,
11
+ Stats: StatsV1Module,
12
+ Loan: LoanV1Module,
13
+ Leverage: LeverageV1ZapV1Module,
14
+ LeverageZapV2: LeverageV1ZapV2Module,
15
+ },
16
+ v2: {
17
+ UserPosition: UserPositionModule,
18
+ Wallet: WalletModule,
19
+ Prices: PricesModule,
20
+ Amm: AmmModule,
21
+ Vault: VaultModule,
22
+ Stats: StatsV2Module,
23
+ Loan: LoanV2Module,
24
+ Leverage: LeverageV2ZapV1Module,
25
+ LeverageZapV2: LeverageV2ZapV2Module,
26
+ },
9
27
  };
10
- import memoize from "memoizee";
11
- import BigNumber from "bignumber.js";
12
- import { _getAddress, parseUnits, BN, toBN, fromBN, getBalances, _ensureAllowance, ensureAllowance, hasAllowance, ensureAllowanceEstimateGas, _cutZeros, formatUnits, formatNumber, MAX_ALLOWANCE, MAX_ACTIVE_BAND, _mulBy1_3, _getUsdRate, DIGas, smartNumber, calculateFutureLeverage, } from "../utils.js";
13
- import { _getExpectedOdos, _getQuoteOdos, _assembleTxOdos, _getUserCollateral, _getUserCollateralForce, _getMarketsData } from "../external-api.js";
14
- import ERC20Abi from '../constants/abis/ERC20.json' with { type: 'json' };
15
- import { cacheKey, cacheStats } from "../cache/index.js";
16
- import { LeverageZapV2Module } from "./modules/leverageZapV2.js";
17
- const DAY = 86400;
18
- const WEEK = 7 * DAY;
19
28
  export class LendMarketTemplate {
20
29
  constructor(id, marketData, llamalend) {
21
30
  this.swapDataCache = {};
22
- this._getMarketId = () => Number(this.id.split("-").slice(-1)[0]);
23
- this._calcCrvApr = (...args_1) => __awaiter(this, [...args_1], void 0, function* (futureWorkingSupplyBN = null) {
24
- const totalLiquidityUSD = yield this.vaultTotalLiquidity();
25
- if (Number(totalLiquidityUSD) === 0)
26
- return [0, 0];
27
- let inflationRateBN, workingSupplyBN, totalSupplyBN;
28
- if (this.llamalend.chainId !== 1) {
29
- const gaugeContract = this.llamalend.contracts[this.addresses.gauge].multicallContract;
30
- const lpTokenContract = this.llamalend.contracts[this.addresses.vault].multicallContract;
31
- const crvContract = this.llamalend.contracts[this.llamalend.constants.ALIASES.crv].contract;
32
- const currentWeek = Math.floor(Date.now() / 1000 / WEEK);
33
- [inflationRateBN, workingSupplyBN, totalSupplyBN] = (yield this.llamalend.multicallProvider.all([
34
- gaugeContract.inflation_rate(currentWeek),
35
- gaugeContract.working_supply(),
36
- lpTokenContract.totalSupply(),
37
- ])).map((value) => toBN(value));
38
- if (inflationRateBN.eq(0)) {
39
- inflationRateBN = toBN(yield crvContract.balanceOf(this.addresses.gauge, this.llamalend.constantOptions)).div(WEEK);
40
- }
41
- }
42
- else {
43
- const gaugeContract = this.llamalend.contracts[this.addresses.gauge].multicallContract;
44
- const lpTokenContract = this.llamalend.contracts[this.addresses.vault].multicallContract;
45
- const gaugeControllerContract = this.llamalend.contracts[this.llamalend.constants.ALIASES.gauge_controller].multicallContract;
46
- let weightBN;
47
- [inflationRateBN, weightBN, workingSupplyBN, totalSupplyBN] = (yield this.llamalend.multicallProvider.all([
48
- gaugeContract.inflation_rate(),
49
- gaugeControllerContract.gauge_relative_weight(this.addresses.gauge),
50
- gaugeContract.working_supply(),
51
- lpTokenContract.totalSupply(),
52
- ])).map((value) => toBN(value));
53
- inflationRateBN = inflationRateBN.times(weightBN);
54
- }
55
- if (inflationRateBN.eq(0))
56
- return [0, 0];
57
- if (futureWorkingSupplyBN !== null)
58
- workingSupplyBN = futureWorkingSupplyBN;
59
- // If you added 1$ value of LP it would be 0.4$ of working LP. So your annual reward per 1$ in USD is:
60
- // (annual reward per working liquidity in $) * (0.4$ of working LP)
61
- const rateBN = inflationRateBN.times(31536000).div(workingSupplyBN).times(totalSupplyBN).div(Number(totalLiquidityUSD)).times(0.4);
62
- const crvPrice = yield _getUsdRate.call(this.llamalend, this.llamalend.constants.ALIASES.crv);
63
- const baseApyBN = rateBN.times(crvPrice);
64
- const boostedApyBN = baseApyBN.times(2.5);
65
- return [baseApyBN.times(100).toNumber(), boostedApyBN.times(100).toNumber()];
66
- });
67
- this.vaultRewardTokens = memoize(() => __awaiter(this, void 0, void 0, function* () {
68
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS)
69
- return [];
70
- // if (useApi) {
71
- // const rewards = await _getRewardsFromApi();
72
- // if (!rewards[this.addresses.gauge]) return [];
73
- // rewards[this.addresses.gauge].forEach((r) => _setContracts(r.tokenAddress, ERC20Abi));
74
- // return rewards[this.addresses.gauge].map((r) => ({ token: r.tokenAddress, symbol: r.symbol, decimals: Number(r.decimals) }));
75
- // }
76
- const gaugeContract = this.llamalend.contracts[this.addresses.gauge].contract;
77
- const gaugeMulticallContract = this.llamalend.contracts[this.addresses.gauge].multicallContract;
78
- const rewardCount = Number(this.llamalend.formatUnits(yield gaugeContract.reward_count(this.llamalend.constantOptions), 0));
79
- const tokenCalls = [];
80
- for (let i = 0; i < rewardCount; i++) {
81
- tokenCalls.push(gaugeMulticallContract.reward_tokens(i));
82
- }
83
- const tokens = (yield this.llamalend.multicallProvider.all(tokenCalls))
84
- .filter((addr) => addr !== this.llamalend.constants.ZERO_ADDRESS)
85
- .map((addr) => addr.toLowerCase())
86
- .filter((addr) => this.llamalend.chainId === 1 || addr !== this.llamalend.constants.COINS.crv);
87
- const tokenInfoCalls = [];
88
- for (const token of tokens) {
89
- this.llamalend.setContract(token, ERC20Abi);
90
- const tokenMulticallContract = this.llamalend.contracts[token].multicallContract;
91
- tokenInfoCalls.push(tokenMulticallContract.symbol(), tokenMulticallContract.decimals());
92
- }
93
- const tokenInfo = yield this.llamalend.multicallProvider.all(tokenInfoCalls);
94
- for (let i = 0; i < tokens.length; i++) {
95
- this.llamalend.constants.DECIMALS[tokens[i]] = Number(tokenInfo[(i * 2) + 1]);
96
- }
97
- return tokens.map((token, i) => ({ token, symbol: tokenInfo[i * 2], decimals: Number(tokenInfo[(i * 2) + 1]) }));
98
- }), {
99
- promise: true,
100
- maxAge: 30 * 60 * 1000, // 30m
101
- });
102
- this.vaultRewardsApr = (...args_1) => __awaiter(this, [...args_1], void 0, function* (useApi = true) {
103
- if (useApi) {
104
- const response = yield _getMarketsData(this.llamalend.constants.NETWORK_NAME);
105
- const market = response.lendingVaultData.find((item) => item.address.toLowerCase() === this.addresses.vault.toLowerCase());
106
- if (market) {
107
- return market.gaugeRewards;
108
- }
109
- else {
110
- throw new Error('Market not found in API');
111
- }
112
- }
113
- else {
114
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS)
115
- return [];
116
- // const isDisabledChain = [1313161554].includes(this.llamalend.chainId); // Disable Aurora
117
- // if (useApi && !isDisabledChain) {
118
- // const rewards = await _getRewardsFromApi();
119
- // if (!rewards[this.addresses.gauge]) return [];
120
- // return rewards[this.addresses.gauge].map((r) => ({ gaugeAddress: r.gaugeAddress, tokenAddress: r.tokenAddress, symbol: r.symbol, apy: r.apy }));
121
- // }
122
- const apy = [];
123
- const rewardTokens = yield this.vaultRewardTokens();
124
- for (const rewardToken of rewardTokens) {
125
- const gaugeContract = this.llamalend.contracts[this.addresses.gauge].multicallContract;
126
- const lpTokenContract = this.llamalend.contracts[this.addresses.vault].multicallContract;
127
- const rewardContract = this.llamalend.contracts[this.addresses.gauge].multicallContract;
128
- const totalLiquidityUSD = yield this.vaultTotalLiquidity();
129
- const rewardRate = yield _getUsdRate.call(this.llamalend, rewardToken.token);
130
- const [rewardData, _stakedSupply, _totalSupply] = yield this.llamalend.multicallProvider.all([
131
- rewardContract.reward_data(rewardToken.token),
132
- gaugeContract.totalSupply(),
133
- lpTokenContract.totalSupply(),
134
- ]);
135
- const stakedSupplyBN = toBN(_stakedSupply);
136
- const totalSupplyBN = toBN(_totalSupply);
137
- const inflationBN = toBN(rewardData.rate, rewardToken.decimals);
138
- const periodFinish = Number(this.llamalend.formatUnits(rewardData.period_finish, 0)) * 1000;
139
- const baseApy = periodFinish > Date.now() ?
140
- inflationBN.times(31536000).times(rewardRate).div(stakedSupplyBN).times(totalSupplyBN).div(Number(totalLiquidityUSD)) :
141
- BN(0);
142
- apy.push({
143
- gaugeAddress: this.addresses.gauge,
144
- tokenAddress: rewardToken.token,
145
- symbol: rewardToken.symbol,
146
- apy: baseApy.times(100).toNumber(),
147
- });
148
- }
149
- return apy;
150
- }
151
- });
152
- // ---------------- STATS ----------------
153
- this.statsParameters = memoize(() => __awaiter(this, void 0, void 0, function* () {
154
- const llammaContract = this.llamalend.contracts[this.addresses.amm].multicallContract;
155
- const controllerContract = this.llamalend.contracts[this.addresses.controller].multicallContract;
156
- const calls = [
157
- llammaContract.fee(),
158
- llammaContract.admin_fee(),
159
- controllerContract.liquidation_discount(),
160
- controllerContract.loan_discount(),
161
- llammaContract.get_base_price(),
162
- llammaContract.A(),
163
- ];
164
- const [_fee, _admin_fee, _liquidation_discount, _loan_discount, _base_price, _A] = yield this.llamalend.multicallProvider.all(calls);
165
- const A = formatUnits(_A, 0);
166
- const base_price = formatUnits(_base_price);
167
- const [fee, admin_fee, liquidation_discount, loan_discount] = [_fee, _admin_fee, _liquidation_discount, _loan_discount]
168
- .map((_x) => formatUnits(_x * BigInt(100)));
169
- return { fee, admin_fee, liquidation_discount, loan_discount, base_price, A };
170
- }), {
171
- promise: true,
172
- maxAge: 5 * 60 * 1000, // 5m
173
- });
174
- this._getRate = (...args_1) => __awaiter(this, [...args_1], void 0, function* (isGetter = true) {
175
- let _rate;
176
- if (isGetter) {
177
- _rate = cacheStats.get(cacheKey(this.addresses.amm, 'rate'));
178
- }
179
- else {
180
- _rate = yield this.llamalend.contracts[this.addresses.amm].contract.rate(this.llamalend.constantOptions);
181
- cacheStats.set(cacheKey(this.addresses.controller, 'rate'), _rate);
182
- }
183
- return _rate;
184
- });
185
- this._getFutureRate = (_dReserves, _dDebt) => __awaiter(this, void 0, void 0, function* () {
186
- const mpContract = this.llamalend.contracts[this.addresses.monetary_policy].contract;
187
- return yield mpContract.future_rate(this.addresses.controller, _dReserves, _dDebt);
188
- });
189
- this.statsBandsInfo = memoize(() => __awaiter(this, void 0, void 0, function* () {
190
- const ammContract = this.llamalend.contracts[this.addresses.amm].multicallContract;
191
- const calls = [
192
- ammContract.active_band_with_skip(),
193
- ammContract.max_band(),
194
- ammContract.min_band(),
195
- ];
196
- const [activeBand, maxBand, minBand] = (yield this.llamalend.multicallProvider.all(calls)).map((_b) => Number(_b));
197
- const { borrowed, collateral } = yield this.statsBandBalances(activeBand);
198
- let liquidationBand = null;
199
- if (Number(borrowed) > 0 && Number(collateral) > 0)
200
- liquidationBand = activeBand;
201
- return { activeBand, maxBand, minBand, liquidationBand };
202
- }), {
203
- promise: true,
204
- maxAge: 60 * 1000, // 1m
205
- });
206
- this.statsAmmBalances = (...args_1) => __awaiter(this, [...args_1], void 0, function* (isGetter = true, useAPI = false) {
207
- if (useAPI) {
208
- const response = yield _getMarketsData(this.llamalend.constants.NETWORK_NAME);
209
- const market = response.lendingVaultData.find((item) => item.address.toLowerCase() === this.addresses.vault.toLowerCase());
210
- if (market) {
211
- return {
212
- borrowed: market.ammBalances.ammBalanceBorrowed.toString(),
213
- collateral: market.ammBalances.ammBalanceCollateral.toString(),
214
- };
215
- }
216
- else {
217
- throw new Error('Market not found in API');
218
- }
219
- }
220
- else {
221
- const borrowedContract = this.llamalend.contracts[this.addresses.borrowed_token].multicallContract;
222
- const collateralContract = this.llamalend.contracts[this.addresses.collateral_token].multicallContract;
223
- const ammContract = this.llamalend.contracts[this.addresses.amm].multicallContract;
224
- let _balance_x, _fee_x, _balance_y, _fee_y;
225
- if (isGetter) {
226
- [_balance_x, _fee_x, _balance_y, _fee_y] = [
227
- cacheStats.get(cacheKey(this.addresses.borrowed_token, 'balanceOf', this.addresses.amm)),
228
- cacheStats.get(cacheKey(this.addresses.amm, 'admin_fees_x')),
229
- cacheStats.get(cacheKey(this.addresses.collateral_token, 'balanceOf', this.addresses.amm)),
230
- cacheStats.get(cacheKey(this.addresses.amm, 'admin_fees_y')),
231
- ];
232
- }
233
- else {
234
- [_balance_x, _fee_x, _balance_y, _fee_y] = yield this.llamalend.multicallProvider.all([
235
- borrowedContract.balanceOf(this.addresses.amm),
236
- ammContract.admin_fees_x(),
237
- collateralContract.balanceOf(this.addresses.amm),
238
- ammContract.admin_fees_y(),
239
- ]);
240
- cacheStats.set(cacheKey(this.addresses.borrowed_token, 'balanceOf', this.addresses.amm), _balance_x);
241
- cacheStats.set(cacheKey(this.addresses.amm, 'admin_fees_x'), _fee_x);
242
- cacheStats.set(cacheKey(this.addresses.collateral_token, 'balanceOf', this.addresses.amm), _balance_y);
243
- cacheStats.set(cacheKey(this.addresses.amm, 'admin_fees_y'), _fee_y);
244
- }
245
- return {
246
- borrowed: toBN(_balance_x, this.borrowed_token.decimals).minus(toBN(_fee_x, this.borrowed_token.decimals)).toString(),
247
- collateral: toBN(_balance_y, this.collateral_token.decimals).minus(toBN(_fee_y, this.collateral_token.decimals)).toString(),
248
- };
249
- }
250
- });
251
- // ---------------- PRICES ----------------
252
- this.A = memoize(() => __awaiter(this, void 0, void 0, function* () {
253
- const _A = yield this.llamalend.contracts[this.addresses.amm].contract.A(this.llamalend.constantOptions);
254
- return formatUnits(_A, 0);
255
- }), {
256
- promise: true,
257
- maxAge: 86400 * 1000, // 1d
258
- });
259
- this.basePrice = memoize(() => __awaiter(this, void 0, void 0, function* () {
260
- const _price = yield this.llamalend.contracts[this.addresses.amm].contract.get_base_price(this.llamalend.constantOptions);
261
- return formatUnits(_price);
262
- }), {
263
- promise: true,
264
- maxAge: 86400 * 1000, // 1d
265
- });
266
- this.oraclePrice = memoize(() => __awaiter(this, void 0, void 0, function* () {
267
- const _price = yield this.llamalend.contracts[this.addresses.amm].contract.price_oracle(this.llamalend.constantOptions);
268
- return formatUnits(_price);
269
- }), {
270
- promise: true,
271
- maxAge: 60 * 1000, // 1m
272
- });
273
- this.oracleAddress = memoize(() => __awaiter(this, void 0, void 0, function* () {
274
- const _address = yield this.llamalend.contracts[this.addresses.amm].contract.price_oracle_contract(this.llamalend.constantOptions);
275
- return _address;
276
- }), {
277
- promise: true,
278
- });
279
- this._userState = memoize((...args_1) => __awaiter(this, [...args_1], void 0, function* (address = "") {
280
- address = _getAddress.call(this.llamalend, address);
281
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
282
- const [_collateral, _borrowed, _debt, _N] = yield contract.user_state(address, this.llamalend.constantOptions);
283
- return { _collateral, _borrowed, _debt, _N };
284
- }), {
285
- promise: true,
286
- maxAge: 10 * 1000, // 10s
287
- });
288
- this.createLoanMaxRecvAllRanges = memoize((collateral) => __awaiter(this, void 0, void 0, function* () {
289
- const _collateral = parseUnits(collateral, this.collateral_token.decimals);
290
- const calls = [];
291
- for (let N = this.minBands; N <= this.maxBands; N++) {
292
- calls.push(this.llamalend.contracts[this.addresses.controller].multicallContract.max_borrowable(_collateral, N, 0));
293
- }
294
- const _amounts = yield this.llamalend.multicallProvider.all(calls);
295
- const res = {};
296
- for (let N = this.minBands; N <= this.maxBands; N++) {
297
- res[N] = formatUnits(_amounts[N - this.minBands], this.borrowed_token.decimals);
298
- }
299
- return res;
300
- }), {
301
- promise: true,
302
- maxAge: 5 * 60 * 1000, // 5m
303
- });
304
- // ---------------- LEVERAGE CREATE LOAN ----------------
305
- this.hasLeverage = () => {
306
- return this.llamalend.constants.ALIASES.leverage_zap !== this.llamalend.constants.ZERO_ADDRESS &&
307
- this._getMarketId() >= Number(this.llamalend.constants.ALIASES["leverage_markets_start_id"]);
308
- };
309
- this.leverageCreateLoanMaxRecvAllRanges = memoize((userCollateral, userBorrowed) => __awaiter(this, void 0, void 0, function* () {
310
- this._checkLeverageZap();
311
- const _userCollateral = parseUnits(userCollateral, this.collateral_token.decimals);
312
- const contract = this.llamalend.contracts[this.llamalend.constants.ALIASES.leverage_zap].multicallContract;
313
- const oraclePriceBand = yield this.oraclePriceBand();
314
- const pAvgApproxBN = BN(yield this.calcTickPrice(oraclePriceBand)); // upper tick of oracle price band
315
- let pAvgBN = null;
316
- const arrLength = this.maxBands - this.minBands + 1;
317
- let maxLeverageCollateralBN = new Array(arrLength).fill(BN(0));
318
- let _maxLeverageCollateral = new Array(arrLength).fill(BigInt(0));
319
- let maxBorrowablePrevBN = new Array(arrLength).fill(BN(0));
320
- let maxBorrowableBN = new Array(arrLength).fill(BN(0));
321
- let _maxBorrowable = new Array(arrLength).fill(BigInt(0));
322
- for (let i = 0; i < 5; i++) {
323
- const pBN = pAvgBN !== null && pAvgBN !== void 0 ? pAvgBN : pAvgApproxBN;
324
- maxBorrowablePrevBN = maxBorrowableBN;
325
- const _userEffectiveCollateral = _userCollateral + fromBN(BN(userBorrowed).div(pBN), this.collateral_token.decimals);
326
- const calls = [];
327
- for (let N = this.minBands; N <= this.maxBands; N++) {
328
- const j = N - this.minBands;
329
- calls.push(contract.max_borrowable(this.addresses.controller, _userEffectiveCollateral, _maxLeverageCollateral[j], N, fromBN(pBN)));
330
- }
331
- _maxBorrowable = (yield this.llamalend.multicallProvider.all(calls)).map((_mb) => _mb * BigInt(998) / BigInt(1000));
332
- maxBorrowableBN = _maxBorrowable.map((_mb) => toBN(_mb, this.borrowed_token.decimals));
333
- const deltaBN = maxBorrowableBN.map((mb, l) => mb.minus(maxBorrowablePrevBN[l]).abs().div(mb));
334
- if (BigNumber.max(...deltaBN).lt(0.0005)) {
335
- maxBorrowableBN = maxBorrowablePrevBN;
336
- break;
337
- }
338
- if (pAvgBN === null) {
339
- const _y = BigInt(yield _getExpectedOdos.call(this.llamalend, this.addresses.borrowed_token, this.addresses.collateral_token, _maxBorrowable[0], this.addresses.amm));
340
- const yBN = toBN(_y, this.collateral_token.decimals);
341
- pAvgBN = maxBorrowableBN[0].div(yBN);
342
- }
343
- maxLeverageCollateralBN = maxBorrowableBN.map((mb) => mb.div(pAvgBN));
344
- _maxLeverageCollateral = maxLeverageCollateralBN.map((mlc) => fromBN(mlc, this.collateral_token.decimals));
345
- }
346
- const userEffectiveCollateralBN = BN(userCollateral).plus(BN(userBorrowed).div(pAvgBN));
347
- const res = {};
348
- for (let N = this.minBands; N <= this.maxBands; N++) {
349
- const j = N - this.minBands;
350
- res[N] = {
351
- maxDebt: formatNumber(maxBorrowableBN[j].toString(), this.borrowed_token.decimals),
352
- maxTotalCollateral: formatNumber(maxLeverageCollateralBN[j].plus(userEffectiveCollateralBN).toString(), this.collateral_token.decimals),
353
- userCollateral: formatNumber(userCollateral, this.collateral_token.decimals),
354
- collateralFromUserBorrowed: formatNumber(BN(userBorrowed).div(pAvgBN).toString(), this.collateral_token.decimals),
355
- collateralFromMaxDebt: formatNumber(maxLeverageCollateralBN[j].toString(), this.collateral_token.decimals),
356
- maxLeverage: maxLeverageCollateralBN[j].plus(userEffectiveCollateralBN).div(userEffectiveCollateralBN).toString(),
357
- avgPrice: pAvgBN.toString(),
358
- };
359
- }
360
- return res;
361
- }), {
362
- promise: true,
363
- maxAge: 60 * 1000, // 1m
364
- });
365
- this._setSwapDataToCache = (inputCoinAddress, outputCoinAddress, _amount, slippage) => __awaiter(this, void 0, void 0, function* () {
366
- let swapData = yield _getQuoteOdos.call(this.llamalend, inputCoinAddress, outputCoinAddress, _amount, this.addresses.amm, true, slippage);
367
- while (swapData.pathId == null) {
368
- swapData = yield _getQuoteOdos.call(this.llamalend, inputCoinAddress, outputCoinAddress, _amount, this.addresses.amm, true, slippage);
369
- }
370
- const key = `${inputCoinAddress}-${_amount}`;
371
- this.swapDataCache[key] = Object.assign(Object.assign({}, swapData), { slippage });
372
- });
373
- this._getSwapDataFromCache = (inputCoinAddress, _amount) => {
374
- const key = `${inputCoinAddress}-${_amount}`;
375
- if (!(key in this.swapDataCache))
376
- throw Error("You must call corresponding `expected` method first " +
377
- "(leverage.createLoanExpectedCollateral, leverage.borrowMoreExpectedCollateral or leverage.repayExpectedBorrowed)");
378
- return this.swapDataCache[key];
379
- };
380
- this._leverageExpectedCollateral = (userCollateral, userBorrowed, debt, user) => __awaiter(this, void 0, void 0, function* () {
381
- const _userCollateral = parseUnits(userCollateral, this.collateral_token.decimals);
382
- const _debt = parseUnits(debt, this.borrowed_token.decimals);
383
- const _userBorrowed = parseUnits(userBorrowed, this.borrowed_token.decimals);
384
- // additionalCollateral = (userBorrowed / p) + leverageCollateral
385
- const _additionalCollateral = BigInt(this._getSwapDataFromCache(this.addresses.borrowed_token, _debt + _userBorrowed).outAmounts[0]);
386
- const _collateralFromDebt = _debt * BigInt(Math.pow(10, 18)) / (_debt + _userBorrowed) * _additionalCollateral / BigInt(Math.pow(10, 18));
387
- const _collateralFromUserBorrowed = _additionalCollateral - _collateralFromDebt;
388
- let _stateCollateral = BigInt(0);
389
- if (user) {
390
- const { _collateral, _borrowed } = yield this._userState(user);
391
- if (_borrowed > BigInt(0))
392
- throw Error(`User ${user} is already in liquidation mode`);
393
- _stateCollateral = _collateral;
394
- }
395
- const _totalCollateral = _userCollateral + _additionalCollateral;
396
- const _futureStateCollateral = _stateCollateral + _totalCollateral;
397
- const avgPrice = toBN(_debt + _userBorrowed, this.borrowed_token.decimals).div(toBN(_additionalCollateral, this.collateral_token.decimals)).toString();
398
- return { _futureStateCollateral, _totalCollateral, _userCollateral, _collateralFromUserBorrowed, _collateralFromDebt, avgPrice };
399
- });
400
- this._leverageCalcN1 = memoize((userCollateral, userBorrowed, debt, range, user) => __awaiter(this, void 0, void 0, function* () {
401
- if (range > 0)
402
- this._checkRange(range);
403
- let _stateDebt = BigInt(0);
404
- if (user) {
405
- const { _debt, _borrowed, _N } = yield this._userState(user);
406
- if (_borrowed > BigInt(0))
407
- throw Error(`User ${user} is already in liquidation mode`);
408
- _stateDebt = _debt;
409
- if (range < 0)
410
- range = Number(this.llamalend.formatUnits(_N, 0));
411
- }
412
- const { _futureStateCollateral } = yield this._leverageExpectedCollateral(userCollateral, userBorrowed, debt, user);
413
- const _debt = _stateDebt + parseUnits(debt, this.borrowed_token.decimals);
414
- return yield this.llamalend.contracts[this.addresses.controller].contract.calculate_debt_n1(_futureStateCollateral, _debt, range, this.llamalend.constantOptions);
415
- }), {
416
- promise: true,
417
- maxAge: 60 * 1000, // 1m
418
- });
419
- this._leverageCalcN1AllRanges = memoize((userCollateral, userBorrowed, debt, maxN) => __awaiter(this, void 0, void 0, function* () {
420
- const { _futureStateCollateral } = yield this._leverageExpectedCollateral(userCollateral, userBorrowed, debt);
421
- const _debt = parseUnits(debt, this.borrowed_token.decimals);
422
- const calls = [];
423
- for (let N = this.minBands; N <= maxN; N++) {
424
- calls.push(this.llamalend.contracts[this.addresses.controller].multicallContract.calculate_debt_n1(_futureStateCollateral, _debt, N));
425
- }
426
- return yield this.llamalend.multicallProvider.all(calls);
427
- }), {
428
- promise: true,
429
- maxAge: 60 * 1000, // 1m
430
- });
431
- // ---------------- LEVERAGE REPAY ----------------
432
- this._leverageRepayExpectedBorrowed = (stateCollateral, userCollateral, userBorrowed) => {
433
- this._checkLeverageZap();
434
- const _stateCollateral = parseUnits(stateCollateral, this.collateral_token.decimals);
435
- const _userCollateral = parseUnits(userCollateral, this.collateral_token.decimals);
436
- let _borrowedExpected = BigInt(0);
437
- let _borrowedFromStateCollateral = BigInt(0);
438
- let _borrowedFromUserCollateral = BigInt(0);
439
- if (_stateCollateral + _userCollateral > BigInt(0)) {
440
- _borrowedExpected = BigInt(this._getSwapDataFromCache(this.addresses.collateral_token, _stateCollateral + _userCollateral).outAmounts[0]);
441
- _borrowedFromStateCollateral = _stateCollateral * BigInt(Math.pow(10, 18)) / (_stateCollateral + _userCollateral) * _borrowedExpected / BigInt(Math.pow(10, 18));
442
- _borrowedFromUserCollateral = _borrowedExpected - _borrowedFromStateCollateral;
443
- }
444
- const _totalBorrowed = _borrowedExpected + parseUnits(userBorrowed, this.borrowed_token.decimals);
445
- const avgPrice = toBN(_borrowedExpected, this.borrowed_token.decimals).div(toBN(_stateCollateral + _userCollateral, this.collateral_token.decimals)).toString();
446
- return { _totalBorrowed, _borrowedFromStateCollateral, _borrowedFromUserCollateral, avgPrice };
447
- };
448
- this.leverageRepayExpectedBorrowed = (stateCollateral_1, userCollateral_1, userBorrowed_1, ...args_1) => __awaiter(this, [stateCollateral_1, userCollateral_1, userBorrowed_1, ...args_1], void 0, function* (stateCollateral, userCollateral, userBorrowed, slippage = 0.1) {
449
- this._checkLeverageZap();
450
- const _stateCollateral = parseUnits(stateCollateral, this.collateral_token.decimals);
451
- const _userCollateral = parseUnits(userCollateral, this.collateral_token.decimals);
452
- if (_stateCollateral + _userCollateral > BigInt(0)) {
453
- yield this._setSwapDataToCache(this.addresses.collateral_token, this.addresses.borrowed_token, _stateCollateral + _userCollateral, slippage);
454
- }
455
- const { _totalBorrowed, _borrowedFromStateCollateral, _borrowedFromUserCollateral, avgPrice } = this._leverageRepayExpectedBorrowed(stateCollateral, userCollateral, userBorrowed);
456
- return {
457
- totalBorrowed: formatUnits(_totalBorrowed, this.borrowed_token.decimals),
458
- borrowedFromStateCollateral: formatUnits(_borrowedFromStateCollateral, this.borrowed_token.decimals),
459
- borrowedFromUserCollateral: formatUnits(_borrowedFromUserCollateral, this.borrowed_token.decimals),
460
- userBorrowed: formatNumber(userBorrowed, this.borrowed_token.decimals),
461
- avgPrice,
462
- };
463
- });
464
- this._leverageRepayBands = memoize((stateCollateral, userCollateral, userBorrowed, address) => __awaiter(this, void 0, void 0, function* () {
465
- address = _getAddress.call(this.llamalend, address);
466
- if (!(yield this.leverageRepayIsAvailable(stateCollateral, userCollateral, userBorrowed, address)))
467
- return [parseUnits(0, 0), parseUnits(0, 0)];
468
- const _stateRepayCollateral = parseUnits(stateCollateral, this.collateral_token.decimals);
469
- const { _collateral: _stateCollateral, _debt: _stateDebt, _N } = yield this._userState(address);
470
- if (_stateDebt == BigInt(0))
471
- throw Error(`Loan for ${address} does not exist`);
472
- if (_stateCollateral < _stateRepayCollateral)
473
- throw Error(`Can't use more collateral than user's position has (${_stateRepayCollateral}) > ${_stateCollateral})`);
474
- let _n1 = parseUnits(0, 0);
475
- let _n2 = parseUnits(0, 0);
476
- const { _totalBorrowed: _repayExpected } = this._leverageRepayExpectedBorrowed(stateCollateral, userCollateral, userBorrowed);
477
- try {
478
- _n1 = yield this.llamalend.contracts[this.addresses.controller].contract.calculate_debt_n1(_stateCollateral - _stateRepayCollateral, _stateDebt - _repayExpected, _N);
479
- _n2 = _n1 + (_N - BigInt(1));
480
- }
481
- catch (_a) {
482
- console.log("Full repayment");
483
- }
484
- return [_n2, _n1];
485
- }), {
486
- promise: true,
487
- maxAge: 5 * 60 * 1000, // 5m
488
- });
489
31
  this.llamalend = llamalend;
32
+ this.version = marketData.version || 'v1';
490
33
  this.id = id;
491
34
  this.name = marketData.name;
492
35
  this.addresses = marketData.addresses;
@@ -497,138 +40,229 @@ export class LendMarketTemplate {
497
40
  this.defaultBands = 10;
498
41
  this.minBands = 4;
499
42
  this.maxBands = 50;
500
- this.estimateGas = {
501
- createLoanApprove: this.createLoanApproveEstimateGas.bind(this),
502
- createLoan: this.createLoanEstimateGas.bind(this),
503
- borrowMoreApprove: this.borrowMoreApproveEstimateGas.bind(this),
504
- borrowMore: this.borrowMoreEstimateGas.bind(this),
505
- addCollateralApprove: this.addCollateralApproveEstimateGas.bind(this),
506
- addCollateral: this.addCollateralEstimateGas.bind(this),
507
- removeCollateral: this.removeCollateralEstimateGas.bind(this),
508
- repayApprove: this.repayApproveEstimateGas.bind(this),
509
- repay: this.repayEstimateGas.bind(this),
510
- fullRepayApprove: this.fullRepayApproveEstimateGas.bind(this),
511
- fullRepay: this.fullRepayEstimateGas.bind(this),
512
- swapApprove: this.swapApproveEstimateGas.bind(this),
513
- swap: this.swapEstimateGas.bind(this),
514
- liquidateApprove: this.liquidateApproveEstimateGas.bind(this),
515
- liquidate: this.liquidateEstimateGas.bind(this),
516
- selfLiquidateApprove: this.selfLiquidateApproveEstimateGas.bind(this),
517
- selfLiquidate: this.selfLiquidateEstimateGas.bind(this),
518
- partialSelfLiquidateApprove: this.partialSelfLiquidateApproveEstimateGas.bind(this),
519
- partialSelfLiquidate: this.partialSelfLiquidateEstimateGas.bind(this),
43
+ const modules = versionModules[this.version];
44
+ const userPosition = new modules.UserPosition(this);
45
+ const stats = new modules.Stats(this);
46
+ const wallet = new modules.Wallet(this);
47
+ const prices = new modules.Prices(this);
48
+ const amm = new modules.Amm(this);
49
+ const vault = new modules.Vault(this);
50
+ const loan = new modules.Loan(this);
51
+ const leverageZapV1 = new modules.Leverage(this);
52
+ const leverageZapV2 = new modules.LeverageZapV2(this);
53
+ this.userPosition = {
54
+ userLoanExists: userPosition.userLoanExists.bind(userPosition),
55
+ userStateBigInt: userPosition.userStateBigInt.bind(userPosition),
56
+ userState: userPosition.userState.bind(userPosition),
57
+ userHealth: userPosition.userHealth.bind(userPosition),
58
+ userBandsBigInt: userPosition.userBandsBigInt.bind(userPosition),
59
+ userBands: userPosition.userBands.bind(userPosition),
60
+ userRange: userPosition.userRange.bind(userPosition),
61
+ userPrices: userPosition.userPrices.bind(userPosition),
62
+ userLoss: userPosition.userLoss.bind(userPosition),
63
+ userBandsBalances: userPosition.userBandsBalances.bind(userPosition),
64
+ currentLeverage: userPosition.currentLeverage.bind(userPosition),
65
+ currentPnL: userPosition.currentPnL.bind(userPosition),
66
+ userBoost: userPosition.userBoost.bind(userPosition),
67
+ forceUpdateUserState: userPosition.forceUpdateUserState.bind(userPosition),
68
+ getCurrentLeverageParams: userPosition.getCurrentLeverageParams.bind(userPosition),
520
69
  };
521
70
  this.stats = {
522
- parameters: this.statsParameters.bind(this),
523
- rates: this.statsRates.bind(this),
524
- futureRates: this.statsFutureRates.bind(this),
525
- balances: this.statsBalances.bind(this),
526
- bandsInfo: this.statsBandsInfo.bind(this),
527
- bandBalances: this.statsBandBalances.bind(this),
528
- bandsBalances: this.statsBandsBalances.bind(this),
529
- totalDebt: this.statsTotalDebt.bind(this),
530
- ammBalances: this.statsAmmBalances.bind(this),
531
- capAndAvailable: this.statsCapAndAvailable.bind(this),
71
+ parameters: stats.statsParameters.bind(this),
72
+ rates: stats.statsRates.bind(this),
73
+ futureRates: stats.statsFutureRates.bind(this),
74
+ balances: stats.statsBalances.bind(this),
75
+ bandsInfo: stats.statsBandsInfo.bind(this),
76
+ bandBalances: stats.statsBandBalances.bind(this),
77
+ bandsBalances: stats.statsBandsBalances.bind(this),
78
+ totalDebt: stats.statsTotalDebt.bind(this),
79
+ ammBalances: stats.statsAmmBalances.bind(this),
80
+ capAndAvailable: stats.statsCapAndAvailable.bind(this),
532
81
  };
533
82
  this.wallet = {
534
- balances: this.walletBalances.bind(this),
83
+ balances: wallet.balances.bind(this),
84
+ };
85
+ this.prices = {
86
+ A: prices.A.bind(prices),
87
+ basePrice: prices.basePrice.bind(prices),
88
+ oraclePrice: prices.oraclePrice.bind(prices),
89
+ oraclePriceBand: prices.oraclePriceBand.bind(prices),
90
+ price: prices.price.bind(prices),
91
+ calcTickPrice: prices.calcTickPrice.bind(prices),
92
+ calcBandPrices: prices.calcBandPrices.bind(prices),
93
+ calcRangePct: prices.calcRangePct.bind(prices),
94
+ getPrices: prices.getPrices.bind(prices),
95
+ calcPrices: prices.getPrices.bind(prices),
96
+ checkRange: prices.checkRange.bind(prices),
97
+ };
98
+ this.amm = {
99
+ maxSwappable: amm.maxSwappable.bind(amm),
100
+ swapExpected: amm.swapExpected.bind(amm),
101
+ swapRequired: amm.swapRequired.bind(amm),
102
+ swapPriceImpact: amm.swapPriceImpact.bind(amm),
103
+ swapIsApproved: amm.swapIsApproved.bind(amm),
104
+ swapApprove: amm.swapApprove.bind(amm),
105
+ swap: amm.swap.bind(amm),
106
+ };
107
+ this.loan = {
108
+ createLoanMaxRecv: loan.createLoanMaxRecv.bind(loan),
109
+ createLoanMaxRecvAllRanges: loan.createLoanMaxRecvAllRanges.bind(loan),
110
+ getMaxRange: loan.getMaxRange.bind(loan),
111
+ createLoanBands: loan.createLoanBands.bind(loan),
112
+ createLoanBandsAllRanges: loan.createLoanBandsAllRanges.bind(loan),
113
+ createLoanPrices: loan.createLoanPrices.bind(loan),
114
+ createLoanPricesAllRanges: loan.createLoanPricesAllRanges.bind(loan),
115
+ createLoanHealth: loan.createLoanHealth.bind(loan),
116
+ createLoanIsApproved: loan.createLoanIsApproved.bind(loan),
117
+ createLoanApprove: loan.createLoanApprove.bind(loan),
118
+ createLoan: loan.createLoan.bind(loan),
119
+ borrowMoreMaxRecv: loan.borrowMoreMaxRecv.bind(loan),
120
+ borrowMoreBands: loan.borrowMoreBands.bind(loan),
121
+ borrowMorePrices: loan.borrowMorePrices.bind(loan),
122
+ borrowMoreHealth: loan.borrowMoreHealth.bind(loan),
123
+ borrowMoreIsApproved: loan.borrowMoreIsApproved.bind(loan),
124
+ borrowMoreApprove: loan.borrowMoreApprove.bind(loan),
125
+ borrowMore: loan.borrowMore.bind(loan),
126
+ borrowMoreFutureLeverage: loan.borrowMoreFutureLeverage.bind(loan),
127
+ addCollateralBands: loan.addCollateralBands.bind(loan),
128
+ addCollateralPrices: loan.addCollateralPrices.bind(loan),
129
+ addCollateralHealth: loan.addCollateralHealth.bind(loan),
130
+ addCollateralIsApproved: loan.addCollateralIsApproved.bind(loan),
131
+ addCollateralApprove: loan.addCollateralApprove.bind(loan),
132
+ addCollateral: loan.addCollateral.bind(loan),
133
+ addCollateralFutureLeverage: loan.addCollateralFutureLeverage.bind(loan),
134
+ maxRemovable: loan.maxRemovable.bind(loan),
135
+ removeCollateralBands: loan.removeCollateralBands.bind(loan),
136
+ removeCollateralPrices: loan.removeCollateralPrices.bind(loan),
137
+ removeCollateralHealth: loan.removeCollateralHealth.bind(loan),
138
+ removeCollateral: loan.removeCollateral.bind(loan),
139
+ removeCollateralFutureLeverage: loan.removeCollateralFutureLeverage.bind(loan),
140
+ repayBands: loan.repayBands.bind(loan),
141
+ repayPrices: loan.repayPrices.bind(loan),
142
+ repayIsApproved: loan.repayIsApproved.bind(loan),
143
+ repayApprove: loan.repayApprove.bind(loan),
144
+ repayHealth: loan.repayHealth.bind(loan),
145
+ repay: loan.repay.bind(loan),
146
+ repayFutureLeverage: loan.repayFutureLeverage.bind(loan),
147
+ fullRepayIsApproved: loan.fullRepayIsApproved.bind(loan),
148
+ fullRepayApprove: loan.fullRepayApprove.bind(loan),
149
+ fullRepay: loan.fullRepay.bind(loan),
150
+ tokensToLiquidate: loan.tokensToLiquidate.bind(loan),
151
+ calcPartialFrac: loan.calcPartialFrac.bind(loan),
152
+ liquidateIsApproved: loan.liquidateIsApproved.bind(loan),
153
+ liquidateApprove: loan.liquidateApprove.bind(loan),
154
+ liquidate: loan.liquidate.bind(loan),
155
+ selfLiquidateIsApproved: loan.selfLiquidateIsApproved.bind(loan),
156
+ selfLiquidateApprove: loan.selfLiquidateApprove.bind(loan),
157
+ selfLiquidate: loan.selfLiquidate.bind(loan),
158
+ partialSelfLiquidateIsApproved: loan.partialSelfLiquidateIsApproved.bind(loan),
159
+ partialSelfLiquidateApprove: loan.partialSelfLiquidateApprove.bind(loan),
160
+ partialSelfLiquidate: loan.partialSelfLiquidate.bind(loan),
161
+ estimateGas: {
162
+ createLoan: loan.createLoanEstimateGas.bind(loan),
163
+ borrowMore: loan.borrowMoreEstimateGas.bind(loan),
164
+ addCollateral: loan.addCollateralEstimateGas.bind(loan),
165
+ removeCollateral: loan.removeCollateralEstimateGas.bind(loan),
166
+ repay: loan.repayEstimateGas.bind(loan),
167
+ fullRepay: loan.fullRepayEstimateGas.bind(loan),
168
+ liquidate: loan.liquidateEstimateGas.bind(loan),
169
+ selfLiquidate: loan.selfLiquidateEstimateGas.bind(loan),
170
+ partialSelfLiquidate: loan.partialSelfLiquidateEstimateGas.bind(loan),
171
+ },
535
172
  };
536
173
  this.vault = {
537
- maxDeposit: this.vaultMaxDeposit.bind(this),
538
- previewDeposit: this.vaultPreviewDeposit.bind(this),
539
- depositIsApproved: this.vaultDepositIsApproved.bind(this),
540
- depositApprove: this.vaultDepositApprove.bind(this),
541
- deposit: this.vaultDeposit.bind(this),
542
- maxMint: this.vaultMaxMint.bind(this),
543
- previewMint: this.vaultPreviewMint.bind(this),
544
- mintIsApproved: this.vaultMintIsApproved.bind(this),
545
- mintApprove: this.vaultMintApprove.bind(this),
546
- mint: this.vaultMint.bind(this),
547
- maxWithdraw: this.vaultMaxWithdraw.bind(this),
548
- previewWithdraw: this.vaultPreviewWithdraw.bind(this),
549
- withdraw: this.vaultWithdraw.bind(this),
550
- maxRedeem: this.vaultMaxRedeem.bind(this),
551
- previewRedeem: this.vaultPreviewRedeem.bind(this),
552
- redeem: this.vaultRedeem.bind(this),
553
- convertToShares: this.vaultConvertToShares.bind(this),
554
- convertToAssets: this.vaultConvertToAssets.bind(this),
555
- stakeIsApproved: this.vaultStakeIsApproved.bind(this),
556
- stakeApprove: this.vaultStakeApprove.bind(this),
557
- stake: this.vaultStake.bind(this),
558
- unstake: this.vaultUnstake.bind(this),
559
- rewardsOnly: this.vaultRewardsOnly.bind(this),
560
- totalLiquidity: this.vaultTotalLiquidity.bind(this),
561
- crvApr: this.vaultCrvApr.bind(this),
562
- claimableCrv: this.vaultClaimableCrv.bind(this),
563
- claimCrv: this.vaultClaimCrv.bind(this),
564
- rewardTokens: this.vaultRewardTokens.bind(this),
565
- rewardsApr: this.vaultRewardsApr.bind(this),
566
- claimableRewards: this.vaultClaimableRewards.bind(this),
567
- claimRewards: this.vaultClaimRewards.bind(this),
174
+ maxDeposit: vault.vaultMaxDeposit.bind(vault),
175
+ previewDeposit: vault.vaultPreviewDeposit.bind(vault),
176
+ depositIsApproved: vault.vaultDepositIsApproved.bind(vault),
177
+ depositApprove: vault.vaultDepositApprove.bind(vault),
178
+ deposit: vault.vaultDeposit.bind(vault),
179
+ maxMint: vault.vaultMaxMint.bind(vault),
180
+ previewMint: vault.vaultPreviewMint.bind(vault),
181
+ mintIsApproved: vault.vaultMintIsApproved.bind(vault),
182
+ mintApprove: vault.vaultMintApprove.bind(vault),
183
+ mint: vault.vaultMint.bind(vault),
184
+ maxWithdraw: vault.vaultMaxWithdraw.bind(vault),
185
+ previewWithdraw: vault.vaultPreviewWithdraw.bind(vault),
186
+ withdraw: vault.vaultWithdraw.bind(vault),
187
+ maxRedeem: vault.vaultMaxRedeem.bind(vault),
188
+ previewRedeem: vault.vaultPreviewRedeem.bind(vault),
189
+ redeem: vault.vaultRedeem.bind(vault),
190
+ convertToShares: vault.vaultConvertToShares.bind(vault),
191
+ convertToAssets: vault.vaultConvertToAssets.bind(vault),
192
+ stakeIsApproved: vault.vaultStakeIsApproved.bind(vault),
193
+ stakeApprove: vault.vaultStakeApprove.bind(vault),
194
+ stake: vault.vaultStake.bind(vault),
195
+ unstake: vault.vaultUnstake.bind(vault),
196
+ rewardsOnly: vault.vaultRewardsOnly.bind(vault),
197
+ totalLiquidity: vault.vaultTotalLiquidity.bind(vault),
198
+ crvApr: vault.vaultCrvApr.bind(vault),
199
+ claimableCrv: vault.vaultClaimableCrv.bind(vault),
200
+ claimCrv: vault.vaultClaimCrv.bind(vault),
201
+ rewardTokens: vault.vaultRewardTokens.bind(vault),
202
+ rewardsApr: vault.vaultRewardsApr.bind(vault),
203
+ claimableRewards: vault.vaultClaimableRewards.bind(vault),
204
+ claimRewards: vault.vaultClaimRewards.bind(vault),
568
205
  estimateGas: {
569
- depositApprove: this.vaultDepositApproveEstimateGas.bind(this),
570
- deposit: this.vaultDepositEstimateGas.bind(this),
571
- mintApprove: this.vaultMintApproveEstimateGas.bind(this),
572
- mint: this.vaultMintEstimateGas.bind(this),
573
- withdraw: this.vaultWithdrawEstimateGas.bind(this),
574
- redeem: this.vaultRedeemEstimateGas.bind(this),
575
- stakeApprove: this.vaultStakeApproveEstimateGas.bind(this),
576
- stake: this.vaultStakeEstimateGas.bind(this),
577
- unstake: this.vaultUnstakeEstimateGas.bind(this),
578
- claimCrv: this.vaultClaimCrvEstimateGas.bind(this),
579
- claimRewards: this.vaultClaimRewardsEstimateGas.bind(this),
206
+ depositApprove: vault.vaultDepositApproveEstimateGas.bind(vault),
207
+ deposit: vault.vaultDepositEstimateGas.bind(vault),
208
+ mintApprove: vault.vaultMintApproveEstimateGas.bind(vault),
209
+ mint: vault.vaultMintEstimateGas.bind(vault),
210
+ withdraw: vault.vaultWithdrawEstimateGas.bind(vault),
211
+ redeem: vault.vaultRedeemEstimateGas.bind(vault),
212
+ stakeApprove: vault.vaultStakeApproveEstimateGas.bind(vault),
213
+ stake: vault.vaultStakeEstimateGas.bind(vault),
214
+ unstake: vault.vaultUnstakeEstimateGas.bind(vault),
215
+ claimCrv: vault.vaultClaimCrvEstimateGas.bind(vault),
216
+ claimRewards: vault.vaultClaimRewardsEstimateGas.bind(vault),
580
217
  },
581
218
  };
582
219
  this.leverage = {
583
- hasLeverage: this.hasLeverage.bind(this),
584
- maxLeverage: this.maxLeverage.bind(this),
585
- createLoanMaxRecv: this.leverageCreateLoanMaxRecv.bind(this),
586
- createLoanMaxRecvAllRanges: this.leverageCreateLoanMaxRecvAllRanges.bind(this),
587
- createLoanExpectedCollateral: this.leverageCreateLoanExpectedCollateral.bind(this),
588
- createLoanPriceImpact: this.leverageCreateLoanPriceImpact.bind(this),
589
- createLoanMaxRange: this.leverageCreateLoanMaxRange.bind(this),
590
- createLoanBands: this.leverageCreateLoanBands.bind(this),
591
- createLoanBandsAllRanges: this.leverageCreateLoanBandsAllRanges.bind(this),
592
- createLoanPrices: this.leverageCreateLoanPrices.bind(this),
593
- createLoanPricesAllRanges: this.leverageCreateLoanPricesAllRanges.bind(this),
594
- createLoanHealth: this.leverageCreateLoanHealth.bind(this),
595
- createLoanIsApproved: this.leverageCreateLoanIsApproved.bind(this),
596
- createLoanApprove: this.leverageCreateLoanApprove.bind(this),
597
- createLoanRouteImage: this.leverageCreateLoanRouteImage.bind(this),
598
- createLoan: this.leverageCreateLoan.bind(this),
599
- borrowMoreMaxRecv: this.leverageBorrowMoreMaxRecv.bind(this),
600
- borrowMoreExpectedCollateral: this.leverageBorrowMoreExpectedCollateral.bind(this),
601
- borrowMorePriceImpact: this.leverageBorrowMorePriceImpact.bind(this),
602
- borrowMoreBands: this.leverageBorrowMoreBands.bind(this),
603
- borrowMorePrices: this.leverageBorrowMorePrices.bind(this),
604
- borrowMoreHealth: this.leverageBorrowMoreHealth.bind(this),
605
- borrowMoreIsApproved: this.leverageCreateLoanIsApproved.bind(this),
606
- borrowMoreApprove: this.leverageCreateLoanApprove.bind(this),
607
- borrowMoreRouteImage: this.leverageBorrowMoreRouteImage.bind(this),
608
- borrowMore: this.leverageBorrowMore.bind(this),
609
- borrowMoreFutureLeverage: this.leverageBorrowMoreFutureLeverage.bind(this),
610
- repayExpectedBorrowed: this.leverageRepayExpectedBorrowed.bind(this),
611
- repayPriceImpact: this.leverageRepayPriceImpact.bind(this),
612
- repayIsFull: this.leverageRepayIsFull.bind(this),
613
- repayIsAvailable: this.leverageRepayIsAvailable.bind(this),
614
- repayBands: this.leverageRepayBands.bind(this),
615
- repayPrices: this.leverageRepayPrices.bind(this),
616
- repayHealth: this.leverageRepayHealth.bind(this),
617
- repayIsApproved: this.leverageRepayIsApproved.bind(this),
618
- repayApprove: this.leverageRepayApprove.bind(this),
619
- repayRouteImage: this.leverageRepayRouteImage.bind(this),
620
- repay: this.leverageRepay.bind(this),
621
- repayFutureLeverage: this.leverageRepayFutureLeverage.bind(this),
220
+ hasLeverage: leverageZapV1.hasLeverage.bind(leverageZapV1),
221
+ maxLeverage: leverageZapV1.maxLeverage.bind(leverageZapV1),
222
+ createLoanMaxRecv: leverageZapV1.leverageCreateLoanMaxRecv.bind(leverageZapV1),
223
+ createLoanMaxRecvAllRanges: leverageZapV1.leverageCreateLoanMaxRecvAllRanges.bind(leverageZapV1),
224
+ createLoanExpectedCollateral: leverageZapV1.leverageCreateLoanExpectedCollateral.bind(leverageZapV1),
225
+ createLoanPriceImpact: leverageZapV1.leverageCreateLoanPriceImpact.bind(leverageZapV1),
226
+ createLoanMaxRange: leverageZapV1.leverageCreateLoanMaxRange.bind(leverageZapV1),
227
+ createLoanBands: leverageZapV1.leverageCreateLoanBands.bind(leverageZapV1),
228
+ createLoanBandsAllRanges: leverageZapV1.leverageCreateLoanBandsAllRanges.bind(leverageZapV1),
229
+ createLoanPrices: leverageZapV1.leverageCreateLoanPrices.bind(leverageZapV1),
230
+ createLoanPricesAllRanges: leverageZapV1.leverageCreateLoanPricesAllRanges.bind(leverageZapV1),
231
+ createLoanHealth: leverageZapV1.leverageCreateLoanHealth.bind(leverageZapV1),
232
+ createLoanIsApproved: leverageZapV1.leverageCreateLoanIsApproved.bind(leverageZapV1),
233
+ createLoanApprove: leverageZapV1.leverageCreateLoanApprove.bind(leverageZapV1),
234
+ createLoanRouteImage: leverageZapV1.leverageCreateLoanRouteImage.bind(leverageZapV1),
235
+ createLoan: leverageZapV1.leverageCreateLoan.bind(leverageZapV1),
236
+ borrowMoreMaxRecv: leverageZapV1.leverageBorrowMoreMaxRecv.bind(leverageZapV1),
237
+ borrowMoreExpectedCollateral: leverageZapV1.leverageBorrowMoreExpectedCollateral.bind(leverageZapV1),
238
+ borrowMorePriceImpact: leverageZapV1.leverageBorrowMorePriceImpact.bind(leverageZapV1),
239
+ borrowMoreBands: leverageZapV1.leverageBorrowMoreBands.bind(leverageZapV1),
240
+ borrowMorePrices: leverageZapV1.leverageBorrowMorePrices.bind(leverageZapV1),
241
+ borrowMoreHealth: leverageZapV1.leverageBorrowMoreHealth.bind(leverageZapV1),
242
+ borrowMoreIsApproved: leverageZapV1.leverageCreateLoanIsApproved.bind(leverageZapV1),
243
+ borrowMoreApprove: leverageZapV1.leverageCreateLoanApprove.bind(leverageZapV1),
244
+ borrowMoreRouteImage: leverageZapV1.leverageBorrowMoreRouteImage.bind(leverageZapV1),
245
+ borrowMore: leverageZapV1.leverageBorrowMore.bind(leverageZapV1),
246
+ repayExpectedBorrowed: leverageZapV1.leverageRepayExpectedBorrowed.bind(leverageZapV1),
247
+ repayPriceImpact: leverageZapV1.leverageRepayPriceImpact.bind(leverageZapV1),
248
+ repayIsFull: leverageZapV1.leverageRepayIsFull.bind(leverageZapV1),
249
+ repayIsAvailable: leverageZapV1.leverageRepayIsAvailable.bind(leverageZapV1),
250
+ repayBands: leverageZapV1.leverageRepayBands.bind(leverageZapV1),
251
+ repayPrices: leverageZapV1.leverageRepayPrices.bind(leverageZapV1),
252
+ repayHealth: leverageZapV1.leverageRepayHealth.bind(leverageZapV1),
253
+ repayIsApproved: leverageZapV1.leverageRepayIsApproved.bind(leverageZapV1),
254
+ repayApprove: leverageZapV1.leverageRepayApprove.bind(leverageZapV1),
255
+ repayRouteImage: leverageZapV1.leverageRepayRouteImage.bind(leverageZapV1),
256
+ repay: leverageZapV1.leverageRepay.bind(leverageZapV1),
622
257
  estimateGas: {
623
- createLoanApprove: this.leverageCreateLoanApproveEstimateGas.bind(this),
624
- createLoan: this.leverageCreateLoanEstimateGas.bind(this),
625
- borrowMoreApprove: this.leverageCreateLoanApproveEstimateGas.bind(this),
626
- borrowMore: this.leverageBorrowMoreEstimateGas.bind(this),
627
- repayApprove: this.leverageRepayApproveEstimateGas.bind(this),
628
- repay: this.leverageRepayEstimateGas.bind(this),
258
+ createLoanApprove: leverageZapV1.leverageCreateLoanApproveEstimateGas.bind(leverageZapV1),
259
+ createLoan: leverageZapV1.leverageCreateLoanEstimateGas.bind(leverageZapV1),
260
+ borrowMoreApprove: leverageZapV1.leverageCreateLoanApproveEstimateGas.bind(leverageZapV1),
261
+ borrowMore: leverageZapV1.leverageBorrowMoreEstimateGas.bind(leverageZapV1),
262
+ repayApprove: leverageZapV1.leverageRepayApproveEstimateGas.bind(leverageZapV1),
263
+ repay: leverageZapV1.leverageRepayEstimateGas.bind(leverageZapV1),
629
264
  },
630
265
  };
631
- const leverageZapV2 = new LeverageZapV2Module(this);
632
266
  this.leverageZapV2 = {
633
267
  hasLeverage: leverageZapV2.hasLeverage.bind(leverageZapV2),
634
268
  maxLeverage: leverageZapV2.maxLeverage.bind(leverageZapV2),
@@ -668,2263 +302,6 @@ export class LendMarketTemplate {
668
302
  },
669
303
  };
670
304
  }
671
- // ---------------- VAULT ----------------
672
- vaultMaxDeposit() {
673
- return __awaiter(this, arguments, void 0, function* (address = "") {
674
- address = _getAddress.call(this.llamalend, address);
675
- // const _amount = await this.llamalend.contracts[this.addresses.vault].contract.maxDeposit(address); TODO use maxDeposit
676
- const _amount = yield this.llamalend.contracts[this.addresses.borrowed_token].contract.balanceOf(address);
677
- return formatUnits(_amount, this.borrowed_token.decimals);
678
- });
679
- }
680
- vaultPreviewDeposit(amount) {
681
- return __awaiter(this, void 0, void 0, function* () {
682
- const _amount = parseUnits(amount, this.borrowed_token.decimals);
683
- const _shares = yield this.llamalend.contracts[this.addresses.vault].contract.previewDeposit(_amount);
684
- return formatUnits(_shares, 18);
685
- });
686
- }
687
- vaultDepositIsApproved(borrowed) {
688
- return __awaiter(this, void 0, void 0, function* () {
689
- return yield hasAllowance.call(this.llamalend, [this.borrowed_token.address], [borrowed], this.llamalend.signerAddress, this.addresses.vault);
690
- });
691
- }
692
- vaultDepositApproveEstimateGas(borrowed) {
693
- return __awaiter(this, void 0, void 0, function* () {
694
- return yield ensureAllowanceEstimateGas.call(this.llamalend, [this.borrowed_token.address], [borrowed], this.addresses.vault);
695
- });
696
- }
697
- vaultDepositApprove(borrowed) {
698
- return __awaiter(this, void 0, void 0, function* () {
699
- return yield ensureAllowance.call(this.llamalend, [this.borrowed_token.address], [borrowed], this.addresses.vault);
700
- });
701
- }
702
- _vaultDeposit(amount_1) {
703
- return __awaiter(this, arguments, void 0, function* (amount, estimateGas = false) {
704
- const _amount = parseUnits(amount, this.borrowed_token.decimals);
705
- const gas = yield this.llamalend.contracts[this.addresses.vault].contract.deposit.estimateGas(_amount, Object.assign({}, this.llamalend.constantOptions));
706
- if (estimateGas)
707
- return smartNumber(gas);
708
- yield this.llamalend.updateFeeData();
709
- const gasLimit = _mulBy1_3(DIGas(gas));
710
- return (yield this.llamalend.contracts[this.addresses.vault].contract.deposit(_amount, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
711
- });
712
- }
713
- vaultDepositEstimateGas(amount) {
714
- return __awaiter(this, void 0, void 0, function* () {
715
- if (!(yield this.vaultDepositIsApproved(amount)))
716
- throw Error("Approval is needed for gas estimation");
717
- return yield this._vaultDeposit(amount, true);
718
- });
719
- }
720
- vaultDeposit(amount) {
721
- return __awaiter(this, void 0, void 0, function* () {
722
- yield this.vaultDepositApprove(amount);
723
- return yield this._vaultDeposit(amount, false);
724
- });
725
- }
726
- vaultMaxMint() {
727
- return __awaiter(this, arguments, void 0, function* (address = "") {
728
- address = _getAddress.call(this.llamalend, address);
729
- // const _shares = await this.llamalend.contracts[this.addresses.vault].contract.maxMint(address); TODO use maxMint
730
- const _assetBalance = yield this.llamalend.contracts[this.addresses.borrowed_token].contract.balanceOf(address);
731
- const _shares = yield this.llamalend.contracts[this.addresses.vault].contract.convertToShares(_assetBalance);
732
- return formatUnits(_shares, 18);
733
- });
734
- }
735
- vaultPreviewMint(amount) {
736
- return __awaiter(this, void 0, void 0, function* () {
737
- const _amount = parseUnits(amount, 18);
738
- const _assets = yield this.llamalend.contracts[this.addresses.vault].contract.previewMint(_amount);
739
- return formatUnits(_assets, this.borrowed_token.decimals);
740
- });
741
- }
742
- vaultMintIsApproved(borrowed) {
743
- return __awaiter(this, void 0, void 0, function* () {
744
- return yield hasAllowance.call(this.llamalend, [this.borrowed_token.address], [borrowed], this.llamalend.signerAddress, this.addresses.vault);
745
- });
746
- }
747
- vaultMintApproveEstimateGas(borrowed) {
748
- return __awaiter(this, void 0, void 0, function* () {
749
- return yield ensureAllowanceEstimateGas.call(this.llamalend, [this.borrowed_token.address], [borrowed], this.addresses.vault);
750
- });
751
- }
752
- vaultMintApprove(borrowed) {
753
- return __awaiter(this, void 0, void 0, function* () {
754
- return yield ensureAllowance.call(this.llamalend, [this.borrowed_token.address], [borrowed], this.addresses.vault);
755
- });
756
- }
757
- _vaultMint(amount_1) {
758
- return __awaiter(this, arguments, void 0, function* (amount, estimateGas = false) {
759
- const _amount = parseUnits(amount, 18);
760
- const gas = yield this.llamalend.contracts[this.addresses.vault].contract.mint.estimateGas(_amount, Object.assign({}, this.llamalend.constantOptions));
761
- if (estimateGas)
762
- return smartNumber(gas);
763
- yield this.llamalend.updateFeeData();
764
- const gasLimit = _mulBy1_3(DIGas(gas));
765
- return (yield this.llamalend.contracts[this.addresses.vault].contract.mint(_amount, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
766
- });
767
- }
768
- vaultMintEstimateGas(amount) {
769
- return __awaiter(this, void 0, void 0, function* () {
770
- if (!(yield this.vaultMintIsApproved(amount)))
771
- throw Error("Approval is needed for gas estimation");
772
- return yield this._vaultMint(amount, true);
773
- });
774
- }
775
- vaultMint(amount) {
776
- return __awaiter(this, void 0, void 0, function* () {
777
- yield this.vaultMintApprove(amount);
778
- return yield this._vaultMint(amount, false);
779
- });
780
- }
781
- vaultMaxWithdraw() {
782
- return __awaiter(this, arguments, void 0, function* (address = "") {
783
- address = _getAddress.call(this.llamalend, address);
784
- const _assets = yield this.llamalend.contracts[this.addresses.vault].contract.maxWithdraw(address);
785
- return formatUnits(_assets, this.borrowed_token.decimals);
786
- });
787
- }
788
- vaultPreviewWithdraw(amount) {
789
- return __awaiter(this, void 0, void 0, function* () {
790
- const _amount = parseUnits(amount, this.borrowed_token.decimals);
791
- const _shares = yield this.llamalend.contracts[this.addresses.vault].contract.previewWithdraw(_amount);
792
- return formatUnits(_shares, 18);
793
- });
794
- }
795
- _vaultWithdraw(amount_1) {
796
- return __awaiter(this, arguments, void 0, function* (amount, estimateGas = false) {
797
- const _amount = parseUnits(amount, this.borrowed_token.decimals);
798
- const gas = yield this.llamalend.contracts[this.addresses.vault].contract.withdraw.estimateGas(_amount, Object.assign({}, this.llamalend.constantOptions));
799
- if (estimateGas)
800
- return smartNumber(gas);
801
- yield this.llamalend.updateFeeData();
802
- const gasLimit = _mulBy1_3(DIGas(gas));
803
- return (yield this.llamalend.contracts[this.addresses.vault].contract.withdraw(_amount, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
804
- });
805
- }
806
- vaultWithdrawEstimateGas(amount) {
807
- return __awaiter(this, void 0, void 0, function* () {
808
- return yield this._vaultWithdraw(amount, true);
809
- });
810
- }
811
- vaultWithdraw(amount) {
812
- return __awaiter(this, void 0, void 0, function* () {
813
- return yield this._vaultWithdraw(amount, false);
814
- });
815
- }
816
- vaultMaxRedeem() {
817
- return __awaiter(this, arguments, void 0, function* (address = "") {
818
- address = _getAddress.call(this.llamalend, address);
819
- const _shares = yield this.llamalend.contracts[this.addresses.vault].contract.maxRedeem(address);
820
- return formatUnits(_shares, 18);
821
- });
822
- }
823
- vaultPreviewRedeem(amount) {
824
- return __awaiter(this, void 0, void 0, function* () {
825
- const _amount = parseUnits(amount, 18);
826
- const _assets = yield this.llamalend.contracts[this.addresses.vault].contract.previewRedeem(_amount);
827
- return formatUnits(_assets, this.borrowed_token.decimals);
828
- });
829
- }
830
- _vaultRedeem(amount_1) {
831
- return __awaiter(this, arguments, void 0, function* (amount, estimateGas = false) {
832
- const _amount = parseUnits(amount, 18);
833
- const gas = yield this.llamalend.contracts[this.addresses.vault].contract.redeem.estimateGas(_amount, Object.assign({}, this.llamalend.constantOptions));
834
- if (estimateGas)
835
- return smartNumber(gas);
836
- yield this.llamalend.updateFeeData();
837
- const gasLimit = _mulBy1_3(DIGas(gas));
838
- return (yield this.llamalend.contracts[this.addresses.vault].contract.redeem(_amount, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
839
- });
840
- }
841
- vaultRedeemEstimateGas(amount) {
842
- return __awaiter(this, void 0, void 0, function* () {
843
- return yield this._vaultRedeem(amount, true);
844
- });
845
- }
846
- vaultRedeem(amount) {
847
- return __awaiter(this, void 0, void 0, function* () {
848
- return yield this._vaultRedeem(amount, false);
849
- });
850
- }
851
- // ---------------- VAULT UTILS ----------------
852
- vaultConvertToShares(assets) {
853
- return __awaiter(this, void 0, void 0, function* () {
854
- const _assets = parseUnits(assets, this.borrowed_token.decimals);
855
- const _shares = yield this.llamalend.contracts[this.addresses.vault].contract.convertToShares(_assets);
856
- return this.llamalend.formatUnits(_shares);
857
- });
858
- }
859
- vaultConvertToAssets(shares) {
860
- return __awaiter(this, void 0, void 0, function* () {
861
- const _shares = parseUnits(shares);
862
- const _assets = yield this.llamalend.contracts[this.addresses.vault].contract.convertToAssets(_shares);
863
- return this.llamalend.formatUnits(_assets, this.borrowed_token.decimals);
864
- });
865
- }
866
- // ---------------- VAULT STAKING ----------------
867
- vaultStakeIsApproved(vaultShares) {
868
- return __awaiter(this, void 0, void 0, function* () {
869
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS) {
870
- throw Error(`stakeIsApproved method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
871
- }
872
- return yield hasAllowance.call(this.llamalend, [this.addresses.vault], [vaultShares], this.llamalend.signerAddress, this.addresses.gauge);
873
- });
874
- }
875
- vaultStakeApproveEstimateGas(vaultShares) {
876
- return __awaiter(this, void 0, void 0, function* () {
877
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS) {
878
- throw Error(`stakeApproveEstimateGas method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
879
- }
880
- return yield ensureAllowanceEstimateGas.call(this.llamalend, [this.addresses.vault], [vaultShares], this.addresses.gauge);
881
- });
882
- }
883
- vaultStakeApprove(vaultShares) {
884
- return __awaiter(this, void 0, void 0, function* () {
885
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS) {
886
- throw Error(`stakeApprove method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
887
- }
888
- return yield ensureAllowance.call(this.llamalend, [this.addresses.vault], [vaultShares], this.addresses.gauge);
889
- });
890
- }
891
- vaultStakeEstimateGas(vaultShares) {
892
- return __awaiter(this, void 0, void 0, function* () {
893
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS) {
894
- throw Error(`stakeEstimateGas method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
895
- }
896
- const _vaultShares = parseUnits(vaultShares);
897
- return smartNumber(yield this.llamalend.contracts[this.addresses.gauge].contract.deposit.estimateGas(_vaultShares, this.llamalend.constantOptions));
898
- });
899
- }
900
- vaultStake(vaultShares) {
901
- return __awaiter(this, void 0, void 0, function* () {
902
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS) {
903
- throw Error(`stake method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
904
- }
905
- const _vaultShares = parseUnits(vaultShares);
906
- yield _ensureAllowance.call(this.llamalend, [this.addresses.vault], [_vaultShares], this.addresses.gauge);
907
- yield this.llamalend.updateFeeData();
908
- const gasLimit = _mulBy1_3(DIGas(yield this.llamalend.contracts[this.addresses.gauge].contract.deposit.estimateGas(_vaultShares, this.llamalend.constantOptions)));
909
- return (yield this.llamalend.contracts[this.addresses.gauge].contract.deposit(_vaultShares, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
910
- });
911
- }
912
- vaultUnstakeEstimateGas(vaultShares) {
913
- return __awaiter(this, void 0, void 0, function* () {
914
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS) {
915
- throw Error(`unstakeEstimateGas method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
916
- }
917
- const _vaultShares = parseUnits(vaultShares);
918
- return smartNumber(yield this.llamalend.contracts[this.addresses.gauge].contract.withdraw.estimateGas(_vaultShares, this.llamalend.constantOptions));
919
- });
920
- }
921
- vaultUnstake(vaultShares) {
922
- return __awaiter(this, void 0, void 0, function* () {
923
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS) {
924
- throw Error(`unstake method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
925
- }
926
- const _vaultShares = parseUnits(vaultShares);
927
- yield this.llamalend.updateFeeData();
928
- const gasLimit = _mulBy1_3(DIGas((yield this.llamalend.contracts[this.addresses.gauge].contract.withdraw.estimateGas(_vaultShares, this.llamalend.constantOptions))));
929
- return (yield this.llamalend.contracts[this.addresses.gauge].contract.withdraw(_vaultShares, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
930
- });
931
- }
932
- // ---------------- VAULT STAKING REWARDS ----------------
933
- vaultRewardsOnly() {
934
- if (this.llamalend.chainId === 2222 || this.llamalend.chainId === 324)
935
- return true; // TODO remove this for Kava and ZkSync
936
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS)
937
- throw Error(`${this.name} doesn't have gauge`);
938
- const gaugeContract = this.llamalend.contracts[this.addresses.gauge].contract;
939
- return !('inflation_rate()' in gaugeContract || 'inflation_rate(uint256)' in gaugeContract);
940
- }
941
- vaultTotalLiquidity() {
942
- return __awaiter(this, arguments, void 0, function* (useAPI = true) {
943
- const { cap } = yield this.statsCapAndAvailable(true, useAPI);
944
- const price = yield _getUsdRate.call(this.llamalend, this.addresses.borrowed_token);
945
- return BN(cap).times(price).toFixed(6);
946
- });
947
- }
948
- vaultCrvApr() {
949
- return __awaiter(this, void 0, void 0, function* () {
950
- if (this.vaultRewardsOnly())
951
- throw Error(`${this.name} has Rewards-Only Gauge. Use stats.rewardsApy instead`);
952
- // const isDisabledChain = [1313161554].includes(this.llamalend.chainId); // Disable Aurora
953
- // if (useApi && !isDisabledChain) {
954
- // const crvAPYs = await _getCrvApyFromApi();
955
- // const poolCrvApy = crvAPYs[this.addresses.gauge] ?? [0, 0]; // new pools might be missing
956
- // return [poolCrvApy[0], poolCrvApy[1]];
957
- // }
958
- return yield this._calcCrvApr();
959
- });
960
- }
961
- vaultClaimableCrv() {
962
- return __awaiter(this, arguments, void 0, function* (address = "") {
963
- if (this.vaultRewardsOnly())
964
- throw Error(`${this.name} has Rewards-Only Gauge. Use claimableRewards instead`);
965
- address = address || this.llamalend.signerAddress;
966
- if (!address)
967
- throw Error("Need to connect wallet or pass address into args");
968
- return this.llamalend.formatUnits(yield this.llamalend.contracts[this.addresses.gauge].contract.claimable_tokens(address, this.llamalend.constantOptions));
969
- });
970
- }
971
- _vaultClaimCrv(estimateGas) {
972
- return __awaiter(this, void 0, void 0, function* () {
973
- if (this.vaultRewardsOnly())
974
- throw Error(`${this.name} has Rewards-Only Gauge. Use claimRewards instead`);
975
- let isOldFactory = false;
976
- let contract;
977
- if (this.llamalend.chainId !== 1) {
978
- if (this.llamalend.constants.ALIASES.gauge_factory_old && this.llamalend.constants.ALIASES.gauge_factory_old !== this.llamalend.constants.ZERO_ADDRESS) {
979
- const oldFactoryContract = this.llamalend.contracts[this.llamalend.constants.ALIASES.gauge_factory_old].contract;
980
- const lpToken = yield this.llamalend.contracts[this.addresses.gauge].contract.lp_token();
981
- const gaugeAddress = yield oldFactoryContract.get_gauge_from_lp_token(lpToken);
982
- isOldFactory = gaugeAddress.toLowerCase() === this.addresses.gauge.toLowerCase();
983
- if (isOldFactory) {
984
- contract = oldFactoryContract;
985
- }
986
- }
987
- }
988
- if (!isOldFactory) {
989
- contract = this.llamalend.contracts[this.llamalend.constants.ALIASES.minter].contract;
990
- }
991
- if (!contract) {
992
- throw Error(`${this.name} couldn't match gauge factory`);
993
- }
994
- const gas = yield contract.mint.estimateGas(this.addresses.gauge, this.llamalend.constantOptions);
995
- if (estimateGas)
996
- return smartNumber(gas);
997
- yield this.llamalend.updateFeeData();
998
- const gasLimit = _mulBy1_3(DIGas(gas));
999
- return (yield contract.mint(this.addresses.gauge, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
1000
- });
1001
- }
1002
- vaultClaimCrvEstimateGas() {
1003
- return __awaiter(this, void 0, void 0, function* () {
1004
- return yield this._vaultClaimCrv(true);
1005
- });
1006
- }
1007
- vaultClaimCrv() {
1008
- return __awaiter(this, void 0, void 0, function* () {
1009
- return yield this._vaultClaimCrv(false);
1010
- });
1011
- }
1012
- vaultClaimableRewards() {
1013
- return __awaiter(this, arguments, void 0, function* (address = "") {
1014
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS) {
1015
- throw Error(`claimableRewards method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
1016
- }
1017
- address = address || this.llamalend.signerAddress;
1018
- if (!address)
1019
- throw Error("Need to connect wallet or pass address into args");
1020
- const gaugeContract = this.llamalend.contracts[this.addresses.gauge].contract;
1021
- const rewardTokens = yield this.vaultRewardTokens();
1022
- const rewards = [];
1023
- for (const rewardToken of rewardTokens) {
1024
- const _amount = yield gaugeContract.claimable_reward(address, rewardToken.token, this.llamalend.constantOptions);
1025
- rewards.push({
1026
- token: rewardToken.token,
1027
- symbol: rewardToken.symbol,
1028
- amount: this.llamalend.formatUnits(_amount, rewardToken.decimals),
1029
- });
1030
- }
1031
- return rewards;
1032
- });
1033
- }
1034
- _vaultClaimRewards(estimateGas) {
1035
- return __awaiter(this, void 0, void 0, function* () {
1036
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS) {
1037
- throw Error(`claimRewards method doesn't exist for pool ${this.name} (id: ${this.name}). There is no gauge`);
1038
- }
1039
- const gaugeContract = this.llamalend.contracts[this.addresses.gauge].contract;
1040
- if (!("claim_rewards()" in gaugeContract))
1041
- throw Error(`${this.name} pool doesn't have such method`);
1042
- const gas = yield gaugeContract.claim_rewards.estimateGas(this.llamalend.constantOptions);
1043
- if (estimateGas)
1044
- return smartNumber(gas);
1045
- yield this.llamalend.updateFeeData();
1046
- const gasLimit = _mulBy1_3(DIGas(gas));
1047
- return (yield gaugeContract.claim_rewards(Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
1048
- });
1049
- }
1050
- vaultClaimRewardsEstimateGas() {
1051
- return __awaiter(this, void 0, void 0, function* () {
1052
- return yield this._vaultClaimRewards(true);
1053
- });
1054
- }
1055
- vaultClaimRewards() {
1056
- return __awaiter(this, void 0, void 0, function* () {
1057
- return yield this._vaultClaimRewards(false);
1058
- });
1059
- }
1060
- statsRates() {
1061
- return __awaiter(this, arguments, void 0, function* (isGetter = true, useAPI = false) {
1062
- if (useAPI) {
1063
- const response = yield _getMarketsData(this.llamalend.constants.NETWORK_NAME);
1064
- const market = response.lendingVaultData.find((item) => item.address.toLowerCase() === this.addresses.vault.toLowerCase());
1065
- if (market) {
1066
- return {
1067
- borrowApr: (market.rates.borrowApr * 100).toString(),
1068
- lendApr: (market.rates.lendApr * 100).toString(),
1069
- borrowApy: (market.rates.borrowApy * 100).toString(),
1070
- lendApy: (market.rates.lendApy * 100).toString(),
1071
- };
1072
- }
1073
- else {
1074
- throw new Error('Market not found in API');
1075
- }
1076
- }
1077
- else {
1078
- const _rate = yield this._getRate(isGetter);
1079
- const borrowApr = toBN(_rate).times(365).times(86400).times(100).toString();
1080
- // borrowApy = e**(rate*365*86400) - 1
1081
- const borrowApy = String(((Math.pow(2.718281828459, (toBN(_rate).times(365).times(86400)).toNumber())) - 1) * 100);
1082
- let lendApr = "0";
1083
- let lendApy = "0";
1084
- const debt = yield this.statsTotalDebt(isGetter);
1085
- if (Number(debt) > 0) {
1086
- const { cap } = yield this.statsCapAndAvailable(isGetter);
1087
- lendApr = toBN(_rate).times(365).times(86400).times(debt).div(cap).times(100).toString();
1088
- // lendApy = (debt * e**(rate*365*86400) - debt) / cap
1089
- const debtInAYearBN = BN(debt).times(Math.pow(2.718281828459, (toBN(_rate).times(365).times(86400)).toNumber()));
1090
- lendApy = debtInAYearBN.minus(debt).div(cap).times(100).toString();
1091
- }
1092
- return { borrowApr, lendApr, borrowApy, lendApy };
1093
- }
1094
- });
1095
- }
1096
- statsFutureRates(dReserves_1, dDebt_1) {
1097
- return __awaiter(this, arguments, void 0, function* (dReserves, dDebt, useAPI = true) {
1098
- const _dReserves = parseUnits(dReserves, this.borrowed_token.decimals);
1099
- const _dDebt = parseUnits(dDebt, this.borrowed_token.decimals);
1100
- const _rate = yield this._getFutureRate(_dReserves, _dDebt);
1101
- const borrowApr = toBN(_rate).times(365).times(86400).times(100).toString();
1102
- // borrowApy = e**(rate*365*86400) - 1
1103
- const borrowApy = String(((Math.pow(2.718281828459, (toBN(_rate).times(365).times(86400)).toNumber())) - 1) * 100);
1104
- let lendApr = "0";
1105
- let lendApy = "0";
1106
- const debt = Number(yield this.statsTotalDebt()) + Number(dDebt);
1107
- if (Number(debt) > 0) {
1108
- const cap = Number((yield this.statsCapAndAvailable(true, useAPI)).cap) + Number(dReserves);
1109
- lendApr = toBN(_rate).times(365).times(86400).times(debt).div(cap).times(100).toString();
1110
- // lendApy = (debt * e**(rate*365*86400) - debt) / cap
1111
- const debtInAYearBN = BN(debt).times(Math.pow(2.718281828459, (toBN(_rate).times(365).times(86400)).toNumber()));
1112
- lendApy = debtInAYearBN.minus(debt).div(cap).times(100).toString();
1113
- }
1114
- return { borrowApr, lendApr, borrowApy, lendApy };
1115
- });
1116
- }
1117
- statsBalances() {
1118
- return __awaiter(this, void 0, void 0, function* () {
1119
- const borrowedContract = this.llamalend.contracts[this.borrowed_token.address].multicallContract;
1120
- const collateralContract = this.llamalend.contracts[this.collateral_token.address].multicallContract;
1121
- const ammContract = this.llamalend.contracts[this.addresses.amm].multicallContract;
1122
- const calls = [
1123
- borrowedContract.balanceOf(this.addresses.amm),
1124
- collateralContract.balanceOf(this.addresses.amm),
1125
- ammContract.admin_fees_x(),
1126
- ammContract.admin_fees_y(),
1127
- ];
1128
- const [_borrowedBalance, _collateralBalance, _borrowedAdminFees, _collateralAdminFees] = yield this.llamalend.multicallProvider.all(calls);
1129
- return [
1130
- formatUnits(_borrowedBalance - _borrowedAdminFees, this.borrowed_token.decimals),
1131
- formatUnits(_collateralBalance - _collateralAdminFees, this.collateral_token.decimals),
1132
- ];
1133
- });
1134
- }
1135
- statsBandBalances(n) {
1136
- return __awaiter(this, void 0, void 0, function* () {
1137
- const ammContract = this.llamalend.contracts[this.addresses.amm].multicallContract;
1138
- const calls = [];
1139
- calls.push(ammContract.bands_x(n), ammContract.bands_y(n));
1140
- const _balances = yield this.llamalend.multicallProvider.all(calls);
1141
- // bands_x and bands_y always return amounts with 18 decimals
1142
- return {
1143
- borrowed: formatNumber(formatUnits(_balances[0]), this.borrowed_token.decimals),
1144
- collateral: formatNumber(formatUnits(_balances[1]), this.collateral_token.decimals),
1145
- };
1146
- });
1147
- }
1148
- statsBandsBalances() {
1149
- return __awaiter(this, void 0, void 0, function* () {
1150
- const { maxBand, minBand } = yield this.statsBandsInfo();
1151
- const ammContract = this.llamalend.contracts[this.addresses.amm].multicallContract;
1152
- const calls = [];
1153
- for (let i = minBand; i <= maxBand; i++) {
1154
- calls.push(ammContract.bands_x(i), ammContract.bands_y(i));
1155
- }
1156
- const _bands = yield this.llamalend.multicallProvider.all(calls);
1157
- const bands = {};
1158
- for (let i = minBand; i <= maxBand; i++) {
1159
- const _i = i - minBand;
1160
- // bands_x and bands_y always return amounts with 18 decimals
1161
- bands[i] = {
1162
- borrowed: formatNumber(formatUnits(_bands[2 * _i]), this.borrowed_token.decimals),
1163
- collateral: formatNumber(formatUnits(_bands[(2 * _i) + 1]), this.collateral_token.decimals),
1164
- };
1165
- }
1166
- return bands;
1167
- });
1168
- }
1169
- statsTotalDebt() {
1170
- return __awaiter(this, arguments, void 0, function* (isGetter = true, useAPI = true) {
1171
- if (useAPI) {
1172
- const response = yield _getMarketsData(this.llamalend.constants.NETWORK_NAME);
1173
- const market = response.lendingVaultData.find((item) => item.address.toLowerCase() === this.addresses.vault.toLowerCase());
1174
- if (market) {
1175
- return market.borrowed.total.toString();
1176
- }
1177
- else {
1178
- throw new Error('Market not found in API');
1179
- }
1180
- }
1181
- else {
1182
- let _debt;
1183
- if (isGetter) {
1184
- _debt = cacheStats.get(cacheKey(this.addresses.controller, 'total_debt'));
1185
- }
1186
- else {
1187
- _debt = yield this.llamalend.contracts[this.addresses.controller].contract.total_debt(this.llamalend.constantOptions);
1188
- cacheStats.set(cacheKey(this.addresses.controller, 'total_debt'), _debt);
1189
- }
1190
- return formatUnits(_debt, this.borrowed_token.decimals);
1191
- }
1192
- });
1193
- }
1194
- statsCapAndAvailable() {
1195
- return __awaiter(this, arguments, void 0, function* (isGetter = true, useAPI = false) {
1196
- if (useAPI) {
1197
- const response = yield _getMarketsData(this.llamalend.constants.NETWORK_NAME);
1198
- const market = response.lendingVaultData.find((item) => item.address.toLowerCase() === this.addresses.vault.toLowerCase());
1199
- if (market) {
1200
- return {
1201
- cap: market.totalSupplied.total.toString(),
1202
- available: market.availableToBorrow.total.toString(),
1203
- };
1204
- }
1205
- else {
1206
- throw new Error('Market not found in API');
1207
- }
1208
- }
1209
- else {
1210
- const vaultContract = this.llamalend.contracts[this.addresses.vault].multicallContract;
1211
- const borrowedContract = this.llamalend.contracts[this.addresses.borrowed_token].multicallContract;
1212
- let _cap, _available;
1213
- if (isGetter) {
1214
- _cap = cacheStats.get(cacheKey(this.addresses.vault, 'totalAssets', this.addresses.controller));
1215
- _available = cacheStats.get(cacheKey(this.addresses.borrowed_token, 'balanceOf', this.addresses.controller));
1216
- }
1217
- else {
1218
- [_cap, _available] = yield this.llamalend.multicallProvider.all([
1219
- vaultContract.totalAssets(this.addresses.controller),
1220
- borrowedContract.balanceOf(this.addresses.controller),
1221
- ]);
1222
- cacheStats.set(cacheKey(this.addresses.vault, 'totalAssets', this.addresses.controller), _cap);
1223
- cacheStats.set(cacheKey(this.addresses.borrowed_token, 'balanceOf', this.addresses.controller), _available);
1224
- }
1225
- return {
1226
- cap: this.llamalend.formatUnits(_cap, this.borrowed_token.decimals),
1227
- available: this.llamalend.formatUnits(_available, this.borrowed_token.decimals),
1228
- };
1229
- }
1230
- });
1231
- }
1232
- oraclePriceBand() {
1233
- return __awaiter(this, void 0, void 0, function* () {
1234
- const oraclePriceBN = BN(yield this.oraclePrice());
1235
- const basePriceBN = BN(yield this.basePrice());
1236
- const A_BN = BN(yield this.A());
1237
- const multiplier = oraclePriceBN.lte(basePriceBN) ? A_BN.minus(1).div(A_BN) : A_BN.div(A_BN.minus(1));
1238
- const term = oraclePriceBN.lte(basePriceBN) ? 1 : -1;
1239
- const compareFunc = oraclePriceBN.lte(basePriceBN) ?
1240
- (oraclePriceBN, currentTickPriceBN) => oraclePriceBN.lte(currentTickPriceBN) :
1241
- (oraclePriceBN, currentTickPriceBN) => oraclePriceBN.gt(currentTickPriceBN);
1242
- let band = 0;
1243
- let currentTickPriceBN = oraclePriceBN.lte(basePriceBN) ? basePriceBN.times(multiplier) : basePriceBN;
1244
- while (compareFunc(oraclePriceBN, currentTickPriceBN)) {
1245
- currentTickPriceBN = currentTickPriceBN.times(multiplier);
1246
- band += term;
1247
- }
1248
- return band;
1249
- });
1250
- }
1251
- price() {
1252
- return __awaiter(this, void 0, void 0, function* () {
1253
- const _price = yield this.llamalend.contracts[this.addresses.amm].contract.get_p(this.llamalend.constantOptions);
1254
- return formatUnits(_price);
1255
- });
1256
- }
1257
- calcTickPrice(n) {
1258
- return __awaiter(this, void 0, void 0, function* () {
1259
- const basePrice = yield this.basePrice();
1260
- const basePriceBN = BN(basePrice);
1261
- const A_BN = BN(yield this.A());
1262
- return _cutZeros(basePriceBN.times(A_BN.minus(1).div(A_BN).pow(n)).toFixed(18));
1263
- });
1264
- }
1265
- calcBandPrices(n) {
1266
- return __awaiter(this, void 0, void 0, function* () {
1267
- return [yield this.calcTickPrice(n + 1), yield this.calcTickPrice(n)];
1268
- });
1269
- }
1270
- calcRangePct(range) {
1271
- return __awaiter(this, void 0, void 0, function* () {
1272
- const A_BN = BN(yield this.A());
1273
- const startBN = BN(1);
1274
- const endBN = A_BN.minus(1).div(A_BN).pow(range);
1275
- return startBN.minus(endBN).times(100).toFixed(6);
1276
- });
1277
- }
1278
- // ---------------- WALLET BALANCES ----------------
1279
- walletBalances() {
1280
- return __awaiter(this, arguments, void 0, function* (address = "") {
1281
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS) {
1282
- const [collateral, borrowed, vaultShares] = yield getBalances.call(this.llamalend, [this.collateral_token.address, this.borrowed_token.address, this.addresses.vault], address);
1283
- return { collateral, borrowed, vaultShares, gauge: "0" };
1284
- }
1285
- else {
1286
- const [collateral, borrowed, vaultShares, gauge] = yield getBalances.call(this.llamalend, [this.collateral_token.address, this.borrowed_token.address, this.addresses.vault, this.addresses.gauge], address);
1287
- return { collateral, borrowed, vaultShares, gauge };
1288
- }
1289
- });
1290
- }
1291
- // ---------------- USER POSITION ----------------
1292
- userLoanExists() {
1293
- return __awaiter(this, arguments, void 0, function* (address = "") {
1294
- address = _getAddress.call(this.llamalend, address);
1295
- return yield this.llamalend.contracts[this.addresses.controller].contract.loan_exists(address, this.llamalend.constantOptions);
1296
- });
1297
- }
1298
- userState() {
1299
- return __awaiter(this, arguments, void 0, function* (address = "") {
1300
- const { _collateral, _borrowed, _debt, _N } = yield this._userState(address);
1301
- return {
1302
- collateral: formatUnits(_collateral, this.collateral_token.decimals),
1303
- borrowed: formatUnits(_borrowed, this.borrowed_token.decimals),
1304
- debt: formatUnits(_debt, this.borrowed_token.decimals),
1305
- N: formatUnits(_N, 0),
1306
- };
1307
- });
1308
- }
1309
- userHealth() {
1310
- return __awaiter(this, arguments, void 0, function* (full = true, address = "") {
1311
- address = _getAddress.call(this.llamalend, address);
1312
- let _health = yield this.llamalend.contracts[this.addresses.controller].contract.health(address, full, this.llamalend.constantOptions);
1313
- _health = _health * BigInt(100);
1314
- return formatUnits(_health);
1315
- });
1316
- }
1317
- _userBands(address) {
1318
- return __awaiter(this, void 0, void 0, function* () {
1319
- address = _getAddress.call(this.llamalend, address);
1320
- const _bands = yield this.llamalend.contracts[this.addresses.amm].contract.read_user_tick_numbers(address, this.llamalend.constantOptions);
1321
- return Array.from(_bands).reverse();
1322
- });
1323
- }
1324
- userBands() {
1325
- return __awaiter(this, arguments, void 0, function* (address = "") {
1326
- return (yield this._userBands(address)).map((_t) => Number(_t));
1327
- });
1328
- }
1329
- userRange() {
1330
- return __awaiter(this, arguments, void 0, function* (address = "") {
1331
- const [n2, n1] = yield this.userBands(address);
1332
- if (n1 == n2)
1333
- return 0;
1334
- return n2 - n1 + 1;
1335
- });
1336
- }
1337
- userPrices() {
1338
- return __awaiter(this, arguments, void 0, function* (address = "") {
1339
- address = _getAddress.call(this.llamalend, address);
1340
- const _prices = yield this.llamalend.contracts[this.addresses.controller].contract.user_prices(address, this.llamalend.constantOptions);
1341
- return _prices.map((_p) => formatUnits(_p)).reverse();
1342
- });
1343
- }
1344
- userLoss() {
1345
- return __awaiter(this, arguments, void 0, function* (userAddress = "") {
1346
- userAddress = _getAddress.call(this.llamalend, userAddress);
1347
- const [userCollateral, _current_collateral_estimation] = yield Promise.all([
1348
- _getUserCollateral(this.llamalend.constants.NETWORK_NAME, this.addresses.controller, userAddress),
1349
- this.llamalend.contracts[this.addresses.amm].contract.get_y_up(userAddress),
1350
- ]);
1351
- const deposited_collateral = userCollateral.total_deposit_precise;
1352
- const current_collateral_estimation = this.llamalend.formatUnits(_current_collateral_estimation, this.collateral_token.decimals);
1353
- if (BN(deposited_collateral).lte(0)) {
1354
- return {
1355
- deposited_collateral,
1356
- current_collateral_estimation,
1357
- loss: "0.0",
1358
- loss_pct: "0.0",
1359
- };
1360
- }
1361
- const loss = BN(deposited_collateral).minus(current_collateral_estimation).toString();
1362
- const loss_pct = BN(loss).div(deposited_collateral).times(100).toString();
1363
- return {
1364
- deposited_collateral,
1365
- current_collateral_estimation,
1366
- loss,
1367
- loss_pct,
1368
- };
1369
- });
1370
- }
1371
- userBandsBalances() {
1372
- return __awaiter(this, arguments, void 0, function* (address = "") {
1373
- const [n2, n1] = yield this.userBands(address);
1374
- if (n1 == 0 && n2 == 0)
1375
- return {};
1376
- address = _getAddress.call(this.llamalend, address);
1377
- const contract = this.llamalend.contracts[this.addresses.amm].contract;
1378
- const [_borrowed, _collateral] = yield contract.get_xy(address, this.llamalend.constantOptions);
1379
- const res = {};
1380
- for (let i = n1; i <= n2; i++) {
1381
- res[i] = {
1382
- collateral: formatUnits(_collateral[i - n1], this.collateral_token.decimals),
1383
- borrowed: formatUnits(_borrowed[i - n1], this.borrowed_token.decimals),
1384
- };
1385
- }
1386
- return res;
1387
- });
1388
- }
1389
- // ---------------- CREATE LOAN ----------------
1390
- _checkRange(range) {
1391
- if (range < this.minBands)
1392
- throw Error(`range must be >= ${this.minBands}`);
1393
- if (range > this.maxBands)
1394
- throw Error(`range must be <= ${this.maxBands}`);
1395
- }
1396
- createLoanMaxRecv(collateral, range) {
1397
- return __awaiter(this, void 0, void 0, function* () {
1398
- this._checkRange(range);
1399
- const _collateral = parseUnits(collateral, this.collateral_token.decimals);
1400
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
1401
- return formatUnits(yield contract.max_borrowable(_collateral, range, 0, this.llamalend.constantOptions), this.borrowed_token.decimals);
1402
- });
1403
- }
1404
- getMaxRange(collateral, debt) {
1405
- return __awaiter(this, void 0, void 0, function* () {
1406
- const maxRecv = yield this.createLoanMaxRecvAllRanges(collateral);
1407
- for (let N = this.minBands; N <= this.maxBands; N++) {
1408
- if (BN(debt).gt(BN(maxRecv[N])))
1409
- return N - 1;
1410
- }
1411
- return this.maxBands;
1412
- });
1413
- }
1414
- _calcN1(_collateral, _debt, range) {
1415
- return __awaiter(this, void 0, void 0, function* () {
1416
- this._checkRange(range);
1417
- return yield this.llamalend.contracts[this.addresses.controller].contract.calculate_debt_n1(_collateral, _debt, range, this.llamalend.constantOptions);
1418
- });
1419
- }
1420
- _calcN1AllRanges(_collateral, _debt, maxN) {
1421
- return __awaiter(this, void 0, void 0, function* () {
1422
- const calls = [];
1423
- for (let N = this.minBands; N <= maxN; N++) {
1424
- calls.push(this.llamalend.contracts[this.addresses.controller].multicallContract.calculate_debt_n1(_collateral, _debt, N));
1425
- }
1426
- return yield this.llamalend.multicallProvider.all(calls);
1427
- });
1428
- }
1429
- _getPrices(_n2, _n1) {
1430
- return __awaiter(this, void 0, void 0, function* () {
1431
- const contract = this.llamalend.contracts[this.addresses.amm].multicallContract;
1432
- return (yield this.llamalend.multicallProvider.all([
1433
- contract.p_oracle_down(_n2),
1434
- contract.p_oracle_up(_n1),
1435
- ])).map((_p) => formatUnits(_p));
1436
- });
1437
- }
1438
- _calcPrices(_n2, _n1) {
1439
- return __awaiter(this, void 0, void 0, function* () {
1440
- return [yield this.calcTickPrice(Number(_n2) + 1), yield this.calcTickPrice(Number(_n1))];
1441
- });
1442
- }
1443
- _createLoanBands(collateral, debt, range) {
1444
- return __awaiter(this, void 0, void 0, function* () {
1445
- const _n1 = yield this._calcN1(parseUnits(collateral, this.collateral_token.decimals), parseUnits(debt, this.borrowed_token.decimals), range);
1446
- const _n2 = _n1 + BigInt(range - 1);
1447
- return [_n2, _n1];
1448
- });
1449
- }
1450
- _createLoanBandsAllRanges(collateral, debt) {
1451
- return __awaiter(this, void 0, void 0, function* () {
1452
- const maxN = yield this.getMaxRange(collateral, debt);
1453
- const _n1_arr = yield this._calcN1AllRanges(parseUnits(collateral, this.collateral_token.decimals), parseUnits(debt, this.borrowed_token.decimals), maxN);
1454
- const _n2_arr = [];
1455
- for (let N = this.minBands; N <= maxN; N++) {
1456
- _n2_arr.push(_n1_arr[N - this.minBands] + BigInt(N - 1));
1457
- }
1458
- const res = {};
1459
- for (let N = this.minBands; N <= maxN; N++) {
1460
- res[N] = [_n2_arr[N - this.minBands], _n1_arr[N - this.minBands]];
1461
- }
1462
- return res;
1463
- });
1464
- }
1465
- createLoanBands(collateral, debt, range) {
1466
- return __awaiter(this, void 0, void 0, function* () {
1467
- const [_n2, _n1] = yield this._createLoanBands(collateral, debt, range);
1468
- return [Number(_n2), Number(_n1)];
1469
- });
1470
- }
1471
- createLoanBandsAllRanges(collateral, debt) {
1472
- return __awaiter(this, void 0, void 0, function* () {
1473
- const _bandsAllRanges = yield this._createLoanBandsAllRanges(collateral, debt);
1474
- const bandsAllRanges = {};
1475
- for (let N = this.minBands; N <= this.maxBands; N++) {
1476
- if (_bandsAllRanges[N]) {
1477
- bandsAllRanges[N] = _bandsAllRanges[N].map(Number);
1478
- }
1479
- else {
1480
- bandsAllRanges[N] = null;
1481
- }
1482
- }
1483
- return bandsAllRanges;
1484
- });
1485
- }
1486
- createLoanPrices(collateral, debt, range) {
1487
- return __awaiter(this, void 0, void 0, function* () {
1488
- const [_n2, _n1] = yield this._createLoanBands(collateral, debt, range);
1489
- return yield this._getPrices(_n2, _n1);
1490
- });
1491
- }
1492
- createLoanPricesAllRanges(collateral, debt) {
1493
- return __awaiter(this, void 0, void 0, function* () {
1494
- const _bandsAllRanges = yield this._createLoanBandsAllRanges(collateral, debt);
1495
- const pricesAllRanges = {};
1496
- for (let N = this.minBands; N <= this.maxBands; N++) {
1497
- if (_bandsAllRanges[N]) {
1498
- pricesAllRanges[N] = yield this._calcPrices(..._bandsAllRanges[N]);
1499
- }
1500
- else {
1501
- pricesAllRanges[N] = null;
1502
- }
1503
- }
1504
- return pricesAllRanges;
1505
- });
1506
- }
1507
- createLoanHealth(collateral_1, debt_1, range_1) {
1508
- return __awaiter(this, arguments, void 0, function* (collateral, debt, range, full = true) {
1509
- const _collateral = parseUnits(collateral, this.collateral_token.decimals);
1510
- const _debt = parseUnits(debt, this.borrowed_token.decimals);
1511
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
1512
- let _health = yield contract.health_calculator(this.llamalend.constants.ZERO_ADDRESS, _collateral, _debt, full, range, this.llamalend.constantOptions);
1513
- _health = _health * BigInt(100);
1514
- return formatUnits(_health);
1515
- });
1516
- }
1517
- createLoanIsApproved(collateral) {
1518
- return __awaiter(this, void 0, void 0, function* () {
1519
- return yield hasAllowance.call(this.llamalend, [this.collateral_token.address], [collateral], this.llamalend.signerAddress, this.addresses.controller);
1520
- });
1521
- }
1522
- createLoanApproveEstimateGas(collateral) {
1523
- return __awaiter(this, void 0, void 0, function* () {
1524
- return yield ensureAllowanceEstimateGas.call(this.llamalend, [this.collateral_token.address], [collateral], this.addresses.controller);
1525
- });
1526
- }
1527
- createLoanApprove(collateral) {
1528
- return __awaiter(this, void 0, void 0, function* () {
1529
- return yield ensureAllowance.call(this.llamalend, [this.collateral_token.address], [collateral], this.addresses.controller);
1530
- });
1531
- }
1532
- _createLoan(collateral, debt, range, estimateGas) {
1533
- return __awaiter(this, void 0, void 0, function* () {
1534
- if (yield this.userLoanExists())
1535
- throw Error("Loan already created");
1536
- this._checkRange(range);
1537
- const _collateral = parseUnits(collateral, this.collateral_token.decimals);
1538
- const _debt = parseUnits(debt, this.borrowed_token.decimals);
1539
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
1540
- const gas = yield contract.create_loan.estimateGas(_collateral, _debt, range, Object.assign({}, this.llamalend.constantOptions));
1541
- if (estimateGas)
1542
- return smartNumber(gas);
1543
- yield this.llamalend.updateFeeData();
1544
- const gasLimit = _mulBy1_3(DIGas(gas));
1545
- return (yield contract.create_loan(_collateral, _debt, range, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
1546
- });
1547
- }
1548
- createLoanEstimateGas(collateral, debt, range) {
1549
- return __awaiter(this, void 0, void 0, function* () {
1550
- if (!(yield this.createLoanIsApproved(collateral)))
1551
- throw Error("Approval is needed for gas estimation");
1552
- return yield this._createLoan(collateral, debt, range, true);
1553
- });
1554
- }
1555
- createLoan(collateral, debt, range) {
1556
- return __awaiter(this, void 0, void 0, function* () {
1557
- yield this.createLoanApprove(collateral);
1558
- return yield this._createLoan(collateral, debt, range, false);
1559
- });
1560
- }
1561
- // ---------------- BORROW MORE ----------------
1562
- borrowMoreMaxRecv(collateralAmount) {
1563
- return __awaiter(this, void 0, void 0, function* () {
1564
- const { _collateral: _currentCollateral, _debt: _currentDebt, _N } = yield this._userState();
1565
- const _collateral = _currentCollateral + parseUnits(collateralAmount, this.collateral_token.decimals);
1566
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
1567
- const _debt = yield contract.max_borrowable(_collateral, _N, _currentDebt, this.llamalend.constantOptions);
1568
- return formatUnits(_debt - _currentDebt, this.borrowed_token.decimals);
1569
- });
1570
- }
1571
- _borrowMoreBands(collateral, debt) {
1572
- return __awaiter(this, void 0, void 0, function* () {
1573
- const { _collateral: _currentCollateral, _debt: _currentDebt, _N } = yield this._userState();
1574
- if (_currentDebt === BigInt(0))
1575
- throw Error(`Loan for ${this.llamalend.signerAddress} does not exist`);
1576
- const _collateral = _currentCollateral + parseUnits(collateral, this.collateral_token.decimals);
1577
- const _debt = _currentDebt + parseUnits(debt, this.borrowed_token.decimals);
1578
- const _n1 = yield this._calcN1(_collateral, _debt, Number(_N));
1579
- const _n2 = _n1 + _N - BigInt(1);
1580
- return [_n2, _n1];
1581
- });
1582
- }
1583
- borrowMoreBands(collateral, debt) {
1584
- return __awaiter(this, void 0, void 0, function* () {
1585
- const [_n2, _n1] = yield this._borrowMoreBands(collateral, debt);
1586
- return [Number(_n2), Number(_n1)];
1587
- });
1588
- }
1589
- borrowMorePrices(collateral, debt) {
1590
- return __awaiter(this, void 0, void 0, function* () {
1591
- const [_n2, _n1] = yield this._borrowMoreBands(collateral, debt);
1592
- return yield this._getPrices(_n2, _n1);
1593
- });
1594
- }
1595
- borrowMoreHealth(collateral_1, debt_1) {
1596
- return __awaiter(this, arguments, void 0, function* (collateral, debt, full = true, address = "") {
1597
- address = _getAddress.call(this.llamalend, address);
1598
- const _collateral = parseUnits(collateral, this.collateral_token.decimals);
1599
- const _debt = parseUnits(debt, this.borrowed_token.decimals);
1600
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
1601
- let _health = yield contract.health_calculator(address, _collateral, _debt, full, 0, this.llamalend.constantOptions);
1602
- _health = _health * BigInt(100);
1603
- return formatUnits(_health);
1604
- });
1605
- }
1606
- borrowMoreIsApproved(collateral) {
1607
- return __awaiter(this, void 0, void 0, function* () {
1608
- return yield hasAllowance.call(this.llamalend, [this.addresses.collateral_token], [collateral], this.llamalend.signerAddress, this.addresses.controller);
1609
- });
1610
- }
1611
- borrowMoreApproveEstimateGas(collateral) {
1612
- return __awaiter(this, void 0, void 0, function* () {
1613
- return yield ensureAllowanceEstimateGas.call(this.llamalend, [this.addresses.collateral_token], [collateral], this.addresses.controller);
1614
- });
1615
- }
1616
- borrowMoreApprove(collateral) {
1617
- return __awaiter(this, void 0, void 0, function* () {
1618
- return yield ensureAllowance.call(this.llamalend, [this.addresses.collateral_token], [collateral], this.addresses.controller);
1619
- });
1620
- }
1621
- _borrowMore(collateral, debt, estimateGas) {
1622
- return __awaiter(this, void 0, void 0, function* () {
1623
- const { borrowed, debt: currentDebt } = yield this.userState();
1624
- if (Number(currentDebt) === 0)
1625
- throw Error(`Loan for ${this.llamalend.signerAddress} does not exist`);
1626
- if (Number(borrowed) > 0)
1627
- throw Error(`User ${this.llamalend.signerAddress} is already in liquidation mode`);
1628
- const _collateral = parseUnits(collateral, this.collateral_token.decimals);
1629
- const _debt = parseUnits(debt, this.borrowed_token.decimals);
1630
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
1631
- const gas = yield contract.borrow_more.estimateGas(_collateral, _debt, Object.assign({}, this.llamalend.constantOptions));
1632
- if (estimateGas)
1633
- return smartNumber(gas);
1634
- yield this.llamalend.updateFeeData();
1635
- const gasLimit = _mulBy1_3(DIGas(gas));
1636
- return (yield contract.borrow_more(_collateral, _debt, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
1637
- });
1638
- }
1639
- borrowMoreEstimateGas(collateral, debt) {
1640
- return __awaiter(this, void 0, void 0, function* () {
1641
- if (!(yield this.borrowMoreIsApproved(collateral)))
1642
- throw Error("Approval is needed for gas estimation");
1643
- return yield this._borrowMore(collateral, debt, true);
1644
- });
1645
- }
1646
- borrowMore(collateral, debt) {
1647
- return __awaiter(this, void 0, void 0, function* () {
1648
- yield this.borrowMoreApprove(collateral);
1649
- return yield this._borrowMore(collateral, debt, false);
1650
- });
1651
- }
1652
- _getCurrentLeverageParams(userAddress) {
1653
- return __awaiter(this, void 0, void 0, function* () {
1654
- const [userCollateralData, { collateral: stateCollateral }] = yield Promise.all([
1655
- _getUserCollateral(this.llamalend.constants.NETWORK_NAME, this.addresses.controller, userAddress),
1656
- this.userState(userAddress),
1657
- ]);
1658
- return {
1659
- stateCollateral,
1660
- totalDepositFromUser: userCollateralData.total_deposit_from_user_precise,
1661
- };
1662
- });
1663
- }
1664
- borrowMoreFutureLeverage(collateral_1, debt_1) {
1665
- return __awaiter(this, arguments, void 0, function* (collateral, debt, userAddress = '') {
1666
- userAddress = _getAddress.call(this.llamalend, userAddress);
1667
- const { stateCollateral, totalDepositFromUser } = yield this._getCurrentLeverageParams(userAddress);
1668
- const collateralFromDebt = yield this.swapExpected(0, 1, debt);
1669
- const futureCollateralState = BN(stateCollateral).plus(collateralFromDebt);
1670
- const futureTotalDepositFromUserPrecise = BN(totalDepositFromUser).plus(collateral);
1671
- return futureCollateralState.div(futureTotalDepositFromUserPrecise).toString();
1672
- });
1673
- }
1674
- // ---------------- ADD COLLATERAL ----------------
1675
- _addCollateralBands(collateral_1) {
1676
- return __awaiter(this, arguments, void 0, function* (collateral, address = "") {
1677
- address = _getAddress.call(this.llamalend, address);
1678
- const { _collateral: _currentCollateral, _debt: _currentDebt, _N } = yield this._userState(address);
1679
- if (_currentDebt === BigInt(0))
1680
- throw Error(`Loan for ${address} does not exist`);
1681
- const _collateral = _currentCollateral + parseUnits(collateral, this.collateral_token.decimals);
1682
- const _n1 = yield this._calcN1(_collateral, _currentDebt, Number(_N));
1683
- const _n2 = _n1 + _N - BigInt(1);
1684
- return [_n2, _n1];
1685
- });
1686
- }
1687
- addCollateralBands(collateral_1) {
1688
- return __awaiter(this, arguments, void 0, function* (collateral, address = "") {
1689
- const [_n2, _n1] = yield this._addCollateralBands(collateral, address);
1690
- return [Number(_n2), Number(_n1)];
1691
- });
1692
- }
1693
- addCollateralPrices(collateral_1) {
1694
- return __awaiter(this, arguments, void 0, function* (collateral, address = "") {
1695
- const [_n2, _n1] = yield this._addCollateralBands(collateral, address);
1696
- return yield this._getPrices(_n2, _n1);
1697
- });
1698
- }
1699
- addCollateralHealth(collateral_1) {
1700
- return __awaiter(this, arguments, void 0, function* (collateral, full = true, address = "") {
1701
- address = _getAddress.call(this.llamalend, address);
1702
- const _collateral = parseUnits(collateral, this.collateral_token.decimals);
1703
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
1704
- let _health = yield contract.health_calculator(address, _collateral, 0, full, 0, this.llamalend.constantOptions);
1705
- _health = _health * BigInt(100);
1706
- return formatUnits(_health);
1707
- });
1708
- }
1709
- addCollateralIsApproved(collateral) {
1710
- return __awaiter(this, void 0, void 0, function* () {
1711
- return yield hasAllowance.call(this.llamalend, [this.addresses.collateral_token], [collateral], this.llamalend.signerAddress, this.addresses.controller);
1712
- });
1713
- }
1714
- addCollateralApproveEstimateGas(collateral) {
1715
- return __awaiter(this, void 0, void 0, function* () {
1716
- return yield ensureAllowanceEstimateGas.call(this.llamalend, [this.addresses.collateral_token], [collateral], this.addresses.controller);
1717
- });
1718
- }
1719
- addCollateralApprove(collateral) {
1720
- return __awaiter(this, void 0, void 0, function* () {
1721
- return yield ensureAllowance.call(this.llamalend, [this.addresses.collateral_token], [collateral], this.addresses.controller);
1722
- });
1723
- }
1724
- _addCollateral(collateral, address, estimateGas) {
1725
- return __awaiter(this, void 0, void 0, function* () {
1726
- const { borrowed, debt: currentDebt } = yield this.userState(address);
1727
- if (Number(currentDebt) === 0)
1728
- throw Error(`Loan for ${address} does not exist`);
1729
- if (Number(borrowed) > 0)
1730
- throw Error(`User ${address} is already in liquidation mode`);
1731
- const _collateral = parseUnits(collateral, this.collateral_token.decimals);
1732
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
1733
- const gas = yield contract.add_collateral.estimateGas(_collateral, address, Object.assign({}, this.llamalend.constantOptions));
1734
- if (estimateGas)
1735
- return smartNumber(gas);
1736
- yield this.llamalend.updateFeeData();
1737
- const gasLimit = _mulBy1_3(DIGas(gas));
1738
- return (yield contract.add_collateral(_collateral, address, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
1739
- });
1740
- }
1741
- addCollateralEstimateGas(collateral_1) {
1742
- return __awaiter(this, arguments, void 0, function* (collateral, address = "") {
1743
- address = _getAddress.call(this.llamalend, address);
1744
- if (!(yield this.addCollateralIsApproved(collateral)))
1745
- throw Error("Approval is needed for gas estimation");
1746
- return yield this._addCollateral(collateral, address, true);
1747
- });
1748
- }
1749
- addCollateral(collateral_1) {
1750
- return __awaiter(this, arguments, void 0, function* (collateral, address = "") {
1751
- address = _getAddress.call(this.llamalend, address);
1752
- yield this.addCollateralApprove(collateral);
1753
- return yield this._addCollateral(collateral, address, false);
1754
- });
1755
- }
1756
- addCollateralFutureLeverage(collateral_1) {
1757
- return __awaiter(this, arguments, void 0, function* (collateral, userAddress = '') {
1758
- userAddress = _getAddress.call(this.llamalend, userAddress);
1759
- const { stateCollateral, totalDepositFromUser } = yield this._getCurrentLeverageParams(userAddress);
1760
- return calculateFutureLeverage(stateCollateral, totalDepositFromUser, collateral, 'add');
1761
- });
1762
- }
1763
- // ---------------- REMOVE COLLATERAL ----------------
1764
- maxRemovable() {
1765
- return __awaiter(this, void 0, void 0, function* () {
1766
- const { _collateral: _currentCollateral, _debt: _currentDebt, _N } = yield this._userState();
1767
- const _requiredCollateral = yield this.llamalend.contracts[this.addresses.controller].contract.min_collateral(_currentDebt, _N, this.llamalend.constantOptions);
1768
- return formatUnits(_currentCollateral - _requiredCollateral, this.collateral_token.decimals);
1769
- });
1770
- }
1771
- _removeCollateralBands(collateral) {
1772
- return __awaiter(this, void 0, void 0, function* () {
1773
- const { _collateral: _currentCollateral, _debt: _currentDebt, _N } = yield this._userState();
1774
- if (_currentDebt === BigInt(0))
1775
- throw Error(`Loan for ${this.llamalend.signerAddress} does not exist`);
1776
- const _collateral = _currentCollateral - parseUnits(collateral, this.collateral_token.decimals);
1777
- const _n1 = yield this._calcN1(_collateral, _currentDebt, Number(_N));
1778
- const _n2 = _n1 + _N - BigInt(1);
1779
- return [_n2, _n1];
1780
- });
1781
- }
1782
- removeCollateralBands(collateral) {
1783
- return __awaiter(this, void 0, void 0, function* () {
1784
- const [_n2, _n1] = yield this._removeCollateralBands(collateral);
1785
- return [Number(_n2), Number(_n1)];
1786
- });
1787
- }
1788
- removeCollateralPrices(collateral) {
1789
- return __awaiter(this, void 0, void 0, function* () {
1790
- const [_n2, _n1] = yield this._removeCollateralBands(collateral);
1791
- return yield this._getPrices(_n2, _n1);
1792
- });
1793
- }
1794
- removeCollateralHealth(collateral_1) {
1795
- return __awaiter(this, arguments, void 0, function* (collateral, full = true, address = "") {
1796
- address = _getAddress.call(this.llamalend, address);
1797
- const _collateral = parseUnits(collateral, this.collateral_token.decimals) * BigInt(-1);
1798
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
1799
- let _health = yield contract.health_calculator(address, _collateral, 0, full, 0, this.llamalend.constantOptions);
1800
- _health = _health * BigInt(100);
1801
- return formatUnits(_health);
1802
- });
1803
- }
1804
- _removeCollateral(collateral, estimateGas) {
1805
- return __awaiter(this, void 0, void 0, function* () {
1806
- const { borrowed, debt: currentDebt } = yield this.userState();
1807
- if (Number(currentDebt) === 0)
1808
- throw Error(`Loan for ${this.llamalend.signerAddress} does not exist`);
1809
- if (Number(borrowed) > 0)
1810
- throw Error(`User ${this.llamalend.signerAddress} is already in liquidation mode`);
1811
- const _collateral = parseUnits(collateral, this.collateral_token.decimals);
1812
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
1813
- const gas = yield contract.remove_collateral.estimateGas(_collateral, this.llamalend.constantOptions);
1814
- if (estimateGas)
1815
- return smartNumber(gas);
1816
- yield this.llamalend.updateFeeData();
1817
- const gasLimit = _mulBy1_3(DIGas(gas));
1818
- return (yield contract.remove_collateral(_collateral, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
1819
- });
1820
- }
1821
- removeCollateralEstimateGas(collateral) {
1822
- return __awaiter(this, void 0, void 0, function* () {
1823
- return yield this._removeCollateral(collateral, true);
1824
- });
1825
- }
1826
- removeCollateral(collateral) {
1827
- return __awaiter(this, void 0, void 0, function* () {
1828
- return yield this._removeCollateral(collateral, false);
1829
- });
1830
- }
1831
- removeCollateralFutureLeverage(collateral_1) {
1832
- return __awaiter(this, arguments, void 0, function* (collateral, userAddress = '') {
1833
- userAddress = _getAddress.call(this.llamalend, userAddress);
1834
- const { stateCollateral, totalDepositFromUser } = yield this._getCurrentLeverageParams(userAddress);
1835
- return calculateFutureLeverage(stateCollateral, totalDepositFromUser, collateral, 'remove');
1836
- });
1837
- }
1838
- // ---------------- REPAY ----------------
1839
- _repayBands(debt, address) {
1840
- return __awaiter(this, void 0, void 0, function* () {
1841
- const { _collateral: _currentCollateral, _borrowed, _debt: _currentDebt, _N } = yield this._userState(address);
1842
- if (_currentDebt === BigInt(0))
1843
- throw Error(`Loan for ${address} does not exist`);
1844
- if (_borrowed > BigInt(0))
1845
- return yield this._userBands(address);
1846
- const _debt = _currentDebt - parseUnits(debt, this.borrowed_token.decimals);
1847
- const _n1 = yield this._calcN1(_currentCollateral, _debt, Number(_N));
1848
- const _n2 = _n1 + _N - BigInt(1);
1849
- return [_n2, _n1];
1850
- });
1851
- }
1852
- repayBands(debt_1) {
1853
- return __awaiter(this, arguments, void 0, function* (debt, address = "") {
1854
- const [_n2, _n1] = yield this._repayBands(debt, address);
1855
- return [Number(_n2), Number(_n1)];
1856
- });
1857
- }
1858
- repayPrices(debt_1) {
1859
- return __awaiter(this, arguments, void 0, function* (debt, address = "") {
1860
- const [_n2, _n1] = yield this._repayBands(debt, address);
1861
- return yield this._getPrices(_n2, _n1);
1862
- });
1863
- }
1864
- repayIsApproved(debt) {
1865
- return __awaiter(this, void 0, void 0, function* () {
1866
- return yield hasAllowance.call(this.llamalend, [this.borrowed_token.address], [debt], this.llamalend.signerAddress, this.addresses.controller);
1867
- });
1868
- }
1869
- repayApproveEstimateGas(debt) {
1870
- return __awaiter(this, void 0, void 0, function* () {
1871
- return yield ensureAllowanceEstimateGas.call(this.llamalend, [this.borrowed_token.address], [debt], this.addresses.controller);
1872
- });
1873
- }
1874
- repayApprove(debt) {
1875
- return __awaiter(this, void 0, void 0, function* () {
1876
- return yield ensureAllowance.call(this.llamalend, [this.borrowed_token.address], [debt], this.addresses.controller);
1877
- });
1878
- }
1879
- repayHealth(debt_1) {
1880
- return __awaiter(this, arguments, void 0, function* (debt, full = true, address = "") {
1881
- address = _getAddress.call(this.llamalend, address);
1882
- const _debt = parseUnits(debt) * BigInt(-1);
1883
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
1884
- let _health = yield contract.health_calculator(address, 0, _debt, full, 0, this.llamalend.constantOptions);
1885
- _health = _health * BigInt(100);
1886
- return formatUnits(_health);
1887
- });
1888
- }
1889
- _repay(debt, address, estimateGas) {
1890
- return __awaiter(this, void 0, void 0, function* () {
1891
- address = _getAddress.call(this.llamalend, address);
1892
- const { debt: currentDebt } = yield this.userState(address);
1893
- if (Number(currentDebt) === 0)
1894
- throw Error(`Loan for ${address} does not exist`);
1895
- const _debt = parseUnits(debt);
1896
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
1897
- const [, n1] = yield this.userBands(address);
1898
- const { borrowed } = yield this.userState(address);
1899
- const n = (BN(borrowed).gt(0)) ? MAX_ACTIVE_BAND : n1 - 1; // In liquidation mode it doesn't matter if active band moves
1900
- const gas = yield contract.repay.estimateGas(_debt, address, n, this.llamalend.constantOptions);
1901
- if (estimateGas)
1902
- return smartNumber(gas);
1903
- yield this.llamalend.updateFeeData();
1904
- const gasLimit = _mulBy1_3(DIGas(gas));
1905
- return (yield contract.repay(_debt, address, n, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
1906
- });
1907
- }
1908
- repayEstimateGas(debt_1) {
1909
- return __awaiter(this, arguments, void 0, function* (debt, address = "") {
1910
- if (!(yield this.repayIsApproved(debt)))
1911
- throw Error("Approval is needed for gas estimation");
1912
- return yield this._repay(debt, address, true);
1913
- });
1914
- }
1915
- repay(debt_1) {
1916
- return __awaiter(this, arguments, void 0, function* (debt, address = "") {
1917
- yield this.repayApprove(debt);
1918
- return yield this._repay(debt, address, false);
1919
- });
1920
- }
1921
- repayFutureLeverage(debt_1) {
1922
- return __awaiter(this, arguments, void 0, function* (debt, userAddress = '') {
1923
- userAddress = _getAddress.call(this.llamalend, userAddress);
1924
- const { stateCollateral, totalDepositFromUser } = yield this._getCurrentLeverageParams(userAddress);
1925
- const collateralFromDebt = yield this.swapExpected(0, 1, debt);
1926
- const futureCollateralState = BN(stateCollateral);
1927
- const futureTotalDepositFromUserPrecise = BN(totalDepositFromUser).plus(collateralFromDebt);
1928
- return futureCollateralState.div(futureTotalDepositFromUserPrecise).toString();
1929
- });
1930
- }
1931
- // ---------------- FULL REPAY ----------------
1932
- _fullRepayAmount() {
1933
- return __awaiter(this, arguments, void 0, function* (address = "") {
1934
- address = _getAddress.call(this.llamalend, address);
1935
- const { debt } = yield this.userState(address);
1936
- return BN(debt).times(1.0001).toString();
1937
- });
1938
- }
1939
- fullRepayIsApproved() {
1940
- return __awaiter(this, arguments, void 0, function* (address = "") {
1941
- address = _getAddress.call(this.llamalend, address);
1942
- const fullRepayAmount = yield this._fullRepayAmount(address);
1943
- return yield this.repayIsApproved(fullRepayAmount);
1944
- });
1945
- }
1946
- fullRepayApproveEstimateGas() {
1947
- return __awaiter(this, arguments, void 0, function* (address = "") {
1948
- address = _getAddress.call(this.llamalend, address);
1949
- const fullRepayAmount = yield this._fullRepayAmount(address);
1950
- return yield this.repayApproveEstimateGas(fullRepayAmount);
1951
- });
1952
- }
1953
- fullRepayApprove() {
1954
- return __awaiter(this, arguments, void 0, function* (address = "") {
1955
- address = _getAddress.call(this.llamalend, address);
1956
- const fullRepayAmount = yield this._fullRepayAmount(address);
1957
- return yield this.repayApprove(fullRepayAmount);
1958
- });
1959
- }
1960
- fullRepayEstimateGas() {
1961
- return __awaiter(this, arguments, void 0, function* (address = "") {
1962
- address = _getAddress.call(this.llamalend, address);
1963
- const fullRepayAmount = yield this._fullRepayAmount(address);
1964
- if (!(yield this.repayIsApproved(fullRepayAmount)))
1965
- throw Error("Approval is needed for gas estimation");
1966
- return yield this._repay(fullRepayAmount, address, true);
1967
- });
1968
- }
1969
- fullRepay() {
1970
- return __awaiter(this, arguments, void 0, function* (address = "") {
1971
- address = _getAddress.call(this.llamalend, address);
1972
- const fullRepayAmount = yield this._fullRepayAmount(address);
1973
- yield this.repayApprove(fullRepayAmount);
1974
- return yield this._repay(fullRepayAmount, address, false);
1975
- });
1976
- }
1977
- // ---------------- SWAP ----------------
1978
- maxSwappable(i, j) {
1979
- return __awaiter(this, void 0, void 0, function* () {
1980
- if (!(i === 0 && j === 1) && !(i === 1 && j === 0))
1981
- throw Error("Wrong index");
1982
- const inDecimals = this.coinDecimals[i];
1983
- const contract = this.llamalend.contracts[this.addresses.amm].contract;
1984
- const [_inAmount, _outAmount] = yield contract.get_dxdy(i, j, MAX_ALLOWANCE, this.llamalend.constantOptions);
1985
- if (_outAmount === BigInt(0))
1986
- return "0";
1987
- return formatUnits(_inAmount, inDecimals);
1988
- });
1989
- }
1990
- _swapExpected(i, j, _amount) {
1991
- return __awaiter(this, void 0, void 0, function* () {
1992
- return yield this.llamalend.contracts[this.addresses.amm].contract.get_dy(i, j, _amount, this.llamalend.constantOptions);
1993
- });
1994
- }
1995
- swapExpected(i, j, amount) {
1996
- return __awaiter(this, void 0, void 0, function* () {
1997
- if (!(i === 0 && j === 1) && !(i === 1 && j === 0))
1998
- throw Error("Wrong index");
1999
- const [inDecimals, outDecimals] = this.coinDecimals;
2000
- const _amount = parseUnits(amount, inDecimals);
2001
- const _expected = yield this._swapExpected(i, j, _amount);
2002
- return formatUnits(_expected, outDecimals);
2003
- });
2004
- }
2005
- swapRequired(i, j, outAmount) {
2006
- return __awaiter(this, void 0, void 0, function* () {
2007
- if (!(i === 0 && j === 1) && !(i === 1 && j === 0))
2008
- throw Error("Wrong index");
2009
- const [inDecimals, outDecimals] = this.coinDecimals;
2010
- const _amount = parseUnits(outAmount, outDecimals);
2011
- const _expected = yield this.llamalend.contracts[this.addresses.amm].contract.get_dx(i, j, _amount, this.llamalend.constantOptions);
2012
- return formatUnits(_expected, inDecimals);
2013
- });
2014
- }
2015
- swapPriceImpact(i, j, amount) {
2016
- return __awaiter(this, void 0, void 0, function* () {
2017
- if (!(i === 0 && j === 1) && !(i === 1 && j === 0))
2018
- throw Error("Wrong index");
2019
- const [inDecimals, outDecimals] = this.coinDecimals;
2020
- const _amount = parseUnits(amount, inDecimals);
2021
- const _output = yield this._swapExpected(i, j, _amount);
2022
- // Find k for which x * k = 10^15 or y * k = 10^15: k = max(10^15 / x, 10^15 / y)
2023
- // For coins with d (decimals) <= 15: k = min(k, 0.2), and x0 = min(x * k, 10^d)
2024
- // x0 = min(x * min(max(10^15 / x, 10^15 / y), 0.2), 10^d), if x0 == 0 then priceImpact = 0
2025
- const target = BN(Math.pow(10, 15));
2026
- const amountIntBN = BN(amount).times(Math.pow(10, inDecimals));
2027
- const outputIntBN = toBN(_output, 0);
2028
- const k = BigNumber.min(BigNumber.max(target.div(amountIntBN), target.div(outputIntBN)), 0.2);
2029
- const smallAmountIntBN = BigNumber.min(amountIntBN.times(k), BN(Math.pow(10, inDecimals)));
2030
- if (smallAmountIntBN.toFixed(0) === '0')
2031
- return '0';
2032
- const _smallAmount = fromBN(smallAmountIntBN.div(Math.pow(10, inDecimals)), inDecimals);
2033
- const _smallOutput = yield this._swapExpected(i, j, _smallAmount);
2034
- const amountBN = BN(amount);
2035
- const outputBN = toBN(_output, outDecimals);
2036
- const smallAmountBN = toBN(_smallAmount, inDecimals);
2037
- const smallOutputBN = toBN(_smallOutput, outDecimals);
2038
- const rateBN = outputBN.div(amountBN);
2039
- const smallRateBN = smallOutputBN.div(smallAmountBN);
2040
- if (rateBN.gt(smallRateBN))
2041
- return "0";
2042
- const slippageBN = BN(1).minus(rateBN.div(smallRateBN)).times(100);
2043
- return _cutZeros(slippageBN.toFixed(6));
2044
- });
2045
- }
2046
- swapIsApproved(i, amount) {
2047
- return __awaiter(this, void 0, void 0, function* () {
2048
- if (i !== 0 && i !== 1)
2049
- throw Error("Wrong index");
2050
- return yield hasAllowance.call(this.llamalend, [this.coinAddresses[i]], [amount], this.llamalend.signerAddress, this.addresses.amm);
2051
- });
2052
- }
2053
- swapApproveEstimateGas(i, amount) {
2054
- return __awaiter(this, void 0, void 0, function* () {
2055
- if (i !== 0 && i !== 1)
2056
- throw Error("Wrong index");
2057
- return yield ensureAllowanceEstimateGas.call(this.llamalend, [this.coinAddresses[i]], [amount], this.addresses.amm);
2058
- });
2059
- }
2060
- swapApprove(i, amount) {
2061
- return __awaiter(this, void 0, void 0, function* () {
2062
- if (i !== 0 && i !== 1)
2063
- throw Error("Wrong index");
2064
- return yield ensureAllowance.call(this.llamalend, [this.coinAddresses[i]], [amount], this.addresses.amm);
2065
- });
2066
- }
2067
- _swap(i, j, amount, slippage, estimateGas) {
2068
- return __awaiter(this, void 0, void 0, function* () {
2069
- if (!(i === 0 && j === 1) && !(i === 1 && j === 0))
2070
- throw Error("Wrong index");
2071
- const [inDecimals, outDecimals] = [this.coinDecimals[i], this.coinDecimals[j]];
2072
- const _amount = parseUnits(amount, inDecimals);
2073
- const _expected = yield this._swapExpected(i, j, _amount);
2074
- const minRecvAmountBN = toBN(_expected, outDecimals).times(100 - slippage).div(100);
2075
- const _minRecvAmount = fromBN(minRecvAmountBN, outDecimals);
2076
- const contract = this.llamalend.contracts[this.addresses.amm].contract;
2077
- const gas = yield contract.exchange.estimateGas(i, j, _amount, _minRecvAmount, this.llamalend.constantOptions);
2078
- if (estimateGas)
2079
- return smartNumber(gas);
2080
- yield this.llamalend.updateFeeData();
2081
- const gasLimit = _mulBy1_3(DIGas(gas));
2082
- return (yield contract.exchange(i, j, _amount, _minRecvAmount, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
2083
- });
2084
- }
2085
- swapEstimateGas(i_1, j_1, amount_1) {
2086
- return __awaiter(this, arguments, void 0, function* (i, j, amount, slippage = 0.1) {
2087
- if (!(yield this.swapIsApproved(i, amount)))
2088
- throw Error("Approval is needed for gas estimation");
2089
- return yield this._swap(i, j, amount, slippage, true);
2090
- });
2091
- }
2092
- swap(i_1, j_1, amount_1) {
2093
- return __awaiter(this, arguments, void 0, function* (i, j, amount, slippage = 0.1) {
2094
- yield this.swapApprove(i, amount);
2095
- return yield this._swap(i, j, amount, slippage, false);
2096
- });
2097
- }
2098
- // ---------------- LIQUIDATE ----------------
2099
- tokensToLiquidate() {
2100
- return __awaiter(this, arguments, void 0, function* (address = "") {
2101
- address = _getAddress.call(this.llamalend, address);
2102
- const _tokens = yield this.llamalend.contracts[this.addresses.controller].contract.tokens_to_liquidate(address, this.llamalend.constantOptions);
2103
- return formatUnits(_tokens, this.borrowed_token.decimals);
2104
- });
2105
- }
2106
- calcPartialFrac(amount_1) {
2107
- return __awaiter(this, arguments, void 0, function* (amount, address = "") {
2108
- address = _getAddress.call(this.llamalend, address);
2109
- const tokensToLiquidate = yield this.tokensToLiquidate(address);
2110
- const amountBN = BN(amount);
2111
- const tokensToLiquidateBN = BN(tokensToLiquidate);
2112
- if (amountBN.gt(tokensToLiquidateBN))
2113
- throw Error("Amount cannot be greater than total tokens to liquidate");
2114
- if (amountBN.lte(0))
2115
- throw Error("Amount must be greater than 0");
2116
- // Calculate frac = amount / tokensToLiquidate * 10**18
2117
- // 100% = 10**18
2118
- const fracDecimalBN = amountBN.div(tokensToLiquidateBN);
2119
- const frac = fromBN(fracDecimalBN);
2120
- return {
2121
- frac: frac.toString(),
2122
- fracDecimal: fracDecimalBN.toString(),
2123
- amount: amountBN.toString(),
2124
- };
2125
- });
2126
- }
2127
- liquidateIsApproved() {
2128
- return __awaiter(this, arguments, void 0, function* (address = "") {
2129
- const tokensToLiquidate = yield this.tokensToLiquidate(address);
2130
- return yield hasAllowance.call(this.llamalend, [this.addresses.borrowed_token], [tokensToLiquidate], this.llamalend.signerAddress, this.addresses.controller);
2131
- });
2132
- }
2133
- liquidateApproveEstimateGas() {
2134
- return __awaiter(this, arguments, void 0, function* (address = "") {
2135
- const tokensToLiquidate = yield this.tokensToLiquidate(address);
2136
- return yield ensureAllowanceEstimateGas.call(this.llamalend, [this.addresses.borrowed_token], [tokensToLiquidate], this.addresses.controller);
2137
- });
2138
- }
2139
- liquidateApprove() {
2140
- return __awaiter(this, arguments, void 0, function* (address = "") {
2141
- const tokensToLiquidate = yield this.tokensToLiquidate(address);
2142
- return yield ensureAllowance.call(this.llamalend, [this.addresses.borrowed_token], [tokensToLiquidate], this.addresses.controller);
2143
- });
2144
- }
2145
- _liquidate(address, slippage, estimateGas) {
2146
- return __awaiter(this, void 0, void 0, function* () {
2147
- const { borrowed, debt: currentDebt } = yield this.userState(address);
2148
- if (slippage <= 0)
2149
- throw Error("Slippage must be > 0");
2150
- if (slippage > 100)
2151
- throw Error("Slippage must be <= 100");
2152
- if (Number(currentDebt) === 0)
2153
- throw Error(`Loan for ${address} does not exist`);
2154
- if (Number(borrowed) === 0)
2155
- throw Error(`User ${address} is not in liquidation mode`);
2156
- const minAmountBN = BN(borrowed).times(100 - slippage).div(100);
2157
- const _minAmount = fromBN(minAmountBN);
2158
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
2159
- const gas = (yield contract.liquidate.estimateGas(address, _minAmount, this.llamalend.constantOptions));
2160
- if (estimateGas)
2161
- return smartNumber(gas);
2162
- yield this.llamalend.updateFeeData();
2163
- const gasLimit = _mulBy1_3(DIGas(gas));
2164
- return (yield contract.liquidate(address, _minAmount, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
2165
- });
2166
- }
2167
- _partialLiquidate(address, partialFrac, slippage, estimateGas) {
2168
- return __awaiter(this, void 0, void 0, function* () {
2169
- const { borrowed, debt: currentDebt } = yield this.userState(address);
2170
- if (slippage <= 0)
2171
- throw Error("Slippage must be > 0");
2172
- if (slippage > 100)
2173
- throw Error("Slippage must be <= 100");
2174
- if (Number(currentDebt) === 0)
2175
- throw Error(`Loan for ${address} does not exist`);
2176
- if (Number(borrowed) === 0)
2177
- throw Error(`User ${address} is not in liquidation mode`);
2178
- const frac = partialFrac.frac;
2179
- const fracBN = BN(partialFrac.fracDecimal);
2180
- const borrowedBN = BN(borrowed);
2181
- const expectedBorrowedBN = borrowedBN.times(fracBN);
2182
- const minAmountBN = expectedBorrowedBN.times(100 - slippage).div(100);
2183
- const _minAmount = fromBN(minAmountBN);
2184
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
2185
- const gas = (yield contract.liquidate_extended.estimateGas(address, _minAmount, frac, this.llamalend.constants.ZERO_ADDRESS, [], this.llamalend.constantOptions));
2186
- if (estimateGas)
2187
- return smartNumber(gas);
2188
- yield this.llamalend.updateFeeData();
2189
- const gasLimit = _mulBy1_3(DIGas(gas));
2190
- return (yield contract.liquidate_extended(address, _minAmount, frac, this.llamalend.constants.ZERO_ADDRESS, [], Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
2191
- });
2192
- }
2193
- liquidateEstimateGas(address_1) {
2194
- return __awaiter(this, arguments, void 0, function* (address, slippage = 0.1) {
2195
- if (!(yield this.liquidateIsApproved(address)))
2196
- throw Error("Approval is needed for gas estimation");
2197
- return yield this._liquidate(address, slippage, true);
2198
- });
2199
- }
2200
- liquidate(address_1) {
2201
- return __awaiter(this, arguments, void 0, function* (address, slippage = 0.1) {
2202
- yield this.liquidateApprove(address);
2203
- return yield this._liquidate(address, slippage, false);
2204
- });
2205
- }
2206
- // ---------------- SELF-LIQUIDATE ----------------
2207
- selfLiquidateIsApproved() {
2208
- return __awaiter(this, void 0, void 0, function* () {
2209
- return yield this.liquidateIsApproved();
2210
- });
2211
- }
2212
- selfLiquidateApproveEstimateGas() {
2213
- return __awaiter(this, void 0, void 0, function* () {
2214
- return this.liquidateApproveEstimateGas();
2215
- });
2216
- }
2217
- selfLiquidateApprove() {
2218
- return __awaiter(this, void 0, void 0, function* () {
2219
- return yield this.liquidateApprove();
2220
- });
2221
- }
2222
- selfLiquidateEstimateGas() {
2223
- return __awaiter(this, arguments, void 0, function* (slippage = 0.1) {
2224
- if (!(yield this.selfLiquidateIsApproved()))
2225
- throw Error("Approval is needed for gas estimation");
2226
- return yield this._liquidate(this.llamalend.signerAddress, slippage, true);
2227
- });
2228
- }
2229
- selfLiquidate() {
2230
- return __awaiter(this, arguments, void 0, function* (slippage = 0.1) {
2231
- yield this.selfLiquidateApprove();
2232
- return yield this._liquidate(this.llamalend.signerAddress, slippage, false);
2233
- });
2234
- }
2235
- // ---------------- PARTIAL SELF-LIQUIDATE ----------------
2236
- partialSelfLiquidateIsApproved(partialFrac) {
2237
- return __awaiter(this, void 0, void 0, function* () {
2238
- return yield hasAllowance.call(this.llamalend, [this.addresses.borrowed_token], [partialFrac.amount], this.llamalend.signerAddress, this.addresses.controller);
2239
- });
2240
- }
2241
- partialSelfLiquidateApproveEstimateGas(partialFrac) {
2242
- return __awaiter(this, void 0, void 0, function* () {
2243
- return yield ensureAllowanceEstimateGas.call(this.llamalend, [this.addresses.borrowed_token], [partialFrac.amount], this.addresses.controller);
2244
- });
2245
- }
2246
- partialSelfLiquidateApprove(partialFrac) {
2247
- return __awaiter(this, void 0, void 0, function* () {
2248
- return yield ensureAllowance.call(this.llamalend, [this.addresses.borrowed_token], [partialFrac.amount], this.addresses.controller);
2249
- });
2250
- }
2251
- partialSelfLiquidateEstimateGas(partialFrac_1) {
2252
- return __awaiter(this, arguments, void 0, function* (partialFrac, slippage = 0.1) {
2253
- if (!(yield this.partialSelfLiquidateIsApproved(partialFrac)))
2254
- throw Error("Approval is needed for gas estimation");
2255
- return yield this._partialLiquidate(this.llamalend.signerAddress, partialFrac, slippage, true);
2256
- });
2257
- }
2258
- partialSelfLiquidate(partialFrac_1) {
2259
- return __awaiter(this, arguments, void 0, function* (partialFrac, slippage = 0.1) {
2260
- yield this.partialSelfLiquidateApprove(partialFrac);
2261
- return yield this._partialLiquidate(this.llamalend.signerAddress, partialFrac, slippage, false);
2262
- });
2263
- }
2264
- _checkLeverageZap() {
2265
- if (!this.hasLeverage()) {
2266
- throw Error("This market does not support leverage");
2267
- }
2268
- }
2269
- _get_k_effective_BN(N) {
2270
- return __awaiter(this, void 0, void 0, function* () {
2271
- // d_k_effective: uint256 = (1 - loan_discount) * sqrt((A-1)/A) / N
2272
- // k_effective = d_k_effective * sum_{0..N-1}(((A-1) / A)**k)
2273
- const { loan_discount, A } = yield this.statsParameters();
2274
- const A_BN = BN(A);
2275
- const A_ratio_BN = A_BN.minus(1).div(A_BN);
2276
- const d_k_effective_BN = BN(100).minus(loan_discount).div(100).times(A_ratio_BN.sqrt()).div(N);
2277
- let S = BN(0);
2278
- for (let n = 0; n < N; n++) {
2279
- S = S.plus(A_ratio_BN.pow(n));
2280
- }
2281
- return d_k_effective_BN.times(S);
2282
- });
2283
- }
2284
- maxLeverage(N) {
2285
- return __awaiter(this, void 0, void 0, function* () {
2286
- // max_leverage = 1 / (k_effective - 1)
2287
- const k_effective_BN = yield this._get_k_effective_BN(N);
2288
- return BN(1).div(BN(1).minus(k_effective_BN)).toString();
2289
- });
2290
- }
2291
- leverageCreateLoanMaxRecv(userCollateral, userBorrowed, range) {
2292
- return __awaiter(this, void 0, void 0, function* () {
2293
- // max_borrowable = userCollateral / (1 / (k_effective * max_p_base) - 1 / p_avg)
2294
- this._checkLeverageZap();
2295
- if (range > 0)
2296
- this._checkRange(range);
2297
- const _userCollateral = parseUnits(userCollateral, this.collateral_token.decimals);
2298
- const _userBorrowed = parseUnits(userBorrowed, this.borrowed_token.decimals);
2299
- const oraclePriceBand = yield this.oraclePriceBand();
2300
- let pAvgBN = BN(yield this.calcTickPrice(oraclePriceBand)); // upper tick of oracle price band
2301
- let maxBorrowablePrevBN = BN(0);
2302
- let maxBorrowableBN = BN(0);
2303
- let _userEffectiveCollateral = BigInt(0);
2304
- let _maxLeverageCollateral = BigInt(0);
2305
- const contract = this.llamalend.contracts[this.llamalend.constants.ALIASES.leverage_zap].contract;
2306
- for (let i = 0; i < 5; i++) {
2307
- maxBorrowablePrevBN = maxBorrowableBN;
2308
- _userEffectiveCollateral = _userCollateral + fromBN(BN(userBorrowed).div(pAvgBN), this.collateral_token.decimals);
2309
- let _maxBorrowable = yield contract.max_borrowable(this.addresses.controller, _userEffectiveCollateral, _maxLeverageCollateral, range, fromBN(pAvgBN));
2310
- _maxBorrowable = _maxBorrowable * BigInt(998) / BigInt(1000);
2311
- if (_maxBorrowable === BigInt(0))
2312
- break;
2313
- maxBorrowableBN = toBN(_maxBorrowable, this.borrowed_token.decimals);
2314
- if (maxBorrowableBN.minus(maxBorrowablePrevBN).abs().div(maxBorrowablePrevBN).lt(0.0005)) {
2315
- maxBorrowableBN = maxBorrowablePrevBN;
2316
- break;
2317
- }
2318
- // additionalCollateral = (userBorrowed / p) + leverageCollateral
2319
- const _maxAdditionalCollateral = BigInt(yield _getExpectedOdos.call(this.llamalend, this.addresses.borrowed_token, this.addresses.collateral_token, _maxBorrowable + _userBorrowed, this.addresses.amm));
2320
- pAvgBN = maxBorrowableBN.plus(userBorrowed).div(toBN(_maxAdditionalCollateral, this.collateral_token.decimals));
2321
- _maxLeverageCollateral = _maxAdditionalCollateral - fromBN(BN(userBorrowed).div(pAvgBN), this.collateral_token.decimals);
2322
- }
2323
- const userEffectiveCollateralBN = maxBorrowableBN.gt(0) ? toBN(_userEffectiveCollateral, this.collateral_token.decimals) : BN(0);
2324
- const maxLeverageCollateralBN = toBN(_maxLeverageCollateral, this.collateral_token.decimals);
2325
- return {
2326
- maxDebt: formatNumber(maxBorrowableBN.toString(), this.borrowed_token.decimals),
2327
- maxTotalCollateral: formatNumber(maxLeverageCollateralBN.plus(userEffectiveCollateralBN).toString(), this.collateral_token.decimals),
2328
- userCollateral: formatNumber(userCollateral, this.collateral_token.decimals),
2329
- collateralFromUserBorrowed: formatNumber(BN(userBorrowed).div(pAvgBN).toString(), this.collateral_token.decimals),
2330
- collateralFromMaxDebt: formatNumber(maxLeverageCollateralBN.toString(), this.collateral_token.decimals),
2331
- maxLeverage: maxLeverageCollateralBN.plus(userEffectiveCollateralBN).div(userEffectiveCollateralBN).toString(),
2332
- avgPrice: pAvgBN.toString(),
2333
- };
2334
- });
2335
- }
2336
- leverageCreateLoanExpectedCollateral(userCollateral_1, userBorrowed_1, debt_1) {
2337
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, debt, slippage = 0.1) {
2338
- this._checkLeverageZap();
2339
- const _debt = parseUnits(debt, this.borrowed_token.decimals);
2340
- const _userBorrowed = parseUnits(userBorrowed, this.borrowed_token.decimals);
2341
- yield this._setSwapDataToCache(this.addresses.borrowed_token, this.addresses.collateral_token, _debt + _userBorrowed, slippage);
2342
- const { _totalCollateral, _userCollateral, _collateralFromUserBorrowed, _collateralFromDebt, avgPrice } = yield this._leverageExpectedCollateral(userCollateral, userBorrowed, debt);
2343
- return {
2344
- totalCollateral: formatUnits(_totalCollateral, this.collateral_token.decimals),
2345
- userCollateral: formatUnits(_userCollateral, this.collateral_token.decimals),
2346
- collateralFromUserBorrowed: formatUnits(_collateralFromUserBorrowed, this.collateral_token.decimals),
2347
- collateralFromDebt: formatUnits(_collateralFromDebt, this.collateral_token.decimals),
2348
- leverage: toBN(_collateralFromDebt + _userCollateral + _collateralFromUserBorrowed, this.collateral_token.decimals)
2349
- .div(toBN(_userCollateral + _collateralFromUserBorrowed, this.collateral_token.decimals)).toString(),
2350
- avgPrice,
2351
- };
2352
- });
2353
- }
2354
- leverageCreateLoanPriceImpact(userBorrowed, debt) {
2355
- return __awaiter(this, void 0, void 0, function* () {
2356
- this._checkLeverageZap();
2357
- const _debt = parseUnits(debt, this.borrowed_token.decimals);
2358
- const _userBorrowed = parseUnits(userBorrowed, this.borrowed_token.decimals);
2359
- return this._getSwapDataFromCache(this.addresses.borrowed_token, _debt + _userBorrowed).priceImpact.toString();
2360
- });
2361
- }
2362
- leverageCreateLoanMaxRange(userCollateral, userBorrowed, debt) {
2363
- return __awaiter(this, void 0, void 0, function* () {
2364
- this._checkLeverageZap();
2365
- const maxRecv = yield this.leverageCreateLoanMaxRecvAllRanges(userCollateral, userBorrowed);
2366
- for (let N = this.minBands; N <= this.maxBands; N++) {
2367
- if (BN(debt).gt(maxRecv[N].maxDebt))
2368
- return N - 1;
2369
- }
2370
- return this.maxBands;
2371
- });
2372
- }
2373
- _leverageBands(userCollateral, userBorrowed, debt, range, user) {
2374
- return __awaiter(this, void 0, void 0, function* () {
2375
- const _n1 = yield this._leverageCalcN1(userCollateral, userBorrowed, debt, range, user);
2376
- if (range < 0) {
2377
- const { N } = yield this.userState(user);
2378
- range = Number(N);
2379
- }
2380
- const _n2 = _n1 + BigInt(range - 1);
2381
- return [_n2, _n1];
2382
- });
2383
- }
2384
- _leverageCreateLoanBandsAllRanges(userCollateral, userBorrowed, debt) {
2385
- return __awaiter(this, void 0, void 0, function* () {
2386
- const maxN = yield this.leverageCreateLoanMaxRange(userCollateral, userBorrowed, debt);
2387
- const _n1_arr = yield this._leverageCalcN1AllRanges(userCollateral, userBorrowed, debt, maxN);
2388
- const _n2_arr = [];
2389
- for (let N = this.minBands; N <= maxN; N++) {
2390
- _n2_arr.push(_n1_arr[N - this.minBands] + BigInt(N - 1));
2391
- }
2392
- const _bands = {};
2393
- for (let N = this.minBands; N <= maxN; N++) {
2394
- _bands[N] = [_n2_arr[N - this.minBands], _n1_arr[N - this.minBands]];
2395
- }
2396
- return _bands;
2397
- });
2398
- }
2399
- leverageCreateLoanBands(userCollateral, userBorrowed, debt, range) {
2400
- return __awaiter(this, void 0, void 0, function* () {
2401
- this._checkLeverageZap();
2402
- const [_n2, _n1] = yield this._leverageBands(userCollateral, userBorrowed, debt, range);
2403
- return [Number(_n2), Number(_n1)];
2404
- });
2405
- }
2406
- leverageCreateLoanBandsAllRanges(userCollateral, userBorrowed, debt) {
2407
- return __awaiter(this, void 0, void 0, function* () {
2408
- this._checkLeverageZap();
2409
- const _bands = yield this._leverageCreateLoanBandsAllRanges(userCollateral, userBorrowed, debt);
2410
- const bands = {};
2411
- for (let N = this.minBands; N <= this.maxBands; N++) {
2412
- if (_bands[N]) {
2413
- bands[N] = _bands[N].map(Number);
2414
- }
2415
- else {
2416
- bands[N] = null;
2417
- }
2418
- }
2419
- return bands;
2420
- });
2421
- }
2422
- leverageCreateLoanPrices(userCollateral, userBorrowed, debt, range) {
2423
- return __awaiter(this, void 0, void 0, function* () {
2424
- this._checkLeverageZap();
2425
- const [_n2, _n1] = yield this._leverageBands(userCollateral, userBorrowed, debt, range);
2426
- return yield this._getPrices(_n2, _n1);
2427
- });
2428
- }
2429
- leverageCreateLoanPricesAllRanges(userCollateral, userBorrowed, debt) {
2430
- return __awaiter(this, void 0, void 0, function* () {
2431
- this._checkLeverageZap();
2432
- const _bands = yield this._leverageCreateLoanBandsAllRanges(userCollateral, userBorrowed, debt);
2433
- const prices = {};
2434
- for (let N = this.minBands; N <= this.maxBands; N++) {
2435
- if (_bands[N]) {
2436
- prices[N] = yield this._calcPrices(..._bands[N]);
2437
- }
2438
- else {
2439
- prices[N] = null;
2440
- }
2441
- }
2442
- return prices;
2443
- });
2444
- }
2445
- _leverageHealth(userCollateral_1, userBorrowed_1, dDebt_1, range_1, full_1) {
2446
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, dDebt, range, full, user = this.llamalend.constants.ZERO_ADDRESS) {
2447
- if (range > 0)
2448
- this._checkRange(range);
2449
- const { _totalCollateral } = yield this._leverageExpectedCollateral(userCollateral, userBorrowed, dDebt, user);
2450
- const { _borrowed, _N } = yield this._userState(user);
2451
- if (_borrowed > BigInt(0))
2452
- throw Error(`User ${user} is already in liquidation mode`);
2453
- if (range < 0)
2454
- range = Number(this.llamalend.formatUnits(_N, 0));
2455
- const _dDebt = parseUnits(dDebt, this.borrowed_token.decimals);
2456
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
2457
- let _health = yield contract.health_calculator(user, _totalCollateral, _dDebt, full, range, this.llamalend.constantOptions);
2458
- _health = _health * BigInt(100);
2459
- return formatUnits(_health);
2460
- });
2461
- }
2462
- leverageCreateLoanHealth(userCollateral_1, userBorrowed_1, debt_1, range_1) {
2463
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, debt, range, full = true) {
2464
- this._checkLeverageZap();
2465
- return yield this._leverageHealth(userCollateral, userBorrowed, debt, range, full);
2466
- });
2467
- }
2468
- leverageCreateLoanIsApproved(userCollateral, userBorrowed) {
2469
- return __awaiter(this, void 0, void 0, function* () {
2470
- this._checkLeverageZap();
2471
- const collateralAllowance = yield hasAllowance.call(this.llamalend, [this.collateral_token.address], [userCollateral], this.llamalend.signerAddress, this.addresses.controller);
2472
- const borrowedAllowance = yield hasAllowance.call(this.llamalend, [this.borrowed_token.address], [userBorrowed], this.llamalend.signerAddress, this.llamalend.constants.ALIASES.leverage_zap);
2473
- return collateralAllowance && borrowedAllowance;
2474
- });
2475
- }
2476
- leverageCreateLoanApproveEstimateGas(userCollateral, userBorrowed) {
2477
- return __awaiter(this, void 0, void 0, function* () {
2478
- this._checkLeverageZap();
2479
- const collateralGas = yield ensureAllowanceEstimateGas.call(this.llamalend, [this.collateral_token.address], [userCollateral], this.addresses.controller);
2480
- const borrowedGas = yield ensureAllowanceEstimateGas.call(this.llamalend, [this.borrowed_token.address], [userBorrowed], this.llamalend.constants.ALIASES.leverage_zap);
2481
- if (Array.isArray(collateralGas) && Array.isArray(borrowedGas)) {
2482
- return [collateralGas[0] + borrowedGas[0], collateralGas[1] + borrowedGas[1]];
2483
- }
2484
- else {
2485
- return collateralGas + borrowedGas;
2486
- }
2487
- });
2488
- }
2489
- leverageCreateLoanApprove(userCollateral, userBorrowed) {
2490
- return __awaiter(this, void 0, void 0, function* () {
2491
- this._checkLeverageZap();
2492
- const collateralApproveTx = yield ensureAllowance.call(this.llamalend, [this.collateral_token.address], [userCollateral], this.addresses.controller);
2493
- const borrowedApproveTx = yield ensureAllowance.call(this.llamalend, [this.borrowed_token.address], [userBorrowed], this.llamalend.constants.ALIASES.leverage_zap);
2494
- return [...collateralApproveTx, ...borrowedApproveTx];
2495
- });
2496
- }
2497
- leverageCreateLoanRouteImage(userBorrowed, debt) {
2498
- return __awaiter(this, void 0, void 0, function* () {
2499
- this._checkLeverageZap();
2500
- const _userBorrowed = parseUnits(userBorrowed, this.borrowed_token.decimals);
2501
- const _debt = parseUnits(debt, this.borrowed_token.decimals);
2502
- return this._getSwapDataFromCache(this.addresses.borrowed_token, _debt + _userBorrowed).pathVizImage;
2503
- });
2504
- }
2505
- _leverageCreateLoan(userCollateral, userBorrowed, debt, range, slippage, estimateGas) {
2506
- return __awaiter(this, void 0, void 0, function* () {
2507
- if (yield this.userLoanExists())
2508
- throw Error("Loan already created");
2509
- this._checkRange(range);
2510
- const _userCollateral = parseUnits(userCollateral, this.collateral_token.decimals);
2511
- const _userBorrowed = parseUnits(userBorrowed, this.borrowed_token.decimals);
2512
- const _debt = parseUnits(debt, this.borrowed_token.decimals);
2513
- const swapData = this._getSwapDataFromCache(this.addresses.borrowed_token, _debt + _userBorrowed);
2514
- if (slippage !== swapData.slippage)
2515
- throw Error(`You must call leverage.createLoanExpectedCollateral() with slippage=${slippage} first`);
2516
- const calldata = yield _assembleTxOdos.call(this.llamalend, swapData.pathId);
2517
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
2518
- const gas = yield contract.create_loan_extended.estimateGas(_userCollateral, _debt, range, this.llamalend.constants.ALIASES.leverage_zap, [0, parseUnits(this._getMarketId(), 0), _userBorrowed], calldata, Object.assign({}, this.llamalend.constantOptions));
2519
- if (estimateGas)
2520
- return smartNumber(gas);
2521
- yield this.llamalend.updateFeeData();
2522
- const gasLimit = _mulBy1_3(DIGas(gas));
2523
- return (yield contract.create_loan_extended(_userCollateral, _debt, range, this.llamalend.constants.ALIASES.leverage_zap, [0, parseUnits(this._getMarketId(), 0), _userBorrowed], calldata, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
2524
- });
2525
- }
2526
- leverageCreateLoanEstimateGas(userCollateral_1, userBorrowed_1, debt_1, range_1) {
2527
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, debt, range, slippage = 0.1) {
2528
- this._checkLeverageZap();
2529
- if (!(yield this.leverageCreateLoanIsApproved(userCollateral, userBorrowed)))
2530
- throw Error("Approval is needed for gas estimation");
2531
- return yield this._leverageCreateLoan(userCollateral, userBorrowed, debt, range, slippage, true);
2532
- });
2533
- }
2534
- leverageCreateLoan(userCollateral_1, userBorrowed_1, debt_1, range_1) {
2535
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, debt, range, slippage = 0.1) {
2536
- this._checkLeverageZap();
2537
- yield this.leverageCreateLoanApprove(userCollateral, userBorrowed);
2538
- return yield this._leverageCreateLoan(userCollateral, userBorrowed, debt, range, slippage, false);
2539
- });
2540
- }
2541
- // ---------------- LEVERAGE BORROW MORE ----------------
2542
- leverageBorrowMoreMaxRecv(userCollateral_1, userBorrowed_1) {
2543
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, address = "") {
2544
- // max_borrowable = userCollateral / (1 / (k_effective * max_p_base) - 1 / p_avg)
2545
- this._checkLeverageZap();
2546
- address = _getAddress.call(this.llamalend, address);
2547
- const { _collateral: _stateCollateral, _borrowed: _stateBorrowed, _debt: _stateDebt, _N } = yield this._userState(address);
2548
- if (_stateBorrowed > BigInt(0))
2549
- throw Error(`User ${address} is already in liquidation mode`);
2550
- const _userCollateral = parseUnits(userCollateral, this.collateral_token.decimals);
2551
- const controllerContract = this.llamalend.contracts[this.addresses.controller].contract;
2552
- const _borrowedFromStateCollateral = (yield controllerContract.max_borrowable(_stateCollateral, _N, _stateDebt, this.llamalend.constantOptions)) - _stateDebt;
2553
- const _userBorrowed = _borrowedFromStateCollateral + parseUnits(userBorrowed, this.borrowed_token.decimals);
2554
- userBorrowed = formatUnits(_userBorrowed, this.borrowed_token.decimals);
2555
- const oraclePriceBand = yield this.oraclePriceBand();
2556
- let pAvgBN = BN(yield this.calcTickPrice(oraclePriceBand)); // upper tick of oracle price band
2557
- let maxBorrowablePrevBN = BN(0);
2558
- let maxBorrowableBN = BN(0);
2559
- let _userEffectiveCollateral = BigInt(0);
2560
- let _maxLeverageCollateral = BigInt(0);
2561
- const contract = this.llamalend.contracts[this.llamalend.constants.ALIASES.leverage_zap].contract;
2562
- for (let i = 0; i < 5; i++) {
2563
- maxBorrowablePrevBN = maxBorrowableBN;
2564
- _userEffectiveCollateral = _userCollateral + fromBN(BN(userBorrowed).div(pAvgBN), this.collateral_token.decimals);
2565
- let _maxBorrowable = yield contract.max_borrowable(this.addresses.controller, _userEffectiveCollateral, _maxLeverageCollateral, _N, fromBN(pAvgBN));
2566
- _maxBorrowable = _maxBorrowable * BigInt(998) / BigInt(1000);
2567
- if (_maxBorrowable === BigInt(0))
2568
- break;
2569
- maxBorrowableBN = toBN(_maxBorrowable, this.borrowed_token.decimals);
2570
- if (maxBorrowableBN.minus(maxBorrowablePrevBN).abs().div(maxBorrowablePrevBN).lt(0.0005)) {
2571
- maxBorrowableBN = maxBorrowablePrevBN;
2572
- break;
2573
- }
2574
- // additionalCollateral = (userBorrowed / p) + leverageCollateral
2575
- const _maxAdditionalCollateral = BigInt(yield _getExpectedOdos.call(this.llamalend, this.addresses.borrowed_token, this.addresses.collateral_token, _maxBorrowable + _userBorrowed, this.addresses.amm));
2576
- pAvgBN = maxBorrowableBN.plus(userBorrowed).div(toBN(_maxAdditionalCollateral, this.collateral_token.decimals));
2577
- _maxLeverageCollateral = _maxAdditionalCollateral - fromBN(BN(userBorrowed).div(pAvgBN), this.collateral_token.decimals);
2578
- }
2579
- if (maxBorrowableBN.eq(0))
2580
- _userEffectiveCollateral = BigInt(0);
2581
- const _maxTotalCollateral = _userEffectiveCollateral + _maxLeverageCollateral;
2582
- let _maxBorrowable = (yield controllerContract.max_borrowable(_stateCollateral + _maxTotalCollateral, _N, _stateDebt, this.llamalend.constantOptions)) - _stateDebt;
2583
- _maxBorrowable = _maxBorrowable * BigInt(998) / BigInt(1000);
2584
- return {
2585
- maxDebt: formatUnits(_maxBorrowable, this.borrowed_token.decimals),
2586
- maxTotalCollateral: formatUnits(_maxTotalCollateral, this.collateral_token.decimals),
2587
- userCollateral: formatNumber(userCollateral, this.collateral_token.decimals),
2588
- collateralFromUserBorrowed: formatNumber(BN(userBorrowed).div(pAvgBN).toString(), this.collateral_token.decimals),
2589
- collateralFromMaxDebt: formatUnits(_maxLeverageCollateral, this.collateral_token.decimals),
2590
- avgPrice: pAvgBN.toString(),
2591
- };
2592
- });
2593
- }
2594
- leverageBorrowMoreExpectedCollateral(userCollateral_1, userBorrowed_1, dDebt_1) {
2595
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, dDebt, slippage = 0.1, address = "") {
2596
- this._checkLeverageZap();
2597
- address = _getAddress.call(this.llamalend, address);
2598
- const _dDebt = parseUnits(dDebt, this.borrowed_token.decimals);
2599
- const _userBorrowed = parseUnits(userBorrowed, this.borrowed_token.decimals);
2600
- if (_dDebt + _userBorrowed <= BigInt(0)) {
2601
- throw Error("userBorrowed + dDebt must be greater than 0");
2602
- }
2603
- yield this._setSwapDataToCache(this.addresses.borrowed_token, this.addresses.collateral_token, _dDebt + _userBorrowed, slippage);
2604
- const { _totalCollateral, _userCollateral, _collateralFromUserBorrowed, _collateralFromDebt, avgPrice } = yield this._leverageExpectedCollateral(userCollateral, userBorrowed, dDebt, address);
2605
- return {
2606
- totalCollateral: formatUnits(_totalCollateral, this.collateral_token.decimals),
2607
- userCollateral: formatUnits(_userCollateral, this.collateral_token.decimals),
2608
- collateralFromUserBorrowed: formatUnits(_collateralFromUserBorrowed, this.collateral_token.decimals),
2609
- collateralFromDebt: formatUnits(_collateralFromDebt, this.collateral_token.decimals),
2610
- avgPrice,
2611
- };
2612
- });
2613
- }
2614
- leverageBorrowMorePriceImpact(userBorrowed, dDebt) {
2615
- return __awaiter(this, void 0, void 0, function* () {
2616
- this._checkLeverageZap();
2617
- const _dDebt = parseUnits(dDebt, this.borrowed_token.decimals);
2618
- const _userBorrowed = parseUnits(userBorrowed, this.borrowed_token.decimals);
2619
- return this._getSwapDataFromCache(this.addresses.borrowed_token, _dDebt + _userBorrowed).priceImpact.toString();
2620
- });
2621
- }
2622
- leverageBorrowMoreBands(userCollateral_1, userBorrowed_1, dDebt_1) {
2623
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, dDebt, address = "") {
2624
- address = _getAddress.call(this.llamalend, address);
2625
- this._checkLeverageZap();
2626
- const [_n2, _n1] = yield this._leverageBands(userCollateral, userBorrowed, dDebt, -1, address);
2627
- return [Number(_n2), Number(_n1)];
2628
- });
2629
- }
2630
- leverageBorrowMorePrices(userCollateral_1, userBorrowed_1, dDebt_1) {
2631
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, dDebt, address = "") {
2632
- address = _getAddress.call(this.llamalend, address);
2633
- this._checkLeverageZap();
2634
- const [_n2, _n1] = yield this._leverageBands(userCollateral, userBorrowed, dDebt, -1, address);
2635
- return yield this._getPrices(_n2, _n1);
2636
- });
2637
- }
2638
- leverageBorrowMoreHealth(userCollateral_1, userBorrowed_1, dDebt_1) {
2639
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, dDebt, full = true, address = "") {
2640
- this._checkLeverageZap();
2641
- address = _getAddress.call(this.llamalend, address);
2642
- return yield this._leverageHealth(userCollateral, userBorrowed, dDebt, -1, full, address);
2643
- });
2644
- }
2645
- leverageBorrowMoreRouteImage(userBorrowed, debt) {
2646
- return __awaiter(this, void 0, void 0, function* () {
2647
- this._checkLeverageZap();
2648
- const _userBorrowed = parseUnits(userBorrowed, this.borrowed_token.decimals);
2649
- const _debt = parseUnits(debt, this.borrowed_token.decimals);
2650
- return this._getSwapDataFromCache(this.addresses.borrowed_token, _debt + _userBorrowed).pathVizImage;
2651
- });
2652
- }
2653
- _leverageBorrowMore(userCollateral, userBorrowed, debt, slippage, estimateGas) {
2654
- return __awaiter(this, void 0, void 0, function* () {
2655
- if (!(yield this.userLoanExists()))
2656
- throw Error("Loan does not exist");
2657
- const _userCollateral = parseUnits(userCollateral, this.collateral_token.decimals);
2658
- const _userBorrowed = parseUnits(userBorrowed, this.borrowed_token.decimals);
2659
- const _debt = parseUnits(debt, this.borrowed_token.decimals);
2660
- const swapData = this._getSwapDataFromCache(this.addresses.borrowed_token, _debt + _userBorrowed);
2661
- if (slippage !== swapData.slippage)
2662
- throw Error(`You must call leverage.borrowMoreExpectedCollateral() with slippage=${slippage} first`);
2663
- const calldata = yield _assembleTxOdos.call(this.llamalend, swapData.pathId);
2664
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
2665
- const gas = yield contract.borrow_more_extended.estimateGas(_userCollateral, _debt, this.llamalend.constants.ALIASES.leverage_zap, [0, parseUnits(this._getMarketId(), 0), _userBorrowed], calldata, Object.assign({}, this.llamalend.constantOptions));
2666
- if (estimateGas)
2667
- return smartNumber(gas);
2668
- yield this.llamalend.updateFeeData();
2669
- const gasLimit = _mulBy1_3(DIGas(gas));
2670
- return (yield contract.borrow_more_extended(_userCollateral, _debt, this.llamalend.constants.ALIASES.leverage_zap, [0, parseUnits(this._getMarketId(), 0), _userBorrowed], calldata, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
2671
- });
2672
- }
2673
- leverageBorrowMoreEstimateGas(userCollateral_1, userBorrowed_1, debt_1) {
2674
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, debt, slippage = 0.1) {
2675
- this._checkLeverageZap();
2676
- if (!(yield this.leverageCreateLoanIsApproved(userCollateral, userBorrowed)))
2677
- throw Error("Approval is needed for gas estimation");
2678
- return yield this._leverageBorrowMore(userCollateral, userBorrowed, debt, slippage, true);
2679
- });
2680
- }
2681
- leverageBorrowMore(userCollateral_1, userBorrowed_1, debt_1) {
2682
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, debt, slippage = 0.1) {
2683
- this._checkLeverageZap();
2684
- yield this.leverageCreateLoanApprove(userCollateral, userBorrowed);
2685
- return yield this._leverageBorrowMore(userCollateral, userBorrowed, debt, slippage, false);
2686
- });
2687
- }
2688
- leverageBorrowMoreFutureLeverage(userCollateral_1, userBorrowed_1, debt_1) {
2689
- return __awaiter(this, arguments, void 0, function* (userCollateral, userBorrowed, debt, userAddress = '', slippage = 0.1) {
2690
- userAddress = _getAddress.call(this.llamalend, userAddress);
2691
- this._checkLeverageZap();
2692
- const { stateCollateral, totalDepositFromUser } = yield this._getCurrentLeverageParams(userAddress);
2693
- const expected = yield this.leverageBorrowMoreExpectedCollateral(userCollateral, userBorrowed, debt, slippage, userAddress);
2694
- const futureCollateralState = BN(stateCollateral).plus(expected.totalCollateral);
2695
- const futureTotalDepositFromUserPrecise = BN(totalDepositFromUser).plus(userCollateral).plus(expected.collateralFromUserBorrowed);
2696
- return futureCollateralState.div(futureTotalDepositFromUserPrecise).toString();
2697
- });
2698
- }
2699
- leverageRepayPriceImpact(stateCollateral, userCollateral) {
2700
- return __awaiter(this, void 0, void 0, function* () {
2701
- this._checkLeverageZap();
2702
- const _stateCollateral = parseUnits(stateCollateral, this.collateral_token.decimals);
2703
- const _userCollateral = parseUnits(userCollateral, this.collateral_token.decimals);
2704
- if (_stateCollateral + _userCollateral > BigInt(0)) {
2705
- return this._getSwapDataFromCache(this.addresses.collateral_token, _stateCollateral + _userCollateral).priceImpact.toString();
2706
- }
2707
- else {
2708
- return "0.0";
2709
- }
2710
- });
2711
- }
2712
- leverageRepayIsFull(stateCollateral_1, userCollateral_1, userBorrowed_1) {
2713
- return __awaiter(this, arguments, void 0, function* (stateCollateral, userCollateral, userBorrowed, address = "") {
2714
- this._checkLeverageZap();
2715
- address = _getAddress.call(this.llamalend, address);
2716
- const { _borrowed: _stateBorrowed, _debt } = yield this._userState(address);
2717
- const { _totalBorrowed } = this._leverageRepayExpectedBorrowed(stateCollateral, userCollateral, userBorrowed);
2718
- return _stateBorrowed + _totalBorrowed > _debt;
2719
- });
2720
- }
2721
- leverageRepayIsAvailable(stateCollateral_1, userCollateral_1, userBorrowed_1) {
2722
- return __awaiter(this, arguments, void 0, function* (stateCollateral, userCollateral, userBorrowed, address = "") {
2723
- // 0. const { collateral, stablecoin, debt } = await this.userState(address);
2724
- // 1. maxCollateral for deleverage is collateral from line above.
2725
- // 2. If user is underwater (stablecoin > 0), only full repayment is available:
2726
- // await this.deleverageRepayStablecoins(deleverageCollateral) + stablecoin > debt
2727
- this._checkLeverageZap();
2728
- address = _getAddress.call(this.llamalend, address);
2729
- const { collateral, borrowed, debt } = yield this.userState(address);
2730
- // Loan does not exist
2731
- if (BN(debt).eq(0))
2732
- return false;
2733
- // Can't spend more than user has
2734
- if (BN(stateCollateral).gt(collateral))
2735
- return false;
2736
- // Only full repayment and closing the position is available if user is underwater+
2737
- if (BN(borrowed).gt(0))
2738
- return yield this.leverageRepayIsFull(stateCollateral, userCollateral, userBorrowed, address);
2739
- return true;
2740
- });
2741
- }
2742
- leverageRepayBands(stateCollateral_1, userCollateral_1, userBorrowed_1) {
2743
- return __awaiter(this, arguments, void 0, function* (stateCollateral, userCollateral, userBorrowed, address = "") {
2744
- this._checkLeverageZap();
2745
- const [_n2, _n1] = yield this._leverageRepayBands(stateCollateral, userCollateral, userBorrowed, address);
2746
- return [Number(_n2), Number(_n1)];
2747
- });
2748
- }
2749
- leverageRepayPrices(stateCollateral_1, userCollateral_1, userBorrowed_1) {
2750
- return __awaiter(this, arguments, void 0, function* (stateCollateral, userCollateral, userBorrowed, address = "") {
2751
- this._checkLeverageZap();
2752
- const [_n2, _n1] = yield this._leverageRepayBands(stateCollateral, userCollateral, userBorrowed, address);
2753
- return yield this._getPrices(_n2, _n1);
2754
- });
2755
- }
2756
- leverageRepayHealth(stateCollateral_1, userCollateral_1, userBorrowed_1) {
2757
- return __awaiter(this, arguments, void 0, function* (stateCollateral, userCollateral, userBorrowed, full = true, address = "") {
2758
- this._checkLeverageZap();
2759
- address = _getAddress.call(this.llamalend, address);
2760
- const { _borrowed: _stateBorrowed, _debt, _N } = yield this._userState(address);
2761
- if (_stateBorrowed > BigInt(0))
2762
- return "0.0";
2763
- if (!(yield this.leverageRepayIsAvailable(stateCollateral, userCollateral, userBorrowed, address)))
2764
- return "0.0";
2765
- const { _totalBorrowed } = this._leverageRepayExpectedBorrowed(stateCollateral, userCollateral, userBorrowed);
2766
- const _dCollateral = parseUnits(stateCollateral, this.collateral_token.decimals) * BigInt(-1);
2767
- const _dDebt = _totalBorrowed * BigInt(-1);
2768
- if (_debt + _dDebt <= BigInt(0))
2769
- return "0.0";
2770
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
2771
- let _health = yield contract.health_calculator(address, _dCollateral, _dDebt, full, _N, this.llamalend.constantOptions);
2772
- _health = _health * BigInt(100);
2773
- return this.llamalend.formatUnits(_health);
2774
- });
2775
- }
2776
- leverageRepayIsApproved(userCollateral, userBorrowed) {
2777
- return __awaiter(this, void 0, void 0, function* () {
2778
- this._checkLeverageZap();
2779
- return yield hasAllowance.call(this.llamalend, [this.collateral_token.address, this.borrowed_token.address], [userCollateral, userBorrowed], this.llamalend.signerAddress, this.llamalend.constants.ALIASES.leverage_zap);
2780
- });
2781
- }
2782
- leverageRepayApproveEstimateGas(userCollateral, userBorrowed) {
2783
- return __awaiter(this, void 0, void 0, function* () {
2784
- this._checkLeverageZap();
2785
- return yield ensureAllowanceEstimateGas.call(this.llamalend, [this.collateral_token.address, this.borrowed_token.address], [userCollateral, userBorrowed], this.llamalend.constants.ALIASES.leverage_zap);
2786
- });
2787
- }
2788
- leverageRepayApprove(userCollateral, userBorrowed) {
2789
- return __awaiter(this, void 0, void 0, function* () {
2790
- this._checkLeverageZap();
2791
- return yield ensureAllowance.call(this.llamalend, [this.collateral_token.address, this.borrowed_token.address], [userCollateral, userBorrowed], this.llamalend.constants.ALIASES.leverage_zap);
2792
- });
2793
- }
2794
- leverageRepayRouteImage(stateCollateral, userCollateral) {
2795
- return __awaiter(this, void 0, void 0, function* () {
2796
- this._checkLeverageZap();
2797
- const _stateCollateral = parseUnits(stateCollateral, this.collateral_token.decimals);
2798
- const _userCollateral = parseUnits(userCollateral, this.collateral_token.decimals);
2799
- return this._getSwapDataFromCache(this.addresses.collateral_token, _stateCollateral + _userCollateral).pathVizImage;
2800
- });
2801
- }
2802
- _leverageRepay(stateCollateral, userCollateral, userBorrowed, slippage, estimateGas) {
2803
- return __awaiter(this, void 0, void 0, function* () {
2804
- if (!(yield this.userLoanExists()))
2805
- throw Error("Loan does not exist");
2806
- const _stateCollateral = parseUnits(stateCollateral, this.collateral_token.decimals);
2807
- const _userCollateral = parseUnits(userCollateral, this.collateral_token.decimals);
2808
- const _userBorrowed = parseUnits(userBorrowed, this.borrowed_token.decimals);
2809
- let calldata = "0x";
2810
- if (_stateCollateral + _userCollateral > BigInt(0)) {
2811
- const swapData = this._getSwapDataFromCache(this.addresses.collateral_token, _stateCollateral + _userCollateral);
2812
- if (slippage !== swapData.slippage)
2813
- throw Error(`You must call leverage.repayExpectedBorrowed() with slippage=${slippage} first`);
2814
- calldata = yield _assembleTxOdos.call(this.llamalend, swapData.pathId);
2815
- }
2816
- const contract = this.llamalend.contracts[this.addresses.controller].contract;
2817
- const gas = yield contract.repay_extended.estimateGas(this.llamalend.constants.ALIASES.leverage_zap, [0, parseUnits(this._getMarketId(), 0), _userCollateral, _userBorrowed], calldata);
2818
- if (estimateGas)
2819
- return smartNumber(gas);
2820
- yield this.llamalend.updateFeeData();
2821
- const gasLimit = _mulBy1_3(DIGas(gas));
2822
- return (yield contract.repay_extended(this.llamalend.constants.ALIASES.leverage_zap, [0, parseUnits(this._getMarketId(), 0), _userCollateral, _userBorrowed], calldata, Object.assign(Object.assign({}, this.llamalend.options), { gasLimit }))).hash;
2823
- });
2824
- }
2825
- leverageRepayEstimateGas(stateCollateral_1, userCollateral_1, userBorrowed_1) {
2826
- return __awaiter(this, arguments, void 0, function* (stateCollateral, userCollateral, userBorrowed, slippage = 0.1) {
2827
- this._checkLeverageZap();
2828
- if (!(yield this.leverageRepayIsApproved(userCollateral, userBorrowed)))
2829
- throw Error("Approval is needed for gas estimation");
2830
- return yield this._leverageRepay(stateCollateral, userCollateral, userBorrowed, slippage, true);
2831
- });
2832
- }
2833
- leverageRepay(stateCollateral_1, userCollateral_1, userBorrowed_1) {
2834
- return __awaiter(this, arguments, void 0, function* (stateCollateral, userCollateral, userBorrowed, slippage = 0.1) {
2835
- this._checkLeverageZap();
2836
- yield this.leverageRepayApprove(userCollateral, userBorrowed);
2837
- return yield this._leverageRepay(stateCollateral, userCollateral, userBorrowed, slippage, false);
2838
- });
2839
- }
2840
- leverageRepayFutureLeverage(stateCollateral_1, userCollateral_1, userBorrowed_1) {
2841
- return __awaiter(this, arguments, void 0, function* (stateCollateral, userCollateral, userBorrowed, userAddress = '') {
2842
- userAddress = _getAddress.call(this.llamalend, userAddress);
2843
- this._checkLeverageZap();
2844
- const [userCollateralData, { collateral: currentStateCollateral }] = yield Promise.all([
2845
- _getUserCollateral(this.llamalend.constants.NETWORK_NAME, this.addresses.controller, userAddress),
2846
- this.userState(userAddress),
2847
- ]);
2848
- const totalDepositFromUser = userCollateralData.total_deposit_from_user_precise;
2849
- const collateralFromUserBorrowed = yield this.swapExpected(0, 1, userBorrowed);
2850
- const futureCollateralState = BN(currentStateCollateral).minus(stateCollateral);
2851
- const futureTotalDepositFromUserPrecise = BN(totalDepositFromUser).plus(userCollateral).plus(collateralFromUserBorrowed);
2852
- return futureCollateralState.div(futureTotalDepositFromUserPrecise).toString();
2853
- });
2854
- }
2855
- currentLeverage() {
2856
- return __awaiter(this, arguments, void 0, function* (userAddress = '') {
2857
- userAddress = _getAddress.call(this.llamalend, userAddress);
2858
- const { stateCollateral, totalDepositFromUser } = yield this._getCurrentLeverageParams(userAddress);
2859
- return BN(stateCollateral).div(totalDepositFromUser).toString();
2860
- });
2861
- }
2862
- currentPnL() {
2863
- return __awaiter(this, arguments, void 0, function* (userAddress = '') {
2864
- userAddress = _getAddress.call(this.llamalend, userAddress);
2865
- const calls = [
2866
- this.llamalend.contracts[this.addresses.controller].multicallContract.user_state(userAddress, this.llamalend.constantOptions),
2867
- this.llamalend.contracts[this.addresses.amm].multicallContract.price_oracle(userAddress),
2868
- ];
2869
- const [userState, oraclePrice] = yield this.llamalend.multicallProvider.all(calls);
2870
- if (!(userState || oraclePrice)) {
2871
- throw new Error('Multicall error');
2872
- }
2873
- const debt = userState[2];
2874
- const userCollateral = yield _getUserCollateral(this.llamalend.constants.NETWORK_NAME, this.addresses.controller, userAddress);
2875
- const totalDepositUsdValueFull = userCollateral.total_deposit_usd_value;
2876
- const totalDepositUsdValueUser = userCollateral.total_deposit_from_user_usd_value;
2877
- const totalBorrowed = userCollateral.total_borrowed;
2878
- const oraclePriceFormatted = this.llamalend.formatUnits(oraclePrice, 18);
2879
- const debtFormatted = this.llamalend.formatUnits(debt, 18);
2880
- const { _collateral: AmmCollateral, _borrowed: AmmBorrowed } = yield this._userState(userAddress);
2881
- const [AmmCollateralFormatted, AmmBorrowedFormatted] = [this.llamalend.formatUnits(AmmCollateral, this.collateral_token.decimals), this.llamalend.formatUnits(AmmBorrowed, this.borrowed_token.decimals)];
2882
- const a = BN(AmmCollateralFormatted).times(oraclePriceFormatted);
2883
- const b = BN(totalBorrowed).minus(debtFormatted);
2884
- const currentPosition = a.plus(AmmBorrowedFormatted).plus(b);
2885
- const currentProfit = currentPosition.minus(totalDepositUsdValueFull);
2886
- const percentage = currentProfit.div(totalDepositUsdValueUser).times(100);
2887
- return {
2888
- currentPosition: currentPosition.toFixed(this.borrowed_token.decimals).toString(),
2889
- deposited: totalDepositUsdValueUser.toString(),
2890
- currentProfit: currentProfit.toFixed(this.borrowed_token.decimals).toString(),
2891
- percentage: percentage.toFixed(2).toString(),
2892
- };
2893
- });
2894
- }
2895
- userBoost() {
2896
- return __awaiter(this, arguments, void 0, function* (address = "") {
2897
- if (this.addresses.gauge === this.llamalend.constants.ZERO_ADDRESS) {
2898
- throw Error(`${this.name} doesn't have gauge`);
2899
- }
2900
- if (this.vaultRewardsOnly()) {
2901
- throw Error(`${this.name} has Rewards-Only Gauge. Use stats.rewardsApy instead`);
2902
- }
2903
- address = _getAddress.call(this.llamalend, address);
2904
- const gaugeContract = this.llamalend.contracts[this.addresses.gauge].multicallContract;
2905
- const [workingBalanceBN, balanceBN] = (yield this.llamalend.multicallProvider.all([
2906
- gaugeContract.working_balances(address),
2907
- gaugeContract.balanceOf(address),
2908
- ])).map((value) => toBN(value));
2909
- if (balanceBN.isZero()) {
2910
- return '1.0';
2911
- }
2912
- const boostBN = workingBalanceBN.div(0.4).div(balanceBN);
2913
- if (boostBN.lt(1))
2914
- return '1.0';
2915
- if (boostBN.gt(2.5))
2916
- return '2.5';
2917
- return boostBN.toFixed(4).replace(/([0-9])0+$/, '$1');
2918
- });
2919
- }
2920
- forceUpdateUserState(newTx, userAddress) {
2921
- return __awaiter(this, void 0, void 0, function* () {
2922
- const address = userAddress || this.llamalend.signerAddress;
2923
- if (!address)
2924
- throw Error("Need to connect wallet or pass address into args");
2925
- yield _getUserCollateralForce(this.llamalend.constants.NETWORK_NAME, this.addresses.controller, address, newTx);
2926
- });
2927
- }
2928
305
  getLlamalend() {
2929
306
  return this.llamalend;
2930
307
  }