@aurigami/sdk 1.23.0 → 1.24.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 (101) hide show
  1. package/dist/SDK.d.ts +48 -65
  2. package/dist/SDK.js +165 -0
  3. package/dist/abis/index.d.ts +18 -18
  4. package/dist/abis/index.js +39 -0
  5. package/dist/consts/constants.d.ts +139 -139
  6. package/dist/consts/constants.js +185 -0
  7. package/dist/consts/decimals.d.ts +1 -1
  8. package/dist/consts/decimals.js +35 -0
  9. package/dist/consts/deployments.d.ts +3 -3
  10. package/dist/consts/deployments.js +9 -0
  11. package/dist/consts/dummy.d.ts +13 -13
  12. package/dist/consts/dummy.js +43 -0
  13. package/dist/consts/index.d.ts +5 -5
  14. package/dist/consts/index.js +9 -0
  15. package/dist/consts/symbols.d.ts +1 -1
  16. package/dist/consts/symbols.js +10 -0
  17. package/dist/entities/BlockchainEntity.d.ts +13 -13
  18. package/dist/entities/BlockchainEntity.js +36 -0
  19. package/dist/entities/auriEnv.d.ts +34 -40
  20. package/dist/entities/auriEnv.js +166 -0
  21. package/dist/entities/index.d.ts +4 -4
  22. package/dist/entities/index.js +8 -0
  23. package/dist/entities/token.d.ts +7 -7
  24. package/dist/entities/token.js +27 -0
  25. package/dist/entities/tokenAmount.d.ts +13 -13
  26. package/dist/entities/tokenAmount.js +52 -0
  27. package/dist/helpers/aurigami-api.d.ts +13 -13
  28. package/dist/helpers/aurigami-api.js +26 -0
  29. package/dist/helpers/aurora-api-helpers.d.ts +1 -1
  30. package/dist/helpers/aurora-api-helpers.js +15 -0
  31. package/dist/helpers/graphql-helpers.d.ts +1 -1
  32. package/dist/helpers/graphql-helpers.js +13 -0
  33. package/dist/helpers/helpers.d.ts +23 -40
  34. package/dist/helpers/helpers.js +148 -0
  35. package/dist/helpers/historicalPriceFetcher.d.ts +15 -15
  36. package/dist/helpers/historicalPriceFetcher.js +142 -0
  37. package/dist/helpers/index.d.ts +7 -7
  38. package/dist/helpers/index.js +11 -0
  39. package/dist/helpers/kyber-aggregator-api.d.ts +5 -5
  40. package/dist/helpers/kyber-aggregator-api.js +27 -0
  41. package/dist/helpers/multicall.d.ts +40 -0
  42. package/dist/helpers/multicall.js +203 -0
  43. package/dist/helpers/notification-api.d.ts +2 -2
  44. package/dist/helpers/notification-api.js +21 -0
  45. package/dist/helpers/one-inch-aggregator-api.d.ts +21 -21
  46. package/dist/helpers/one-inch-aggregator-api.js +19 -0
  47. package/dist/helpers/priceFetcher.d.ts +36 -36
  48. package/dist/helpers/priceFetcher.js +296 -0
  49. package/dist/helpers/subgraphQuery.d.ts +1 -1
  50. package/dist/helpers/subgraphQuery.js +22 -0
  51. package/dist/helpers/transfer-event-query.d.ts +17 -26
  52. package/dist/helpers/transfer-event-query.js +41 -0
  53. package/dist/index.d.ts +7 -7
  54. package/dist/index.js +17 -8
  55. package/dist/interactors/Airdrop.d.ts +17 -26
  56. package/dist/interactors/Airdrop.js +48 -0
  57. package/dist/interactors/MoneyMarket.d.ts +63 -63
  58. package/dist/interactors/MoneyMarket.js +392 -0
  59. package/dist/interactors/Multicall.d.ts +15 -18
  60. package/dist/interactors/Multicall.js +36 -0
  61. package/dist/interactors/Papermill.d.ts +27 -57
  62. package/dist/interactors/Papermill.js +125 -0
  63. package/dist/interactors/PlyGame.d.ts +30 -42
  64. package/dist/interactors/PlyGame.js +146 -0
  65. package/dist/interactors/PlyTokenLock.d.ts +16 -16
  66. package/dist/interactors/PlyTokenLock.js +44 -0
  67. package/dist/interactors/Pulp.d.ts +17 -17
  68. package/dist/interactors/Pulp.js +43 -0
  69. package/dist/interactors/Referral.d.ts +35 -78
  70. package/dist/interactors/Referral.js +158 -0
  71. package/dist/interactors/Staking.d.ts +20 -26
  72. package/dist/interactors/Staking.js +106 -0
  73. package/dist/interactors/index.d.ts +9 -9
  74. package/dist/interactors/index.js +13 -0
  75. package/dist/interactors/misc.d.ts +31 -39
  76. package/dist/interactors/misc.js +318 -0
  77. package/dist/types/index.d.ts +175 -197
  78. package/dist/types/index.js +18 -0
  79. package/package.json +3 -3
  80. package/src/SDK.ts +1 -1
  81. package/src/entities/auriEnv.ts +29 -27
  82. package/src/helpers/historicalPriceFetcher.ts +9 -12
  83. package/src/helpers/multicall.ts +251 -0
  84. package/src/helpers/priceFetcher.ts +19 -21
  85. package/src/interactors/Airdrop.ts +2 -2
  86. package/src/interactors/MoneyMarket.ts +31 -27
  87. package/src/interactors/Multicall.ts +3 -3
  88. package/src/interactors/Papermill.ts +9 -9
  89. package/src/interactors/PlyGame.ts +10 -10
  90. package/src/interactors/PlyTokenLock.ts +2 -3
  91. package/src/interactors/Pulp.ts +4 -2
  92. package/src/interactors/Referral.ts +6 -6
  93. package/src/interactors/Staking.ts +13 -9
  94. package/src/interactors/misc.ts +7 -5
  95. package/src/types/index.ts +32 -2
  96. package/dist/sdk.cjs.development.js +0 -6325
  97. package/dist/sdk.cjs.development.js.map +0 -1
  98. package/dist/sdk.cjs.production.min.js +0 -2
  99. package/dist/sdk.cjs.production.min.js.map +0 -1
  100. package/dist/sdk.esm.js +0 -6193
  101. package/dist/sdk.esm.js.map +0 -1
@@ -0,0 +1,251 @@
1
+ import type { BlockTag } from '@ethersproject/abstract-provider';
2
+ import type { Provider } from '@ethersproject/providers';
3
+
4
+ import { CallOverrides, Contract, ContractInterface, Signer } from 'ethers';
5
+ import { FunctionFragment, Interface } from 'ethers/lib/utils';
6
+ import { Multicall2ABI } from '../abis';
7
+ import { MulticallOverrides, MulticallStatic } from '../types';
8
+
9
+ // export const MULTICALL_ADDRESSES: Record<ChainId, Address> = {
10
+ // [CHAIN_ID_MAPPING.ETHEREUM]: toAddress('0x5ba1e12693dc8f9c48aad8770482f4739beed696'),
11
+ // [CHAIN_ID_MAPPING.FUJI]: toAddress('0x07e46d95cc98f0d7493d679e89e396ea99020185'),
12
+ // [CHAIN_ID_MAPPING.MUMBAI]: toAddress('0x7De28d05a0781122565F3b49aA60331ced983a19'),
13
+ // [CHAIN_ID_MAPPING.ARBITRUM]: toAddress('0xcA11bde05977b3631167028862bE2a173976CA11'),
14
+ // } as const;
15
+
16
+ /**
17
+ * Multicall implementation, allowing to call function of contract.callStatic functions
18
+ * using multicall with Promise (without overrides).
19
+ *
20
+ * Example usage:
21
+ * const multicall = new Multicall({
22
+ * chainId,
23
+ * provider,
24
+ * });
25
+ * const contract = new Contract(address, PendleERC20ABI, networkConnection.provider) as PendleERC20;
26
+ *
27
+ * // very small interface changes
28
+ * const balance = await multicall.wrap(contract).callStatic.balanceOf(userAddress);
29
+ *
30
+ * // multiple calls
31
+ * const users = [addr1, addr2, addr3];
32
+ * const balances = await Promise.all(user.map((addr) => multicall.wrap(contract).callStatic.balanceOf(addr)));
33
+ *
34
+ * ### Result caching
35
+ * Multicall#wrap will cache the result right in the contract object. To access the cache result without
36
+ * calling the wrap function, use
37
+ *
38
+ * contract[multicall.multicallStaticSymbol]
39
+ *
40
+ * Note that the field `multicallStaticSymbol` is **not** static, but local to the multicall instance.
41
+ */
42
+
43
+ const TRANSFORMER = new Interface([]);
44
+ export const DEFAULT_CALL_LIMIT = 32;
45
+
46
+ class ContractCall {
47
+ fragment: FunctionFragment;
48
+ address: string;
49
+ params: any[];
50
+
51
+ constructor({
52
+ fragment,
53
+ address,
54
+ params,
55
+ }: {
56
+ fragment: FunctionFragment;
57
+ address: string;
58
+ params: any[];
59
+ }) {
60
+ this.fragment = fragment;
61
+ this.address = address;
62
+ this.params = params;
63
+ }
64
+ }
65
+
66
+ export class Multicall {
67
+ static isMulticallOverrides(
68
+ overrides?: CallOverrides
69
+ ): overrides is MulticallOverrides | undefined {
70
+ if (overrides === undefined) {
71
+ return true;
72
+ }
73
+ for (const key of Object.keys(overrides)) {
74
+ if (key !== 'blockTag' && (overrides as any)[key] != undefined) {
75
+ return false;
76
+ }
77
+ }
78
+ return true;
79
+ }
80
+
81
+ private multicallContract: Contract;
82
+ public readonly batchMap = new Map<BlockTag, MulticallBatch>();
83
+ readonly callLimit: number;
84
+
85
+ // Note: this symbol is unique for each Multicall instance
86
+ readonly multicallStaticSymbol = Symbol.for('multicallStatic');
87
+
88
+ /**
89
+ * Perform _soft_ wrapping. If muticall is presented, multicall.wrap(contract) will be returned.
90
+ * Otherwise the contract itself will be returned. Note that this function is also type-safe,
91
+ * that is, even if the contract is returned, the user is disallowed to call functions
92
+ * with overrides.
93
+ *
94
+ * This function is useful in case where the user when to choose whether to use multicall
95
+ * by themselves.
96
+ */
97
+ static wrap<T extends Contract>(
98
+ contract: T,
99
+ multicall: Multicall | undefined
100
+ ): MulticallStatic<T> {
101
+ return multicall ? multicall.wrap(contract) : (contract as unknown as MulticallStatic<T>);
102
+ }
103
+
104
+ constructor({
105
+ address,
106
+ provider,
107
+ callLimit,
108
+ }: {
109
+ address: string;
110
+ provider: Provider | Signer;
111
+ callLimit?: number;
112
+ }) {
113
+ this.multicallContract = new Contract(address, Multicall2ABI.abi, provider);
114
+ this.callLimit = callLimit ?? DEFAULT_CALL_LIMIT;
115
+ }
116
+
117
+ async doAggregateCalls(calls: readonly ContractCall[], blockTag: BlockTag) {
118
+ const callRequests = calls.map((call) => ({
119
+ target: call.address,
120
+ callData: TRANSFORMER.encodeFunctionData(call.fragment, call.params),
121
+ }));
122
+
123
+ const responses = await this.multicallContract.callStatic.tryAggregate(false, callRequests, {
124
+ blockTag: blockTag,
125
+ });
126
+
127
+ const result = calls.map((call, i) => {
128
+ const [success, returnData] = responses[i];
129
+
130
+ try {
131
+ const outputs: any[] = call.fragment.outputs!;
132
+ const params = TRANSFORMER.decodeFunctionResult(call.fragment, returnData);
133
+
134
+ // If we do the !success check before the decode, we cannot get the error message of
135
+ // decodeFunctionResult. So we always decode first, then check the success later.
136
+ if (!success) {
137
+ const callId = FunctionFragment.from(call.fragment).format();
138
+ throw new Error(`Call ${call.address}:${callId} failed`);
139
+ }
140
+
141
+ return outputs.length === 1 ? params[0] : params;
142
+ } catch (e: any) {
143
+ if (e.reason == null) {
144
+ e.reason = 'Call failed for unknown reason';
145
+ }
146
+ return e;
147
+ }
148
+ });
149
+
150
+ return result;
151
+ }
152
+
153
+ wrap<T extends Contract>(contract_: T): MulticallStatic<T> {
154
+ const contract = contract_ as T & { [key in symbol]: MulticallStatic<T> };
155
+ if (contract[this.multicallStaticSymbol]) {
156
+ return contract[this.multicallStaticSymbol];
157
+ }
158
+ const functions = contract_.interface.functions;
159
+ const funcs: Record<string, (...args: any[]) => Promise<any>> = {};
160
+
161
+ for (const [_, fn] of Object.entries(functions)) {
162
+ funcs[fn.name] = async (...params: any[]) => {
163
+ let blockTag: BlockTag = 'latest';
164
+ if (params.length === fn.inputs.length + 1) {
165
+ const overrides: MulticallOverrides = params.pop() ?? {};
166
+ if (!Multicall.isMulticallOverrides(overrides)) {
167
+ throw new Error('Overrides for multicall should contain only blockTag property');
168
+ }
169
+ blockTag = (await overrides.blockTag) ?? 'latest';
170
+ }
171
+
172
+ const contractCall = new ContractCall({
173
+ fragment: fn,
174
+ address: contract.address,
175
+ params,
176
+ });
177
+ const res = new Promise((resolve, reject) => {
178
+ let currentBatch = this.batchMap.get(blockTag);
179
+ if (currentBatch === undefined) {
180
+ currentBatch = new MulticallBatch(this, blockTag);
181
+ this.batchMap.set(blockTag, currentBatch);
182
+ }
183
+ const dataPos = currentBatch.pendingContractCalls.length;
184
+ currentBatch.pendingContractCalls.push(contractCall);
185
+ currentBatch.promise
186
+ .then((currentResult) =>
187
+ currentResult[dataPos] instanceof Error
188
+ ? reject(currentResult[dataPos])
189
+ : resolve(currentResult[dataPos])
190
+ )
191
+ .catch(reject);
192
+ if (currentBatch.pendingContractCalls.length >= this.callLimit) {
193
+ this.batchMap.delete(blockTag);
194
+ }
195
+ });
196
+
197
+ return res;
198
+ };
199
+ }
200
+
201
+ const res = {
202
+ callStatic: funcs,
203
+ address: contract.address,
204
+ raw: contract,
205
+ } as unknown as MulticallStatic<T>;
206
+
207
+ // Do this to avoid typescript error.
208
+ Object.assign(contract, { [this.multicallStaticSymbol]: res });
209
+
210
+ return res;
211
+ }
212
+ }
213
+
214
+ class MulticallBatch {
215
+ readonly pendingContractCalls: ContractCall[] = [];
216
+ readonly promise: Promise<any[]>;
217
+
218
+ constructor(
219
+ private readonly multicallInstance: Multicall,
220
+ readonly blockTag: BlockTag = 'latest'
221
+ ) {
222
+ this.promise = Promise.resolve().then(async () => {
223
+ // effects
224
+
225
+ // instance comparison
226
+ if (this.multicallInstance.batchMap.get(this.blockTag) === this) {
227
+ this.multicallInstance.batchMap.delete(this.blockTag);
228
+ }
229
+
230
+ // interactions
231
+ return this.multicallInstance.doAggregateCalls(this.pendingContractCalls, this.blockTag);
232
+ });
233
+ }
234
+ }
235
+
236
+ let multicall: Multicall | undefined;
237
+
238
+ export function createContract<T extends Contract>(
239
+ addressOrName: string,
240
+ contractInterface: ContractInterface,
241
+ signerOrProvider: Signer | Provider
242
+ ) {
243
+ const contract = new Contract(addressOrName, contractInterface, signerOrProvider) as T;
244
+ if (!multicall) {
245
+ multicall = new Multicall({
246
+ address: '0xcA11bde05977b3631167028862bE2a173976CA11',
247
+ provider: signerOrProvider,
248
+ });
249
+ }
250
+ return Multicall.wrap(contract, multicall);
251
+ }
@@ -2,7 +2,7 @@ import AuriLensABI from '@aurigami/contracts/artifacts/contracts/AuriLens.sol/Au
2
2
  import { AuriPythOracle, ERC20, IUniswapV2Pair } from '@aurigami/contracts/typechain';
3
3
  import axios from 'axios';
4
4
  import BigNumber from 'bignumber.js';
5
- import { BigNumber as BN, Contract, ethers, providers } from 'ethers';
5
+ import { BigNumber as BN, ethers, providers } from 'ethers';
6
6
  import { AuriOracleABI, EIP20InterfaceABI, IUniswapV2PairABI } from '../abis';
7
7
  import {
8
8
  DECIMAL_PRECISION,
@@ -16,11 +16,12 @@ import { TokenAmount } from '../entities/tokenAmount';
16
16
  import { Address, TokenValuation } from '../types';
17
17
  import { assert, decimalFactor, devLog, getDecimal, isSameAddress } from './helpers';
18
18
  import { getSwapInfo } from './kyber-aggregator-api';
19
+ import { createContract } from './multicall';
19
20
  import { getQuoteOneInch } from './one-inch-aggregator-api';
20
21
 
21
22
  export async function prepareParamsAggregator(address: string, provider: providers.Provider) {
22
- const tokenInErc20 = new Contract(address, EIP20InterfaceABI.abi, provider) as ERC20;
23
- const tokenInDecimal = await tokenInErc20.decimals();
23
+ const tokenInErc20 = createContract<ERC20>(address, EIP20InterfaceABI.abi, provider);
24
+ const tokenInDecimal = await tokenInErc20.callStatic.decimals();
24
25
  const tokenInQuantity = BN.from(10).pow(tokenInDecimal).toString();
25
26
  const usdtAddress =
26
27
  networkAddresses.auTokens.find((autoken) => autoken.name == 'auUSDT')?.underlying ?? '';
@@ -137,12 +138,12 @@ export async function fetchLPPositions(
137
138
  reserve1: BN;
138
139
  totalSupply: BN;
139
140
  }> {
140
- const LPContract = new Contract(LPAddress, IUniswapV2PairABI.abi, provider) as IUniswapV2Pair;
141
+ const LPContract = createContract<IUniswapV2Pair>(LPAddress, IUniswapV2PairABI.abi, provider);
141
142
  const [token0, token1, reserves, totalSupply] = await Promise.all([
142
- LPContract.token0(),
143
- LPContract.token1(),
144
- LPContract.getReserves(),
145
- LPContract.totalSupply(),
143
+ LPContract.callStatic.token0(),
144
+ LPContract.callStatic.token1(),
145
+ LPContract.callStatic.getReserves(),
146
+ LPContract.callStatic.totalSupply(),
146
147
  ]);
147
148
 
148
149
  return {
@@ -229,15 +230,17 @@ export async function fetchPriceFromOracle(
229
230
  underlyingDecimal: number,
230
231
  provider: providers.Provider
231
232
  ): Promise<BigNumber> {
232
- const oracleContract: AuriPythOracle = new Contract(
233
+ const oracleContract = createContract<AuriPythOracle>(
233
234
  networkAddresses.misc.PYTH_ORACLE,
234
235
  AuriOracleABI.abi,
235
236
  provider
236
- ) as AuriPythOracle;
237
- const rawPrice = await oracleContract.getUnderlyingPrice(auTokenAddress).catch((e: any) => {
238
- console.log(`Unable to fetch price from oracle for ${auTokenAddress}`);
239
- return BN.from(0);
240
- });
237
+ );
238
+ const rawPrice = await oracleContract.callStatic
239
+ .getUnderlyingPrice(auTokenAddress)
240
+ .catch((e: any) => {
241
+ console.log(`Unable to fetch price from oracle for ${auTokenAddress}`);
242
+ return BN.from(0);
243
+ });
241
244
 
242
245
  // In case of error, probally it is because the underlying token is not supported
243
246
  // by the backup oracle. In that case, we will fetch from third-party.
@@ -259,16 +262,12 @@ export async function fetchUnderlyingTokensPrices(provider: providers.Provider):
259
262
  underlyingPrice: BigNumber;
260
263
  }[]
261
264
  > {
262
- const auriLens: Contract = new Contract(
263
- networkAddresses.misc.AURILENS,
264
- AuriLensABI.abi,
265
- provider
266
- );
265
+ const auriLens = createContract(networkAddresses.misc.AURILENS, AuriLensABI.abi, provider);
267
266
  const auTokenAddresses = networkAddresses.auTokens.map((auToken) => auToken.address);
268
267
  const underlyingDecimals = networkAddresses.auTokens.map((auToken) =>
269
268
  getDecimal(auToken.underlying)
270
269
  );
271
- const rawPrices = await auriLens.auTokenUnderlyingPriceAll(auTokenAddresses);
270
+ const rawPrices = await auriLens.callStatic.auTokenUnderlyingPriceAll(auTokenAddresses);
272
271
  return rawPrices.map((res: any, ind: number) => {
273
272
  return {
274
273
  auToken: res.auToken,
@@ -280,7 +279,6 @@ export async function fetchUnderlyingTokensPrices(provider: providers.Provider):
280
279
  function shouldFetchFromKyberSwap(address: string) {
281
280
  address = address.toLowerCase();
282
281
  return (
283
- address == networkAddresses.tokens.AURORA ||
284
282
  address == networkAddresses.tokens.TRI ||
285
283
  address == networkAddresses.tokens.META ||
286
284
  address == networkAddresses.tokens.STADER
@@ -22,7 +22,7 @@ export class AirdropRead extends BlockchainEntityRead {
22
22
  ): Promise<TokenAmount> {
23
23
  let tokenInstance: Token = new Token(token, helpers.getDecimal(token));
24
24
 
25
- let rewards: BN = await this.env.auriAirdrop.getRedeemableReward(
25
+ let rewards: BN = await this.env.auriAirdrop.raw.getRedeemableReward(
26
26
  utils.formatBytes32String(campaign),
27
27
  token,
28
28
  user
@@ -44,7 +44,7 @@ export class AirdropReadWrite extends AirdropRead {
44
44
  campaigns.length == tokens.length,
45
45
  'campaigns and tokens must have the same length'
46
46
  );
47
- return this.env.auriAirdrop.connect(this._networkConnection.signer!).redeem(
47
+ return this.env.auriAirdrop.raw.connect(this._networkConnection.signer!).redeem(
48
48
  campaigns.map((e) => utils.formatBytes32String(e)),
49
49
  tokens,
50
50
  await this._networkConnection.signer!.getAddress()
@@ -2,7 +2,7 @@ import { AuETH, AuErc20, EthRepayHelper } from '@aurigami/contracts/typechain';
2
2
  import { TransactionResponse } from '@ethersproject/abstract-provider';
3
3
  import BigNumber from 'bignumber.js';
4
4
  import { CacheType, cache } from 'cache-decorator';
5
- import { BigNumber as BN, Contract } from 'ethers';
5
+ import { BigNumber as BN } from 'ethers';
6
6
  import * as abis from '../abis';
7
7
  import * as consts from '../consts';
8
8
  import { CACHE_TIMEOUT, ONE_DAY } from '../consts';
@@ -15,8 +15,9 @@ import {
15
15
  TokenAmount,
16
16
  } from '../entities';
17
17
  import * as helpers from '../helpers';
18
+ import { createContract } from '../helpers/multicall';
18
19
  import { calcValuation, fetchPrice, fetchValuation } from '../helpers/priceFetcher';
19
- import { Address, Apy, MoneyMarketDetails, NetworkConnection } from '../types';
20
+ import { Address, Apy, MoneyMarketDetails, MulticallStatic, NetworkConnection } from '../types';
20
21
 
21
22
  type RewardSpeeds = {
22
23
  plyRewardSupplySpeed: BN;
@@ -27,19 +28,19 @@ type RewardSpeeds = {
27
28
 
28
29
  export class MoneyMarketRead extends BlockchainEntityRead {
29
30
  public underlying: Token;
30
- public auToken: AuErc20 | AuETH;
31
+ public auToken: MulticallStatic<AuErc20 | AuETH>;
31
32
  public readonly env: AuriEnv;
32
33
  constructor(networkConnection: NetworkConnection, auToken: Address, underlyingAsset: Address) {
33
34
  super(networkConnection);
34
35
  this.env = new AuriEnv(networkConnection);
35
36
  if (helpers.isSameAddress(underlyingAsset, consts.ETHAddress)) {
36
- this.auToken = new Contract(auToken, abis.AuETHABI.abi, networkConnection.provider) as AuETH;
37
+ this.auToken = createContract<AuETH>(auToken, abis.AuETHABI.abi, networkConnection.provider);
37
38
  } else {
38
- this.auToken = new Contract(
39
+ this.auToken = createContract<AuErc20>(
39
40
  auToken,
40
41
  abis.AuErc20ABI.abi,
41
42
  networkConnection.provider
42
- ) as AuErc20;
43
+ );
43
44
  }
44
45
  this.underlying = new Token(underlyingAsset, helpers.getDecimal(underlyingAsset));
45
46
  }
@@ -56,7 +57,7 @@ export class MoneyMarketRead extends BlockchainEntityRead {
56
57
 
57
58
  @cache({ ttl: CACHE_TIMEOUT, type: CacheType.MEMO })
58
59
  protected async getRewardSpeeds(): Promise<RewardSpeeds> {
59
- var speeds = await this.env.auriLens.getRewardSpeeds(
60
+ var speeds = await this.env.auriLens.callStatic.getRewardSpeeds(
60
61
  this.env.comptroller.address,
61
62
  this.auToken.address
62
63
  );
@@ -65,14 +66,17 @@ export class MoneyMarketRead extends BlockchainEntityRead {
65
66
 
66
67
  @cache({ ttl: CACHE_TIMEOUT, type: CacheType.MEMO })
67
68
  public async getTotalTokenBorrowed(): Promise<TokenAmount> {
68
- return new TokenAmount(this.underlying, (await this.auToken.totalBorrows()).toString());
69
+ return new TokenAmount(
70
+ this.underlying,
71
+ (await this.auToken.callStatic.totalBorrows()).toString()
72
+ );
69
73
  }
70
74
 
71
75
  @cache({ ttl: CACHE_TIMEOUT, type: CacheType.MEMO })
72
76
  public async getTotalTokenDeposited(): Promise<TokenAmount> {
73
77
  const [totalBorrow, totalCash] = await Promise.all([
74
78
  this.getTotalTokenBorrowed(),
75
- this.auToken.getCash(),
79
+ this.auToken.callStatic.getCash(),
76
80
  ]);
77
81
  return new TokenAmount(
78
82
  this.underlying,
@@ -84,7 +88,7 @@ export class MoneyMarketRead extends BlockchainEntityRead {
84
88
 
85
89
  @cache({ ttl: CACHE_TIMEOUT, type: CacheType.MEMO })
86
90
  public async getDepositAPY(): Promise<BigNumber> {
87
- const supplyRatePerTimestamp = await this.auToken.supplyRatePerTimestamp();
91
+ const supplyRatePerTimestamp = await this.auToken.callStatic.supplyRatePerTimestamp();
88
92
  const supplyRatePerDay = new BigNumber(supplyRatePerTimestamp.toString())
89
93
  .multipliedBy(ONE_DAY)
90
94
  .div(helpers.decimalFactor(18));
@@ -94,7 +98,7 @@ export class MoneyMarketRead extends BlockchainEntityRead {
94
98
 
95
99
  @cache({ ttl: CACHE_TIMEOUT, type: CacheType.MEMO })
96
100
  public async getBorrowAPY(): Promise<BigNumber> {
97
- const borrowRatePerTimestamp = await this.auToken.borrowRatePerTimestamp();
101
+ const borrowRatePerTimestamp = await this.auToken.callStatic.borrowRatePerTimestamp();
98
102
  const borrowRatePerDay = new BigNumber(borrowRatePerTimestamp.toString())
99
103
  .multipliedBy(ONE_DAY)
100
104
  .div(helpers.decimalFactor(18));
@@ -103,7 +107,7 @@ export class MoneyMarketRead extends BlockchainEntityRead {
103
107
 
104
108
  @cache({ ttl: CACHE_TIMEOUT, type: CacheType.MEMO })
105
109
  public async getCollateralRatio(): Promise<BigNumber> {
106
- return this.env.comptroller.markets(this.auToken.address).then((res: any) => {
110
+ return this.env.comptroller.callStatic.markets(this.auToken.address).then((res: any) => {
107
111
  return new BigNumber(res.collateralFactorMantissa.toString()).div(helpers.decimalFactor(18));
108
112
  });
109
113
  }
@@ -318,13 +322,13 @@ export class MoneyMarketRead extends BlockchainEntityRead {
318
322
  public async mintCap(): Promise<TokenAmount> {
319
323
  return new TokenAmount(
320
324
  this.underlying,
321
- (await this.env.comptroller.mintCaps(this.auToken.address)).toString()
325
+ (await this.env.comptroller.callStatic.mintCaps(this.auToken.address)).toString()
322
326
  );
323
327
  }
324
328
  public async borrowCap(): Promise<TokenAmount> {
325
329
  return new TokenAmount(
326
330
  this.underlying,
327
- (await this.env.comptroller.borrowCaps(this.auToken.address)).toString()
331
+ (await this.env.comptroller.callStatic.borrowCaps(this.auToken.address)).toString()
328
332
  );
329
333
  }
330
334
 
@@ -404,60 +408,60 @@ export class MoneyMarketRead extends BlockchainEntityRead {
404
408
  }
405
409
 
406
410
  export class MoneyMarketReadWrite extends MoneyMarketRead {
407
- protected _EthRepayHelper: EthRepayHelper;
411
+ protected _EthRepayHelper: MulticallStatic<EthRepayHelper>;
408
412
  constructor(networkConnection: NetworkConnection, auToken: Address, underlyingAsset: Address) {
409
413
  super(networkConnection, auToken, underlyingAsset);
410
- this._EthRepayHelper = new Contract(
414
+ this._EthRepayHelper = createContract<EthRepayHelper>(
411
415
  consts.networkAddresses.misc.ETHREPAYHELPER,
412
416
  abis.EthRepayHelperABI.abi,
413
417
  networkConnection.provider
414
- ) as EthRepayHelper;
418
+ );
415
419
  }
416
420
 
417
421
  public async deposit(amount: TokenAmount): Promise<TransactionResponse> {
418
422
  if (helpers.isSameAddress(amount.token.address, consts.ETHAddress)) {
419
- return (this.auToken as AuETH)
423
+ return (this.auToken.raw as AuETH)
420
424
  .connect(this._networkConnection.signer!)
421
425
  .mint({ value: amount.rawAmount() });
422
426
  } else {
423
- return (this.auToken as AuErc20)
427
+ return (this.auToken.raw as AuErc20)
424
428
  .connect(this._networkConnection.signer!)
425
429
  .mint(amount.rawAmount());
426
430
  }
427
431
  }
428
432
  public async borrow(amount: TokenAmount): Promise<TransactionResponse> {
429
- return this.auToken.connect(this._networkConnection.signer!).borrow(amount.rawAmount());
433
+ return this.auToken.raw.connect(this._networkConnection.signer!).borrow(amount.rawAmount());
430
434
  }
431
435
  public async withdraw(amount: TokenAmount): Promise<TransactionResponse> {
432
436
  if (new BigNumber(amount.rawAmount()).lt(0)) {
433
- return this.auToken.connect(this._networkConnection.signer!).redeemUnderlying(consts.INF);
437
+ return this.auToken.raw.connect(this._networkConnection.signer!).redeemUnderlying(consts.INF);
434
438
  }
435
- return this.auToken
439
+ return this.auToken.raw
436
440
  .connect(this._networkConnection.signer!)
437
441
  .redeemUnderlying(amount.rawAmount());
438
442
  }
439
443
  public async repay(amount: TokenAmount): Promise<TransactionResponse> {
440
444
  if (helpers.isSameAddress(amount.token.address, consts.ETHAddress)) {
441
- return this._EthRepayHelper
445
+ return this._EthRepayHelper.raw
442
446
  .connect(this._networkConnection.signer!)
443
447
  .repayBorrow({ value: amount.rawAmount() });
444
448
  } else {
445
449
  if (new BigNumber(amount.rawAmount()).lt(0)) {
446
- return this.auToken.connect(this._networkConnection.signer!).repayBorrow(consts.INF);
450
+ return this.auToken.raw.connect(this._networkConnection.signer!).repayBorrow(consts.INF);
447
451
  } else {
448
- return this.auToken
452
+ return this.auToken.raw
449
453
  .connect(this._networkConnection.signer!)
450
454
  .repayBorrow(amount.rawAmount());
451
455
  }
452
456
  }
453
457
  }
454
458
  public async enableCollateral(): Promise<TransactionResponse> {
455
- return this.env.comptroller
459
+ return this.env.comptroller.raw
456
460
  .connect(this._networkConnection.signer!)
457
461
  .enterMarkets([this.auToken.address]);
458
462
  }
459
463
  public async disableCollateral(): Promise<TransactionResponse> {
460
- return this.env.comptroller
464
+ return this.env.comptroller.raw
461
465
  .connect(this._networkConnection.signer!)
462
466
  .exitMarket(this.auToken.address);
463
467
  }
@@ -4,7 +4,7 @@ import { Result } from 'ethers/lib/utils';
4
4
  import * as abis from '../abis';
5
5
  import * as consts from '../consts';
6
6
  import { BlockchainEntityRead } from '../entities';
7
- import { NetworkConnection } from '../types';
7
+ import { MulticallStatic, NetworkConnection } from '../types';
8
8
 
9
9
  export class MulticallRead extends BlockchainEntityRead {
10
10
  public readonly multicall: Multicall2;
@@ -22,7 +22,7 @@ export class MulticallRead extends BlockchainEntityRead {
22
22
  */
23
23
  public async aggregate(
24
24
  calls: {
25
- contract: Contract;
25
+ contract: MulticallStatic<Contract>;
26
26
  method: string;
27
27
  args: any[];
28
28
  returnTypes: string[];
@@ -32,7 +32,7 @@ export class MulticallRead extends BlockchainEntityRead {
32
32
  // prepare transactions
33
33
  for (let i = 0; i < calls.length; i++) {
34
34
  const call = calls[i];
35
- let txn = await call.contract.populateTransaction[call.method](...call.args);
35
+ let txn = await call.contract.raw.populateTransaction[call.method](...call.args);
36
36
  txns.push({ target: txn.to!, callData: txn.data! });
37
37
  }
38
38
 
@@ -24,12 +24,12 @@ export class PapermillRead extends BlockchainEntityRead {
24
24
  }
25
25
 
26
26
  public async getPlyBalance(userAddress: Address): Promise<TokenAmount> {
27
- const plyBalance = await this.env.ply.balanceOf(userAddress);
27
+ const plyBalance = await this.env.ply.raw.balanceOf(userAddress);
28
28
  return new TokenAmount(this.plyToken, plyBalance.toString());
29
29
  }
30
30
 
31
31
  public async getPulpBalance(userAddress: Address): Promise<TokenAmount> {
32
- const pulpBalance = await this.env.pulp.balanceOf(userAddress);
32
+ const pulpBalance = await this.env.pulp.raw.balanceOf(userAddress);
33
33
  return new TokenAmount(this.pulpToken, pulpBalance.toString());
34
34
  }
35
35
 
@@ -37,7 +37,7 @@ export class PapermillRead extends BlockchainEntityRead {
37
37
  * Get all unclaimed PLY reward of the user in all markets + all staking pools
38
38
  */
39
39
  public async getUnclaimedPlyReward(userAddress: Address): Promise<TokenAmount> {
40
- let rewardBalancesMetadata = await this.env.auriLens.callStatic.claimRewards(
40
+ let rewardBalancesMetadata = await this.env.auriLens.raw.callStatic.claimRewards(
41
41
  this.env.comptroller.address,
42
42
  this.env.auriFairLaunch.address,
43
43
  consts.ALL_STAKING_POOLS,
@@ -60,8 +60,8 @@ export class PapermillRead extends BlockchainEntityRead {
60
60
  const currentWeek = this.getWeek(helpers.getCurrentTimestamp());
61
61
 
62
62
  const values = await Promise.all([
63
- this.env.auriLens.getPercentLock(this.env.pulp.address, userAddress, currentWeek),
64
- this.env.auriLens.getPercentLock(this.env.pulp.address, userAddress, currentWeek + 1),
63
+ this.env.auriLens.raw.getPercentLock(this.env.pulp.address, userAddress, currentWeek),
64
+ this.env.auriLens.raw.getPercentLock(this.env.pulp.address, userAddress, currentWeek + 1),
65
65
  this.getUnclaimedPlyReward(userAddress),
66
66
  ]);
67
67
 
@@ -69,7 +69,7 @@ export class PapermillRead extends BlockchainEntityRead {
69
69
  let percentLockNextWeek = BN.from(values[1]);
70
70
  let totalRewards = values[2] as TokenAmount;
71
71
 
72
- let [pulpAmountCurrentWeek, plyAmountCurrentWeek] = await this.env.pulp.calcLockAmount(
72
+ let [pulpAmountCurrentWeek, plyAmountCurrentWeek] = await this.env.pulp.raw.calcLockAmount(
73
73
  userAddress,
74
74
  totalRewards.rawAmount()
75
75
  );
@@ -109,7 +109,7 @@ export class PapermillRead extends BlockchainEntityRead {
109
109
  userAddress: Address,
110
110
  targetUnlockPortion: number
111
111
  ): Promise<number> {
112
- let weekId = await this.env.auriLens.getWeekToUnlock(
112
+ let weekId = await this.env.auriLens.raw.getWeekToUnlock(
113
113
  this.env.pulp.address,
114
114
  userAddress,
115
115
  targetUnlockPortion * 100
@@ -131,7 +131,7 @@ export class PapermillRead extends BlockchainEntityRead {
131
131
  }
132
132
 
133
133
  public async getUnlockPortionAt(userAddress: Address, timestamp: number): Promise<number> {
134
- let lockPortion = await this.env.auriLens.getPercentLock(
134
+ let lockPortion = await this.env.auriLens.raw.getPercentLock(
135
135
  this.env.pulp.address,
136
136
  userAddress,
137
137
  this.getWeek(timestamp)
@@ -155,7 +155,7 @@ export class PapermillReadWrite extends PapermillRead {
155
155
  * Set to ethers.constants.MaxUint256 for max redeem.
156
156
  */
157
157
  public async redeem(recipient: Address, amount: TokenAmount): Promise<TransactionResponse> {
158
- return this.env.pulp
158
+ return this.env.pulp.raw
159
159
  .connect(this._networkConnection.signer!)
160
160
  .redeem(recipient, amount.rawAmount());
161
161
  }