@paraswap/dex-lib 3.7.3 → 3.7.4-stata

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 (36) hide show
  1. package/build/dex/aave-v3-stata/aave-v3-stata.d.ts +0 -2
  2. package/build/dex/aave-v3-stata/aave-v3-stata.js +84 -41
  3. package/build/dex/aave-v3-stata/aave-v3-stata.js.map +1 -1
  4. package/build/dex/aave-v3-stata/tokens.d.ts +1 -0
  5. package/build/dex/aave-v3-stata/tokens.js +11 -5
  6. package/build/dex/aave-v3-stata/tokens.js.map +1 -1
  7. package/build/dex/balancer-v2/balancer-v2.js.map +1 -1
  8. package/build/dex/idle-dao/idle-dao.js +10 -8
  9. package/build/dex/idle-dao/idle-dao.js.map +1 -1
  10. package/build/dex/index.js +2 -0
  11. package/build/dex/index.js.map +1 -1
  12. package/build/dex/pancakeswap-v3/pancakeswap-v3.js +1 -0
  13. package/build/dex/pancakeswap-v3/pancakeswap-v3.js.map +1 -1
  14. package/build/dex/solidly-v3/solidly-v3.js +1 -0
  15. package/build/dex/solidly-v3/solidly-v3.js.map +1 -1
  16. package/build/dex/uniswap-v3/forks/velodrome-slipstream/velodrome-slipstream.js +1 -0
  17. package/build/dex/uniswap-v3/forks/velodrome-slipstream/velodrome-slipstream.js.map +1 -1
  18. package/build/dex/uniswap-v3/uniswap-v3.js +1 -0
  19. package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
  20. package/package.json +1 -1
  21. package/src/abi/aavev3stata/Factory.json +128 -0
  22. package/src/abi/aavev3stata/Token.json +735 -0
  23. package/src/dex/aave-v3-stata/aave-v3-stata-e2e.test.ts +355 -0
  24. package/src/dex/aave-v3-stata/aave-v3-stata-integration.test.ts +282 -0
  25. package/src/dex/aave-v3-stata/aave-v3-stata.ts +517 -0
  26. package/src/dex/aave-v3-stata/config.ts +61 -0
  27. package/src/dex/aave-v3-stata/tokens.ts +48 -0
  28. package/src/dex/aave-v3-stata/types.ts +69 -0
  29. package/src/dex/aave-v3-stata/utils.ts +84 -0
  30. package/src/dex/balancer-v2/balancer-v2.ts +0 -1
  31. package/src/dex/index.ts +2 -0
  32. package/src/dex/pancakeswap-v3/pancakeswap-v3.ts +2 -0
  33. package/src/dex/solidly-v3/solidly-v3.ts +2 -0
  34. package/src/dex/uniswap-v3/forks/velodrome-slipstream/velodrome-slipstream.ts +2 -0
  35. package/src/dex/uniswap-v3/uniswap-v3.ts +2 -0
  36. package/tests/constants-e2e.ts +78 -0
@@ -0,0 +1,517 @@
1
+ import { AsyncOrSync } from 'ts-essentials';
2
+ import {
3
+ Token,
4
+ Address,
5
+ ExchangePrices,
6
+ PoolPrices,
7
+ AdapterExchangeParam,
8
+ PoolLiquidity,
9
+ Logger,
10
+ NumberAsString,
11
+ DexExchangeParam,
12
+ } from '../../types';
13
+ import { SwapSide, Network } from '../../constants';
14
+ import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
15
+ import { Utils, getBigIntPow, getDexKeysWithNetwork } from '../../utils';
16
+ import { Context, IDex } from '../../dex/idex';
17
+ import { IDexHelper } from '../../dex-helper/idex-helper';
18
+ import {
19
+ AaveV3StataData,
20
+ Rounding,
21
+ StataFunctions,
22
+ StataToken,
23
+ TokenType,
24
+ } from './types';
25
+ import { SimpleExchange } from '../simple-exchange';
26
+ import { AaveV3StataConfig, Adapters } from './config';
27
+ import { Interface } from '@ethersproject/abi';
28
+ import { fetchTokenList } from './utils';
29
+ import {
30
+ Tokens,
31
+ getTokenFromAddress,
32
+ getTokenType,
33
+ setTokensOnNetwork,
34
+ } from './tokens';
35
+ import { uint256ToBigInt } from '../../lib/decoders';
36
+ import TokenABI from '../../abi/aavev3stata/Token.json';
37
+ import { extractReturnAmountPosition } from '../../executor/utils';
38
+ import { RETURN_AMOUNT_POS_32 } from '../../executor/constants';
39
+ // import { IStaticATokenLM_ABI } from '@bgd-labs/aave-address-book';
40
+ // slimmed down version of @bgd-labs/aave-address-book
41
+ // required as version of web3-utils used is buggy
42
+ //import IStaticATokenFactory_ABI from '../../abi/aave-v3-stata/StaticATokenFactory.json';
43
+
44
+ export const TOKEN_LIST_CACHE_KEY = 'stata-token-list';
45
+ const TOKEN_LIST_TTL_SECONDS = 24 * 60 * 60; // 1 day
46
+ const RAY = BigInt(`1${'0'.repeat(27)}`);
47
+
48
+ export class AaveV3Stata
49
+ extends SimpleExchange
50
+ implements IDex<AaveV3StataData>
51
+ {
52
+ readonly hasConstantPriceLargeAmounts = false;
53
+
54
+ readonly isFeeOnTransferSupported = false;
55
+
56
+ public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
57
+ getDexKeysWithNetwork(AaveV3StataConfig);
58
+
59
+ logger: Logger;
60
+
61
+ // static readonly stata = new Interface(IStaticATokenLM_ABI);
62
+ static readonly stata = new Interface(TokenABI);
63
+
64
+ private state: Record<string, { blockNumber: number; rate: bigint }> = {};
65
+
66
+ constructor(
67
+ readonly network: Network,
68
+ readonly dexKey: string,
69
+ readonly dexHelper: IDexHelper,
70
+ protected config = AaveV3StataConfig[dexKey][network],
71
+ protected adapters = Adapters[network],
72
+ ) {
73
+ super(dexHelper, dexKey);
74
+ this.logger = dexHelper.getLogger(dexKey);
75
+ }
76
+
77
+ async initializePricing(blockNumber: number) {
78
+ let cachedTokenList = await this.dexHelper.cache.get(
79
+ this.dexKey,
80
+ this.network,
81
+ TOKEN_LIST_CACHE_KEY,
82
+ );
83
+ if (cachedTokenList !== null) {
84
+ const tokenListParsed = JSON.parse(cachedTokenList);
85
+ setTokensOnNetwork(this.network, tokenListParsed);
86
+
87
+ tokenListParsed.forEach((token: StataToken) => {
88
+ this.state[token.address] = {
89
+ blockNumber: 0,
90
+ rate: 0n,
91
+ };
92
+ });
93
+ return;
94
+ }
95
+
96
+ let tokenList = await fetchTokenList(
97
+ this.dexHelper.web3Provider,
98
+ blockNumber,
99
+ this.config.factoryAddress,
100
+ this.dexHelper.multiWrapper,
101
+ );
102
+
103
+ await this.dexHelper.cache.setex(
104
+ this.dexKey,
105
+ this.network,
106
+ TOKEN_LIST_CACHE_KEY,
107
+ TOKEN_LIST_TTL_SECONDS,
108
+ JSON.stringify(tokenList),
109
+ );
110
+
111
+ setTokensOnNetwork(this.network, tokenList);
112
+
113
+ // init state for all tokens as empty
114
+ tokenList.forEach(token => {
115
+ this.state[token.address] = {
116
+ blockNumber: 0,
117
+ rate: 0n,
118
+ };
119
+ });
120
+ }
121
+
122
+ // Returns the list of contract adapters (name and index)
123
+ // for a buy/sell. Return null if there are no adapters.
124
+ getAdapters(side: SwapSide): { name: string; index: number }[] | null {
125
+ return null;
126
+ }
127
+
128
+ private _getPoolIdentifier(srcToken: Token, destToken: Token): string {
129
+ return (
130
+ this.dexKey +
131
+ '-' +
132
+ [srcToken.address.toLowerCase(), destToken.address.toLowerCase()]
133
+ .sort((a, b) => (a > b ? 1 : -1))
134
+ .join('_')
135
+ );
136
+ }
137
+
138
+ // Returns list of pool identifiers that can be used
139
+ // for a given swap. poolIdentifiers must be unique
140
+ // across DEXes. It is recommended to use
141
+ // ${dexKey}_${poolAddress} as a poolIdentifier
142
+ async getPoolIdentifiers(
143
+ srcToken: Token,
144
+ destToken: Token,
145
+ side: SwapSide,
146
+ blockNumber: number,
147
+ ): Promise<string[]> {
148
+ return [this._getPoolIdentifier(srcToken, destToken)];
149
+ }
150
+
151
+ // Returns pool prices for amounts.
152
+ // If limitPools is defined only pools in limitPools
153
+ // should be used. If limitPools is undefined then
154
+ // any pools can be used.
155
+ async getPricesVolume(
156
+ srcToken: Token,
157
+ destToken: Token,
158
+ amounts: bigint[],
159
+ side: SwapSide,
160
+ blockNumber: number,
161
+ limitPools?: string[],
162
+ ): Promise<null | ExchangePrices<AaveV3StataData>> {
163
+ const src = getTokenType(this.network, srcToken.address);
164
+ const dest = getTokenType(this.network, destToken.address);
165
+
166
+ // one of the tokens must be stata
167
+ if (![src, dest].includes(TokenType.STATA_TOKEN) || src === dest) {
168
+ return null;
169
+ }
170
+
171
+ const isSrcStata = src === TokenType.STATA_TOKEN;
172
+
173
+ const [stataToken, otherAddressLower] = isSrcStata
174
+ ? [
175
+ getTokenFromAddress(this.network, srcToken.address),
176
+ destToken.address.toLowerCase(),
177
+ ]
178
+ : [
179
+ getTokenFromAddress(this.network, destToken.address),
180
+ srcToken.address.toLowerCase(),
181
+ ];
182
+
183
+ // the token itself can only swap from/to underlying and aToken, so
184
+ // - at least one must be stata
185
+ // - maximum one can be stata
186
+ // - second one must be underlying or aUnderlying
187
+ // on the buy side (mint, withdraw) we only support the underlying<->stata conversion, not the aUnderlying
188
+ if (side === SwapSide.SELL) {
189
+ if (
190
+ otherAddressLower !== stataToken.underlying.toLowerCase() &&
191
+ otherAddressLower !== stataToken.underlyingAToken.toLowerCase()
192
+ ) {
193
+ return null;
194
+ }
195
+ } else {
196
+ if (otherAddressLower !== stataToken.underlying.toLowerCase()) {
197
+ return null;
198
+ }
199
+ }
200
+
201
+ const stataAddressLower = stataToken.address.toLowerCase();
202
+
203
+ if (
204
+ !this.state[stataAddressLower]?.blockNumber ||
205
+ blockNumber > this.state[stataAddressLower].blockNumber
206
+ ) {
207
+ const cached = await this.dexHelper.cache.get(
208
+ this.dexKey,
209
+ this.network,
210
+ `state_${stataAddressLower}`,
211
+ );
212
+ if (cached) {
213
+ this.state[stataAddressLower] = Utils.Parse(cached);
214
+ } else {
215
+ const results = await this.dexHelper.multiWrapper.tryAggregate<bigint>(
216
+ true,
217
+ [
218
+ {
219
+ target: stataToken.address,
220
+ callData: AaveV3Stata.stata.encodeFunctionData('rate'),
221
+ decodeFunction: uint256ToBigInt,
222
+ },
223
+ ],
224
+ blockNumber,
225
+ );
226
+ this.state[stataAddressLower] = {
227
+ blockNumber,
228
+ rate: results[0].returnData,
229
+ };
230
+ this.dexHelper.cache.setex(
231
+ this.dexKey,
232
+ this.network,
233
+ `state_${stataAddressLower}`,
234
+ 60,
235
+ Utils.Serialize(this.state[stataAddressLower]),
236
+ );
237
+ }
238
+ }
239
+
240
+ return [
241
+ {
242
+ prices: amounts.map(amount => {
243
+ const rate = this.state[stataAddressLower].rate;
244
+ if (side === SwapSide.SELL) {
245
+ if (isSrcStata) {
246
+ return this.previewRedeem(amount, rate);
247
+ } else {
248
+ return this.previewDeposit(amount, rate);
249
+ }
250
+ } else {
251
+ if (isSrcStata) {
252
+ return this.previewWithdraw(amount, rate);
253
+ } else {
254
+ return this.previewMint(amount, rate);
255
+ }
256
+ }
257
+ }),
258
+ unit: getBigIntPow(
259
+ (side === SwapSide.SELL ? destToken : srcToken).decimals,
260
+ ),
261
+ gasCost: 270000, // 250_000 from underlying, far less from aToken
262
+ exchange: this.dexKey,
263
+ data: {
264
+ srcType: src,
265
+ destType: dest,
266
+ exchange: stataToken.address,
267
+ },
268
+ poolAddresses: [stataAddressLower],
269
+ },
270
+ ];
271
+ }
272
+
273
+ getCalldataGasCost(
274
+ poolPrices: PoolPrices<AaveV3StataData>,
275
+ ): number | number[] {
276
+ return CALLDATA_GAS_COST.DEX_NO_PAYLOAD;
277
+ }
278
+
279
+ // Not used for V6
280
+ getAdapterParam(): AdapterExchangeParam {
281
+ return {
282
+ targetExchange: '0x',
283
+ payload: '0x',
284
+ networkFee: '0',
285
+ };
286
+ }
287
+
288
+ // Encode call data used by simpleSwap like routers
289
+ // Used for simpleSwap & simpleBuy
290
+ // Hint: this.buildSimpleParamWithoutWETHConversion
291
+ // could be useful
292
+ // async getSimpleParam(
293
+ // srcToken: string,
294
+ // destToken: string,
295
+ // srcAmount: string,
296
+ // destAmount: string,
297
+ // data: AaveV3StataData,
298
+ // side: SwapSide,
299
+ // ): Promise<SimpleExchangeParam> {
300
+ // const { exchange, srcType, destType } = data;
301
+ // let swapData;
302
+ //
303
+ // if (side === SwapSide.SELL) {
304
+ // if (srcType === TokenType.STATA_TOKEN) {
305
+ // // e.g. sell srcAmount 100 srcToken stataUSDC for destToken USDC
306
+ // swapData = AaveV3Stata.stata.encodeFunctionData(StataFunctions.redeem, [
307
+ // srcAmount,
308
+ // this.augustusAddress, // receiver
309
+ // this.augustusAddress, // owner
310
+ // destType === TokenType.UNDERLYING, // withdraw from aToken
311
+ // ]);
312
+ // } else {
313
+ // // sell srcAmount 100 srcToken USDC for destToken stataUSDC
314
+ // swapData = AaveV3Stata.stata.encodeFunctionData(
315
+ // StataFunctions.deposit,
316
+ // [
317
+ // srcAmount,
318
+ // this.augustusAddress, // receiver
319
+ // 0, // referrer (noop)
320
+ // srcType === TokenType.UNDERLYING, // deposit to aave
321
+ // ],
322
+ // );
323
+ // }
324
+ // } else {
325
+ // if (srcType === TokenType.STATA_TOKEN) {
326
+ // // e.g. buy destAmount 100 destToken USDC for srcToken stataUSDC
327
+ // swapData = AaveV3Stata.stata.encodeFunctionData(
328
+ // StataFunctions.withdraw,
329
+ // [
330
+ // destAmount,
331
+ // this.augustusAddress, // receiver
332
+ // this.augustusAddress, // owner
333
+ // ],
334
+ // );
335
+ // } else {
336
+ // // e.g. buy destAmount 100 destToken stataUSDC for srcToken USDC
337
+ // swapData = AaveV3Stata.stata.encodeFunctionData(StataFunctions.mint, [
338
+ // destAmount,
339
+ // this.augustusAddress,
340
+ // ]);
341
+ // }
342
+ // }
343
+ //
344
+ // return this.buildSimpleParamWithoutWETHConversion(
345
+ // srcToken,
346
+ // srcAmount,
347
+ // destToken,
348
+ // destAmount,
349
+ // swapData,
350
+ // exchange,
351
+ // );
352
+ // }
353
+
354
+ getDexParam(
355
+ srcToken: Address,
356
+ destToken: Address,
357
+ srcAmount: NumberAsString,
358
+ destAmount: NumberAsString,
359
+ recipient: Address,
360
+ data: AaveV3StataData,
361
+ side: SwapSide,
362
+ _: Context,
363
+ executorAddress: Address,
364
+ ): DexExchangeParam {
365
+ const { exchange, srcType, destType } = data;
366
+ let swapData;
367
+ let returnAmountPos = undefined;
368
+
369
+ if (side === SwapSide.SELL) {
370
+ if (srcType === TokenType.STATA_TOKEN) {
371
+ // e.g. sell srcAmount 100 srcToken stataUSDC for destToken USDC
372
+ swapData = AaveV3Stata.stata.encodeFunctionData(StataFunctions.redeem, [
373
+ srcAmount,
374
+ recipient, // receiver
375
+ executorAddress, // owner
376
+ destType === TokenType.UNDERLYING, // withdraw from aToken
377
+ ]);
378
+
379
+ returnAmountPos = RETURN_AMOUNT_POS_32;
380
+ } else {
381
+ // sell srcAmount 100 srcToken USDC for destToken stataUSDC
382
+ swapData = AaveV3Stata.stata.encodeFunctionData(
383
+ StataFunctions.deposit,
384
+ [
385
+ srcAmount,
386
+ recipient, // receiver
387
+ 0, // referrer (noop)
388
+ srcType === TokenType.UNDERLYING, // deposit to aave
389
+ ],
390
+ );
391
+ returnAmountPos = extractReturnAmountPosition(
392
+ AaveV3Stata.stata,
393
+ StataFunctions.deposit,
394
+ );
395
+ }
396
+ } else {
397
+ if (srcType === TokenType.STATA_TOKEN) {
398
+ // e.g. buy destAmount 100 destToken USDC for srcToken stataUSDC
399
+ swapData = AaveV3Stata.stata.encodeFunctionData(
400
+ StataFunctions.withdraw,
401
+ [
402
+ destAmount,
403
+ recipient, // receiver
404
+ executorAddress, // owner
405
+ ],
406
+ );
407
+ } else {
408
+ // e.g. buy destAmount 100 destToken stataUSDC for srcToken USDC
409
+ swapData = AaveV3Stata.stata.encodeFunctionData(StataFunctions.mint, [
410
+ destAmount,
411
+ recipient,
412
+ ]);
413
+ }
414
+ }
415
+
416
+ return {
417
+ needWrapNative: this.needWrapNative,
418
+ dexFuncHasRecipient: true,
419
+ exchangeData: swapData,
420
+ targetExchange: exchange,
421
+ returnAmountPos,
422
+ };
423
+ }
424
+
425
+ async updatePoolState(): Promise<void> {}
426
+
427
+ async getTopPoolsForToken(
428
+ tokenAddress: Address,
429
+ limit: number,
430
+ ): Promise<PoolLiquidity[]> {
431
+ if (Object.keys(Tokens).length === 0) {
432
+ const blockNumber =
433
+ await this.dexHelper.web3Provider.eth.getBlockNumber();
434
+ this.initializePricing(blockNumber);
435
+ }
436
+ const tokenType = getTokenType(this.network, tokenAddress);
437
+
438
+ if (tokenType === TokenType.UNKNOWN) {
439
+ return [];
440
+ }
441
+
442
+ const stata = getTokenFromAddress(this.network, tokenAddress);
443
+
444
+ if (tokenType === TokenType.STATA_TOKEN) {
445
+ return [
446
+ {
447
+ liquidityUSD: 1e12,
448
+ exchange: this.dexKey,
449
+ address: stata.address,
450
+ connectorTokens: [
451
+ { address: stata.underlying, decimals: stata.decimals },
452
+ { address: stata.underlyingAToken, decimals: stata.decimals },
453
+ ],
454
+ },
455
+ ];
456
+ } else {
457
+ return [
458
+ {
459
+ liquidityUSD: 1e12,
460
+ exchange: this.dexKey,
461
+ address: stata.address,
462
+ connectorTokens: [
463
+ { address: stata.address, decimals: stata.decimals },
464
+ ],
465
+ },
466
+ ];
467
+ }
468
+ }
469
+
470
+ // TODO: Move to pool implementation when migrating to event based
471
+ previewRedeem(shares: bigint, rate: bigint) {
472
+ return this._convertToAssets(shares, rate, Rounding.DOWN);
473
+ }
474
+
475
+ previewMint(shares: bigint, rate: bigint) {
476
+ return this._convertToAssets(shares, rate, Rounding.UP);
477
+ }
478
+
479
+ previewWithdraw(assets: bigint, rate: bigint) {
480
+ return this._convertToShares(assets, rate, Rounding.UP);
481
+ }
482
+
483
+ previewDeposit(assets: bigint, rate: bigint) {
484
+ return this._convertToShares(assets, rate, Rounding.DOWN);
485
+ }
486
+
487
+ _convertToAssets(shares: bigint, rate: bigint, rounding: Rounding): bigint {
488
+ if (rounding == Rounding.UP) return this.rayMulRoundUp(shares, rate);
489
+ return this.rayMulRoundDown(shares, rate);
490
+ }
491
+ _convertToShares(assets: bigint, rate: bigint, rounding: Rounding): bigint {
492
+ if (rounding == Rounding.UP) return this.rayDivRoundUp(assets, rate);
493
+ return this.rayDivRoundDown(assets, rate);
494
+ }
495
+
496
+ rayMulRoundDown(a: bigint, b: bigint): bigint {
497
+ if (a === 0n || b === 0n) {
498
+ return 0n;
499
+ }
500
+ return (a * b) / RAY;
501
+ }
502
+
503
+ rayMulRoundUp(a: bigint, b: bigint) {
504
+ if (a === 0n || b === 0n) {
505
+ return 0n;
506
+ }
507
+ return (a * b + RAY - 1n) / RAY;
508
+ }
509
+
510
+ rayDivRoundDown(a: bigint, b: bigint) {
511
+ return (a * RAY) / b;
512
+ }
513
+
514
+ rayDivRoundUp(a: bigint, b: bigint) {
515
+ return (a * RAY + b - 1n) / b;
516
+ }
517
+ }
@@ -0,0 +1,61 @@
1
+ import { DexParams } from './types';
2
+ import { DexConfigMap, AdapterMappings } from '../../types';
3
+ import { Network, SwapSide } from '../../constants';
4
+ import {
5
+ AaveV3Arbitrum,
6
+ AaveV3Avalanche,
7
+ AaveV3BNB,
8
+ AaveV3Base,
9
+ AaveV3Ethereum,
10
+ // AaveV3Gnosis,
11
+ // AaveV3Metis,
12
+ AaveV3Optimism,
13
+ AaveV3Polygon,
14
+ // AaveV3Scroll,
15
+ } from '@bgd-labs/aave-address-book';
16
+
17
+ export const AaveV3StataConfig: DexConfigMap<DexParams> = {
18
+ AaveV3Stata: {
19
+ [Network.MAINNET]: {
20
+ factoryAddress: AaveV3Ethereum.STATIC_A_TOKEN_FACTORY,
21
+ },
22
+ [Network.POLYGON]: {
23
+ factoryAddress: AaveV3Polygon.STATIC_A_TOKEN_FACTORY,
24
+ },
25
+ [Network.AVALANCHE]: {
26
+ factoryAddress: AaveV3Avalanche.STATIC_A_TOKEN_FACTORY,
27
+ },
28
+ [Network.ARBITRUM]: {
29
+ factoryAddress: AaveV3Arbitrum.STATIC_A_TOKEN_FACTORY,
30
+ },
31
+ [Network.OPTIMISM]: {
32
+ factoryAddress: AaveV3Optimism.STATIC_A_TOKEN_FACTORY,
33
+ },
34
+ [Network.BASE]: {
35
+ factoryAddress: AaveV3Base.STATIC_A_TOKEN_FACTORY,
36
+ },
37
+ [Network.BSC]: {
38
+ factoryAddress: AaveV3BNB.STATIC_A_TOKEN_FACTORY,
39
+ },
40
+ // [Network.Gnosis]: {
41
+ // factoryAddress: AaveV3Gnosis.STATIC_A_TOKEN_FACTORY,
42
+ // },
43
+ // [Network.Scroll]: {
44
+ // factoryAddress: AaveV3Scroll.STATIC_A_TOKEN_FACTORY,
45
+ // },
46
+ // [Network.Metis]: {
47
+ // factoryAddress: AaveV3Metis.STATIC_A_TOKEN_FACTORY,
48
+ // },
49
+ },
50
+ };
51
+
52
+ export const Adapters: Record<number, AdapterMappings> = {
53
+ // TODO: add adapters for each chain for V5 support
54
+ [Network.MAINNET]: { [SwapSide.SELL]: [{ name: '', index: 0 }] },
55
+ [Network.POLYGON]: { [SwapSide.SELL]: [{ name: '', index: 0 }] },
56
+ [Network.AVALANCHE]: { [SwapSide.SELL]: [{ name: '', index: 0 }] },
57
+ [Network.ARBITRUM]: { [SwapSide.SELL]: [{ name: '', index: 0 }] },
58
+ [Network.OPTIMISM]: { [SwapSide.SELL]: [{ name: '', index: 0 }] },
59
+ [Network.BASE]: { [SwapSide.SELL]: [{ name: '', index: 0 }] },
60
+ [Network.BSC]: { [SwapSide.SELL]: [{ name: '', index: 0 }] },
61
+ };
@@ -0,0 +1,48 @@
1
+ import { Network } from '../../constants';
2
+ import { StataToken, TokenType } from './types';
3
+
4
+ export const Tokens: { [network: number]: { [symbol: string]: StataToken } } =
5
+ {};
6
+
7
+ const TokensByAddress: {
8
+ [network: number]: { [address: string]: StataToken };
9
+ } = {};
10
+
11
+ export function setTokensOnNetwork(network: Network, tokens: StataToken[]) {
12
+ if (Tokens[network] === undefined) {
13
+ Tokens[network] = {};
14
+ }
15
+
16
+ if (TokensByAddress[network] === undefined) {
17
+ TokensByAddress[network] = {};
18
+ }
19
+
20
+ for (let token of tokens) {
21
+ token.address = token.address.toLowerCase();
22
+ token.underlying = token.underlying.toLowerCase();
23
+ token.underlyingAToken = token.underlyingAToken.toLowerCase();
24
+
25
+ Tokens[network][token.stataSymbol] = token;
26
+ TokensByAddress[network][token.address] = token;
27
+ TokensByAddress[network][token.underlying] = token;
28
+ TokensByAddress[network][token.underlyingAToken] = token;
29
+ }
30
+ }
31
+
32
+ export function getTokenType(network: Network, address: string): TokenType {
33
+ const addressLower = address.toLowerCase();
34
+ const token = TokensByAddress[network]?.[addressLower];
35
+
36
+ if (!token) return TokenType.UNKNOWN;
37
+ if (token.address === addressLower) return TokenType.STATA_TOKEN;
38
+ if (token.underlying === addressLower) return TokenType.UNDERLYING;
39
+ if (token.underlyingAToken === addressLower) return TokenType.A_TOKEN;
40
+ return TokenType.UNKNOWN;
41
+ }
42
+
43
+ export function getTokenFromAddress(
44
+ network: Network,
45
+ address: string,
46
+ ): StataToken {
47
+ return TokensByAddress[network]?.[address.toLowerCase()];
48
+ }
@@ -0,0 +1,69 @@
1
+ import { Address } from '../../types';
2
+
3
+ export type PoolState = {
4
+ // TODO: poolState is the state of event
5
+ // subscriber. This should be the minimum
6
+ // set of parameters required to compute
7
+ // pool prices. Complete me!
8
+ };
9
+
10
+ export enum TokenType {
11
+ UNDERLYING,
12
+ A_TOKEN,
13
+ STATA_TOKEN,
14
+ UNKNOWN,
15
+ }
16
+
17
+ export type AaveV3StataData = {
18
+ // TODO: AaveV3StataData is the dex data that is
19
+ // returned by the API that can be used for
20
+ // tx building. The data structure should be minimal.
21
+ // Complete me!
22
+ exchange: Address;
23
+ srcType: TokenType;
24
+ destType: TokenType;
25
+ };
26
+
27
+ export type DexParams = {
28
+ factoryAddress: string;
29
+ };
30
+
31
+ export type StataToken = {
32
+ address: string;
33
+ underlying: string;
34
+ underlyingAToken: string;
35
+ stataSymbol: string;
36
+ decimals: number;
37
+ };
38
+
39
+ export type DepositParams = [
40
+ // amount of assets to deposit
41
+ assets: string,
42
+ receiver: string,
43
+ referralCode: number,
44
+ // true if depositing the underlying, false if depositing the aToken
45
+ depositToAave: boolean,
46
+ ];
47
+
48
+ export type RedeemParams = [
49
+ // amount of shares to redeem
50
+ shares: string,
51
+ receiver: string,
52
+ owner: string,
53
+ // true if redeeming the underlying, false if redeeming the aToken
54
+ withdrawFromAave: string,
55
+ ];
56
+
57
+ export type Param = DepositParams | RedeemParams;
58
+
59
+ export enum StataFunctions {
60
+ deposit = 'deposit(uint256,address,uint16,bool)',
61
+ redeem = 'redeem(uint256,address,address,bool)',
62
+ mint = 'mint',
63
+ withdraw = 'withdraw',
64
+ }
65
+
66
+ export enum Rounding {
67
+ UP = 'UP',
68
+ DOWN = 'DOWN',
69
+ }