@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
@@ -0,0 +1,195 @@
1
+ import { PoolState, TokenState } from './types';
2
+ import { Address, Logger } from '../../types';
3
+ import { BI_POWS } from '../../bigint-constants';
4
+ import { _require } from '../../utils';
5
+ import { NULL_STATE } from './constants';
6
+
7
+ function handleMathError(e: unknown, logger: Logger) {
8
+ if (e instanceof Error && e.message.startsWith('WooGuardian:')) {
9
+ logger.warn('WooFi Guardian check Error:', e);
10
+ return;
11
+ }
12
+ logger.error('Unexpected error in WooFi math:', e);
13
+ }
14
+
15
+ function max(a: bigint, b: bigint): bigint {
16
+ return a > b ? a : b;
17
+ }
18
+
19
+ export class WooFiV2Math {
20
+ state: PoolState = NULL_STATE;
21
+
22
+ constructor(
23
+ private readonly logger: Logger,
24
+ private readonly _quoteToken: Address,
25
+ ) {}
26
+
27
+ query(
28
+ fromToken: Address,
29
+ toToken: Address,
30
+ fromAmounts: bigint[],
31
+ ): bigint[] | null {
32
+ try {
33
+ if (fromToken === this._quoteToken) {
34
+ return this._querySellQuote(toToken, fromAmounts);
35
+ } else if (toToken === this._quoteToken) {
36
+ return this._querySellBase(fromToken, fromAmounts);
37
+ } else {
38
+ return this._queryBaseToBase(fromToken, toToken, fromAmounts);
39
+ }
40
+ } catch (e) {
41
+ handleMathError(e, this.logger);
42
+ return null;
43
+ }
44
+ }
45
+
46
+ _querySellBase(baseToken: Address, baseAmounts: bigint[]): bigint[] | null {
47
+ try {
48
+ const _state = this.state.tokenStates[baseToken];
49
+ let quoteAmounts = this._calcQuoteAmountSellBase(
50
+ baseToken,
51
+ baseAmounts,
52
+ _state,
53
+ );
54
+
55
+ quoteAmounts = quoteAmounts.map(amount => {
56
+ return amount <= this.state.tokenInfos[this._quoteToken].reserve
57
+ ? amount
58
+ : 0n;
59
+ });
60
+
61
+ const feeRate = this.state.tokenInfos[baseToken].feeRate;
62
+ return this._takeFee(quoteAmounts, feeRate);
63
+ } catch (e) {
64
+ handleMathError(e, this.logger);
65
+ return null;
66
+ }
67
+ }
68
+
69
+ _querySellQuote(baseToken: Address, quoteAmounts: bigint[]): bigint[] | null {
70
+ try {
71
+ const feeRate = this.state.tokenInfos[baseToken].feeRate;
72
+ quoteAmounts = this._takeFee(quoteAmounts, feeRate);
73
+
74
+ const _state = this.state.tokenStates[baseToken];
75
+ let toAmounts = this._calcBaseAmountSellQuote(
76
+ baseToken,
77
+ quoteAmounts,
78
+ _state,
79
+ );
80
+
81
+ const baseReserve = this.state.tokenInfos[baseToken].reserve;
82
+ return toAmounts.map(amount => {
83
+ return amount <= baseReserve ? amount : 0n;
84
+ });
85
+ } catch (e) {
86
+ handleMathError(e, this.logger);
87
+ return null;
88
+ }
89
+ }
90
+
91
+ _queryBaseToBase(
92
+ baseToken1: Address,
93
+ baseToken2: Address,
94
+ base1Amounts: bigint[],
95
+ ): bigint[] | null {
96
+ try {
97
+ let state1: TokenState = this.state.tokenStates[baseToken1];
98
+ let state2: TokenState = this.state.tokenStates[baseToken2];
99
+
100
+ const feeRate1 = this.state.tokenInfos[baseToken1].feeRate;
101
+ const feeRate2 = this.state.tokenInfos[baseToken2].feeRate;
102
+
103
+ const spread = max(state1.spread, state2.spread) / 2n;
104
+ const feeRate = max(feeRate1, feeRate2);
105
+
106
+ state1.spread = spread;
107
+ state2.spread = spread;
108
+
109
+ let quoteAmounts = this._calcQuoteAmountSellBase(
110
+ baseToken1,
111
+ base1Amounts,
112
+ state1,
113
+ );
114
+ quoteAmounts = this._takeFeeAndCheckReserve(quoteAmounts, feeRate);
115
+
116
+ let toAmounts = this._calcBaseAmountSellQuote(
117
+ baseToken2,
118
+ quoteAmounts,
119
+ state2,
120
+ );
121
+
122
+ return toAmounts.map(toAmount => {
123
+ return toAmount <= this.state.tokenInfos[baseToken2].reserve
124
+ ? toAmount
125
+ : 0n;
126
+ });
127
+ } catch (e) {
128
+ handleMathError(e, this.logger);
129
+ return null;
130
+ }
131
+ }
132
+
133
+ protected _takeFeeAndCheckReserve(
134
+ amounts: bigint[],
135
+ feeRate: bigint,
136
+ ): bigint[] {
137
+ return amounts.map(amount => {
138
+ if (amount === 0n) return 0n;
139
+ const lpFee = (amount * feeRate) / BI_POWS[5];
140
+ const reserve = this.state.tokenInfos[this._quoteToken].reserve;
141
+ return lpFee > reserve ? 0n : amount - lpFee;
142
+ });
143
+ }
144
+
145
+ protected _takeFee(amounts: bigint[], feeRate: bigint): bigint[] {
146
+ return amounts.map(amount => {
147
+ const lpFee = (amount * feeRate) / BI_POWS[5];
148
+ return amount === 0n ? 0n : amount - lpFee;
149
+ });
150
+ }
151
+
152
+ protected _calcQuoteAmountSellBase(
153
+ baseToken: Address,
154
+ baseAmounts: bigint[],
155
+ state: TokenState,
156
+ ): bigint[] {
157
+ let { priceDec, quoteDec, baseDec } = this.state.decimals[baseToken];
158
+
159
+ return baseAmounts.map(baseAmount => {
160
+ if (baseAmount === 0n) return 0n;
161
+
162
+ const coef: bigint =
163
+ BI_POWS[18] -
164
+ (state.coeff * baseAmount * state.price) / baseDec / priceDec -
165
+ state.spread;
166
+
167
+ return (
168
+ (((baseAmount * quoteDec * state.price) / priceDec) * coef) /
169
+ BI_POWS[18] /
170
+ baseDec
171
+ );
172
+ });
173
+ }
174
+
175
+ protected _calcBaseAmountSellQuote(
176
+ baseToken: string,
177
+ quoteAmounts: bigint[],
178
+ state: TokenState,
179
+ ): bigint[] {
180
+ let { priceDec, quoteDec, baseDec } = this.state.decimals[baseToken];
181
+
182
+ return quoteAmounts.map(quoteAmount => {
183
+ if (quoteAmount === 0n) return 0n;
184
+
185
+ const coef: bigint =
186
+ BI_POWS[18] - (quoteAmount * state.coeff) / quoteDec - state.spread;
187
+
188
+ return (
189
+ (((quoteAmount * baseDec * priceDec) / state.price) * coef) /
190
+ BI_POWS[18] /
191
+ quoteDec
192
+ );
193
+ });
194
+ }
195
+ }
@@ -0,0 +1,112 @@
1
+ import _ from 'lodash';
2
+ import { IDexHelper } from '../../dex-helper/idex-helper';
3
+ import {
4
+ DecimalInfo,
5
+ DexParams,
6
+ MulticallResultOutputs,
7
+ PoolState,
8
+ TokenInfo,
9
+ TokenState,
10
+ } from './types';
11
+ import { StatefulRpcPoller } from '../../lib/stateful-rpc-poller/stateful-rpc-poller';
12
+ import { pollingManagerCbExtractor } from '../../lib/stateful-rpc-poller/utils';
13
+ import { StatePollingManager } from '../../lib/stateful-rpc-poller/state-polling-manager';
14
+ import { MultiCallParams } from '../../lib/multi-wrapper';
15
+ import { booleanDecode, uint256ToBigInt } from '../../lib/decoders';
16
+ import { ifaces } from './utils';
17
+ import { Token } from '../../types';
18
+ import { decimalInfoDecoder, stateDecoder, tokenInfoDecoder } from './decoders';
19
+
20
+ export class WooFiV2PollingPool extends StatefulRpcPoller<
21
+ PoolState,
22
+ MulticallResultOutputs
23
+ > {
24
+ constructor(
25
+ dexKey: string,
26
+ poolIdentifier: string,
27
+ dexHelper: IDexHelper,
28
+ protected config: DexParams,
29
+ // It already includes quoteToken
30
+ protected tokens: Token[],
31
+ ) {
32
+ const callbacks = pollingManagerCbExtractor(
33
+ StatePollingManager.getInstance(dexHelper),
34
+ );
35
+
36
+ super(dexKey, poolIdentifier, dexHelper, 0, 0, false, callbacks);
37
+ }
38
+
39
+ protected _getFetchStateMultiCalls(): MultiCallParams<MulticallResultOutputs>[] {
40
+ return (
41
+ [
42
+ {
43
+ target: this.config.wooPPV2Address,
44
+ callData: ifaces.PPV2.encodeFunctionData('paused', []),
45
+ decodeFunction: booleanDecode,
46
+ },
47
+ {
48
+ target: this.config.wooOracleV2Address,
49
+ callData: ifaces.oracleV2.encodeFunctionData('timestamp', []),
50
+ decodeFunction: uint256ToBigInt,
51
+ },
52
+ ] as MultiCallParams<MulticallResultOutputs>[]
53
+ ).concat(
54
+ this.tokens
55
+ .map(t => [
56
+ {
57
+ target: this.config.wooPPV2Address,
58
+ callData: ifaces.PPV2.encodeFunctionData('tokenInfos', [t.address]),
59
+ decodeFunction: tokenInfoDecoder,
60
+ },
61
+ {
62
+ target: this.config.wooPPV2Address,
63
+ callData: ifaces.PPV2.encodeFunctionData('decimalInfo', [
64
+ t.address,
65
+ ]),
66
+ decodeFunction: decimalInfoDecoder,
67
+ },
68
+ {
69
+ target: this.config.wooOracleV2Address,
70
+ callData: ifaces.oracleV2.encodeFunctionData('state', [t.address]),
71
+ decodeFunction: stateDecoder,
72
+ },
73
+ ])
74
+ .flat(),
75
+ );
76
+ }
77
+
78
+ protected _parseStateFromMultiResults(
79
+ multiOutputs: MulticallResultOutputs[],
80
+ ): PoolState {
81
+ const [isPaused, oracleTimestamp, ...remained] = multiOutputs as [
82
+ boolean,
83
+ bigint,
84
+ ...MulticallResultOutputs[],
85
+ ];
86
+
87
+ const tokenInfos: Record<string, TokenInfo> = {};
88
+ const decimals: Record<string, DecimalInfo> = {};
89
+ const tokenStates: Record<string, TokenState> = {};
90
+
91
+ _.chunk(remained, 3).forEach((chunk, i) => {
92
+ const [tokenInfo, decimalInfo, tokenState] = chunk as [
93
+ TokenInfo,
94
+ DecimalInfo,
95
+ TokenState,
96
+ ];
97
+ const token = this.tokens[i];
98
+
99
+ tokenInfos[token.address] = tokenInfo;
100
+ decimals[token.address] = decimalInfo;
101
+ tokenStates[token.address] = tokenState;
102
+ });
103
+
104
+ return {
105
+ tokenInfos,
106
+ tokenStates,
107
+ decimals,
108
+ oracleTimestamp,
109
+ isPaused,
110
+ };
111
+ }
112
+ }