@aurigami/sdk 1.6.0-no-src → 1.6.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.
@@ -0,0 +1,510 @@
1
+ import AuErc20ABI from '@aurigami/contracts/artifacts/contracts/AuErc20.sol/AuErc20.json';
2
+ import AuETHABI from '@aurigami/contracts/artifacts/contracts/AuETH.sol/AuETH.json';
3
+ import AuriLensABI from '@aurigami/contracts/artifacts/contracts/AuriLens.sol/AuriLens.json';
4
+ import ComptrollerABI from '@aurigami/contracts/artifacts/contracts/Comptroller.sol/Comptroller.json';
5
+ import EthRepayHelperABI from '@aurigami/contracts/artifacts/contracts/EthRepayHelper.sol/EthRepayHelper.json';
6
+ import {
7
+ AuErc20,
8
+ AuETH,
9
+ AuriLens,
10
+ Comptroller,
11
+ EthRepayHelper,
12
+ } from '@aurigami/contracts/typechain';
13
+ import { TransactionResponse } from '@ethersproject/abstract-provider';
14
+ import BigNumber from 'bignumber.js';
15
+ import { BigNumber as BN, Contract } from 'ethers';
16
+ import * as consts from '../consts';
17
+ import {
18
+ BlockchainEntity,
19
+ BlockchainEntityRead,
20
+ PLYToken,
21
+ Token,
22
+ TokenAmount,
23
+ } from '../entities';
24
+ import * as helpers from '../helpers/';
25
+ import {
26
+ calcValuation,
27
+ fetchPrice,
28
+ fetchValuation,
29
+ } from '../helpers/priceFetcher';
30
+ import {
31
+ Address,
32
+ ComptrollerRewardType,
33
+ MoneyMarketDetails,
34
+ NetworkConnection,
35
+ } from '../types';
36
+
37
+ type RewardSpeeds = {
38
+ plyRewardSupplySpeed: BN;
39
+ plyRewardBorrowSpeed: BN;
40
+ auroraRewardSupplySpeed: BN;
41
+ auroraRewardBorrowSpeed: BN;
42
+ };
43
+
44
+ export class MoneyMarketRead extends BlockchainEntityRead {
45
+ public underlying: Token;
46
+ public auToken: AuErc20 | AuETH;
47
+ protected _comptroller: Comptroller;
48
+
49
+ protected _auriLens: AuriLens;
50
+ constructor(
51
+ networkConnection: NetworkConnection,
52
+ auToken: Address,
53
+ underlyingAsset: Address
54
+ ) {
55
+ super(networkConnection);
56
+ if (helpers.isSameAddress(underlyingAsset, consts.ETHAddress)) {
57
+ this.auToken = new Contract(
58
+ auToken,
59
+ AuETHABI.abi,
60
+ networkConnection.provider
61
+ ) as AuETH;
62
+ } else {
63
+ this.auToken = new Contract(
64
+ auToken,
65
+ AuErc20ABI.abi,
66
+ networkConnection.provider
67
+ ) as AuErc20;
68
+ }
69
+ this.underlying = new Token(
70
+ underlyingAsset,
71
+ helpers.getDecimal(underlyingAsset)
72
+ );
73
+ this._comptroller = new Contract(
74
+ consts.networkAddresses.misc.COMPTROLLER,
75
+ ComptrollerABI.abi,
76
+ networkConnection.provider
77
+ ) as Comptroller;
78
+ this._auriLens = new Contract(
79
+ consts.networkAddresses.misc.AURILENS,
80
+ AuriLensABI.abi,
81
+ networkConnection.provider
82
+ ) as AuriLens;
83
+ }
84
+
85
+ protected async getRewardSpeeds(): Promise<RewardSpeeds> {
86
+ var speeds = await this._auriLens.getRewardSpeeds(
87
+ this._comptroller.address,
88
+ this.auToken.address
89
+ );
90
+ return speeds;
91
+ }
92
+ public async getTotalTokenBorrowed(): Promise<TokenAmount> {
93
+ return new TokenAmount(
94
+ this.underlying,
95
+ (await this.auToken.totalBorrows()).toString()
96
+ );
97
+ }
98
+ public async getTotalTokenDeposited(): Promise<TokenAmount> {
99
+ var promises = [];
100
+ var totalBorrow: TokenAmount, totalCash: TokenAmount;
101
+ promises.push(
102
+ this.getTotalTokenBorrowed().then((res: TokenAmount) => {
103
+ totalBorrow = res;
104
+ })
105
+ );
106
+ promises.push(
107
+ this.auToken.getCash().then((res: BN) => {
108
+ totalCash = new TokenAmount(this.underlying, res.toString());
109
+ })
110
+ );
111
+ await Promise.all(promises);
112
+ return new TokenAmount(
113
+ this.underlying,
114
+ BN.from(totalCash!.rawAmount()).add(totalBorrow!.rawAmount()).toString()
115
+ );
116
+ }
117
+
118
+ public async getDepositAPY(): Promise<BigNumber> {
119
+ const supplyRatePerTimestamp = await this.auToken.supplyRatePerTimestamp();
120
+ return new BigNumber(supplyRatePerTimestamp.toString())
121
+ .multipliedBy(60 * 60 * 24 * 365)
122
+ .div(helpers.decimalFactor(18));
123
+ }
124
+
125
+ public async getBorrowAPY(): Promise<BigNumber> {
126
+ const borrowRatePerTimestamp = await this.auToken.borrowRatePerTimestamp();
127
+ return new BigNumber(borrowRatePerTimestamp.toString())
128
+ .multipliedBy(60 * 60 * 24 * 365)
129
+ .div(helpers.decimalFactor(18));
130
+ }
131
+
132
+ public async getCollateralRatio(): Promise<BigNumber> {
133
+ return this._comptroller.markets(this.auToken.address).then((res: any) => {
134
+ return new BigNumber(res.collateralFactorMantissa.toString()).div(
135
+ helpers.decimalFactor(18)
136
+ );
137
+ });
138
+ }
139
+
140
+ public async getBorrowPlyAPY(): Promise<BigNumber> {
141
+ var promises = [];
142
+ var totalBorrowed: TokenAmount,
143
+ rewardSpeed: TokenAmount,
144
+ plyPrice: BigNumber,
145
+ underlyingPrice: BigNumber;
146
+ promises.push(
147
+ this.getTotalTokenBorrowed().then((res: TokenAmount) => {
148
+ totalBorrowed = res;
149
+ })
150
+ );
151
+ promises.push(
152
+ this._comptroller
153
+ .rewardSpeeds(ComptrollerRewardType.PLY, this.auToken.address, false)
154
+ .then((res) => {
155
+ rewardSpeed = new TokenAmount(PLYToken, res.toString());
156
+ })
157
+ );
158
+ promises.push(
159
+ fetchPrice(
160
+ consts.networkAddresses.tokens.PLY,
161
+ this._networkConnection.provider
162
+ ).then((res) => {
163
+ plyPrice = res;
164
+ })
165
+ );
166
+ promises.push(
167
+ fetchPrice(
168
+ this.underlying.address,
169
+ this._networkConnection.provider
170
+ ).then((res) => {
171
+ underlyingPrice = res;
172
+ })
173
+ );
174
+ await Promise.all(promises);
175
+ return helpers.calcLMRewardApr(
176
+ plyPrice!.multipliedBy(rewardSpeed!.formattedAmount()),
177
+ underlyingPrice!.multipliedBy(totalBorrowed!.formattedAmount()),
178
+ consts.ONE_YEAR
179
+ );
180
+ }
181
+
182
+ public async getDepositPlyAPY(): Promise<BigNumber> {
183
+ var promises = [];
184
+ var totalDeposited: TokenAmount,
185
+ rewardSpeed: TokenAmount,
186
+ plyPrice: BigNumber,
187
+ underlyingPrice: BigNumber;
188
+ promises.push(
189
+ this.getTotalTokenDeposited().then((res: TokenAmount) => {
190
+ totalDeposited = res;
191
+ })
192
+ );
193
+ promises.push(
194
+ this._comptroller
195
+ .rewardSpeeds(ComptrollerRewardType.PLY, this.auToken.address, true)
196
+ .then((res) => {
197
+ rewardSpeed = new TokenAmount(PLYToken, res.toString());
198
+ })
199
+ );
200
+ promises.push(
201
+ fetchPrice(
202
+ consts.networkAddresses.tokens.PLY,
203
+ this._networkConnection.provider
204
+ ).then((res) => {
205
+ plyPrice = res;
206
+ })
207
+ );
208
+ promises.push(
209
+ fetchPrice(
210
+ this.underlying.address,
211
+ this._networkConnection.provider
212
+ ).then((res) => {
213
+ underlyingPrice = res;
214
+ })
215
+ );
216
+ await Promise.all(promises);
217
+ return helpers.calcLMRewardApr(
218
+ plyPrice!.multipliedBy(rewardSpeed!.formattedAmount()),
219
+ underlyingPrice!.multipliedBy(totalDeposited!.formattedAmount()),
220
+ consts.ONE_YEAR
221
+ );
222
+ }
223
+ public async getDetails(): Promise<MoneyMarketDetails> {
224
+ var promises = [],
225
+ totalDeposited: TokenAmount,
226
+ totalBorrowed: TokenAmount,
227
+ depositAPY: number,
228
+ borrowAPY: number,
229
+ collateralRatio: number;
230
+ promises.push(
231
+ this.getTotalTokenDeposited().then((res: TokenAmount) => {
232
+ totalDeposited = res;
233
+ })
234
+ );
235
+ promises.push(
236
+ this.getTotalTokenBorrowed().then((res: TokenAmount) => {
237
+ totalBorrowed = res;
238
+ })
239
+ );
240
+ promises.push(
241
+ this.getDepositAPY().then((res: BigNumber) => {
242
+ depositAPY = res.toNumber();
243
+ })
244
+ );
245
+ promises.push(
246
+ this.getBorrowAPY().then((res: BigNumber) => {
247
+ borrowAPY = res.toNumber();
248
+ })
249
+ );
250
+ promises.push(
251
+ this.getCollateralRatio().then((res: BigNumber) => {
252
+ collateralRatio = res.toNumber();
253
+ })
254
+ );
255
+
256
+ var plyPrice: BigNumber,
257
+ underlyingPrice: BigNumber,
258
+ rewardSpeeds: RewardSpeeds;
259
+ promises.push(
260
+ this.getRewardSpeeds().then((res) => {
261
+ rewardSpeeds = res;
262
+ })
263
+ );
264
+ promises.push(
265
+ fetchPrice(
266
+ consts.networkAddresses.tokens.PLY,
267
+ this._networkConnection.provider
268
+ ).then((res) => {
269
+ plyPrice = res;
270
+ })
271
+ );
272
+ promises.push(
273
+ fetchPrice(
274
+ this.underlying.address,
275
+ this._networkConnection.provider
276
+ ).then((res) => {
277
+ underlyingPrice = res;
278
+ })
279
+ );
280
+
281
+ await Promise.all(promises);
282
+
283
+ var borrowPlyApy = helpers.calcLMRewardApr(
284
+ calcValuation(
285
+ new TokenAmount(
286
+ PLYToken,
287
+ rewardSpeeds!.plyRewardBorrowSpeed.toString()
288
+ ),
289
+ plyPrice!
290
+ ),
291
+ underlyingPrice!.multipliedBy(totalBorrowed!.formattedAmount()),
292
+ consts.ONE_YEAR
293
+ );
294
+ var depositPlyApy = helpers.calcLMRewardApr(
295
+ calcValuation(
296
+ new TokenAmount(
297
+ PLYToken,
298
+ rewardSpeeds!.plyRewardSupplySpeed.toString()
299
+ ),
300
+ plyPrice!
301
+ ),
302
+ underlyingPrice!.multipliedBy(totalDeposited!.formattedAmount()),
303
+ consts.ONE_YEAR
304
+ );
305
+
306
+ var depositNEARApy = helpers.calcLMRewardApr(
307
+ await fetchValuation(
308
+ this.getDepositNEARRewardPerWeek(),
309
+ this._networkConnection.provider
310
+ ),
311
+ underlyingPrice!.multipliedBy(totalDeposited!.formattedAmount()),
312
+ 52
313
+ );
314
+ var borrowNEARApy = helpers.calcLMRewardApr(
315
+ await fetchValuation(
316
+ this.getBorrowNEARRewardPerWeek(),
317
+ this._networkConnection.provider
318
+ ),
319
+ underlyingPrice!.multipliedBy(totalBorrowed!.formattedAmount()),
320
+ 52
321
+ );
322
+ var depositMETAApy;
323
+ if (
324
+ helpers.isSameAddress(
325
+ this.underlying.address,
326
+ consts.networkAddresses.tokens.stNEAR
327
+ )
328
+ ) {
329
+ depositMETAApy = helpers.calcLMRewardApr(
330
+ new BigNumber(50000),
331
+ underlyingPrice!.multipliedBy(totalDeposited!.formattedAmount()),
332
+ 12
333
+ );
334
+ } else {
335
+ depositMETAApy = new BigNumber(0);
336
+ }
337
+
338
+ return {
339
+ auTokenAddress: this.auToken.address,
340
+ totalTokenDeposited: totalDeposited!,
341
+ totalTokenBorrowed: totalBorrowed!,
342
+ depositApy: depositAPY!,
343
+ depositPlyApy: depositPlyApy.toNumber(),
344
+ borrowApy: borrowAPY!,
345
+ borrowPlyApy: borrowPlyApy.toNumber() * -1,
346
+ collateralRatio: collateralRatio!,
347
+ depositPlyPerWeek: new TokenAmount(
348
+ PLYToken,
349
+ rewardSpeeds!.plyRewardSupplySpeed.mul(consts.ONE_DAY).mul(7).toString()
350
+ ),
351
+ borrowPlyPerWeek: new TokenAmount(
352
+ PLYToken,
353
+ rewardSpeeds!.plyRewardBorrowSpeed.mul(consts.ONE_DAY).mul(7).toString()
354
+ ),
355
+ depositNEARApy: depositNEARApy.toNumber(),
356
+ borrowNEARApy: borrowNEARApy.toNumber() * -1,
357
+ depositMETAApy: depositMETAApy.toNumber(),
358
+ };
359
+ }
360
+
361
+ public async getUserBorrowBalance(userAddress: string): Promise<TokenAmount> {
362
+ const totalBorrow: BN = await this.auToken.callStatic.borrowBalanceCurrent(
363
+ userAddress
364
+ );
365
+ return new TokenAmount(this.underlying, totalBorrow.toString());
366
+ }
367
+
368
+ public async getUserDepositBalance(
369
+ userAddress: string
370
+ ): Promise<TokenAmount> {
371
+ const totalDeposit: BN = await this.auToken.callStatic.balanceOfUnderlying(
372
+ userAddress
373
+ );
374
+ return new TokenAmount(this.underlying, totalDeposit.toString());
375
+ }
376
+
377
+ private getDepositNEARRewardPerWeek(): TokenAmount {
378
+ const NEARToken = new Token(
379
+ consts.networkAddresses.tokens.WNEAR,
380
+ helpers.getDecimal(consts.networkAddresses.tokens.WNEAR)
381
+ );
382
+ const rewardStartTime = 1650636000;
383
+ const rewardStopTime = 1651845600; // May 06, 2022 2 PM GMT
384
+ const currentTime = helpers.getCurrentTimestamp();
385
+ if (currentTime <= rewardStopTime && currentTime > rewardStartTime) {
386
+ const reward =
387
+ consts.DEPOSIT_NEAR_REWARDS_PER_WEEK[
388
+ this.underlying.address.toLocaleLowerCase()
389
+ ] ?? '0';
390
+ return new TokenAmount(NEARToken, reward, false);
391
+ } else {
392
+ return new TokenAmount(NEARToken, '0');
393
+ }
394
+ }
395
+
396
+ private getBorrowNEARRewardPerWeek(): TokenAmount {
397
+ const NEARToken = new Token(
398
+ consts.networkAddresses.tokens.WNEAR,
399
+ helpers.getDecimal(consts.networkAddresses.tokens.WNEAR)
400
+ );
401
+ const rewardStartTime = 1650636000;
402
+ const rewardStopTime = 1651845600; // May 06, 2022 2 PM GMT
403
+ const currentTime = helpers.getCurrentTimestamp();
404
+ if (currentTime <= rewardStopTime && currentTime > rewardStartTime) {
405
+ const reward =
406
+ consts.BORROW_NEAR_REWARDS_PER_WEEK[
407
+ this.underlying.address.toLocaleLowerCase()
408
+ ] ?? '0';
409
+ return new TokenAmount(NEARToken, reward, false);
410
+ } else {
411
+ return new TokenAmount(NEARToken, '0');
412
+ }
413
+ }
414
+ }
415
+
416
+ export class MoneyMarketReadWrite extends MoneyMarketRead {
417
+ protected _EthRepayHelper: EthRepayHelper;
418
+ constructor(
419
+ networkConnection: NetworkConnection,
420
+ auToken: Address,
421
+ underlyingAsset: Address
422
+ ) {
423
+ super(networkConnection, auToken, underlyingAsset);
424
+ this._EthRepayHelper = new Contract(
425
+ consts.networkAddresses.misc.ETHREPAYHELPER,
426
+ EthRepayHelperABI.abi,
427
+ networkConnection.provider
428
+ ) as EthRepayHelper;
429
+ }
430
+
431
+ public async deposit(amount: TokenAmount): Promise<TransactionResponse> {
432
+ if (helpers.isSameAddress(amount.token.address, consts.ETHAddress)) {
433
+ return (this.auToken as AuETH)
434
+ .connect(this._networkConnection.signer!)
435
+ .mint({ value: amount.rawAmount() });
436
+ } else {
437
+ return (this.auToken as AuErc20)
438
+ .connect(this._networkConnection.signer!)
439
+ .mint(amount.rawAmount());
440
+ }
441
+ }
442
+ public async borrow(amount: TokenAmount): Promise<TransactionResponse> {
443
+ return this.auToken
444
+ .connect(this._networkConnection.signer!)
445
+ .borrow(amount.rawAmount());
446
+ }
447
+ public async withdraw(amount: TokenAmount): Promise<TransactionResponse> {
448
+ if (new BigNumber(amount.rawAmount()).lt(0)) {
449
+ return this.auToken
450
+ .connect(this._networkConnection.signer!)
451
+ .redeemUnderlying(consts.INF);
452
+ }
453
+ return this.auToken
454
+ .connect(this._networkConnection.signer!)
455
+ .redeemUnderlying(amount.rawAmount());
456
+ }
457
+ public async repay(amount: TokenAmount): Promise<TransactionResponse> {
458
+ if (helpers.isSameAddress(amount.token.address, consts.ETHAddress)) {
459
+ return this._EthRepayHelper
460
+ .connect(this._networkConnection.signer!)
461
+ .repayBorrow({ value: amount.rawAmount() });
462
+ } else {
463
+ if (new BigNumber(amount.rawAmount()).lt(0)) {
464
+ return this.auToken
465
+ .connect(this._networkConnection.signer!)
466
+ .repayBorrow(consts.INF);
467
+ } else {
468
+ return this.auToken
469
+ .connect(this._networkConnection.signer!)
470
+ .repayBorrow(amount.rawAmount());
471
+ }
472
+ }
473
+ }
474
+ public async enableCollateral(): Promise<TransactionResponse> {
475
+ return this._comptroller
476
+ .connect(this._networkConnection.signer!)
477
+ .enterMarkets([this.auToken.address]);
478
+ }
479
+ public async disableCollateral(): Promise<TransactionResponse> {
480
+ return this._comptroller
481
+ .connect(this._networkConnection.signer!)
482
+ .exitMarket(this.auToken.address);
483
+ }
484
+ }
485
+
486
+ export class MoneyMarket extends BlockchainEntity {
487
+ protected address: Address;
488
+
489
+ protected underlying: Address;
490
+ constructor(address: string, underlying: string) {
491
+ super();
492
+ this.address = helpers.validateAndParseAddress(address);
493
+ this.underlying = helpers.validateAndParseAddress(underlying);
494
+ }
495
+ public read(networkConnection: NetworkConnection): MoneyMarketRead {
496
+ return new MoneyMarketRead(
497
+ networkConnection,
498
+ this.address,
499
+ this.underlying
500
+ );
501
+ }
502
+
503
+ public readWrite(networkConnection: NetworkConnection): MoneyMarketReadWrite {
504
+ return new MoneyMarketReadWrite(
505
+ networkConnection,
506
+ this.address,
507
+ this.underlying
508
+ );
509
+ }
510
+ }