@paraswap/dex-lib 2.14.0 → 2.14.2

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 (107) hide show
  1. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  2. package/.idea/misc.xml +6 -0
  3. package/.idea/modules.xml +8 -0
  4. package/.idea/vcs.xml +6 -0
  5. package/.vscode/launch.json +21 -0
  6. package/build/config.js +23 -5
  7. package/build/config.js.map +1 -1
  8. package/build/dex/aave-v3/tokens/arbitrum.json +50 -0
  9. package/build/dex/aave-v3/tokens/avalanche.json +50 -0
  10. package/build/dex/aave-v3/tokens/fantom.json +62 -0
  11. package/build/dex/aave-v3/tokens/mainnet.json +44 -0
  12. package/build/dex/aave-v3/tokens/optimism.json +50 -0
  13. package/build/dex/aave-v3/tokens/polygon.json +98 -0
  14. package/build/dex/balancer-v2/VirtualBoostedPool.d.ts +79 -0
  15. package/build/dex/balancer-v2/VirtualBoostedPool.js +382 -0
  16. package/build/dex/balancer-v2/VirtualBoostedPool.js.map +1 -0
  17. package/build/dex/generic-rfq/e2e-test-config.d.ts +9 -0
  18. package/build/dex/generic-rfq/e2e-test-config.js +33 -0
  19. package/build/dex/generic-rfq/e2e-test-config.js.map +1 -0
  20. package/build/dex/generic-rfq/rate-fetcher.js +2 -0
  21. package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
  22. package/build/dex/generic-rfq/validators.d.ts +1 -1
  23. package/build/dex/generic-rfq/validators.js +36 -26
  24. package/build/dex/generic-rfq/validators.js.map +1 -1
  25. package/build/dex/index.js +2 -2
  26. package/build/dex/index.js.map +1 -1
  27. package/build/dex/simple-exchange.d.ts +1 -0
  28. package/build/dex/simple-exchange.js +2 -0
  29. package/build/dex/simple-exchange.js.map +1 -1
  30. package/build/dex/test-aave-v3/config.d.ts +4 -0
  31. package/build/dex/test-aave-v3/config.js +15 -0
  32. package/build/dex/test-aave-v3/config.js.map +1 -0
  33. package/build/dex/test-aave-v3/test-aave-v3-pool.d.ts +39 -0
  34. package/build/dex/test-aave-v3/test-aave-v3-pool.js +63 -0
  35. package/build/dex/test-aave-v3/test-aave-v3-pool.js.map +1 -0
  36. package/build/dex/test-aave-v3/test-aave-v3.d.ts +37 -0
  37. package/build/dex/test-aave-v3/test-aave-v3.js +126 -0
  38. package/build/dex/test-aave-v3/test-aave-v3.js.map +1 -0
  39. package/build/dex/test-aave-v3/types.d.ts +6 -0
  40. package/build/dex/test-aave-v3/types.js +3 -0
  41. package/build/dex/test-aave-v3/types.js.map +1 -0
  42. package/build/lib/decoders.d.ts +2 -1
  43. package/build/lib/decoders.js +8 -1
  44. package/build/lib/decoders.js.map +1 -1
  45. package/build/lib/fetcher/fetcher.js +3 -0
  46. package/build/lib/fetcher/fetcher.js.map +1 -1
  47. package/build/lib/multi-wrapper.d.ts +2 -1
  48. package/build/lib/multi-wrapper.js.map +1 -1
  49. package/build/lib/tokens/balancer-fetcher.js +4 -5
  50. package/build/lib/tokens/balancer-fetcher.js.map +1 -1
  51. package/build/lib/tokens/utils.d.ts +2 -2
  52. package/build/lib/tokens/utils.js +1 -1
  53. package/build/lib/tokens/utils.js.map +1 -1
  54. package/build/types.d.ts +3 -0
  55. package/dex-template/__DexName__-e2e.test.ts.template +1 -0
  56. package/dex-template/__DexName__-events.test.ts.template +1 -0
  57. package/dex-template/__DexName__-integration.test.ts.template +1 -0
  58. package/dex-template/__DexName__-pool.ts.template +8 -5
  59. package/package.json +1 -1
  60. package/scripts/generate-bytecode.ts +2 -0
  61. package/src/abi/woo-fi-v2/IntegrationHelper.abi.json +116 -0
  62. package/src/abi/{woo-fi/Wooracle.abi.json → woo-fi-v2/WooOracleV2.abi.json} +148 -50
  63. package/src/abi/{woo-fi/WooPP.abi.json → woo-fi-v2/WooPPV2.abi.json} +201 -169
  64. package/src/config.ts +27 -5
  65. package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +0 -1
  66. package/src/dex/generic-rfq/e2e-test-config.ts +37 -0
  67. package/src/dex/generic-rfq/generic-rfq-e2e.test.ts +63 -258
  68. package/src/dex/generic-rfq/generic-rfq-local-e2e.test.ts +121 -0
  69. package/src/dex/generic-rfq/rate-fetcher.ts +2 -0
  70. package/src/dex/generic-rfq/validators.test.ts +6 -32
  71. package/src/dex/generic-rfq/validators.ts +57 -32
  72. package/src/dex/index.ts +2 -2
  73. package/src/dex/simple-exchange.ts +3 -0
  74. package/src/dex/woo-fi-v2/config.ts +87 -0
  75. package/src/dex/woo-fi-v2/constants.ts +22 -0
  76. package/src/dex/woo-fi-v2/decoders.ts +45 -0
  77. package/src/dex/woo-fi-v2/types.ts +63 -0
  78. package/src/dex/woo-fi-v2/utils.ts +19 -0
  79. package/src/dex/woo-fi-v2/woo-fi-v2-e2e.test.ts +216 -0
  80. package/src/dex/woo-fi-v2/woo-fi-v2-integration.test.ts +495 -0
  81. package/src/dex/woo-fi-v2/woo-fi-v2-math.ts +195 -0
  82. package/src/dex/woo-fi-v2/woo-fi-v2-pool.ts +112 -0
  83. package/src/dex/woo-fi-v2/woo-fi-v2.ts +487 -0
  84. package/src/lib/decoders.ts +12 -1
  85. package/src/lib/fetcher/fetcher.ts +6 -0
  86. package/src/lib/log-messages-suppressor.ts +173 -0
  87. package/src/lib/multi-wrapper.ts +2 -1
  88. package/src/lib/stateful-rpc-poller/state-polling-manager.ts +320 -0
  89. package/src/lib/stateful-rpc-poller/stateful-rpc-poller.ts +604 -0
  90. package/src/lib/stateful-rpc-poller/types.ts +66 -0
  91. package/src/lib/stateful-rpc-poller/utils.ts +23 -0
  92. package/src/lib/tokens/balancer-fetcher.ts +5 -6
  93. package/src/lib/tokens/utils.ts +5 -3
  94. package/src/types.ts +4 -0
  95. package/tests/constants-e2e.ts +10 -3
  96. package/tests/tenderly-simulation.ts +1 -1
  97. package/tests/utils-e2e.ts +61 -48
  98. package/tests/utils.ts +2 -0
  99. package/src/abi/woo-fi/WooFeeManager.abi.json +0 -318
  100. package/src/dex/woo-fi/config.ts +0 -141
  101. package/src/dex/woo-fi/constants.ts +0 -21
  102. package/src/dex/woo-fi/types.ts +0 -55
  103. package/src/dex/woo-fi/woo-fi-decimal-math.ts +0 -45
  104. package/src/dex/woo-fi/woo-fi-e2e.test.ts +0 -183
  105. package/src/dex/woo-fi/woo-fi-integration.test.ts +0 -416
  106. package/src/dex/woo-fi/woo-fi-math.ts +0 -527
  107. package/src/dex/woo-fi/woo-fi.ts +0 -693
@@ -112,10 +112,11 @@ describe('GenericRFQ Validator test', () => {
112
112
  },
113
113
  };
114
114
 
115
- const pricesInvalidBidsNotSortedDesc = {
115
+ const pricesNegativeSpread = {
116
116
  prices: {
117
117
  'WETH/DAI': {
118
118
  bids: [
119
+ ['1337.425240000000000000', '1.166200000000000000'],
119
120
  ['1333.024812000000000000', '1.166200000000000000'],
120
121
  ['1333.425240000000000000', '1.166200000000000000'],
121
122
  ['1332.624384000000000000', '1.166200000000000000'],
@@ -135,29 +136,6 @@ describe('GenericRFQ Validator test', () => {
135
136
  },
136
137
  };
137
138
 
138
- const pricesInvalidAskNotSortedAsc = {
139
- prices: {
140
- 'WETH/DAI': {
141
- bids: [
142
- ['1333.425240000000000000', '1.166200000000000000'],
143
- ['1333.024812000000000000', '1.166200000000000000'],
144
- ['1332.624384000000000000', '1.166200000000000000'],
145
- ['1332.223956000000000000', '1.166200000000000000'],
146
- ['1331.823528000000000000', '1.166200000000000000'],
147
- ['1331.423100000000000000', '1.169000000000000000'],
148
- ],
149
- asks: [
150
- ['1337.146033000000000000', '1.166200000000000000'],
151
- ['1336.745410000000000000', '1.166200000000000000'],
152
- ['1337.546656000000000000', '1.166200000000000000'],
153
- ['1337.947279000000000000', '1.166200000000000000'],
154
- ['1338.347902000000000000', '1.166200000000000000'],
155
- ['1338.748525000000000000', '1.169000000000000000'],
156
- ],
157
- },
158
- },
159
- };
160
-
161
139
  const noPrices = {
162
140
  prices: {
163
141
  'WETH/DAI': {},
@@ -200,12 +178,6 @@ describe('GenericRFQ Validator test', () => {
200
178
 
201
179
  it('Price test', () => {
202
180
  expect(() => validateAndCast(prices, pricesResponse)).not.toThrowError();
203
- expect(() =>
204
- validateAndCast(pricesInvalidBidsNotSortedDesc, pricesResponse),
205
- ).toThrowError();
206
- expect(() =>
207
- validateAndCast(pricesInvalidAskNotSortedAsc, pricesResponse),
208
- ).toThrowError();
209
181
  expect(() =>
210
182
  validateAndCast(noPrices, pricesResponse),
211
183
  ).not.toThrowError();
@@ -218,6 +190,9 @@ describe('GenericRFQ Validator test', () => {
218
190
  expect(() =>
219
191
  validateAndCast(onlyAsks, pricesResponse),
220
192
  ).not.toThrowError();
193
+ expect(() =>
194
+ validateAndCast(pricesNegativeSpread, pricesResponse),
195
+ ).toThrowError('the maximum bid is higher than minimum ask');
221
196
  });
222
197
  });
223
198
 
@@ -261,11 +236,10 @@ describe('GenericRFQ Validator test', () => {
261
236
  },
262
237
  };
263
238
 
264
- it('Blacklist test', () => {
239
+ it('Order test', () => {
265
240
  expect(() =>
266
241
  validateAndCast(order, firmRateResponseValidator),
267
242
  ).not.toThrowError();
268
- // expect(() => validateAndCast(invalidBlacklist, blacklistResponseValidator)).toThrowError();
269
243
  });
270
244
  });
271
245
  });
@@ -56,7 +56,7 @@ const stringNumberValidator = (
56
56
  return value;
57
57
  };
58
58
 
59
- const pricesValidatorWithoutSorting = joi
59
+ const pricesValidator = joi
60
60
  .array()
61
61
  .items(
62
62
  joi
@@ -66,47 +66,58 @@ const pricesValidatorWithoutSorting = joi
66
66
  );
67
67
 
68
68
  const ext: joi.Extension = {
69
- type: 'sortedArray',
70
- base: pricesValidatorWithoutSorting,
69
+ type: 'validatedPrices',
70
+ base: joi.object({
71
+ bids: pricesValidator,
72
+ asks: pricesValidator,
73
+ }),
71
74
  rules: {
72
- asc: {
73
- validate: (values: string[], helpers: CustomHelpers) => {
74
- const prices = values.map(numbers => new BigNumber(numbers[0]));
75
- const isAscOrder = prices.every(
76
- (x, i) => i === 0 || x.gte(prices[i - 1]),
77
- );
78
- return isAscOrder
75
+ bidsLowerThanAsks: {
76
+ validate: (
77
+ values: { bids: string[]; asks: string[] },
78
+ helpers: CustomHelpers,
79
+ ) => {
80
+ if (
81
+ !values.bids ||
82
+ !values.asks ||
83
+ values.bids.length === 0 ||
84
+ values.asks.length === 0
85
+ ) {
86
+ return values;
87
+ }
88
+ const maxBid = values.bids
89
+ .map(numbers => new BigNumber(numbers[0]))
90
+ .reduce(
91
+ (previousValue, currentValue) =>
92
+ currentValue.gte(previousValue) ? currentValue : previousValue,
93
+ new BigNumber(0),
94
+ );
95
+ const minAsk = values.asks
96
+ .map(numbers => new BigNumber(numbers[0]))
97
+ .reduce(
98
+ (previousValue, currentValue) =>
99
+ currentValue.lte(previousValue) ? currentValue : previousValue,
100
+ new BigNumber('123456789012345678901234567890'),
101
+ );
102
+ return maxBid < minAsk
79
103
  ? values
80
104
  : helpers.message({
81
- custom: `array is not asc sorted ${JSON.stringify(values)}`,
82
- });
83
- },
84
- },
85
- desc: {
86
- validate: (values: string[][], helpers: CustomHelpers) => {
87
- const prices = values.map(numbers => new BigNumber(numbers[0]));
88
- const isAscOrder = prices.every(
89
- (x, i) => i === 0 || x.lte(prices[i - 1]),
90
- );
91
- return isAscOrder
92
- ? values
93
- : helpers.message({
94
- custom: `array is not desc sorted ${JSON.stringify(values)}`,
105
+ custom: 'the maximum bid is higher than minimum ask',
95
106
  });
96
107
  },
97
108
  },
98
109
  },
99
110
  };
100
111
 
101
- const pricesArrayValidator = joi.extend(ext);
102
-
103
- export const priceValidator = joi.object({
104
- bids: pricesArrayValidator.sortedArray().desc(),
105
- asks: pricesArrayValidator.sortedArray().asc(),
106
- });
112
+ export const priceValidator = joi.extend(ext);
107
113
 
108
114
  export const pricesResponse = joi.object({
109
- prices: joi.object().pattern(joi.string().min(1), priceValidator),
115
+ prices: joi
116
+ .object()
117
+ .pattern(
118
+ joi.string().min(1),
119
+ priceValidator.validatedPrices().bidsLowerThanAsks(),
120
+ ),
110
121
  });
111
122
 
112
123
  export const validateAndCast = <T>(
@@ -171,12 +182,26 @@ const stringStartWithHex0x = (
171
182
  return value;
172
183
  };
173
184
 
185
+ const mustBeAugustusSwapper = (
186
+ value: string,
187
+ helpers: CustomHelpers,
188
+ ): string | ErrorReport => {
189
+ const allowedTakers = [
190
+ '0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57'.toLowerCase(),
191
+ ];
192
+ return allowedTakers.includes(value.toLowerCase())
193
+ ? value
194
+ : helpers.message({
195
+ custom: `"order.taker" must be any of ${JSON.stringify(allowedTakers)}`,
196
+ });
197
+ };
198
+
174
199
  export const orderWithSignatureValidator = joi
175
200
  .object({
176
201
  nonceAndMeta: joi.string().custom(stringPositiveBigIntValidator),
177
202
  expiry: joi.number().min(0),
178
203
  maker: addressSchema.required(),
179
- taker: addressSchema.required(),
204
+ taker: addressSchema.required().custom(mustBeAugustusSwapper),
180
205
  makerAsset: addressSchema.required(),
181
206
  takerAsset: addressSchema.required(),
182
207
  makerAmount: joi
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
- // import { WooFi } from './woo-fi/woo-fi';
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
- // WooFi,
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
+ };