@paraswap/dex-lib 3.8.33 → 3.8.34-inception

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.
@@ -130,11 +130,6 @@ export class AaveGsm extends SimpleExchange implements IDex<AaveGsmData> {
130
130
  }
131
131
  }
132
132
 
133
- async updatePoolState(): Promise<void> {
134
- const blockNumber = await this.dexHelper.web3Provider.eth.getBlockNumber();
135
- await this.initializePricing(blockNumber);
136
- }
137
-
138
133
  async getPoolState(gsm: string, blockNumber?: number): Promise<PoolState> {
139
134
  if (!blockNumber) {
140
135
  return this.eventPools[gsm].getStaleState()!;
@@ -0,0 +1,109 @@
1
+ import { DexParams, PricePoolParams } from './types';
2
+ import { DexConfigMap } from '../../types';
3
+ import { Network } from '../../constants';
4
+
5
+ export const InceptionConfig: DexConfigMap<DexParams[]> = {
6
+ InceptionLRT: {
7
+ [Network.MAINNET]: [
8
+ {
9
+ symbol: 'instETH',
10
+ token: '0x7FA768E035F956c41d6aeaa3Bd857e7E5141CAd5',
11
+ vault: '0x814CC6B8fd2555845541FB843f37418b05977d8d',
12
+ baseToken: '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84',
13
+ baseTokenSlug: 'STETH',
14
+ },
15
+ {
16
+ symbol: 'inrETH',
17
+ token: '0x80d69e79258FE9D056c822461c4eb0B4ca8802E2',
18
+ vault: '0x1Aa53BC4Beb82aDf7f5EDEE9e3bBF3434aD59F12',
19
+ baseToken: '0xae78736Cd615f374D3085123A210448E74Fc6393',
20
+ baseTokenSlug: 'rETH',
21
+ },
22
+ {
23
+ symbol: 'inoETH',
24
+ token: '0x9181f633e9b9f15a32d5e37094f4c93b333e0e92',
25
+ vault: '0x4878F636A9Aa314B776Ac51A25021C44CAF86bEd',
26
+ baseToken: '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3',
27
+ baseTokenSlug: 'oETH',
28
+ },
29
+ {
30
+ symbol: 'inosETH',
31
+ token: '0xfD07fD5EBEa6F24888a397997E262179Bf494336',
32
+ vault: '0xA9F8c770661BeE8DF2D026edB1Cb6FF763C780FF',
33
+ baseToken: '0xf1C9acDc66974dFB6dEcB12aA385b9cD01190E38',
34
+ baseTokenSlug: 'osETH',
35
+ },
36
+ {
37
+ symbol: 'inankrETH',
38
+ token: '0xfa2629B9cF3998D52726994E0FcdB750224D8B9D',
39
+ vault: '0x36B429439AB227fAB170A4dFb3321741c8815e55',
40
+ baseToken: '0xE95A203B1a91a908F9B9CE46459d101078c2c3cb',
41
+ baseTokenSlug: 'AnkETH',
42
+ },
43
+ {
44
+ symbol: 'incbETH',
45
+ token: '0xbf19eead55a6b100667f04f8fbc5371e03e8ab2e',
46
+ vault: '0xfE715358368416E01d3A961D3a037b7359735d5e',
47
+ baseToken: '0xBe9895146f7AF43049ca1c1AE358B0541Ea49704',
48
+ baseTokenSlug: 'cbETH',
49
+ },
50
+ {
51
+ symbol: 'inwbETH',
52
+ token: '0xda9b11cd701e10c2ec1a284f80820edd128c5246',
53
+ vault: '0xC0660932C5dCaD4A1409b7975d147203B1e9A2B6',
54
+ baseToken: '0xa2E3356610840701BDf5611a53974510Ae27E2e1',
55
+ baseTokenSlug: 'wbETH',
56
+ },
57
+ {
58
+ symbol: 'inswETH',
59
+ token: '0xc3ade5ace1bbb033ccae8177c12ecbfa16bd6a9d',
60
+ vault: '0xc4181dC7BB31453C4A48689ce0CBe975e495321c',
61
+ baseToken: '0xf951E335afb289353dc249e82926178EaC7DEd78',
62
+ baseTokenSlug: 'SWETH',
63
+ },
64
+ {
65
+ symbol: 'inETHx',
66
+ token: '0x57a5a0567187ff4a8dcc1a9bba86155e355878f2',
67
+ vault: '0x90E80E25ABDB6205B08DeBa29a87f7eb039023C2',
68
+ baseToken: '0xA35b1B31Ce002FBF2058D22F30f95D405200A15b',
69
+ baseTokenSlug: 'ETHx',
70
+ },
71
+ {
72
+ symbol: 'insfrxETH',
73
+ token: '0x668308d77be3533c909a692302cb4d135bf8041c',
74
+ vault: '0x295234B7E370a5Db2D2447aCA83bc7448f151161',
75
+ baseToken: '0xac3E018457B222d93114458476f3E3416Abbe38F',
76
+ baseTokenSlug: 'sfrxETH',
77
+ },
78
+ {
79
+ symbol: 'inmETH',
80
+ token: '0xeCf3672A6d2147E2A77f07069Fb48d8Cf6F6Fbf9',
81
+ vault: '0xd0ee89d82183D7Ddaef14C6b4fC0AA742F426355',
82
+ baseToken: '0xd5F7838F5C461fefF7FE49ea5ebaF7728bB0ADfa',
83
+ baseTokenSlug: 'mETH',
84
+ },
85
+ {
86
+ symbol: 'inlsETH',
87
+ token: '0x94b888e11a9e960a9c3b3528eb6ac807b27ca62e',
88
+ vault: '0x6E17a8b5D33e6DBdB9fC61d758BF554b6AD93322',
89
+ baseToken: '0x8c1BEd5b9a0928467c9B1341Da1D7BD5e10b6549',
90
+ baseTokenSlug: 'lsETH',
91
+ },
92
+ {
93
+ symbol: 'inETH',
94
+ token: '0xf073bAC22DAb7FaF4a3Dd6c6189a70D54110525C',
95
+ vault: '0x46199cAa0e453971cedf97f926368d9E5415831a',
96
+ baseToken: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
97
+ baseTokenSlug: 'ETH',
98
+ },
99
+ ],
100
+ },
101
+ };
102
+
103
+ export const InceptionPricePoolConfig: DexConfigMap<PricePoolParams> = {
104
+ InceptionLRT: {
105
+ [Network.MAINNET]: {
106
+ ratioFeed: '0xFd73Be536503B5Aa80Bf99D1Fd65b1306c69B191',
107
+ },
108
+ },
109
+ };
@@ -0,0 +1,67 @@
1
+ /* eslint-disable no-console */
2
+ import dotenv from 'dotenv';
3
+ dotenv.config();
4
+
5
+ import { testE2E } from '../../../tests/utils-e2e';
6
+ import { Holders, Tokens } from '../../../tests/constants-e2e';
7
+ import { ContractMethod, Network, SwapSide } from '../../constants';
8
+ import { StaticJsonRpcProvider } from '@ethersproject/providers';
9
+ import { generateConfig } from '../../config';
10
+ import { InceptionConfig } from './config';
11
+ import { DexParams } from './types';
12
+
13
+ function testForNetwork(
14
+ network: Network,
15
+ inceptionName: string,
16
+ configs: DexParams[],
17
+ ) {
18
+ const provider = new StaticJsonRpcProvider(
19
+ generateConfig(network).privateHttpProvider,
20
+ network,
21
+ );
22
+
23
+ for (const config of configs) {
24
+ const baseSlug = config.baseTokenSlug;
25
+ const tokens = Tokens[network];
26
+ const holders = Holders[network];
27
+ const inceptionSlug = config.symbol;
28
+
29
+ const sideToContractMethods = new Map([
30
+ [SwapSide.SELL, [ContractMethod.swapExactAmountIn]],
31
+ ]);
32
+
33
+ describe(`${inceptionSlug}`, () => {
34
+ sideToContractMethods.forEach((contractMethods, side) =>
35
+ describe(`${side}`, () => {
36
+ contractMethods.forEach((contractMethod: ContractMethod) => {
37
+ describe(`${contractMethod}`, () => {
38
+ it(`${baseSlug} -> ${inceptionSlug}`, async () => {
39
+ await testE2E(
40
+ tokens[baseSlug],
41
+ tokens[inceptionSlug],
42
+ holders[baseSlug],
43
+ '100000000',
44
+ side,
45
+ inceptionName,
46
+ contractMethod,
47
+ network,
48
+ provider,
49
+ );
50
+ });
51
+ });
52
+ });
53
+ }),
54
+ );
55
+ });
56
+ }
57
+ }
58
+
59
+ describe('Inception E2E', () => {
60
+ describe('Mainnet', () => {
61
+ const network = Network.MAINNET;
62
+
63
+ Object.entries(InceptionConfig).forEach(([inceptionName, chainConfig]) => {
64
+ testForNetwork(network, inceptionName, chainConfig[network]);
65
+ });
66
+ });
67
+ });
@@ -0,0 +1,62 @@
1
+ import _ from 'lodash';
2
+ import { AsyncOrSync, DeepReadonly } from 'ts-essentials';
3
+ import { Address, BlockHeader, Log, Logger } from '../../types';
4
+ import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
5
+ import { IDexHelper } from '../../dex-helper/idex-helper';
6
+ import { PoolConfig, PoolState } from './types';
7
+ import { getOnChainState } from './utils';
8
+ import { Interface } from '@ethersproject/abi';
9
+ import INCEPTION_RATIO_FEED from '../../abi/inception/inception-ratio-feed.json';
10
+ import { getTokenFromAddress } from './tokens';
11
+
12
+ export class InceptionEventPool extends StatefulEventSubscriber<PoolState> {
13
+ protected ratioFeedInterface: Interface = new Interface(INCEPTION_RATIO_FEED);
14
+ constructor(
15
+ parentName: string,
16
+ protected network: number,
17
+ protected dexHelper: IDexHelper,
18
+ logger: Logger,
19
+ protected ratioFeedAddress: Address,
20
+ public poolInterface: Interface,
21
+ ) {
22
+ super(parentName, ratioFeedAddress, dexHelper, logger);
23
+
24
+ this.addressesSubscribed = [ratioFeedAddress];
25
+ }
26
+
27
+ protected processLog(
28
+ state: DeepReadonly<PoolState>,
29
+ log: Readonly<Log>,
30
+ blockHeader: Readonly<BlockHeader>,
31
+ ): AsyncOrSync<DeepReadonly<PoolState> | null> {
32
+ try {
33
+ const parsed = this.ratioFeedInterface.parseLog(log);
34
+ const _state: PoolState = _.cloneDeep(state);
35
+ switch (parsed.name) {
36
+ case 'RatioUpdated': {
37
+ const tokenInfo = getTokenFromAddress(this.network, parsed.args[0]);
38
+ if (tokenInfo) {
39
+ _state[tokenInfo.symbol.toLowerCase()] = {
40
+ ratio: BigInt(parsed.args[2].toString()),
41
+ };
42
+ }
43
+ return _state;
44
+ }
45
+ default:
46
+ return _state;
47
+ }
48
+ } catch (e) {
49
+ this.logger.error('Failed to parse log', e);
50
+ return null;
51
+ }
52
+ }
53
+
54
+ async generateState(blockNumber: number): Promise<Readonly<PoolState>> {
55
+ return getOnChainState(
56
+ this.dexHelper.multiContract,
57
+ this.poolInterface,
58
+ this.network,
59
+ blockNumber,
60
+ );
61
+ }
62
+ }
@@ -0,0 +1,64 @@
1
+ import dotenv from 'dotenv';
2
+ dotenv.config();
3
+ import { InceptionEventPool } from './inception-event-pool';
4
+ import { InceptionPricePoolConfig } from './config';
5
+ import { Network } from '../../constants';
6
+ import { DummyDexHelper } from '../../dex-helper/index';
7
+ import INCEPTION_VAULT_ABI from '../../abi/inception/inception-vault.json';
8
+ import { testEventSubscriber } from '../../../tests/utils-events';
9
+ import { PoolState } from './types';
10
+ import { Interface } from '@ethersproject/abi';
11
+ import { setTokensOnNetwork } from './tokens';
12
+ import { getTokenList } from './utils';
13
+
14
+ jest.setTimeout(50 * 1000);
15
+ const dexKey = 'InceptionLRT';
16
+ const network = Network.MAINNET;
17
+ const ratioFeedAddress = InceptionPricePoolConfig[dexKey][network].ratioFeed;
18
+ const poolInterface = new Interface(INCEPTION_VAULT_ABI);
19
+
20
+ async function fetchPoolState(
21
+ inceptionEventPool: InceptionEventPool,
22
+ blockNumber: number,
23
+ ): Promise<PoolState> {
24
+ return inceptionEventPool.generateState(blockNumber);
25
+ }
26
+
27
+ describe('Inception Event', function () {
28
+ const blockNumbers: { [eventName: string]: number[] } = {
29
+ // RatioUpdated: [20438963, 20431766, 20424602],
30
+ RatioUpdated: [20438962, 20431765, 20424601, 20703959, 20711125],
31
+ };
32
+
33
+ describe('InceptionEventPool', function () {
34
+ Object.keys(blockNumbers).forEach((event: string) => {
35
+ blockNumbers[event].forEach((blockNumber: number) => {
36
+ it(`Should return the correct state after the ${blockNumber}: ${event}`, async function () {
37
+ const dexHelper = new DummyDexHelper(network);
38
+ const logger = dexHelper.getLogger(dexKey);
39
+ const inceptionEventPool = new InceptionEventPool(
40
+ dexKey,
41
+ network,
42
+ dexHelper,
43
+ logger,
44
+ ratioFeedAddress,
45
+ poolInterface,
46
+ );
47
+
48
+ const tokenList = await getTokenList(network);
49
+ setTokensOnNetwork(network, tokenList);
50
+
51
+ await testEventSubscriber(
52
+ inceptionEventPool,
53
+ inceptionEventPool.addressesSubscribed,
54
+ (_blockNumber: number) =>
55
+ fetchPoolState(inceptionEventPool, _blockNumber),
56
+ blockNumber,
57
+ `${dexKey}_${ratioFeedAddress}`.toLowerCase(),
58
+ dexHelper.provider,
59
+ );
60
+ });
61
+ });
62
+ });
63
+ });
64
+ });
@@ -0,0 +1,76 @@
1
+ import dotenv from 'dotenv';
2
+ dotenv.config();
3
+
4
+ import { DummyDexHelper } from '../../dex-helper/index';
5
+ import { Network, SwapSide } from '../../constants';
6
+ import { BI_POWS } from '../../bigint-constants';
7
+ import { Inception } from './inception';
8
+ import { checkPoolPrices, checkPoolsLiquidity } from '../../../tests/utils';
9
+ import { Tokens } from '../../../tests/constants-e2e';
10
+ import { InceptionConfig } from './config';
11
+
12
+ const network = Network.MAINNET;
13
+ const dexKey = 'InceptionLRT';
14
+ const dexHelper = new DummyDexHelper(network);
15
+
16
+ describe('Inception', function () {
17
+ let blockNumber: number;
18
+ let inception: Inception;
19
+
20
+ beforeAll(async () => {
21
+ blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
22
+ inception = new Inception(network, dexKey, dexHelper);
23
+ await inception.initializePricing(blockNumber);
24
+ });
25
+
26
+ InceptionConfig[dexKey][network].forEach(Pair => {
27
+ const TokenASymbol = Pair.baseTokenSlug;
28
+ const TokenA = Tokens[network][TokenASymbol];
29
+
30
+ const TokenBSymbol = Pair.symbol;
31
+ const TokenB = Tokens[network][TokenBSymbol];
32
+ const TokenBAmounts = [0n, BI_POWS[6], 2000000n];
33
+
34
+ describe(`deposit() Swap Function for ${TokenBSymbol} <> ${TokenASymbol}`, () => {
35
+ it('getPoolIdentifiers and getPricesVolume SELL', async function () {
36
+ const pools = await inception.getPoolIdentifiers(
37
+ TokenB,
38
+ TokenA,
39
+ SwapSide.SELL,
40
+ blockNumber,
41
+ );
42
+ console.log(
43
+ `${TokenBSymbol} <> ${TokenASymbol} Pool Identifiers: `,
44
+ pools,
45
+ );
46
+
47
+ expect(pools.length).toBeGreaterThan(0);
48
+
49
+ const poolPrices = await inception.getPricesVolume(
50
+ TokenB,
51
+ TokenA,
52
+ TokenBAmounts,
53
+ SwapSide.SELL,
54
+ blockNumber,
55
+ pools,
56
+ );
57
+ console.log(
58
+ `${TokenBSymbol} <> ${TokenASymbol} Pool Prices: `,
59
+ poolPrices,
60
+ );
61
+
62
+ expect(poolPrices).not.toBeNull();
63
+ checkPoolPrices(poolPrices!, TokenBAmounts, SwapSide.SELL, dexKey);
64
+ });
65
+
66
+ it('getTopPoolsForToken', async function () {
67
+ const poolLiquidity = await inception.getTopPoolsForToken(
68
+ TokenA.address,
69
+ 10,
70
+ );
71
+
72
+ checkPoolsLiquidity(poolLiquidity, TokenA.address, dexKey);
73
+ });
74
+ });
75
+ });
76
+ });
@@ -0,0 +1,271 @@
1
+ import { Interface, JsonFragment } from '@ethersproject/abi';
2
+ import { AsyncOrSync } from 'ts-essentials';
3
+ import { NumberAsString, SwapSide } from '@paraswap/core';
4
+ import {
5
+ AdapterExchangeParam,
6
+ Address,
7
+ DexExchangeParam,
8
+ ExchangePrices,
9
+ Logger,
10
+ PoolLiquidity,
11
+ PoolPrices,
12
+ Token,
13
+ TransferFeeParams,
14
+ } from '../../types';
15
+ import INCEPTION_ABI from '../../abi/inception/inception-vault.json';
16
+ import INCEPTION_POOL_ABI from '../../abi/inception/inception-ineth-pool.json';
17
+ import {
18
+ DEST_TOKEN_PARASWAP_TRANSFERS,
19
+ Network,
20
+ NULL_ADDRESS,
21
+ SRC_TOKEN_PARASWAP_TRANSFERS,
22
+ } from '../../constants';
23
+ import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
24
+ import { getDexKeysWithNetwork } from '../../utils';
25
+ import { IDex } from '../../dex/idex';
26
+ import { IDexHelper } from '../../dex-helper/idex-helper';
27
+ import { InceptionDexData, PoolState } from './types';
28
+ import { SimpleExchange } from '../simple-exchange';
29
+ import { InceptionConfig, InceptionPricePoolConfig } from './config';
30
+ import { getTokenFromAddress, setTokensOnNetwork } from './tokens';
31
+ import { getOnChainState, getTokenList } from './utils';
32
+ import { InceptionEventPool } from './inception-event-pool';
33
+ import { applyTransferFee } from '../../lib/token-transfer-fee';
34
+ import { RETURN_AMOUNT_POS_0 } from '../../executor/constants';
35
+
36
+ const DECIMALS = BigInt(1e18);
37
+
38
+ export class Inception
39
+ extends SimpleExchange
40
+ implements IDex<InceptionDexData>
41
+ {
42
+ protected vaultInterface: Interface;
43
+ protected poolInterface: Interface;
44
+
45
+ readonly hasConstantPriceLargeAmounts = false;
46
+ readonly needWrapNative = false;
47
+ readonly isFeeOnTransferSupported = true;
48
+
49
+ public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
50
+ getDexKeysWithNetwork(InceptionConfig);
51
+
52
+ logger: Logger;
53
+
54
+ private eventPool: InceptionEventPool;
55
+
56
+ constructor(
57
+ readonly network: Network,
58
+ readonly dexKey: string,
59
+ readonly dexHelper: IDexHelper,
60
+ protected config = InceptionConfig[dexKey][network],
61
+ ) {
62
+ super(dexHelper, dexKey);
63
+ this.logger = dexHelper.getLogger(dexKey);
64
+ this.vaultInterface = new Interface(INCEPTION_ABI as JsonFragment[]);
65
+ this.poolInterface = new Interface(INCEPTION_POOL_ABI as JsonFragment[]);
66
+ this.eventPool = new InceptionEventPool(
67
+ dexKey,
68
+ network,
69
+ dexHelper,
70
+ this.logger,
71
+ InceptionPricePoolConfig[dexKey][network].ratioFeed,
72
+ this.poolInterface,
73
+ );
74
+ }
75
+
76
+ async initializePricing(blockNumber: number) {
77
+ const poolState = await getOnChainState(
78
+ this.dexHelper.multiContract,
79
+ this.vaultInterface,
80
+ this.network,
81
+ blockNumber,
82
+ );
83
+
84
+ await this.eventPool.initialize(blockNumber, {
85
+ state: poolState,
86
+ });
87
+ await this.initializeTokens();
88
+ }
89
+
90
+ async initializeTokens() {
91
+ let tokenList = await getTokenList(this.network);
92
+
93
+ setTokensOnNetwork(this.network, tokenList);
94
+ }
95
+
96
+ getAdapters(side: SwapSide): { name: string; index: number }[] | null {
97
+ return null;
98
+ }
99
+
100
+ async getPoolIdentifiers(
101
+ srcToken: Token,
102
+ destToken: Token,
103
+ side: SwapSide,
104
+ blockNumber: number,
105
+ ): Promise<string[]> {
106
+ return [
107
+ this.dexKey +
108
+ '-' +
109
+ [srcToken.address.toLowerCase(), destToken.address.toLowerCase()]
110
+ .sort((a, b) => (a > b ? 1 : -1))
111
+ .join('_'),
112
+ ];
113
+ }
114
+
115
+ async getPoolState(
116
+ pool: InceptionEventPool,
117
+ blockNumber: number,
118
+ ): Promise<PoolState> {
119
+ const eventState = pool.getState(blockNumber);
120
+ if (eventState) return eventState;
121
+ const onChainState = await pool.generateState(blockNumber);
122
+ pool.setState(onChainState, blockNumber);
123
+ return onChainState;
124
+ }
125
+
126
+ async getPricesVolume(
127
+ srcToken: Token,
128
+ destToken: Token,
129
+ amounts: bigint[],
130
+ side: SwapSide,
131
+ blockNumber: number,
132
+ limitPools?: string[],
133
+ transferFees: TransferFeeParams = {
134
+ srcFee: 0,
135
+ destFee: 0,
136
+ srcDexFee: 0,
137
+ destDexFee: 0,
138
+ },
139
+ ): Promise<null | ExchangePrices<InceptionDexData>> {
140
+ if (side === SwapSide.BUY) {
141
+ return null;
142
+ }
143
+
144
+ const src = getTokenFromAddress(this.network, srcToken.address);
145
+ const dest = getTokenFromAddress(this.network, destToken.address);
146
+
147
+ if (!src || !dest || src !== dest) {
148
+ return null;
149
+ }
150
+
151
+ const poolState = await this.getPoolState(this.eventPool, blockNumber);
152
+ if (!poolState) return null;
153
+
154
+ const unitPrice = DECIMALS;
155
+ const prices = amounts.map(amount => {
156
+ const ratio = poolState[src.symbol.toLowerCase()].ratio;
157
+ return (ratio * amount) / DECIMALS;
158
+ });
159
+
160
+ const [unitPriceWithFee, ...pricesWithFee] = applyTransferFee(
161
+ [unitPrice, ...prices],
162
+ side,
163
+ side === SwapSide.SELL ? transferFees.srcFee : transferFees.destFee,
164
+ side === SwapSide.SELL
165
+ ? SRC_TOKEN_PARASWAP_TRANSFERS
166
+ : DEST_TOKEN_PARASWAP_TRANSFERS,
167
+ );
168
+
169
+ return [
170
+ {
171
+ prices: pricesWithFee,
172
+ unit: unitPriceWithFee,
173
+ gasCost: 120_000,
174
+ exchange: this.dexKey,
175
+ data: {
176
+ exchange: dest.vault,
177
+ },
178
+ poolAddresses: [dest.vault],
179
+ },
180
+ ];
181
+ }
182
+
183
+ getCalldataGasCost(
184
+ poolPrices: PoolPrices<InceptionDexData>,
185
+ ): number | number[] {
186
+ return CALLDATA_GAS_COST.DEX_OVERHEAD + CALLDATA_GAS_COST.LENGTH_SMALL;
187
+ }
188
+
189
+ getAdapterParam(): AdapterExchangeParam {
190
+ return {
191
+ targetExchange: NULL_ADDRESS,
192
+ payload: '0x',
193
+ networkFee: '0',
194
+ };
195
+ }
196
+
197
+ getDexParam(
198
+ srcToken: Address,
199
+ destToken: Address,
200
+ srcAmount: NumberAsString,
201
+ destAmount: NumberAsString,
202
+ recipient: Address,
203
+ data: InceptionDexData,
204
+ side: SwapSide,
205
+ ): DexExchangeParam {
206
+ const dexParams = getTokenFromAddress(this.network, srcToken);
207
+
208
+ if (!dexParams) {
209
+ throw new Error('Unknown token');
210
+ }
211
+
212
+ const isNative = dexParams.baseTokenSlug === 'ETH';
213
+ let swapData;
214
+ let dexFuncHasRecipient;
215
+ let swappedAmountNotPresentInExchangeData;
216
+ if (isNative) {
217
+ swapData = this.poolInterface.encodeFunctionData('stake()', []);
218
+ dexFuncHasRecipient = false;
219
+ swappedAmountNotPresentInExchangeData = true;
220
+ } else {
221
+ swapData = this.vaultInterface.encodeFunctionData('deposit', [
222
+ srcAmount,
223
+ recipient,
224
+ ]);
225
+ dexFuncHasRecipient = true;
226
+ swappedAmountNotPresentInExchangeData = false;
227
+ }
228
+
229
+ return {
230
+ needWrapNative: false,
231
+ dexFuncHasRecipient,
232
+ exchangeData: swapData,
233
+ targetExchange: dexParams.vault,
234
+ swappedAmountNotPresentInExchangeData,
235
+ returnAmountPos: undefined,
236
+ };
237
+ }
238
+
239
+ async updatePoolState(): Promise<void> {}
240
+
241
+ async getTopPoolsForToken(
242
+ tokenAddress: Address,
243
+ limit: number,
244
+ ): Promise<PoolLiquidity[]> {
245
+ await this.initializeTokens();
246
+
247
+ const token = getTokenFromAddress(this.network, tokenAddress);
248
+
249
+ if (token) {
250
+ return [
251
+ {
252
+ liquidityUSD: 1e9,
253
+ exchange: this.dexKey,
254
+ address: token.vault,
255
+ connectorTokens: [
256
+ {
257
+ address:
258
+ tokenAddress.toLowerCase() === token.token.toLowerCase()
259
+ ? token.baseToken
260
+ : token.token,
261
+ decimals: 1e18,
262
+ },
263
+ ],
264
+ },
265
+ ];
266
+ }
267
+ return [];
268
+ }
269
+
270
+ releaseResources(): AsyncOrSync<void> {}
271
+ }
@@ -0,0 +1,37 @@
1
+ import { Network } from '../../constants';
2
+ import { DexParams } from './types';
3
+
4
+ export const Tokens: { [network: number]: { [symbol: string]: DexParams } } =
5
+ {};
6
+
7
+ const TokensByAddress: {
8
+ [network: number]: { [address: string]: DexParams };
9
+ } = {};
10
+
11
+ export function setTokensOnNetwork(network: Network, tokens: DexParams[]) {
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.vault = token.vault.toLowerCase();
22
+ token.token = token.token.toLowerCase();
23
+ token.baseToken = token.baseToken.toLowerCase();
24
+
25
+ Tokens[network][token.symbol] = token;
26
+ TokensByAddress[network][token.vault] = token;
27
+ TokensByAddress[network][token.token] = token;
28
+ TokensByAddress[network][token.baseToken] = token;
29
+ }
30
+ }
31
+
32
+ export function getTokenFromAddress(
33
+ network: Network,
34
+ address: string,
35
+ ): DexParams | undefined {
36
+ return TokensByAddress[network]?.[address.toLowerCase()];
37
+ }