@paraswap/dex-lib 2.14.0 → 2.14.1
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.
- package/build/config.js +23 -5
- package/build/config.js.map +1 -1
- package/build/dex/index.js +2 -2
- package/build/dex/index.js.map +1 -1
- package/build/dex/simple-exchange.d.ts +1 -0
- package/build/dex/simple-exchange.js +2 -0
- package/build/dex/simple-exchange.js.map +1 -1
- package/build/lib/decoders.d.ts +2 -1
- package/build/lib/decoders.js +8 -1
- package/build/lib/decoders.js.map +1 -1
- package/build/lib/multi-wrapper.d.ts +2 -1
- package/build/lib/multi-wrapper.js.map +1 -1
- package/build/lib/tokens/balancer-fetcher.js +4 -5
- package/build/lib/tokens/balancer-fetcher.js.map +1 -1
- package/build/lib/tokens/utils.d.ts +2 -2
- package/build/lib/tokens/utils.js +1 -1
- package/build/lib/tokens/utils.js.map +1 -1
- package/build/types.d.ts +3 -0
- package/dex-template/__DexName__-e2e.test.ts.template +1 -0
- package/dex-template/__DexName__-events.test.ts.template +1 -0
- package/dex-template/__DexName__-integration.test.ts.template +1 -0
- package/dex-template/__DexName__-pool.ts.template +8 -5
- package/package.json +1 -1
- package/scripts/generate-bytecode.ts +2 -0
- package/src/abi/woo-fi-v2/IntegrationHelper.abi.json +116 -0
- package/src/abi/{woo-fi/Wooracle.abi.json → woo-fi-v2/WooOracleV2.abi.json} +148 -50
- package/src/abi/{woo-fi/WooPP.abi.json → woo-fi-v2/WooPPV2.abi.json} +201 -169
- package/src/config.ts +27 -5
- package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +0 -1
- package/src/dex/index.ts +2 -2
- package/src/dex/simple-exchange.ts +3 -0
- package/src/dex/woo-fi-v2/config.ts +87 -0
- package/src/dex/woo-fi-v2/constants.ts +22 -0
- package/src/dex/woo-fi-v2/decoders.ts +45 -0
- package/src/dex/woo-fi-v2/types.ts +63 -0
- package/src/dex/woo-fi-v2/utils.ts +19 -0
- package/src/dex/woo-fi-v2/woo-fi-v2-e2e.test.ts +216 -0
- package/src/dex/woo-fi-v2/woo-fi-v2-integration.test.ts +495 -0
- package/src/dex/woo-fi-v2/woo-fi-v2-math.ts +195 -0
- package/src/dex/woo-fi-v2/woo-fi-v2-pool.ts +112 -0
- package/src/dex/woo-fi-v2/woo-fi-v2.ts +487 -0
- package/src/lib/decoders.ts +12 -1
- package/src/lib/log-messages-suppressor.ts +173 -0
- package/src/lib/multi-wrapper.ts +2 -1
- package/src/lib/stateful-rpc-poller/state-polling-manager.ts +320 -0
- package/src/lib/stateful-rpc-poller/stateful-rpc-poller.ts +604 -0
- package/src/lib/stateful-rpc-poller/types.ts +66 -0
- package/src/lib/stateful-rpc-poller/utils.ts +23 -0
- package/src/lib/tokens/balancer-fetcher.ts +5 -6
- package/src/lib/tokens/utils.ts +5 -3
- package/src/types.ts +4 -0
- package/tests/constants-e2e.ts +8 -3
- package/tests/tenderly-simulation.ts +1 -1
- package/tests/utils-e2e.ts +2 -0
- package/tests/utils.ts +2 -0
- package/src/abi/woo-fi/WooFeeManager.abi.json +0 -318
- package/src/dex/woo-fi/config.ts +0 -141
- package/src/dex/woo-fi/constants.ts +0 -21
- package/src/dex/woo-fi/types.ts +0 -55
- package/src/dex/woo-fi/woo-fi-decimal-math.ts +0 -45
- package/src/dex/woo-fi/woo-fi-e2e.test.ts +0 -183
- package/src/dex/woo-fi/woo-fi-integration.test.ts +0 -416
- package/src/dex/woo-fi/woo-fi-math.ts +0 -527
- package/src/dex/woo-fi/woo-fi.ts +0 -693
package/src/config.ts
CHANGED
|
@@ -25,6 +25,8 @@ type BaseConfig = {
|
|
|
25
25
|
uniswapV2ExchangeRouterAddress: Address;
|
|
26
26
|
uniswapV3EventLoggingSampleRate?: number;
|
|
27
27
|
rfqConfigs: Record<string, RFQConfig>;
|
|
28
|
+
rpcPollingMaxAllowedStateDelayInBlocks: number;
|
|
29
|
+
rpcPollingBlocksBackToTriggerUpdate: number;
|
|
28
30
|
hashFlowAuthToken?: string;
|
|
29
31
|
hashFlowDisabledMMs: string[];
|
|
30
32
|
};
|
|
@@ -52,6 +54,8 @@ const baseConfigs: { [network: number]: BaseConfig } = {
|
|
|
52
54
|
},
|
|
53
55
|
uniswapV2ExchangeRouterAddress:
|
|
54
56
|
'0xF9234CB08edb93c0d4a4d4c70cC3FfD070e78e07',
|
|
57
|
+
rpcPollingMaxAllowedStateDelayInBlocks: 0,
|
|
58
|
+
rpcPollingBlocksBackToTriggerUpdate: 0,
|
|
55
59
|
hashFlowAuthToken: process.env.API_KEY_HASHFLOW_AUTH_TOKEN,
|
|
56
60
|
hashFlowDisabledMMs:
|
|
57
61
|
process.env[`HASHFLOW_DISABLED_MMS_1`]?.split(',') || [],
|
|
@@ -134,6 +138,8 @@ const baseConfigs: { [network: number]: BaseConfig } = {
|
|
|
134
138
|
uniswapV2ExchangeRouterAddress:
|
|
135
139
|
'0x53e693c6C7FFC4446c53B205Cf513105Bf140D7b',
|
|
136
140
|
rfqConfigs: {},
|
|
141
|
+
rpcPollingMaxAllowedStateDelayInBlocks: 5,
|
|
142
|
+
rpcPollingBlocksBackToTriggerUpdate: 3,
|
|
137
143
|
},
|
|
138
144
|
[Network.BSC]: {
|
|
139
145
|
network: Network.BSC,
|
|
@@ -155,6 +161,8 @@ const baseConfigs: { [network: number]: BaseConfig } = {
|
|
|
155
161
|
BscAdapter02: '0xe102429Ef7CAaBaAA3bc2C017aC784c5F665EE82',
|
|
156
162
|
BscBuyAdapter: '0xA7f4fBCEB76a1B1c05C106a4289C28B3b91C17ca',
|
|
157
163
|
},
|
|
164
|
+
rpcPollingMaxAllowedStateDelayInBlocks: 1,
|
|
165
|
+
rpcPollingBlocksBackToTriggerUpdate: 1,
|
|
158
166
|
uniswapV2ExchangeRouterAddress:
|
|
159
167
|
'0x53e693c6C7FFC4446c53B205Cf513105Bf140D7b',
|
|
160
168
|
rfqConfigs: {},
|
|
@@ -177,13 +185,15 @@ const baseConfigs: { [network: number]: BaseConfig } = {
|
|
|
177
185
|
process.env[`HASHFLOW_DISABLED_MMS_137`]?.split(',') || [],
|
|
178
186
|
adapterAddresses: {
|
|
179
187
|
PolygonAdapter01: '0xE44769f42E1e9592f86B82f206407a8f7C84b4ed',
|
|
180
|
-
PolygonAdapter02: '
|
|
188
|
+
PolygonAdapter02: '0xfb2a3de6c7B8c77b520E3da16021f3D8A4E93168',
|
|
181
189
|
PolygonBuyAdapter: '0xbE36ddfCDB6D60c1B20FfD73594540E5cc2c7E97',
|
|
182
190
|
},
|
|
183
191
|
uniswapV2ExchangeRouterAddress:
|
|
184
192
|
'0xf3938337F7294fEf84e9B2c6D548A93F956Cc281',
|
|
185
193
|
uniswapV3EventLoggingSampleRate: 0,
|
|
186
194
|
rfqConfigs: {},
|
|
195
|
+
rpcPollingMaxAllowedStateDelayInBlocks: 2,
|
|
196
|
+
rpcPollingBlocksBackToTriggerUpdate: 1,
|
|
187
197
|
},
|
|
188
198
|
[Network.AVALANCHE]: {
|
|
189
199
|
network: Network.AVALANCHE,
|
|
@@ -202,13 +212,15 @@ const baseConfigs: { [network: number]: BaseConfig } = {
|
|
|
202
212
|
hashFlowDisabledMMs:
|
|
203
213
|
process.env[`HASHFLOW_DISABLED_MMS_43114`]?.split(',') || [],
|
|
204
214
|
adapterAddresses: {
|
|
205
|
-
AvalancheAdapter01: '
|
|
215
|
+
AvalancheAdapter01: '0x745Ec73855CeC7249E5fF4c9DD81cc65b4D297a9',
|
|
206
216
|
AvalancheAdapter02: '0x3fd845dE49eBa45565d3b58CDEbf88d9bdA7aBf6',
|
|
207
217
|
AvalancheBuyAdapter: '0xad2f7039B0F4c410654886D049ae8406F5aDe709',
|
|
208
218
|
},
|
|
209
219
|
uniswapV2ExchangeRouterAddress:
|
|
210
220
|
'0x53e693c6C7FFC4446c53B205Cf513105Bf140D7b',
|
|
211
221
|
rfqConfigs: {},
|
|
222
|
+
rpcPollingMaxAllowedStateDelayInBlocks: 2,
|
|
223
|
+
rpcPollingBlocksBackToTriggerUpdate: 1,
|
|
212
224
|
},
|
|
213
225
|
[Network.FANTOM]: {
|
|
214
226
|
network: Network.FANTOM,
|
|
@@ -228,12 +240,14 @@ const baseConfigs: { [network: number]: BaseConfig } = {
|
|
|
228
240
|
process.env[`HASHFLOW_DISABLED_MMS_250`]?.split(',') || [],
|
|
229
241
|
|
|
230
242
|
adapterAddresses: {
|
|
231
|
-
FantomAdapter01: '
|
|
243
|
+
FantomAdapter01: '0x66152A2a538644Ae125570De522ADEaC9E41D865',
|
|
232
244
|
FantomBuyAdapter: '0x27eb327B7255a2bF666EBB4D60AB4752dA4611b9',
|
|
233
245
|
},
|
|
234
246
|
uniswapV2ExchangeRouterAddress:
|
|
235
247
|
'0xAB86e2bC9ec5485a9b60E684BA6d49bf4686ACC2',
|
|
236
248
|
rfqConfigs: {},
|
|
249
|
+
rpcPollingMaxAllowedStateDelayInBlocks: 2,
|
|
250
|
+
rpcPollingBlocksBackToTriggerUpdate: 1,
|
|
237
251
|
},
|
|
238
252
|
[Network.ARBITRUM]: {
|
|
239
253
|
network: Network.ARBITRUM,
|
|
@@ -253,13 +267,15 @@ const baseConfigs: { [network: number]: BaseConfig } = {
|
|
|
253
267
|
process.env[`HASHFLOW_DISABLED_MMS_42161`]?.split(',') || [],
|
|
254
268
|
adapterAddresses: {
|
|
255
269
|
ArbitrumAdapter01: '0x745Ec73855CeC7249E5fF4c9DD81cc65b4D297a9',
|
|
256
|
-
ArbitrumAdapter02: '
|
|
270
|
+
ArbitrumAdapter02: '0xCBaeB06C2dF373c07A2Dc205266EC3bCd525DfB6',
|
|
257
271
|
ArbitrumBuyAdapter: '0xfa072107a2CCfE5664794282EF36400735ABB70F',
|
|
258
272
|
},
|
|
259
273
|
uniswapV2ExchangeRouterAddress:
|
|
260
274
|
'0xB41dD984730dAf82f5C41489E21ac79D5e3B61bC',
|
|
261
275
|
uniswapV3EventLoggingSampleRate: 0,
|
|
262
276
|
rfqConfigs: {},
|
|
277
|
+
rpcPollingMaxAllowedStateDelayInBlocks: 4,
|
|
278
|
+
rpcPollingBlocksBackToTriggerUpdate: 3,
|
|
263
279
|
},
|
|
264
280
|
[Network.OPTIMISM]: {
|
|
265
281
|
network: Network.OPTIMISM,
|
|
@@ -279,13 +295,15 @@ const baseConfigs: { [network: number]: BaseConfig } = {
|
|
|
279
295
|
process.env[`HASHFLOW_DISABLED_MMS_10`]?.split(',') || [],
|
|
280
296
|
|
|
281
297
|
adapterAddresses: {
|
|
282
|
-
OptimismAdapter01: '
|
|
298
|
+
OptimismAdapter01: '0x4669D27A649f5451e0D44C20a2b246431F1B0572',
|
|
283
299
|
OptimismBuyAdapter: '0x4Ae8ad57912e207f5bFaFbF2e90486e5feab1634',
|
|
284
300
|
},
|
|
285
301
|
uniswapV2ExchangeRouterAddress:
|
|
286
302
|
'0xB41dD984730dAf82f5C41489E21ac79D5e3B61bC',
|
|
287
303
|
uniswapV3EventLoggingSampleRate: 0,
|
|
288
304
|
rfqConfigs: {},
|
|
305
|
+
rpcPollingMaxAllowedStateDelayInBlocks: 5,
|
|
306
|
+
rpcPollingBlocksBackToTriggerUpdate: 3,
|
|
289
307
|
},
|
|
290
308
|
};
|
|
291
309
|
|
|
@@ -322,6 +340,10 @@ export function generateConfig(network: number): Config {
|
|
|
322
340
|
uniswapV2ExchangeRouterAddress: baseConfig.uniswapV2ExchangeRouterAddress,
|
|
323
341
|
uniswapV3EventLoggingSampleRate: baseConfig.uniswapV3EventLoggingSampleRate,
|
|
324
342
|
rfqConfigs: baseConfig.rfqConfigs,
|
|
343
|
+
rpcPollingMaxAllowedStateDelayInBlocks:
|
|
344
|
+
baseConfig.rpcPollingMaxAllowedStateDelayInBlocks,
|
|
345
|
+
rpcPollingBlocksBackToTriggerUpdate:
|
|
346
|
+
baseConfig.rpcPollingBlocksBackToTriggerUpdate,
|
|
325
347
|
hashFlowAuthToken: baseConfig.hashFlowAuthToken,
|
|
326
348
|
hashFlowDisabledMMs: baseConfig.hashFlowDisabledMMs,
|
|
327
349
|
};
|
package/src/dex/index.ts
CHANGED
|
@@ -38,7 +38,7 @@ import { MakerPsm } from './maker-psm/maker-psm';
|
|
|
38
38
|
import { KyberDmm } from './kyberdmm/kyberdmm';
|
|
39
39
|
import { Platypus } from './platypus/platypus';
|
|
40
40
|
import { GMX } from './gmx/gmx';
|
|
41
|
-
|
|
41
|
+
import { WooFiV2 } from './woo-fi-v2/woo-fi-v2';
|
|
42
42
|
import { ParaSwapLimitOrders } from './paraswap-limit-orders/paraswap-limit-orders';
|
|
43
43
|
import { AugustusRFQOrder } from './augustus-rfq';
|
|
44
44
|
import { Solidly } from './solidly/solidly';
|
|
@@ -107,7 +107,7 @@ const Dexes = [
|
|
|
107
107
|
Platypus,
|
|
108
108
|
GMX,
|
|
109
109
|
JarvisV6,
|
|
110
|
-
|
|
110
|
+
WooFiV2,
|
|
111
111
|
ParaSwapLimitOrders,
|
|
112
112
|
Solidly,
|
|
113
113
|
SolidlyEthereum,
|
|
@@ -4,6 +4,7 @@ import { Address, SimpleExchangeParam, NumberAsString } from '../types';
|
|
|
4
4
|
import { CACHE_PREFIX, ETHER_ADDRESS } from '../constants';
|
|
5
5
|
import SimpleSwapHelperABI from '../abi/SimpleSwapHelperRouter.json';
|
|
6
6
|
import ERC20ABI from '../abi/erc20.json';
|
|
7
|
+
import augustusABI from '../abi/augustus.json';
|
|
7
8
|
import { isETHAddress } from '../utils';
|
|
8
9
|
import { MAX_UINT } from '../constants';
|
|
9
10
|
import Web3 from 'web3';
|
|
@@ -18,6 +19,7 @@ export class SimpleExchange {
|
|
|
18
19
|
isFeeOnTransferSupported = false;
|
|
19
20
|
|
|
20
21
|
protected augustusAddress: Address;
|
|
22
|
+
protected augustusInterface: Interface;
|
|
21
23
|
private provider: Web3;
|
|
22
24
|
|
|
23
25
|
protected network: number;
|
|
@@ -32,6 +34,7 @@ export class SimpleExchange {
|
|
|
32
34
|
|
|
33
35
|
this.network = dexHelper.config.data.network;
|
|
34
36
|
this.augustusAddress = dexHelper.config.data.augustusAddress;
|
|
37
|
+
this.augustusInterface = new Interface(augustusABI);
|
|
35
38
|
this.provider = dexHelper.web3Provider;
|
|
36
39
|
|
|
37
40
|
this.dexmapKey =
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { DexParams } from './types';
|
|
2
|
+
import { DexConfigMap, AdapterMappings } from '../../types';
|
|
3
|
+
import { Network, SwapSide } from '../../constants';
|
|
4
|
+
|
|
5
|
+
export const WooFiV2Config: DexConfigMap<DexParams> = {
|
|
6
|
+
WooFiV2: {
|
|
7
|
+
[Network.OPTIMISM]: {
|
|
8
|
+
wooPPV2Address: '0xd1778F9DF3eee5473A9640f13682e3846f61fEbC',
|
|
9
|
+
wooOracleV2Address: '0x464959aD46e64046B891F562cFF202a465D522F3',
|
|
10
|
+
integrationHelperAddress: '0x96329d66074EB8386Ae8bFD6698B2E3FDA87e15E',
|
|
11
|
+
// USDC
|
|
12
|
+
quoteToken: {
|
|
13
|
+
address: '0x7F5c764cBc14f9669B88837ca1490cCa17c31607',
|
|
14
|
+
decimals: 6,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
[Network.BSC]: {
|
|
18
|
+
wooPPV2Address: '0xEc054126922a9a1918435c9072c32f1B60cB2B90',
|
|
19
|
+
wooOracleV2Address: '0x747f99D619D5612399010Ec5706F13e3345c4a9E',
|
|
20
|
+
integrationHelperAddress: '0xe12dC1F01ccB71ef00ADd1D8A5116b905261D879',
|
|
21
|
+
// BUSD
|
|
22
|
+
quoteToken: {
|
|
23
|
+
address: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56',
|
|
24
|
+
decimals: 18,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
[Network.POLYGON]: {
|
|
28
|
+
wooPPV2Address: '0x7081A38158BD050Ae4a86e38E0225Bc281887d7E',
|
|
29
|
+
wooOracleV2Address: '0xeFF23B4bE1091b53205E35f3AfCD9C7182bf3062',
|
|
30
|
+
integrationHelperAddress: '0x7Ba560eB735AbDCf9a3a5692272652A0cc81850d',
|
|
31
|
+
// USDC
|
|
32
|
+
quoteToken: {
|
|
33
|
+
address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
|
|
34
|
+
decimals: 6,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
[Network.FANTOM]: {
|
|
38
|
+
wooPPV2Address: '0x286ab107c5E9083dBed35A2B5fb0242538F4f9bf',
|
|
39
|
+
wooOracleV2Address: '0x8840e26e0ebf7D100A0644DD8576DC62B03cbf04',
|
|
40
|
+
integrationHelperAddress: '0x6641959FE5EED7166F2254cF04b0d20c96776D9A',
|
|
41
|
+
// USDC
|
|
42
|
+
quoteToken: {
|
|
43
|
+
address: '0x04068DA6C83AFCFA0e13ba15A6696662335D5B75',
|
|
44
|
+
decimals: 6,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
[Network.ARBITRUM]: {
|
|
48
|
+
wooPPV2Address: '0xeFF23B4bE1091b53205E35f3AfCD9C7182bf3062',
|
|
49
|
+
wooOracleV2Address: '0x37a9dE70b6734dFCA54395D8061d9411D9910739',
|
|
50
|
+
integrationHelperAddress: '0x28D2B949024FE50627f1EbC5f0Ca3Ca721148E40',
|
|
51
|
+
// USDC
|
|
52
|
+
quoteToken: {
|
|
53
|
+
address: '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8',
|
|
54
|
+
decimals: 6,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
[Network.AVALANCHE]: {
|
|
58
|
+
wooPPV2Address: '0x3b3E4b4741e91aF52d0e9ad8660573E951c88524',
|
|
59
|
+
wooOracleV2Address: '0x9ACA557590F5020BDA4Ba63065Fc3A1253Bf8000',
|
|
60
|
+
integrationHelperAddress: '0x020630613E296c3E9b06186f630D1bF97A2B6Ad1',
|
|
61
|
+
// USDC
|
|
62
|
+
quoteToken: {
|
|
63
|
+
address: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',
|
|
64
|
+
decimals: 6,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const Adapters: Record<number, AdapterMappings> = {
|
|
71
|
+
[Network.OPTIMISM]: {
|
|
72
|
+
[SwapSide.SELL]: [{ name: 'OptimismAdapter01', index: 11 }],
|
|
73
|
+
},
|
|
74
|
+
[Network.BSC]: { [SwapSide.SELL]: [{ name: 'BscAdapter01', index: 13 }] },
|
|
75
|
+
[Network.POLYGON]: {
|
|
76
|
+
[SwapSide.SELL]: [{ name: 'PolygonAdapter02', index: 4 }],
|
|
77
|
+
},
|
|
78
|
+
[Network.FANTOM]: {
|
|
79
|
+
[SwapSide.SELL]: [{ name: 'FantomAdapter01', index: 8 }],
|
|
80
|
+
},
|
|
81
|
+
[Network.ARBITRUM]: {
|
|
82
|
+
[SwapSide.SELL]: [{ name: 'ArbitrumAdapter02', index: 3 }],
|
|
83
|
+
},
|
|
84
|
+
[Network.AVALANCHE]: {
|
|
85
|
+
[SwapSide.SELL]: [{ name: 'AvalancheAdapter01', index: 12 }],
|
|
86
|
+
},
|
|
87
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PoolState } from './types';
|
|
2
|
+
|
|
3
|
+
export const WOO_FI_V2_GAS_COST = {
|
|
4
|
+
// https://dashboard.tenderly.co/paraswap/paraswap/fork/f5a6da2f-fec7-4d00-ac2c-b9c50f5c9554/simulation/25f3b378-632f-4beb-ba37-e21dd3722b5c/gas-usage
|
|
5
|
+
sellQuote: 145_000,
|
|
6
|
+
// https://dashboard.tenderly.co/paraswap/paraswap/fork/92f13a98-465d-409e-867d-e255e9f86cf1/simulation/09d5d06a-dd90-40fe-8ae6-a65097e804d4/gas-usage
|
|
7
|
+
sellBase: 159_000,
|
|
8
|
+
// https://dashboard.tenderly.co/paraswap/paraswap/fork/d5964ad1-f64f-42b7-8fac-976ad216f05f/simulation/49df18de-8046-463e-a904-5c9f621406d4/gas-usage
|
|
9
|
+
baseToBase: 204_000,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const USD_PRECISION = 2;
|
|
13
|
+
|
|
14
|
+
export const MIN_CONVERSION_RATE = 1;
|
|
15
|
+
|
|
16
|
+
export const NULL_STATE: PoolState = {
|
|
17
|
+
tokenInfos: {},
|
|
18
|
+
tokenStates: {},
|
|
19
|
+
decimals: {},
|
|
20
|
+
oracleTimestamp: 0n,
|
|
21
|
+
isPaused: false,
|
|
22
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { BytesLike } from 'ethers';
|
|
2
|
+
import { defaultAbiCoder } from 'ethers/lib/utils';
|
|
3
|
+
import { extractSuccessAndValue, generalDecoder } from '../../lib/decoders';
|
|
4
|
+
import { MultiResult } from '../../lib/multi-wrapper';
|
|
5
|
+
import { DecimalInfo, TokenInfo, TokenState } from './types';
|
|
6
|
+
|
|
7
|
+
export function tokenInfoDecoder(
|
|
8
|
+
result: MultiResult<BytesLike> | BytesLike,
|
|
9
|
+
): TokenInfo {
|
|
10
|
+
return generalDecoder(result, ['uint192', 'uint16'], undefined, value => ({
|
|
11
|
+
reserve: value[0].toBigInt(),
|
|
12
|
+
feeRate: BigInt(value[1].toString()),
|
|
13
|
+
}));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function decimalInfoDecoder(
|
|
17
|
+
result: MultiResult<BytesLike> | BytesLike,
|
|
18
|
+
): DecimalInfo {
|
|
19
|
+
return generalDecoder(
|
|
20
|
+
result,
|
|
21
|
+
['tuple(uint64 priceDec, uint64 quoteDec, uint64 baseDec)'],
|
|
22
|
+
undefined,
|
|
23
|
+
value => ({
|
|
24
|
+
priceDec: value[0].priceDec.toBigInt(),
|
|
25
|
+
quoteDec: value[0].quoteDec.toBigInt(),
|
|
26
|
+
baseDec: value[0].baseDec.toBigInt(),
|
|
27
|
+
}),
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// This is state from WooOracleV2 contract
|
|
32
|
+
export function stateDecoder(
|
|
33
|
+
result: MultiResult<BytesLike> | BytesLike,
|
|
34
|
+
): TokenState {
|
|
35
|
+
return generalDecoder(
|
|
36
|
+
result,
|
|
37
|
+
['tuple(uint128 price, uint64 spread, uint64 coeff, bool woFeasible)'],
|
|
38
|
+
undefined,
|
|
39
|
+
value => ({
|
|
40
|
+
price: value[0].price.toBigInt(),
|
|
41
|
+
spread: value[0].spread.toBigInt(),
|
|
42
|
+
coeff: value[0].coeff.toBigInt(),
|
|
43
|
+
}),
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Interface } from 'ethers/lib/utils';
|
|
2
|
+
import { Address, Token } from '../../types';
|
|
3
|
+
|
|
4
|
+
export type PoolState = {
|
|
5
|
+
// fetched from WooPPV2.tokenInfos(address baseToken) :
|
|
6
|
+
// https://arbiscan.io/address/0x8693F9701D6DB361Fe9CC15Bc455Ef4366E39AE0
|
|
7
|
+
tokenInfos: Record<Address, TokenInfo>;
|
|
8
|
+
|
|
9
|
+
// fetched from WooracleV2.state(address baseToken)
|
|
10
|
+
// https://arbiscan.io/address/0x962d37fb9d75fe1af9aab323727183e4eae1322d
|
|
11
|
+
tokenStates: Record<Address, TokenState>;
|
|
12
|
+
|
|
13
|
+
// fetched from WooPPV2.decimalInfo(address baseToken)
|
|
14
|
+
// https://arbiscan.io/address/0x8693F9701D6DB361Fe9CC15Bc455Ef4366E39AE0
|
|
15
|
+
decimals: Record<Address, DecimalInfo>;
|
|
16
|
+
oracleTimestamp: bigint;
|
|
17
|
+
isPaused: boolean;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type WooFiV2Data = {};
|
|
21
|
+
|
|
22
|
+
export type DexParams = {
|
|
23
|
+
wooPPV2Address: Address;
|
|
24
|
+
wooOracleV2Address: Address;
|
|
25
|
+
integrationHelperAddress: Address;
|
|
26
|
+
quoteToken: Token;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type TokenInfo = {
|
|
30
|
+
reserve: bigint;
|
|
31
|
+
feeRate: bigint;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type TokenState = {
|
|
35
|
+
price: bigint;
|
|
36
|
+
spread: bigint;
|
|
37
|
+
coeff: bigint;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type DecimalInfo = {
|
|
41
|
+
priceDec: bigint;
|
|
42
|
+
quoteDec: bigint;
|
|
43
|
+
baseDec: bigint;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type LatestRoundData = {
|
|
47
|
+
answer: bigint;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export type MulticallResultOutputs =
|
|
51
|
+
| boolean
|
|
52
|
+
| bigint
|
|
53
|
+
| TokenInfo
|
|
54
|
+
| DecimalInfo
|
|
55
|
+
| TokenState;
|
|
56
|
+
|
|
57
|
+
export type WooFiV2Interfaces = {
|
|
58
|
+
PPV2: Interface;
|
|
59
|
+
oracleV2: Interface;
|
|
60
|
+
integrationHelper: Interface;
|
|
61
|
+
chainlink: Interface;
|
|
62
|
+
erc20BalanceOf: Interface;
|
|
63
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Interface } from 'ethers/lib/utils';
|
|
2
|
+
import wooPPV2ABI from '../../abi/woo-fi-v2/WooPPV2.abi.json';
|
|
3
|
+
import wooOracleV2ABI from '../../abi/woo-fi-v2/WooOracleV2.abi.json';
|
|
4
|
+
import wooIntegrationHelper from '../../abi/woo-fi-v2/IntegrationHelper.abi.json';
|
|
5
|
+
import { WooFiV2Interfaces } from './types';
|
|
6
|
+
|
|
7
|
+
export const ifaces: WooFiV2Interfaces = {
|
|
8
|
+
PPV2: new Interface(wooPPV2ABI),
|
|
9
|
+
oracleV2: new Interface(wooOracleV2ABI),
|
|
10
|
+
integrationHelper: new Interface(wooIntegrationHelper),
|
|
11
|
+
chainlink: new Interface([
|
|
12
|
+
'function latestRoundData() view returns (tuple(uint80 roundId, ' +
|
|
13
|
+
'int256 answer, uint256 startedAt, uint256 updatedAt, ' +
|
|
14
|
+
'uint80 answeredInRound))',
|
|
15
|
+
]),
|
|
16
|
+
erc20BalanceOf: new Interface([
|
|
17
|
+
'function balanceOf(address) view returns (uint256)',
|
|
18
|
+
]),
|
|
19
|
+
};
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
dotenv.config();
|
|
3
|
+
|
|
4
|
+
import { testE2E } from '../../../tests/utils-e2e';
|
|
5
|
+
import { Tokens, Holders } from '../../../tests/constants-e2e';
|
|
6
|
+
import { Network, ContractMethod, SwapSide } from '../../constants';
|
|
7
|
+
import { StaticJsonRpcProvider } from '@ethersproject/providers';
|
|
8
|
+
import { generateConfig } from '../../config';
|
|
9
|
+
|
|
10
|
+
function testForNetwork(
|
|
11
|
+
network: Network,
|
|
12
|
+
dexKey: string,
|
|
13
|
+
tokenBaseA: string,
|
|
14
|
+
tokenBaseB: string,
|
|
15
|
+
tokenQuote: string,
|
|
16
|
+
tokenBaseAAmount: string,
|
|
17
|
+
tokenQuoteAmount: 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
|
+
[
|
|
28
|
+
SwapSide.SELL,
|
|
29
|
+
[
|
|
30
|
+
ContractMethod.simpleSwap,
|
|
31
|
+
ContractMethod.multiSwap,
|
|
32
|
+
ContractMethod.megaSwap,
|
|
33
|
+
],
|
|
34
|
+
],
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
describe(`${network}`, () => {
|
|
38
|
+
sideToContractMethods.forEach((contractMethods, side) =>
|
|
39
|
+
describe(`${side}`, () => {
|
|
40
|
+
contractMethods.forEach((contractMethod: ContractMethod) => {
|
|
41
|
+
describe(`${contractMethod}`, () => {
|
|
42
|
+
it(`${tokenBaseA} -> ${tokenQuote}`, async () => {
|
|
43
|
+
await testE2E(
|
|
44
|
+
tokens[tokenBaseA],
|
|
45
|
+
tokens[tokenQuote],
|
|
46
|
+
holders[tokenBaseA],
|
|
47
|
+
tokenBaseAAmount,
|
|
48
|
+
side,
|
|
49
|
+
dexKey,
|
|
50
|
+
contractMethod,
|
|
51
|
+
network,
|
|
52
|
+
provider,
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
it(`${tokenQuote} -> ${tokenBaseA}`, async () => {
|
|
56
|
+
await testE2E(
|
|
57
|
+
tokens[tokenQuote],
|
|
58
|
+
tokens[tokenBaseA],
|
|
59
|
+
holders[tokenQuote],
|
|
60
|
+
tokenQuoteAmount,
|
|
61
|
+
side,
|
|
62
|
+
dexKey,
|
|
63
|
+
contractMethod,
|
|
64
|
+
network,
|
|
65
|
+
provider,
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
it(`${tokenBaseA} -> ${tokenBaseB}`, async () => {
|
|
69
|
+
await testE2E(
|
|
70
|
+
tokens[tokenBaseA],
|
|
71
|
+
tokens[tokenBaseB],
|
|
72
|
+
holders[tokenBaseA],
|
|
73
|
+
tokenBaseAAmount,
|
|
74
|
+
side,
|
|
75
|
+
dexKey,
|
|
76
|
+
contractMethod,
|
|
77
|
+
network,
|
|
78
|
+
provider,
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}),
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
describe('WooFiV2 E2E', () => {
|
|
89
|
+
const dexKey = 'WooFiV2';
|
|
90
|
+
|
|
91
|
+
describe('Optimism', () => {
|
|
92
|
+
const network = Network.OPTIMISM;
|
|
93
|
+
|
|
94
|
+
const baseATokenSymbol = 'WETH';
|
|
95
|
+
const baseBTokenSymbol = 'WBTC';
|
|
96
|
+
const quoteTokenSymbol = 'USDC';
|
|
97
|
+
|
|
98
|
+
const tokenBaseAAmount = '1000000000000000000';
|
|
99
|
+
const tokenQuoteAmount = '1000000';
|
|
100
|
+
|
|
101
|
+
testForNetwork(
|
|
102
|
+
network,
|
|
103
|
+
dexKey,
|
|
104
|
+
baseATokenSymbol,
|
|
105
|
+
baseBTokenSymbol,
|
|
106
|
+
quoteTokenSymbol,
|
|
107
|
+
tokenBaseAAmount,
|
|
108
|
+
tokenQuoteAmount,
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('BSC', () => {
|
|
113
|
+
const network = Network.BSC;
|
|
114
|
+
|
|
115
|
+
const baseATokenSymbol = 'WBNB';
|
|
116
|
+
const baseBTokenSymbol = 'bBTC';
|
|
117
|
+
const quoteTokenSymbol = 'BUSD';
|
|
118
|
+
|
|
119
|
+
const tokenBaseAAmount = '1000000000000000000';
|
|
120
|
+
const tokenQuoteAmount = '1000000000000000000';
|
|
121
|
+
|
|
122
|
+
testForNetwork(
|
|
123
|
+
network,
|
|
124
|
+
dexKey,
|
|
125
|
+
baseATokenSymbol,
|
|
126
|
+
baseBTokenSymbol,
|
|
127
|
+
quoteTokenSymbol,
|
|
128
|
+
tokenBaseAAmount,
|
|
129
|
+
tokenQuoteAmount,
|
|
130
|
+
);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe('Polygon', () => {
|
|
134
|
+
const network = Network.POLYGON;
|
|
135
|
+
|
|
136
|
+
const baseATokenSymbol = 'WMATIC';
|
|
137
|
+
const baseBTokenSymbol = 'WETH';
|
|
138
|
+
const quoteTokenSymbol = 'USDC';
|
|
139
|
+
|
|
140
|
+
const tokenBaseAAmount = '1000000000000000000';
|
|
141
|
+
const tokenQuoteAmount = '1000000';
|
|
142
|
+
|
|
143
|
+
testForNetwork(
|
|
144
|
+
network,
|
|
145
|
+
dexKey,
|
|
146
|
+
baseATokenSymbol,
|
|
147
|
+
baseBTokenSymbol,
|
|
148
|
+
quoteTokenSymbol,
|
|
149
|
+
tokenBaseAAmount,
|
|
150
|
+
tokenQuoteAmount,
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe('Fantom', () => {
|
|
155
|
+
const network = Network.FANTOM;
|
|
156
|
+
|
|
157
|
+
const baseATokenSymbol = 'WFTM';
|
|
158
|
+
const quoteTokenSymbol = 'USDC';
|
|
159
|
+
const baseBTokenSymbol = 'ETH';
|
|
160
|
+
|
|
161
|
+
const tokenBaseAAmount = '1000000000000000000';
|
|
162
|
+
const tokenQuoteAmount = '1000000';
|
|
163
|
+
|
|
164
|
+
testForNetwork(
|
|
165
|
+
network,
|
|
166
|
+
dexKey,
|
|
167
|
+
baseATokenSymbol,
|
|
168
|
+
baseBTokenSymbol,
|
|
169
|
+
quoteTokenSymbol,
|
|
170
|
+
tokenBaseAAmount,
|
|
171
|
+
tokenQuoteAmount,
|
|
172
|
+
);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe('Arbitrum', () => {
|
|
176
|
+
const network = Network.ARBITRUM;
|
|
177
|
+
|
|
178
|
+
const baseATokenSymbol = 'WETH';
|
|
179
|
+
const baseBTokenSymbol = 'WBTC';
|
|
180
|
+
const quoteTokenSymbol = 'USDC';
|
|
181
|
+
|
|
182
|
+
const tokenBaseAAmount = '1000000000000000000';
|
|
183
|
+
const tokenQuoteAmount = '1000000';
|
|
184
|
+
|
|
185
|
+
testForNetwork(
|
|
186
|
+
network,
|
|
187
|
+
dexKey,
|
|
188
|
+
baseATokenSymbol,
|
|
189
|
+
baseBTokenSymbol,
|
|
190
|
+
quoteTokenSymbol,
|
|
191
|
+
tokenBaseAAmount,
|
|
192
|
+
tokenQuoteAmount,
|
|
193
|
+
);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
describe('Avalanche', () => {
|
|
197
|
+
const network = Network.AVALANCHE;
|
|
198
|
+
|
|
199
|
+
const baseATokenSymbol = 'WAVAX';
|
|
200
|
+
const baseBTokenSymbol = 'BTCb';
|
|
201
|
+
const quoteTokenSymbol = 'USDC';
|
|
202
|
+
|
|
203
|
+
const tokenBaseAAmount = '1000000000000000000';
|
|
204
|
+
const tokenQuoteAmount = '1000000';
|
|
205
|
+
|
|
206
|
+
testForNetwork(
|
|
207
|
+
network,
|
|
208
|
+
dexKey,
|
|
209
|
+
baseATokenSymbol,
|
|
210
|
+
baseBTokenSymbol,
|
|
211
|
+
quoteTokenSymbol,
|
|
212
|
+
tokenBaseAAmount,
|
|
213
|
+
tokenQuoteAmount,
|
|
214
|
+
);
|
|
215
|
+
});
|
|
216
|
+
});
|