@paraswap/dex-lib 4.0.16 → 4.0.17-usual-pp.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 (36) hide show
  1. package/build/abi/usual-pp/abi.json +750 -0
  2. package/build/dex/fluid-dex/fluid-dex.js +2 -0
  3. package/build/dex/fluid-dex/fluid-dex.js.map +1 -1
  4. package/build/dex/index.js +2 -0
  5. package/build/dex/index.js.map +1 -1
  6. package/build/dex/usual/usual.js +1 -1
  7. package/build/dex/usual/usual.js.map +1 -1
  8. package/build/dex/usual-pp/config.d.ts +3 -0
  9. package/build/dex/usual-pp/config.js +19 -0
  10. package/build/dex/usual-pp/config.js.map +1 -0
  11. package/build/dex/usual-pp/pool.d.ts +17 -0
  12. package/build/dex/usual-pp/pool.js +57 -0
  13. package/build/dex/usual-pp/pool.js.map +1 -0
  14. package/build/dex/usual-pp/types.d.ts +15 -0
  15. package/build/dex/usual-pp/types.js +3 -0
  16. package/build/dex/usual-pp/types.js.map +1 -0
  17. package/build/dex/usual-pp/usual-pp.d.ts +36 -0
  18. package/build/dex/usual-pp/usual-pp.js +167 -0
  19. package/build/dex/usual-pp/usual-pp.js.map +1 -0
  20. package/build/dex/usual-pp/utils.d.ts +4 -0
  21. package/build/dex/usual-pp/utils.js +18 -0
  22. package/build/dex/usual-pp/utils.js.map +1 -0
  23. package/package.json +1 -1
  24. package/src/abi/usual-pp/abi.json +750 -0
  25. package/src/dex/fluid-dex/fluid-dex-e2e.test.ts +0 -10
  26. package/src/dex/fluid-dex/fluid-dex.ts +6 -0
  27. package/src/dex/index.ts +2 -0
  28. package/src/dex/usual/usual.ts +1 -1
  29. package/src/dex/usual-pp/config.ts +18 -0
  30. package/src/dex/usual-pp/pool.ts +77 -0
  31. package/src/dex/usual-pp/types.ts +12 -0
  32. package/src/dex/usual-pp/usual-events.test.ts +70 -0
  33. package/src/dex/usual-pp/usual-integration.test.ts +143 -0
  34. package/src/dex/usual-pp/usual-pp.e2e.test.ts +76 -0
  35. package/src/dex/usual-pp/usual-pp.ts +208 -0
  36. package/src/dex/usual-pp/utils.ts +27 -0
@@ -19,16 +19,6 @@ import { FluidDex } from './fluid-dex';
19
19
  README
20
20
  ======
21
21
 
22
- This test script should add e2e tests for FluidDex. The tests
23
- should cover as many cases as possible. Most of the DEXes follow
24
- the following test structure:
25
- - DexName
26
- - ForkName + Network
27
- - ContractMethod
28
- - ETH -> Token swap
29
- - Token -> ETH swap
30
- - Token -> Token swap
31
-
32
22
  The template already enumerates the basic structure which involves
33
23
  testing simpleSwap, multiSwap, megaSwap contract methods for
34
24
  ETH <> TOKEN and TOKEN <> TOKEN swaps. You should replace tokenA and
@@ -206,6 +206,12 @@ export class FluidDex extends SimpleExchange implements IDex<FluidDexData> {
206
206
  pools = pools.filter(pool => limitPools.includes(pool.id));
207
207
  }
208
208
 
209
+ // temporarily limit FLUID-ETH Dex Pool.
210
+ pools = pools.filter(
211
+ pool =>
212
+ pool.id != 'FluidDex_0xc800b0e15c40a1ff0539218100c86f4c1bac8d9c',
213
+ );
214
+
209
215
  if (!pools.length) return null;
210
216
 
211
217
  const liquidityProxyState = await this.liquidityProxy.getStateOrGenerate(
package/src/dex/index.ts CHANGED
@@ -100,6 +100,7 @@ import { Stader } from './stader/stader';
100
100
  import { UsualBond } from './usual/usual-bond';
101
101
  import { UsualMWrappedM } from './usual/usual-m-wrapped-m';
102
102
  import { UsualMUsd0 } from './usual/usual-m-usd0';
103
+ import { UsualPP } from './usual-pp/usual-pp';
103
104
 
104
105
  const LegacyDexes = [
105
106
  CurveV2,
@@ -194,6 +195,7 @@ const Dexes = [
194
195
  FluidDex,
195
196
  UsualMWrappedM,
196
197
  UsualMUsd0,
198
+ UsualPP,
197
199
  ];
198
200
 
199
201
  export type LegacyDexConstructor = new (dexHelper: IDexHelper) => IDexTxBuilder<
@@ -72,7 +72,7 @@ export class Usual extends SimpleExchange implements IDex<UsualBondData> {
72
72
  }
73
73
 
74
74
  if (this.isValidTokens(srcTokenAddress, destTokenAddress)) {
75
- return [`${this.dexKey}_${this.config.toToken}`];
75
+ return [`${this.dexKey}_${this.config.toToken.address}`];
76
76
  }
77
77
 
78
78
  return [];
@@ -0,0 +1,18 @@
1
+ import { Network } from '../../constants';
2
+ import { DexConfigMap } from '../../types';
3
+ import { DexParams } from './types';
4
+
5
+ export const Config: DexConfigMap<DexParams> = {
6
+ UsualPP: {
7
+ [Network.MAINNET]: {
8
+ USD0: {
9
+ address: '0x73a15fed60bf67631dc6cd7bc5b6e8da8190acf5',
10
+ decimals: 18,
11
+ },
12
+ USD0PP: {
13
+ address: '0x35d8949372d46b7a3d5a56006ae77b215fc69bc0',
14
+ decimals: 18,
15
+ },
16
+ },
17
+ },
18
+ };
@@ -0,0 +1,77 @@
1
+ import _ from 'lodash';
2
+ import { Interface } from '@ethersproject/abi';
3
+ import { IDexHelper } from '../../dex-helper';
4
+ import { StatefulEventSubscriber } from '../../stateful-event-subscriber';
5
+ import { Address, Log, Logger } from '../../types';
6
+ import { AsyncOrSync, DeepReadonly } from 'ts-essentials';
7
+ import { PoolState } from './types';
8
+ import { getOnChainState } from './utils';
9
+
10
+ export class UsualPool extends StatefulEventSubscriber<PoolState> {
11
+ decoder = (log: Log) => this.poolInterface.parseLog(log);
12
+
13
+ constructor(
14
+ parentName: string,
15
+ protected dexHelper: IDexHelper,
16
+ private poolAddress: Address,
17
+ private poolInterface: Interface,
18
+ logger: Logger,
19
+ ) {
20
+ super(parentName, 'UsualPool', dexHelper, logger);
21
+ this.addressesSubscribed = [poolAddress];
22
+ }
23
+
24
+ protected processLog(
25
+ state: DeepReadonly<PoolState>,
26
+ log: Readonly<Log>,
27
+ ): AsyncOrSync<DeepReadonly<PoolState> | null> {
28
+ const event = this.decoder(log);
29
+ const _state: PoolState = _.cloneDeep(state);
30
+ if (event.name === 'FloorPriceUpdated') {
31
+ _state.price = BigInt(event.args.newFloorPrice);
32
+ return _state;
33
+ }
34
+ return null;
35
+ }
36
+
37
+ async generateState(
38
+ blockNumber: number | 'latest' = 'latest',
39
+ ): Promise<DeepReadonly<PoolState>> {
40
+ const state = await getOnChainState(
41
+ this.dexHelper.multiContract,
42
+ this.poolAddress,
43
+ this.poolInterface,
44
+ blockNumber,
45
+ );
46
+ return state;
47
+ }
48
+
49
+ async getPrice(blockNumber: number): Promise<bigint> {
50
+ const state = await this.getOrGenerateState(blockNumber);
51
+ if (!state) throw new Error('Cannot compute state');
52
+ return state.price;
53
+ }
54
+
55
+ async getOrGenerateState(
56
+ blockNumber: number,
57
+ ): Promise<DeepReadonly<PoolState> | null> {
58
+ const state = this.getState(blockNumber);
59
+ if (state) {
60
+ return state;
61
+ }
62
+
63
+ this.logger.debug(
64
+ `No state found for ${this.addressesSubscribed[0]}, generating new one`,
65
+ );
66
+ const newState = await this.generateState(blockNumber);
67
+
68
+ if (!newState) {
69
+ this.logger.debug(
70
+ `Could not regenerate state for ${this.addressesSubscribed[0]}`,
71
+ );
72
+ return null;
73
+ }
74
+ this.setState(newState, blockNumber);
75
+ return newState;
76
+ }
77
+ }
@@ -0,0 +1,12 @@
1
+ import { Address } from '../../types';
2
+
3
+ export type PoolState = {
4
+ price: bigint;
5
+ };
6
+
7
+ export type UsualPPData = {};
8
+
9
+ export type DexParams = {
10
+ USD0: { address: Address; decimals: number };
11
+ USD0PP: { address: Address; decimals: number };
12
+ };
@@ -0,0 +1,70 @@
1
+ import dotenv from 'dotenv';
2
+ dotenv.config();
3
+
4
+ import { Network } from '../../constants';
5
+ import { DummyDexHelper } from '../../dex-helper/index';
6
+ import { testEventSubscriber } from '../../../tests/utils-events';
7
+ import { PoolState } from './types';
8
+ import { Config } from './config';
9
+ import { UsualPool } from './pool';
10
+ import { PoolConfig } from '../curve-v1/types';
11
+ import UsualPoolAbi from '../../abi/usual-pp/abi.json';
12
+ import { Interface } from '@ethersproject/abi';
13
+
14
+ jest.setTimeout(50 * 1000);
15
+ const dexKey = 'UsualPP';
16
+ const network = Network.MAINNET;
17
+ const config = Config[dexKey][network];
18
+ const dexHelper = new DummyDexHelper(network);
19
+ const logger = dexHelper.getLogger(dexKey);
20
+
21
+ async function fetchPoolState(
22
+ usualPool: UsualPool,
23
+ blockNumber: number,
24
+ ): Promise<PoolState> {
25
+ return usualPool.generateState(blockNumber);
26
+ }
27
+
28
+ function compareState(state: PoolState, expectedState: PoolState) {
29
+ expect(state).toEqual(expectedState);
30
+ }
31
+
32
+ describe('UsualPP Event', function () {
33
+ const blockNumbers: { [eventName: string]: number[] } = {
34
+ FloorPriceUpdated: [21589702],
35
+ };
36
+
37
+ describe('UsualPool', function () {
38
+ let usualPool: UsualPool;
39
+ let blockNumber: number;
40
+
41
+ const usualPoolIface = new Interface(UsualPoolAbi);
42
+
43
+ beforeAll(async function () {
44
+ blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
45
+ });
46
+
47
+ Object.keys(blockNumbers).forEach((event: string) => {
48
+ blockNumbers[event].forEach((blockNumber: number) => {
49
+ it(`Should return the correct state after the ${blockNumber}:${event}`, async function () {
50
+ usualPool = new UsualPool(
51
+ dexKey,
52
+ dexHelper,
53
+ config.USD0PP.address,
54
+ usualPoolIface,
55
+ logger,
56
+ );
57
+ await testEventSubscriber(
58
+ usualPool,
59
+ usualPool.addressesSubscribed,
60
+ (_blockNumber: number) => fetchPoolState(usualPool, _blockNumber),
61
+ blockNumber,
62
+ `${dexKey}_${config.USD0PP.address}`,
63
+ dexHelper.provider,
64
+ compareState,
65
+ );
66
+ });
67
+ });
68
+ });
69
+ });
70
+ });
@@ -0,0 +1,143 @@
1
+ /* eslint-disable no-console */
2
+ import dotenv from 'dotenv';
3
+ dotenv.config();
4
+
5
+ import { Interface } from '@ethersproject/abi';
6
+ import { DummyDexHelper } from '../../dex-helper/index';
7
+ import { Network, SwapSide } from '../../constants';
8
+ import { BI_POWS } from '../../bigint-constants';
9
+ import {
10
+ checkPoolPrices,
11
+ checkConstantPoolPrices,
12
+ checkPoolsLiquidity,
13
+ } from '../../../tests/utils';
14
+ import { Tokens } from '../../../tests/constants-e2e';
15
+ import { UsualPP } from './usual-pp';
16
+
17
+ async function testPricingOnNetwork(
18
+ usual: UsualPP,
19
+ network: Network,
20
+ dexKey: string,
21
+ blockNumber: number,
22
+ srcTokenSymbol: string,
23
+ destTokenSymbol: string,
24
+ side: SwapSide,
25
+ amounts: bigint[],
26
+ funcNameToCheck: string,
27
+ ) {
28
+ const networkTokens = Tokens[network];
29
+
30
+ console.log(amounts);
31
+
32
+ const pools = await usual.getPoolIdentifiers(
33
+ networkTokens[srcTokenSymbol],
34
+ networkTokens[destTokenSymbol],
35
+ side,
36
+ blockNumber,
37
+ );
38
+ console.log(
39
+ `${srcTokenSymbol} <> ${destTokenSymbol} Pool Identifiers: `,
40
+ pools,
41
+ );
42
+
43
+ expect(pools.length).toBeGreaterThan(0);
44
+
45
+ const poolPrices = await usual.getPricesVolume(
46
+ networkTokens[srcTokenSymbol],
47
+ networkTokens[destTokenSymbol],
48
+ amounts,
49
+ side,
50
+ blockNumber,
51
+ pools,
52
+ );
53
+ console.log(
54
+ `${srcTokenSymbol} <> ${destTokenSymbol} Pool Prices: `,
55
+ poolPrices,
56
+ );
57
+
58
+ expect(poolPrices).not.toBeNull();
59
+ // Check if onchain pricing equals to calculated ones
60
+ }
61
+
62
+ describe('UsualPP', function () {
63
+ const dexKey = 'UsualPP';
64
+ let blockNumber: number;
65
+ let usualPP: UsualPP;
66
+
67
+ describe('Mainnet', () => {
68
+ const network = Network.MAINNET;
69
+ const dexHelper = new DummyDexHelper(network);
70
+
71
+ // Don't forget to update relevant tokens in constant-e2e.ts
72
+
73
+ const amountsForSell = [
74
+ 0n,
75
+ 1n * BI_POWS[18],
76
+ 2n * BI_POWS[18],
77
+ 3n * BI_POWS[18],
78
+ 4n * BI_POWS[18],
79
+ 5n * BI_POWS[18],
80
+ 6n * BI_POWS[18],
81
+ 7n * BI_POWS[18],
82
+ 8n * BI_POWS[18],
83
+ 9n * BI_POWS[18],
84
+ 10n * BI_POWS[18],
85
+ ];
86
+
87
+ beforeAll(async () => {
88
+ blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
89
+ usualPP = new UsualPP(network, dexKey, dexHelper);
90
+ if (usualPP.initializePricing) {
91
+ await usualPP.initializePricing(blockNumber);
92
+ }
93
+ });
94
+
95
+ it('getPoolIdentifiers and getPricesVolume SELL', async function () {
96
+ await testPricingOnNetwork(
97
+ usualPP,
98
+ network,
99
+ dexKey,
100
+ blockNumber,
101
+ 'USD0++',
102
+ 'USD0',
103
+ SwapSide.SELL,
104
+ amountsForSell,
105
+ '',
106
+ );
107
+ });
108
+
109
+ it('getTopPoolsForToken: USD0', async function () {
110
+ const tokenA = Tokens[network]['USD0'];
111
+ const dexHelper = new DummyDexHelper(network);
112
+ const usualPP = new UsualPP(network, dexKey, dexHelper);
113
+
114
+ const poolLiquidity = await usualPP.getTopPoolsForToken(
115
+ tokenA.address,
116
+ 10,
117
+ );
118
+ console.log(
119
+ `${tokenA.symbol} Top Pools:`,
120
+ JSON.stringify(poolLiquidity, null, 2),
121
+ );
122
+
123
+ checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey);
124
+ });
125
+
126
+ it('getTopPoolsForToken: USD0++', async function () {
127
+ const tokenA = Tokens[network]['USD0++'];
128
+ const dexHelper = new DummyDexHelper(network);
129
+ const usualPP = new UsualPP(network, dexKey, dexHelper);
130
+
131
+ const poolLiquidity = await usualPP.getTopPoolsForToken(
132
+ tokenA.address,
133
+ 10,
134
+ );
135
+ console.log(
136
+ `${tokenA.symbol} Top Pools:`,
137
+ JSON.stringify(poolLiquidity, null, 2),
138
+ );
139
+
140
+ checkPoolsLiquidity(poolLiquidity, tokenA.address, dexKey);
141
+ });
142
+ });
143
+ });
@@ -0,0 +1,76 @@
1
+ /* eslint-disable no-console */
2
+ import dotenv from 'dotenv';
3
+ dotenv.config();
4
+
5
+ import { testE2E } from '../../../tests/utils-e2e';
6
+ import { Tokens, Holders } from '../../../tests/constants-e2e';
7
+ import { Network, ContractMethod, SwapSide } from '../../constants';
8
+ import { StaticJsonRpcProvider } from '@ethersproject/providers';
9
+ import { generateConfig } from '../../config';
10
+
11
+ function testForNetwork(
12
+ network: Network,
13
+ dexKey: string,
14
+ tokenASymbol: string,
15
+ tokenBSymbol: string,
16
+ tokenAAmount: string,
17
+ tokenBAmount: string,
18
+ ) {
19
+ const provider = new StaticJsonRpcProvider(
20
+ generateConfig(network).privateHttpProvider,
21
+ network,
22
+ );
23
+ const tokens = Tokens[network];
24
+ const holders = Holders[network];
25
+
26
+ const sideToContractMethods = new Map([
27
+ [SwapSide.SELL, [ContractMethod.swapExactAmountIn]],
28
+ ]);
29
+
30
+ describe(`${network}`, () => {
31
+ sideToContractMethods.forEach((contractMethods, side) =>
32
+ describe(`${side}`, () => {
33
+ contractMethods.forEach((contractMethod: ContractMethod) => {
34
+ describe(`${contractMethod}`, () => {
35
+ it(`${tokenASymbol} -> ${tokenBSymbol}`, async () => {
36
+ await testE2E(
37
+ tokens[tokenASymbol],
38
+ tokens[tokenBSymbol],
39
+ holders[tokenASymbol],
40
+ side === SwapSide.SELL ? tokenAAmount : tokenBAmount,
41
+ side,
42
+ dexKey,
43
+ contractMethod,
44
+ network,
45
+ provider,
46
+ );
47
+ });
48
+ });
49
+ });
50
+ }),
51
+ );
52
+ });
53
+ }
54
+
55
+ describe('UsualPP E2E', () => {
56
+ const dexKey = 'UsualPP';
57
+
58
+ describe('Mainnet', () => {
59
+ const network = Network.MAINNET;
60
+
61
+ const tokenASymbol: string = 'USD0++';
62
+ const tokenBSymbol: string = 'USD0';
63
+
64
+ const tokenAAmount: string = '1000000000000000000';
65
+ const tokenBAmount: string = '1000000000000000000';
66
+
67
+ testForNetwork(
68
+ network,
69
+ dexKey,
70
+ tokenASymbol,
71
+ tokenBSymbol,
72
+ tokenAAmount,
73
+ tokenBAmount,
74
+ );
75
+ });
76
+ });
@@ -0,0 +1,208 @@
1
+ import {
2
+ Token,
3
+ Address,
4
+ ExchangePrices,
5
+ PoolPrices,
6
+ AdapterExchangeParam,
7
+ Logger,
8
+ PoolLiquidity,
9
+ DexExchangeParam,
10
+ NumberAsString,
11
+ } from '../../types';
12
+ import { SwapSide, Network } from '../../constants';
13
+ import * as CALLDATA_GAS_COST from '../../calldata-gas-cost';
14
+ import { IDex } from '../idex';
15
+ import { IDexHelper } from '../../dex-helper/idex-helper';
16
+ import { SimpleExchange } from '../simple-exchange';
17
+ import { BI_POWS } from '../../bigint-constants';
18
+ import { DexParams, UsualPPData } from './types';
19
+ import { UsualPool } from './pool';
20
+ import { Interface } from '@ethersproject/abi';
21
+ import UsualPoolAbi from '../../abi/usual-pp/abi.json';
22
+ import { Config } from './config';
23
+ import { getDexKeysWithNetwork } from '../../utils';
24
+ import { UsualBondData } from '../usual/types';
25
+
26
+ export class UsualPP extends SimpleExchange implements IDex<UsualPPData> {
27
+ readonly hasConstantPriceLargeAmounts = false;
28
+ readonly needWrapNative = false;
29
+ readonly isFeeOnTransferSupported = false;
30
+
31
+ private usualPool: UsualPool;
32
+ private usualPoolIface: Interface;
33
+ private config: DexParams;
34
+
35
+ logger: Logger;
36
+
37
+ public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
38
+ getDexKeysWithNetwork(Config);
39
+
40
+ constructor(
41
+ readonly network: Network,
42
+ readonly dexKey: string,
43
+ readonly dexHelper: IDexHelper,
44
+ protected adapters = {},
45
+ ) {
46
+ super(dexHelper, dexKey);
47
+ this.config = Config[dexKey][network];
48
+ this.logger = dexHelper.getLogger(dexKey);
49
+ this.usualPoolIface = new Interface(UsualPoolAbi);
50
+ this.usualPool = new UsualPool(
51
+ this.dexKey,
52
+ dexHelper,
53
+ this.config.USD0PP.address,
54
+ this.usualPoolIface,
55
+ this.logger,
56
+ );
57
+ }
58
+
59
+ async initializePricing(blockNumber: number) {
60
+ await this.usualPool.initialize(blockNumber);
61
+ }
62
+
63
+ isUsd0PP(token: string) {
64
+ return token.toLowerCase() === this.config.USD0PP.address.toLowerCase();
65
+ }
66
+
67
+ isUsd0(token: string) {
68
+ return token.toLowerCase() === this.config.USD0.address.toLowerCase();
69
+ }
70
+
71
+ isValidTokens(srcToken: string, destToken: string) {
72
+ return this.isUsd0PP(srcToken) && this.isUsd0(destToken);
73
+ }
74
+
75
+ getAdapters() {
76
+ return null;
77
+ }
78
+
79
+ async getPoolIdentifiers(
80
+ srcToken: Token,
81
+ destToken: Token,
82
+ side: SwapSide,
83
+ blockNumber: number,
84
+ ): Promise<string[]> {
85
+ if (!srcToken || !destToken) {
86
+ this.logger.error('Source or destination token is undefined');
87
+ return [];
88
+ }
89
+
90
+ const srcTokenAddress = srcToken.address?.toLowerCase();
91
+ const destTokenAddress = destToken.address?.toLowerCase();
92
+
93
+ if (!srcTokenAddress || !destTokenAddress) {
94
+ this.logger.error('Source or destination token address is undefined');
95
+ return [];
96
+ }
97
+
98
+ if (this.isValidTokens(srcTokenAddress, destTokenAddress)) {
99
+ return [`${this.dexKey}_${this.config.USD0.address}`];
100
+ }
101
+
102
+ return [];
103
+ }
104
+
105
+ async getPricesVolume(
106
+ srcToken: Token,
107
+ destToken: Token,
108
+ amounts: bigint[],
109
+ side: SwapSide,
110
+ blockNumber: number,
111
+ limitPools?: string[],
112
+ ): Promise<null | ExchangePrices<UsualPPData>> {
113
+ if (side === SwapSide.BUY) {
114
+ return null;
115
+ }
116
+
117
+ const isValidSwap = this.isValidTokens(srcToken.address, destToken.address);
118
+
119
+ if (!isValidSwap) {
120
+ return null;
121
+ }
122
+
123
+ const price = await this.usualPool.getPrice(blockNumber);
124
+ const unitOut = price;
125
+
126
+ const amountsOut = amounts.map(
127
+ amount => (amount * price) / BI_POWS[this.config.USD0PP.decimals],
128
+ );
129
+
130
+ return [
131
+ {
132
+ unit: unitOut,
133
+ prices: amountsOut,
134
+ data: {},
135
+ poolAddresses: [this.config.USD0.address],
136
+ exchange: this.dexKey,
137
+ gasCost: 70000,
138
+ poolIdentifier: this.dexKey,
139
+ },
140
+ ];
141
+ }
142
+
143
+ getCalldataGasCost(poolPrices: PoolPrices<UsualPPData>): number | number[] {
144
+ return CALLDATA_GAS_COST.DEX_NO_PAYLOAD;
145
+ }
146
+
147
+ getAdapterParam(
148
+ srcToken: string,
149
+ destToken: string,
150
+ srcAmount: string,
151
+ destAmount: string,
152
+ data: UsualPPData,
153
+ side: SwapSide,
154
+ ): AdapterExchangeParam {
155
+ const payload = '0x';
156
+
157
+ return {
158
+ targetExchange: this.config.USD0.address,
159
+ payload,
160
+ networkFee: '0',
161
+ };
162
+ }
163
+
164
+ async getTopPoolsForToken(
165
+ tokenAddress: Address,
166
+ limit: number,
167
+ ): Promise<PoolLiquidity[]> {
168
+ const isUsd0PP = this.isUsd0PP(tokenAddress);
169
+ const isUsd0 = this.isUsd0(tokenAddress);
170
+
171
+ if (!(isUsd0PP || isUsd0)) return [];
172
+
173
+ return [
174
+ {
175
+ exchange: this.dexKey,
176
+ address: this.config.USD0PP.address,
177
+ connectorTokens: [isUsd0PP ? this.config.USD0 : this.config.USD0PP],
178
+ liquidityUSD: 1000000000, // Just returning a big number so this DEX will be preferred
179
+ },
180
+ ];
181
+ }
182
+
183
+ async getDexParam(
184
+ srcToken: Address,
185
+ destToken: Address,
186
+ srcAmount: NumberAsString,
187
+ destAmount: NumberAsString,
188
+ recipient: Address,
189
+ data: UsualBondData,
190
+ side: SwapSide,
191
+ ): Promise<DexExchangeParam> {
192
+ if (this.isUsd0PP(srcToken) && this.isUsd0(destToken)) {
193
+ const exchangeData = this.usualPoolIface.encodeFunctionData(
194
+ 'unlockUsd0ppFloorPrice',
195
+ [srcAmount],
196
+ );
197
+
198
+ return {
199
+ needWrapNative: false,
200
+ dexFuncHasRecipient: false,
201
+ exchangeData,
202
+ targetExchange: this.config.USD0PP.address,
203
+ returnAmountPos: undefined,
204
+ };
205
+ }
206
+ throw new Error('LOGIC ERROR');
207
+ }
208
+ }
@@ -0,0 +1,27 @@
1
+ import { Contract } from 'web3-eth-contract';
2
+ import { Interface } from '@ethersproject/abi';
3
+ import { PoolState } from './types';
4
+
5
+ export async function getOnChainState(
6
+ multiContract: Contract,
7
+ poolAddress: string,
8
+ poolInterface: Interface,
9
+ blockNumber: number | 'latest',
10
+ ): Promise<PoolState> {
11
+ const data: { returnData: any[] } = await multiContract.methods
12
+ .aggregate([
13
+ {
14
+ target: poolAddress,
15
+ callData: poolInterface.encodeFunctionData('getFloorPrice', []),
16
+ },
17
+ ])
18
+ .call({}, blockNumber);
19
+
20
+ const price = BigInt(
21
+ poolInterface.decodeFunctionResult('getFloorPrice', data.returnData[0])[0],
22
+ );
23
+
24
+ return {
25
+ price,
26
+ };
27
+ }