@curvefi/llamalend-api 1.0.2

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 (125) hide show
  1. package/.eslintrc.json +40 -0
  2. package/.github/workflows/lint.yml +15 -0
  3. package/.github/workflows/publish.yml +55 -0
  4. package/LICENSE +21 -0
  5. package/README.md +1976 -0
  6. package/lib/cache/index.d.ts +14 -0
  7. package/lib/cache/index.js +31 -0
  8. package/lib/constants/L2Networks.d.ts +1 -0
  9. package/lib/constants/L2Networks.js +1 -0
  10. package/lib/constants/abis/Controller.json +1027 -0
  11. package/lib/constants/abis/ERC20.json +222 -0
  12. package/lib/constants/abis/ERC4626.json +1674 -0
  13. package/lib/constants/abis/GaugeController.json +794 -0
  14. package/lib/constants/abis/GaugeFactoryMainnet.json +1 -0
  15. package/lib/constants/abis/GaugeFactorySidechain.json +475 -0
  16. package/lib/constants/abis/GaugeV5.json +958 -0
  17. package/lib/constants/abis/LeverageZap.json +35 -0
  18. package/lib/constants/abis/Llamma.json +984 -0
  19. package/lib/constants/abis/Minter.json +1 -0
  20. package/lib/constants/abis/MonetaryPolicy.json +221 -0
  21. package/lib/constants/abis/OneWayLendingFactoryABI.json +899 -0
  22. package/lib/constants/abis/SidechainGauge.json +939 -0
  23. package/lib/constants/abis/Vault.json +721 -0
  24. package/lib/constants/abis/crvUSD/DeleverageZap.json +248 -0
  25. package/lib/constants/abis/crvUSD/Factory.json +514 -0
  26. package/lib/constants/abis/crvUSD/HealthCalculatorZap.json +54 -0
  27. package/lib/constants/abis/crvUSD/LeverageZap.json +312 -0
  28. package/lib/constants/abis/crvUSD/MonetaryPolicy.json +294 -0
  29. package/lib/constants/abis/crvUSD/MonetaryPolicy2.json +299 -0
  30. package/lib/constants/abis/crvUSD/PegKeeper.json +411 -0
  31. package/lib/constants/abis/crvUSD/controller.json +991 -0
  32. package/lib/constants/abis/crvUSD/llamma.json +984 -0
  33. package/lib/constants/abis/gas_oracle_optimism.json +149 -0
  34. package/lib/constants/abis/gas_oracle_optimism_blob.json +203 -0
  35. package/lib/constants/aliases.d.ts +16 -0
  36. package/lib/constants/aliases.js +124 -0
  37. package/lib/constants/coins.d.ts +16 -0
  38. package/lib/constants/coins.js +24 -0
  39. package/lib/constants/llammas.d.ts +2 -0
  40. package/lib/constants/llammas.js +96 -0
  41. package/lib/constants/utils.d.ts +4 -0
  42. package/lib/constants/utils.js +27 -0
  43. package/lib/external-api.d.ts +13 -0
  44. package/lib/external-api.js +436 -0
  45. package/lib/index.d.ts +104 -0
  46. package/lib/index.js +123 -0
  47. package/lib/interfaces.d.ts +228 -0
  48. package/lib/interfaces.js +1 -0
  49. package/lib/lendMarkets/LendMarketTemplate.d.ts +510 -0
  50. package/lib/lendMarkets/LendMarketTemplate.js +4682 -0
  51. package/lib/lendMarkets/index.d.ts +3 -0
  52. package/lib/lendMarkets/index.js +3 -0
  53. package/lib/lendMarkets/lendMarketConstructor.d.ts +2 -0
  54. package/lib/lendMarkets/lendMarketConstructor.js +6 -0
  55. package/lib/llamalend.d.ts +80 -0
  56. package/lib/llamalend.js +878 -0
  57. package/lib/mintMarkets/MintMarketTemplate.d.ts +308 -0
  58. package/lib/mintMarkets/MintMarketTemplate.js +2998 -0
  59. package/lib/mintMarkets/index.d.ts +3 -0
  60. package/lib/mintMarkets/index.js +3 -0
  61. package/lib/mintMarkets/mintMarketConstructor.d.ts +2 -0
  62. package/lib/mintMarkets/mintMarketConstructor.js +4 -0
  63. package/lib/st-crvUSD.d.ts +35 -0
  64. package/lib/st-crvUSD.js +505 -0
  65. package/lib/utils.d.ts +58 -0
  66. package/lib/utils.js +661 -0
  67. package/package.json +42 -0
  68. package/src/cache/index.ts +41 -0
  69. package/src/constants/L2Networks.ts +1 -0
  70. package/src/constants/abis/Controller.json +1027 -0
  71. package/src/constants/abis/ERC20.json +222 -0
  72. package/src/constants/abis/ERC4626.json +1674 -0
  73. package/src/constants/abis/GaugeController.json +794 -0
  74. package/src/constants/abis/GaugeFactoryMainnet.json +1 -0
  75. package/src/constants/abis/GaugeFactorySidechain.json +475 -0
  76. package/src/constants/abis/GaugeV5.json +958 -0
  77. package/src/constants/abis/LeverageZap.json +35 -0
  78. package/src/constants/abis/Llamma.json +984 -0
  79. package/src/constants/abis/Minter.json +1 -0
  80. package/src/constants/abis/MonetaryPolicy.json +221 -0
  81. package/src/constants/abis/OneWayLendingFactoryABI.json +899 -0
  82. package/src/constants/abis/SidechainGauge.json +939 -0
  83. package/src/constants/abis/Vault.json +721 -0
  84. package/src/constants/abis/crvUSD/DeleverageZap.json +248 -0
  85. package/src/constants/abis/crvUSD/ERC20.json +222 -0
  86. package/src/constants/abis/crvUSD/Factory.json +514 -0
  87. package/src/constants/abis/crvUSD/HealthCalculatorZap.json +54 -0
  88. package/src/constants/abis/crvUSD/LeverageZap.json +312 -0
  89. package/src/constants/abis/crvUSD/MonetaryPolicy.json +294 -0
  90. package/src/constants/abis/crvUSD/MonetaryPolicy2.json +299 -0
  91. package/src/constants/abis/crvUSD/PegKeeper.json +411 -0
  92. package/src/constants/abis/crvUSD/controller.json +991 -0
  93. package/src/constants/abis/crvUSD/llamma.json +984 -0
  94. package/src/constants/abis/gas_oracle_optimism.json +149 -0
  95. package/src/constants/abis/gas_oracle_optimism_blob.json +203 -0
  96. package/src/constants/aliases.ts +141 -0
  97. package/src/constants/coins.ts +41 -0
  98. package/src/constants/llammas.ts +99 -0
  99. package/src/constants/utils.ts +33 -0
  100. package/src/external-api.ts +325 -0
  101. package/src/index.ts +128 -0
  102. package/src/interfaces.ts +237 -0
  103. package/src/lendMarkets/LendMarketTemplate.ts +3022 -0
  104. package/src/lendMarkets/index.ts +7 -0
  105. package/src/lendMarkets/lendMarketConstructor.ts +7 -0
  106. package/src/llamalend.ts +785 -0
  107. package/src/mintMarkets/MintMarketTemplate.ts +1781 -0
  108. package/src/mintMarkets/index.ts +7 -0
  109. package/src/mintMarkets/mintMarketConstructor.ts +5 -0
  110. package/src/st-crvUSD.ts +244 -0
  111. package/src/utils.ts +497 -0
  112. package/test/fetch.test.ts +152 -0
  113. package/test/general.test.ts +216 -0
  114. package/test/leverageBorrowMore.test.ts +245 -0
  115. package/test/leverageCreateLoan.test.ts +236 -0
  116. package/test/leverageRepay.test.ts +240 -0
  117. package/test/readme.test.ts +475 -0
  118. package/test/selfLiquidate.test.ts +57 -0
  119. package/test/selfLiquidateCrvUSD.test.ts +54 -0
  120. package/test/st_crvUSD.test.ts +68 -0
  121. package/test/swap.test.ts +62 -0
  122. package/test/swapCrvUSD.test.ts +56 -0
  123. package/test/vault.test.ts +112 -0
  124. package/tsconfig.build.json +10 -0
  125. package/tsconfig.json +72 -0
@@ -0,0 +1,236 @@
1
+ import { assert } from "chai";
2
+ import llamalend from "../src/index.js";
3
+ import { getOneWayMarket, OneWayMarketTemplate } from "../src/markets/index.js";
4
+ import { BN } from "../src/utils.js";
5
+
6
+
7
+ const ONE_WAY_MARKETS = ['one-way-market-9'];
8
+
9
+ const generalTest = (id: string) => {
10
+ describe(`${id} leverage createLoan test`, function () {
11
+ let oneWayMarket: OneWayMarketTemplate;
12
+
13
+ before(async function () {
14
+ oneWayMarket = getOneWayMarket(id);
15
+ if (Number(await oneWayMarket.vault.totalLiquidity()) === 0) {
16
+ const maxDeposit = Number(await oneWayMarket.vault.maxDeposit()) * 0.7;
17
+ await oneWayMarket.vault.deposit(maxDeposit);
18
+ }
19
+ });
20
+
21
+ it('Leverage createLoan collateral only, debt too high', async function () {
22
+ const initialBalances = await oneWayMarket.wallet.balances();
23
+ const loanExists = await oneWayMarket.userLoanExists();
24
+
25
+ assert.isFalse(loanExists, "loanExists");
26
+ assert.isAbove(Number(initialBalances.collateral), 0, "collateral > 0");
27
+ assert.isAbove(Number(initialBalances.borrowed), 0, "borrowed > 0");
28
+
29
+ const collateralAmount = 0.02;
30
+ const borrowedAmount = 0;
31
+ const N = 10;
32
+ const { maxDebt } = await oneWayMarket.leverage.createLoanMaxRecv(collateralAmount, borrowedAmount, N);
33
+ const debtAmount = (Number(maxDebt) * 1.004).toFixed(oneWayMarket.borrowed_token.decimals);
34
+
35
+ try {
36
+ await oneWayMarket.leverage.createLoanExpectedCollateral(collateralAmount, borrowedAmount, debtAmount, 1);
37
+ await oneWayMarket.leverage.createLoan(collateralAmount, borrowedAmount, debtAmount, N, 1);
38
+ throw Error("Did not revert");
39
+ } catch (e) {
40
+ // @ts-ignore
41
+ assert.notEqual(e.message, "Did not revert", e.message);
42
+ // @ts-ignore
43
+ assert.isTrue(e.message.startsWith('execution reverted: "Debt too high"'), e.message);
44
+ }
45
+ });
46
+
47
+ it('Leverage createLoan borrowed only, debt too high', async function () {
48
+ const initialBalances = await oneWayMarket.wallet.balances();
49
+ const loanExists = await oneWayMarket.userLoanExists();
50
+
51
+ assert.isFalse(loanExists, "loanExists");
52
+ assert.isAbove(Number(initialBalances.collateral), 0, "collateral > 0");
53
+ assert.isAbove(Number(initialBalances.borrowed), 0, "borrowed > 0");
54
+
55
+ const collateralAmount = 0;
56
+ const borrowedAmount = 1000;
57
+ const N = 10;
58
+ const { maxDebt } = await oneWayMarket.leverage.createLoanMaxRecv(collateralAmount, borrowedAmount, N);
59
+ const debtAmount = (Number(maxDebt) * 1.004).toFixed(oneWayMarket.borrowed_token.decimals);
60
+
61
+ try {
62
+ await oneWayMarket.leverage.createLoanExpectedCollateral(collateralAmount, borrowedAmount, debtAmount, 1);
63
+ await oneWayMarket.leverage.createLoan(collateralAmount, borrowedAmount, debtAmount, N, 1);
64
+ throw Error("Did not revert");
65
+ } catch (e) {
66
+ // @ts-ignore
67
+ assert.notEqual(e.message, "Did not revert", e.message);
68
+ // @ts-ignore
69
+ assert.isTrue(e.message.startsWith('execution reverted: "Debt too high"'), e.message);
70
+ }
71
+ });
72
+
73
+ it('Leverage createLoan, debt too high', async function () {
74
+ const initialBalances = await oneWayMarket.wallet.balances();
75
+ const loanExists = await oneWayMarket.userLoanExists();
76
+
77
+ assert.isFalse(loanExists, "loanExists");
78
+ assert.isAbove(Number(initialBalances.collateral), 0, "collateral > 0");
79
+ assert.isAbove(Number(initialBalances.borrowed), 0, "borrowed > 0");
80
+
81
+ const collateralAmount = 0.02;
82
+ const borrowedAmount = 1000;
83
+ const N = 10;
84
+ const { maxDebt } = await oneWayMarket.leverage.createLoanMaxRecv(collateralAmount, borrowedAmount, N);
85
+ const debtAmount = (Number(maxDebt) * 1.004).toFixed(oneWayMarket.borrowed_token.decimals);
86
+
87
+ try {
88
+ await oneWayMarket.leverage.createLoanExpectedCollateral(collateralAmount, borrowedAmount, debtAmount, 1);
89
+ await oneWayMarket.leverage.createLoan(collateralAmount, borrowedAmount, debtAmount, N, 1);
90
+ throw Error("Did not revert");
91
+ } catch (e) {
92
+ // @ts-ignore
93
+ assert.notEqual(e.message, "Did not revert", e.message);
94
+ // @ts-ignore
95
+ assert.isTrue(e.message.startsWith('execution reverted: "Debt too high"'), e.message);
96
+ }
97
+ });
98
+
99
+ it('Leverage createLoan collateral only', async function () {
100
+ const initialBalances = await oneWayMarket.wallet.balances();
101
+ const loanExists = await oneWayMarket.userLoanExists();
102
+
103
+ assert.isFalse(loanExists, "loanExists");
104
+ assert.isAbove(Number(initialBalances.collateral), 0, "collateral > 0");
105
+ assert.isAbove(Number(initialBalances.borrowed), 0, "borrowed > 0");
106
+
107
+ const collateralAmount = 0.02;
108
+ const borrowedAmount = 0;
109
+ const N = 10;
110
+ const { maxDebt } = await oneWayMarket.leverage.createLoanMaxRecv(collateralAmount, borrowedAmount, N);
111
+ const debtAmount = (Number(maxDebt) / 2).toFixed(oneWayMarket.borrowed_token.decimals);
112
+ const { totalCollateral } = await oneWayMarket.leverage.createLoanExpectedCollateral(collateralAmount, borrowedAmount, debtAmount, 1);
113
+ const createLoanBands = await oneWayMarket.leverage.createLoanBands(collateralAmount, borrowedAmount, debtAmount, N);
114
+ const createLoanPrices = await oneWayMarket.leverage.createLoanPrices(collateralAmount, borrowedAmount, debtAmount, N);
115
+ const createLoanFullHealth = await oneWayMarket.leverage.createLoanHealth(collateralAmount, borrowedAmount, debtAmount, N);
116
+ const createLoanHealth = await oneWayMarket.leverage.createLoanHealth(collateralAmount, borrowedAmount, debtAmount, N, false);
117
+
118
+ await oneWayMarket.leverage.createLoan(collateralAmount, borrowedAmount, debtAmount, N, 1);
119
+
120
+ const balances = await oneWayMarket.wallet.balances();
121
+ const state = await oneWayMarket.userState();
122
+ const userBands = await oneWayMarket.userBands();
123
+ const userPrices = await oneWayMarket.userPrices();
124
+ const fullHealth = await oneWayMarket.userHealth();
125
+ const health = await oneWayMarket.userHealth(false);
126
+
127
+ assert.equal(Number(createLoanBands[0]), Number(userBands[0]), 'band 0');
128
+ assert.equal(Number(createLoanBands[1]), Number(userBands[1]), 'band 1');
129
+ assert.approximately(Number(createLoanPrices[0]), Number(userPrices[0]), 1, 'price 0');
130
+ assert.approximately(Number(createLoanPrices[1]), Number(userPrices[1]), 1, 'price 1');
131
+ assert.approximately(Number(createLoanFullHealth), Number(fullHealth), 1, 'full health');
132
+ assert.approximately(Number(createLoanHealth), Number(health), 0.3, 'health');
133
+ assert.equal(Number(balances.collateral), BN(initialBalances.collateral).minus(collateralAmount).toNumber(), 'wallet collateral');
134
+ assert.equal(Number(balances.borrowed), Number(initialBalances.borrowed) - borrowedAmount, 'wallet borrowed');
135
+ assert.isAtMost(Math.abs(Number(state.collateral) - Number(totalCollateral)) / Number(totalCollateral), 0.01, 'state collateral');
136
+ assert.equal(Number(state.debt), Number(debtAmount), 'state debt');
137
+
138
+ await oneWayMarket.fullRepay();
139
+ });
140
+
141
+ it('Leverage createLoan borrowed only', async function () {
142
+ const initialBalances = await oneWayMarket.wallet.balances();
143
+ const loanExists = await oneWayMarket.userLoanExists();
144
+
145
+ assert.isFalse(loanExists, "loanExists");
146
+ assert.isAbove(Number(initialBalances.collateral), 0, "collateral > 0");
147
+ assert.isAbove(Number(initialBalances.borrowed), 0, "borrowed > 0");
148
+
149
+ const collateralAmount = 0;
150
+ const borrowedAmount = 1000;
151
+ const N = 10;
152
+ const { maxDebt } = await oneWayMarket.leverage.createLoanMaxRecv(collateralAmount, borrowedAmount, N);
153
+ const debtAmount = (Number(maxDebt) / 2).toFixed(oneWayMarket.borrowed_token.decimals);
154
+ const { totalCollateral } = await oneWayMarket.leverage.createLoanExpectedCollateral(collateralAmount, borrowedAmount, debtAmount, 1);
155
+ const createLoanBands = await oneWayMarket.leverage.createLoanBands(collateralAmount, borrowedAmount, debtAmount, N);
156
+ const createLoanPrices = await oneWayMarket.leverage.createLoanPrices(collateralAmount, borrowedAmount, debtAmount, N);
157
+ const createLoanFullHealth = await oneWayMarket.leverage.createLoanHealth(collateralAmount, borrowedAmount, debtAmount, N);
158
+ const createLoanHealth = await oneWayMarket.leverage.createLoanHealth(collateralAmount, borrowedAmount, debtAmount, N, false);
159
+
160
+ await oneWayMarket.leverage.createLoan(collateralAmount, borrowedAmount, debtAmount, N, 1);
161
+
162
+ const balances = await oneWayMarket.wallet.balances();
163
+ const state = await oneWayMarket.userState();
164
+ const userBands = await oneWayMarket.userBands();
165
+ const userPrices = await oneWayMarket.userPrices();
166
+ const fullHealth = await oneWayMarket.userHealth();
167
+ const health = await oneWayMarket.userHealth(false);
168
+
169
+ assert.equal(Number(createLoanBands[0]), Number(userBands[0]), 'band 0');
170
+ assert.equal(Number(createLoanBands[1]), Number(userBands[1]), 'band 1');
171
+ assert.approximately(Number(createLoanPrices[0]), Number(userPrices[0]), 1, 'price 0');
172
+ assert.approximately(Number(createLoanPrices[1]), Number(userPrices[1]), 1, 'price 1');
173
+ assert.approximately(Number(createLoanFullHealth), Number(fullHealth), 1, 'full health');
174
+ assert.approximately(Number(createLoanHealth), Number(health), 0.3, 'health');
175
+ assert.equal(Number(balances.collateral), BN(initialBalances.collateral).minus(collateralAmount).toNumber(), 'wallet collateral');
176
+ assert.equal(Number(balances.borrowed), Number(initialBalances.borrowed) - borrowedAmount, 'wallet borrowed');
177
+ assert.isAtMost(Math.abs(Number(state.collateral) - Number(totalCollateral)) / Number(totalCollateral), 0.01, 'state collateral');
178
+ assert.equal(Number(state.debt), Number(debtAmount), 'state debt');
179
+
180
+ await oneWayMarket.fullRepay();
181
+ });
182
+
183
+ it('Leverage createLoan', async function () {
184
+ const initialBalances = await oneWayMarket.wallet.balances();
185
+ const loanExists = await oneWayMarket.userLoanExists();
186
+
187
+ assert.isFalse(loanExists, "loanExists");
188
+ assert.isAbove(Number(initialBalances.collateral), 0, "collateral > 0");
189
+ assert.isAbove(Number(initialBalances.borrowed), 0, "borrowed > 0");
190
+
191
+ const collateralAmount = 0.02;
192
+ const borrowedAmount = 1000;
193
+ const N = 10;
194
+ const { maxDebt } = await oneWayMarket.leverage.createLoanMaxRecv(collateralAmount, borrowedAmount, N);
195
+ const debtAmount = (Number(maxDebt) * 0.999).toFixed(oneWayMarket.borrowed_token.decimals);
196
+ const { totalCollateral } = await oneWayMarket.leverage.createLoanExpectedCollateral(collateralAmount, borrowedAmount, debtAmount, 1);
197
+ const createLoanBands = await oneWayMarket.leverage.createLoanBands(collateralAmount, borrowedAmount, debtAmount, N);
198
+ const createLoanPrices = await oneWayMarket.leverage.createLoanPrices(collateralAmount, borrowedAmount, debtAmount, N);
199
+ const createLoanFullHealth = await oneWayMarket.leverage.createLoanHealth(collateralAmount, borrowedAmount, debtAmount, N);
200
+ const createLoanHealth = await oneWayMarket.leverage.createLoanHealth(collateralAmount, borrowedAmount, debtAmount, N, false);
201
+
202
+ await oneWayMarket.leverage.createLoan(collateralAmount, borrowedAmount, debtAmount, N, 1);
203
+
204
+ const balances = await oneWayMarket.wallet.balances();
205
+ const state = await oneWayMarket.userState();
206
+ const userBands = await oneWayMarket.userBands();
207
+ const userPrices = await oneWayMarket.userPrices();
208
+ const fullHealth = await oneWayMarket.userHealth();
209
+ const health = await oneWayMarket.userHealth(false);
210
+
211
+ assert.equal(Number(createLoanBands[0]), Number(userBands[0]), 'band 0');
212
+ assert.equal(Number(createLoanBands[1]), Number(userBands[1]), 'band 1');
213
+ assert.approximately(Number(createLoanPrices[0]), Number(userPrices[0]), 1, 'price 0');
214
+ assert.approximately(Number(createLoanPrices[1]), Number(userPrices[1]), 1, 'price 1');
215
+ assert.approximately(Number(createLoanFullHealth), Number(fullHealth), 1, 'full health');
216
+ assert.approximately(Number(createLoanHealth), Number(health), 0.3, 'health');
217
+ assert.equal(Number(balances.collateral), BN(initialBalances.collateral).minus(collateralAmount).toNumber(), 'wallet collateral');
218
+ assert.equal(Number(balances.borrowed), Number(initialBalances.borrowed) - borrowedAmount, 'wallet borrowed');
219
+ assert.isAtMost(Math.abs(Number(state.collateral) - Number(totalCollateral)) / Number(totalCollateral), 0.01, 'state collateral');
220
+ assert.equal(Number(state.debt), Number(debtAmount), 'state debt');
221
+ });
222
+ })
223
+ }
224
+
225
+ describe('Leverage createLoan test', async function () {
226
+ this.timeout(180000);
227
+
228
+ before(async function () {
229
+ await llamalend.init('JsonRpc', {},{ gasPrice: 0 });
230
+ await llamalend.oneWayfactory.fetchMarkets();
231
+ });
232
+
233
+ for (const oneWayMarketId of ONE_WAY_MARKETS) {
234
+ generalTest(oneWayMarketId);
235
+ }
236
+ })
@@ -0,0 +1,240 @@
1
+ import { assert } from "chai";
2
+ import llamalend from "../src/index.js";
3
+ import { getOneWayMarket, OneWayMarketTemplate } from "../src/markets/index.js";
4
+ import { BN } from "../src/utils.js";
5
+
6
+
7
+ const ONE_WAY_MARKETS = ['one-way-market-9'];
8
+
9
+ const generalTest = (id: string) => {
10
+ describe(`${id} leverage repay test`, function () {
11
+ let oneWayMarket: OneWayMarketTemplate;
12
+
13
+ before(async function () {
14
+ oneWayMarket = getOneWayMarket(id);
15
+ if (Number(await oneWayMarket.vault.totalLiquidity()) === 0) {
16
+ const maxDeposit = Number(await oneWayMarket.vault.maxDeposit()) * 0.7;
17
+ await oneWayMarket.vault.deposit(maxDeposit);
18
+ }
19
+ if (!(await oneWayMarket.userLoanExists())) {
20
+ const collateralAmount = 0.02;
21
+ const borrowedAmount = 1000;
22
+ const N = 10;
23
+ const { maxDebt } = await oneWayMarket.leverage.createLoanMaxRecv(collateralAmount, borrowedAmount, N);
24
+ const debtAmount = (Number(maxDebt) / 2).toFixed(oneWayMarket.borrowed_token.decimals);
25
+
26
+ await oneWayMarket.leverage.createLoanExpectedCollateral(collateralAmount, borrowedAmount, debtAmount, 1);
27
+ await oneWayMarket.leverage.createLoan(collateralAmount, borrowedAmount, debtAmount, N, 1);
28
+ }
29
+ });
30
+
31
+ it('Leverage repay state collateral only', async function () {
32
+ const initialBalances = await oneWayMarket.wallet.balances();
33
+ const initialState = await oneWayMarket.userState();
34
+ const loanExists = await oneWayMarket.userLoanExists();
35
+
36
+ assert.isTrue(loanExists, "loanExists");
37
+ assert.isAbove(Number(initialBalances.collateral), 0, "collateral > 0");
38
+ assert.isAbove(Number(initialBalances.borrowed), 0, "borrowed > 0");
39
+
40
+ const stateCollateralAmount = 0.0002;
41
+ const collateralAmount = 0;
42
+ const borrowedAmount = 0;
43
+ const { totalBorrowed } = await oneWayMarket.leverage.repayExpectedBorrowed(stateCollateralAmount, collateralAmount, borrowedAmount, 1);
44
+ const repayBands = await oneWayMarket.leverage.repayBands(stateCollateralAmount, collateralAmount, borrowedAmount);
45
+ const repayPrices = await oneWayMarket.leverage.repayPrices(stateCollateralAmount, collateralAmount, borrowedAmount);
46
+ const repayFullHealth = await oneWayMarket.leverage.repayHealth(stateCollateralAmount, collateralAmount, borrowedAmount);
47
+ const repayHealth = await oneWayMarket.leverage.repayHealth(stateCollateralAmount, collateralAmount, borrowedAmount, false);
48
+
49
+ await oneWayMarket.leverage.repay(stateCollateralAmount, collateralAmount, borrowedAmount, 1);
50
+ await new Promise((r) => setTimeout(r, 5000)); // Timeout needed to update fork state
51
+
52
+ const balances = await oneWayMarket.wallet.balances();
53
+ const state = await oneWayMarket.userState();
54
+ const userBands = await oneWayMarket.userBands();
55
+ const userPrices = await oneWayMarket.userPrices();
56
+ const fullHealth = await oneWayMarket.userHealth();
57
+ const health = await oneWayMarket.userHealth(false);
58
+
59
+ assert.equal(Number(repayBands[0]), Number(userBands[0]), 'band 0');
60
+ assert.equal(Number(repayBands[1]), Number(userBands[1]), 'band 1');
61
+ assert.approximately(Number(repayPrices[0]), Number(userPrices[0]), 0.1, 'price 0');
62
+ assert.approximately(Number(repayPrices[1]), Number(userPrices[1]), 0.1, 'price 1');
63
+ assert.approximately(Number(repayFullHealth), Number(fullHealth), 0.1, 'full health');
64
+ assert.approximately(Number(repayHealth), Number(health), 0.1, 'health');
65
+ assert.equal(Number(balances.collateral), BN(initialBalances.collateral).minus(collateralAmount).toNumber(), 'wallet collateral');
66
+ assert.equal(Number(balances.borrowed), Number(initialBalances.borrowed) - borrowedAmount, 'wallet borrowed');
67
+ assert.deepStrictEqual(BN(state.collateral), BN(initialState.collateral).minus(stateCollateralAmount),'state collateral');
68
+ const debtDiff = Number(initialState.debt) - Number(state.debt);
69
+ assert.isAtMost(Math.abs(debtDiff - Number(totalBorrowed)) / Number(totalBorrowed), 0.01, 'state debt');
70
+ });
71
+
72
+ it('Leverage repay user collateral only', async function () {
73
+ const initialBalances = await oneWayMarket.wallet.balances();
74
+ const initialState = await oneWayMarket.userState();
75
+ const loanExists = await oneWayMarket.userLoanExists();
76
+
77
+ assert.isTrue(loanExists, "loanExists");
78
+ assert.isAbove(Number(initialBalances.collateral), 0, "collateral > 0");
79
+ assert.isAbove(Number(initialBalances.borrowed), 0, "borrowed > 0");
80
+
81
+ const stateCollateralAmount = 0;
82
+ const collateralAmount = 0.0002;
83
+ const borrowedAmount = 0;
84
+ const { totalBorrowed } = await oneWayMarket.leverage.repayExpectedBorrowed(stateCollateralAmount, collateralAmount, borrowedAmount, 1);
85
+ const repayBands = await oneWayMarket.leverage.repayBands(stateCollateralAmount, collateralAmount, borrowedAmount);
86
+ const repayPrices = await oneWayMarket.leverage.repayPrices(stateCollateralAmount, collateralAmount, borrowedAmount);
87
+ const repayFullHealth = await oneWayMarket.leverage.repayHealth(stateCollateralAmount, collateralAmount, borrowedAmount);
88
+ const repayHealth = await oneWayMarket.leverage.repayHealth(stateCollateralAmount, collateralAmount, borrowedAmount, false);
89
+
90
+ await oneWayMarket.leverage.repay(stateCollateralAmount, collateralAmount, borrowedAmount, 1);
91
+ await new Promise((r) => setTimeout(r, 5000)); // Timeout needed to update fork state
92
+
93
+ const balances = await oneWayMarket.wallet.balances();
94
+ const state = await oneWayMarket.userState();
95
+ const userBands = await oneWayMarket.userBands();
96
+ const userPrices = await oneWayMarket.userPrices();
97
+ const fullHealth = await oneWayMarket.userHealth();
98
+ const health = await oneWayMarket.userHealth(false);
99
+
100
+ assert.equal(Number(repayBands[0]), Number(userBands[0]), 'band 0');
101
+ assert.equal(Number(repayBands[1]), Number(userBands[1]), 'band 1');
102
+ assert.approximately(Number(repayPrices[0]), Number(userPrices[0]), 0.1, 'price 0');
103
+ assert.approximately(Number(repayPrices[1]), Number(userPrices[1]), 0.1, 'price 1');
104
+ assert.approximately(Number(repayFullHealth), Number(fullHealth), 0.1, 'full health');
105
+ assert.approximately(Number(repayHealth), Number(health), 0.1, 'health');
106
+ assert.equal(Number(balances.collateral), BN(initialBalances.collateral).minus(collateralAmount).toNumber(), 'wallet collateral');
107
+ assert.equal(Number(balances.borrowed), Number(initialBalances.borrowed) - borrowedAmount, 'wallet borrowed');
108
+ assert.equal(Number(state.collateral), Number(initialState.collateral) - Number(stateCollateralAmount), 'state collateral');
109
+ const debtDiff = Number(initialState.debt) - Number(state.debt);
110
+ assert.isAtMost(Math.abs(debtDiff - Number(totalBorrowed)) / Number(totalBorrowed), 0.01, 'state debt');
111
+ });
112
+
113
+ it('Leverage repay user borrowed only', async function () {
114
+ const initialBalances = await oneWayMarket.wallet.balances();
115
+ const initialState = await oneWayMarket.userState();
116
+ const loanExists = await oneWayMarket.userLoanExists();
117
+
118
+ assert.isTrue(loanExists, "loanExists");
119
+ assert.isAbove(Number(initialBalances.collateral), 0, "collateral > 0");
120
+ assert.isAbove(Number(initialBalances.borrowed), 0, "borrowed > 0");
121
+
122
+ const stateCollateralAmount = 0;
123
+ const collateralAmount = 0;
124
+ const borrowedAmount = 500;
125
+ const { totalBorrowed } = await oneWayMarket.leverage.repayExpectedBorrowed(stateCollateralAmount, collateralAmount, borrowedAmount, 1);
126
+ const repayBands = await oneWayMarket.leverage.repayBands(stateCollateralAmount, collateralAmount, borrowedAmount);
127
+ const repayPrices = await oneWayMarket.leverage.repayPrices(stateCollateralAmount, collateralAmount, borrowedAmount);
128
+ const repayFullHealth = await oneWayMarket.leverage.repayHealth(stateCollateralAmount, collateralAmount, borrowedAmount);
129
+ const repayHealth = await oneWayMarket.leverage.repayHealth(stateCollateralAmount, collateralAmount, borrowedAmount, false);
130
+
131
+ await oneWayMarket.leverage.repay(stateCollateralAmount, collateralAmount, borrowedAmount, 1);
132
+ await new Promise((r) => setTimeout(r, 5000)); // Timeout needed to update fork state
133
+
134
+ const balances = await oneWayMarket.wallet.balances();
135
+ const state = await oneWayMarket.userState();
136
+ const userBands = await oneWayMarket.userBands();
137
+ const userPrices = await oneWayMarket.userPrices();
138
+ const fullHealth = await oneWayMarket.userHealth();
139
+ const health = await oneWayMarket.userHealth(false);
140
+
141
+ assert.equal(Number(repayBands[0]), Number(userBands[0]), 'band 0');
142
+ assert.equal(Number(repayBands[1]), Number(userBands[1]), 'band 1');
143
+ assert.approximately(Number(repayPrices[0]), Number(userPrices[0]), 0.1, 'price 0');
144
+ assert.approximately(Number(repayPrices[1]), Number(userPrices[1]), 0.1, 'price 1');
145
+ assert.approximately(Number(repayFullHealth), Number(fullHealth), 0.1, 'full health');
146
+ assert.approximately(Number(repayHealth), Number(health), 0.1, 'health');
147
+ assert.equal(Number(balances.collateral), BN(initialBalances.collateral).minus(collateralAmount).toNumber(), 'wallet collateral');
148
+ assert.equal(Number(balances.borrowed), Number(initialBalances.borrowed) - borrowedAmount, 'wallet borrowed');
149
+ assert.equal(Number(state.collateral), Number(initialState.collateral) - Number(stateCollateralAmount), 'state collateral');
150
+ assert.equal(borrowedAmount, Number(totalBorrowed), 'borrowed amount');
151
+ const debtDiff = Number(initialState.debt) - Number(state.debt);
152
+ assert.isAtMost(Math.abs(debtDiff - Number(totalBorrowed)) / Number(totalBorrowed), 2e-6, 'state debt');
153
+ });
154
+
155
+ it('Leverage repay', async function () {
156
+ const initialBalances = await oneWayMarket.wallet.balances();
157
+ const initialState = await oneWayMarket.userState();
158
+ const loanExists = await oneWayMarket.userLoanExists();
159
+
160
+ assert.isTrue(loanExists, "loanExists");
161
+ assert.isAbove(Number(initialBalances.collateral), 0, "collateral > 0");
162
+ assert.isAbove(Number(initialBalances.borrowed), 0, "borrowed > 0");
163
+
164
+ const stateCollateralAmount = 0.0003;
165
+ const collateralAmount = 0.0002;
166
+ const borrowedAmount = 500;
167
+ const { totalBorrowed } = await oneWayMarket.leverage.repayExpectedBorrowed(stateCollateralAmount, collateralAmount, borrowedAmount, 1);
168
+ const repayBands = await oneWayMarket.leverage.repayBands(stateCollateralAmount, collateralAmount, borrowedAmount);
169
+ const repayPrices = await oneWayMarket.leverage.repayPrices(stateCollateralAmount, collateralAmount, borrowedAmount);
170
+ const repayFullHealth = await oneWayMarket.leverage.repayHealth(stateCollateralAmount, collateralAmount, borrowedAmount);
171
+ const repayHealth = await oneWayMarket.leverage.repayHealth(stateCollateralAmount, collateralAmount, borrowedAmount, false);
172
+
173
+ await oneWayMarket.leverage.repay(stateCollateralAmount, collateralAmount, borrowedAmount, 1);
174
+ await new Promise((r) => setTimeout(r, 5000)); // Timeout needed to update fork state
175
+
176
+ const balances = await oneWayMarket.wallet.balances();
177
+ const state = await oneWayMarket.userState();
178
+ const userBands = await oneWayMarket.userBands();
179
+ const userPrices = await oneWayMarket.userPrices();
180
+ const fullHealth = await oneWayMarket.userHealth();
181
+ const health = await oneWayMarket.userHealth(false);
182
+
183
+ assert.equal(Number(repayBands[0]), Number(userBands[0]), 'band 0');
184
+ assert.equal(Number(repayBands[1]), Number(userBands[1]), 'band 1');
185
+ assert.approximately(Number(repayPrices[0]), Number(userPrices[0]), 0.1, 'price 0');
186
+ assert.approximately(Number(repayPrices[1]), Number(userPrices[1]), 0.1, 'price 1');
187
+ assert.approximately(Number(repayFullHealth), Number(fullHealth), 0.1, 'full health');
188
+ assert.approximately(Number(repayHealth), Number(health), 0.1, 'health');
189
+ assert.equal(Number(balances.collateral), BN(initialBalances.collateral).minus(collateralAmount).toNumber(), 'wallet collateral');
190
+ assert.equal(Number(balances.borrowed), Number(initialBalances.borrowed) - borrowedAmount, 'wallet borrowed');
191
+ assert.deepStrictEqual(BN(state.collateral), BN(initialState.collateral).minus(stateCollateralAmount), 'state collateral');
192
+ const debtDiff = Number(initialState.debt) - Number(state.debt);
193
+ assert.isAtMost(Math.abs(debtDiff - Number(totalBorrowed)) / Number(totalBorrowed), 0.01, 'state debt');
194
+ });
195
+
196
+ it('Leverage full repay', async function () {
197
+ const initialBalances = await oneWayMarket.wallet.balances();
198
+ const initialState = await oneWayMarket.userState();
199
+ let loanExists = await oneWayMarket.userLoanExists();
200
+
201
+ assert.isTrue(loanExists, "loan does not exist");
202
+ assert.isAbove(Number(initialBalances.collateral), 0, "collateral > 0");
203
+ assert.isAbove(Number(initialBalances.borrowed), 0, "borrowed > 0");
204
+
205
+ const stateCollateralAmount = (Number(initialState.collateral) / 3).toFixed(oneWayMarket.collateral_token.decimals);
206
+ const collateralAmount = (Number(initialState.collateral) / 3).toFixed(oneWayMarket.collateral_token.decimals);
207
+ const borrowedAmount = (Number(initialState.debt) / 3).toFixed(oneWayMarket.borrowed_token.decimals);
208
+ const { totalBorrowed } = await oneWayMarket.leverage.repayExpectedBorrowed(stateCollateralAmount, collateralAmount, borrowedAmount, 1);
209
+
210
+ await oneWayMarket.leverage.repay(stateCollateralAmount, collateralAmount, borrowedAmount, 1);
211
+ await new Promise((r) => setTimeout(r, 5000)); // Timeout needed to update fork state
212
+
213
+ const balances = await oneWayMarket.wallet.balances();
214
+ const state = await oneWayMarket.userState();
215
+ loanExists = await oneWayMarket.userLoanExists();
216
+
217
+ assert.isFalse(loanExists, "loan still exists");
218
+ assert.approximately(Number(balances.collateral), Number(initialBalances.collateral) + (Number(initialState.collateral) / 3), 1e-6, 'wallet collateral');
219
+ const borrowedDiff = (Number(balances.borrowed) + Number(initialState.debt)) - (Number(initialBalances.borrowed) - Number(borrowedAmount));
220
+ assert.isTrue(borrowedDiff > 0); // Same sign
221
+ assert.isAtMost(Math.abs(borrowedDiff - Number(totalBorrowed)) / Math.abs(borrowedDiff), 0.01, 'wallet borrowed');
222
+ assert.equal(Number(state.collateral), 0, 'state collateral');
223
+ assert.equal(Number(state.borrowed), 0, 'state borrowed');
224
+ assert.equal(Number(state.debt), 0, 'state debt');
225
+ });
226
+ })
227
+ }
228
+
229
+ describe('Leverage repay test', async function () {
230
+ this.timeout(180000);
231
+
232
+ before(async function () {
233
+ await llamalend.init('JsonRpc', {},{ gasPrice: 0 });
234
+ await llamalend.oneWayfactory.fetchMarkets();
235
+ });
236
+
237
+ for (const oneWayMarketId of ONE_WAY_MARKETS) {
238
+ generalTest(oneWayMarketId);
239
+ }
240
+ })