@paraswap/dex-lib 4.1.3-wusdl.0 → 4.1.3

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 (39) hide show
  1. package/build/dex/aave-v3-stata-v2/config.js +13 -0
  2. package/build/dex/aave-v3-stata-v2/config.js.map +1 -1
  3. package/build/dex/algebra/config.js +1 -1
  4. package/build/dex/algebra/config.js.map +1 -1
  5. package/build/dex/balancer-v2/pools/gyro/GyroEPool.js.map +1 -1
  6. package/build/dex/balancer-v3/balancer-v3-pool.d.ts +2 -0
  7. package/build/dex/balancer-v3/balancer-v3-pool.js +14 -4
  8. package/build/dex/balancer-v3/balancer-v3-pool.js.map +1 -1
  9. package/build/dex/balancer-v3/balancer-v3.js +1 -1
  10. package/build/dex/balancer-v3/balancer-v3.js.map +1 -1
  11. package/build/dex/balancer-v3/config.js +12 -0
  12. package/build/dex/balancer-v3/config.js.map +1 -1
  13. package/build/dex/cables/cables.d.ts +1 -1
  14. package/build/dex/cables/cables.js +26 -7
  15. package/build/dex/cables/cables.js.map +1 -1
  16. package/build/generic-swap-transaction-builder.d.ts +1 -1
  17. package/build/generic-swap-transaction-builder.js +6 -1
  18. package/build/generic-swap-transaction-builder.js.map +1 -1
  19. package/build/implementations/local-paraswap-sdk.js +1 -1
  20. package/build/implementations/local-paraswap-sdk.js.map +1 -1
  21. package/package.json +3 -3
  22. package/src/dex/aave-v3-stata-v2/aave-v3-stata-v2-e2e.test.ts +11 -32
  23. package/src/dex/aave-v3-stata-v2/config.ts +16 -0
  24. package/src/dex/algebra/config.ts +1 -1
  25. package/src/dex/balancer-v2/balancer-v2-integration.test.ts +11 -12
  26. package/src/dex/balancer-v2/pools/gyro/GyroEPool.ts +0 -1
  27. package/src/dex/balancer-v3/balancer-v3-e2e.test.ts +110 -0
  28. package/src/dex/balancer-v3/balancer-v3-events.test.ts +157 -84
  29. package/src/dex/balancer-v3/balancer-v3-integration.test.ts +101 -5
  30. package/src/dex/balancer-v3/balancer-v3-pool.ts +33 -13
  31. package/src/dex/balancer-v3/balancer-v3.ts +1 -1
  32. package/src/dex/balancer-v3/config.ts +12 -0
  33. package/src/dex/cables/cables-e2e.test.ts +40 -40
  34. package/src/dex/cables/cables.ts +37 -10
  35. package/src/generic-swap-transaction-builder.ts +10 -2
  36. package/src/implementations/local-paraswap-sdk.ts +1 -1
  37. package/tests/constants-e2e.ts +46 -1
  38. package/tests/tenderly-simulation.ts +2 -0
  39. package/tests/utils-e2e.ts +4 -7
@@ -129,95 +129,168 @@ type EventData = { blockNumbers: number[]; poolAddress: string[] };
129
129
 
130
130
  describe('BalancerV3 EventPool', function () {
131
131
  const dexKey = 'BalancerV3';
132
- const network = Network.SEPOLIA;
133
- const dexHelper = new DummyDexHelper(network);
134
- const logger = dexHelper.getLogger(dexKey);
135
- let balancerV3Pool: BalancerV3EventPool;
136
-
137
- // vault -> EventMappings
138
- // TODO once we have a new test deployment add tests for: AggregateSwapFeePercentageChanged, SwapFeePercentageChanged, PoolPausedStateChanged
139
- const eventsToTest: Record<Address, EventMappings> = {
140
- [BalancerV3Config.BalancerV3[network].vaultAddress]: {
141
- // https://eth-sepolia.blockscout.com/tx/0xc417d38ad6e21250c9ddded37680b40f0991cfd3f8ae2d8b5800507a58d48c44
142
- LiquidityAdded: {
143
- blockNumbers: [7170937],
144
- poolAddress: ['0x2ff3b96e0057a1f25f1d62ab800554ccdb268ab8'],
145
- },
146
- // https://sepolia.etherscan.io/tx/0xc1596e26d51104b9236a0debc3e1946b30b82f92b8331639ad6f6aea2ff2decc
147
- LiquidityRemoved: {
148
- blockNumbers: [7170957],
149
- poolAddress: ['0x2ff3b96e0057a1f25f1d62ab800554ccdb268ab8'],
150
- },
151
- // https://sepolia.etherscan.io/tx/0x78d18503c2dd4458c94ec916b10c088bb4e8b90059676d00dbcec83f763d8c0e
152
- Swap: {
153
- blockNumbers: [7175721],
154
- poolAddress: ['0x2ff3b96e0057a1f25f1d62ab800554ccdb268ab8'],
155
- },
156
- // 7170034, AmpUpdateStarted, https://eth-sepolia.blockscout.com/tx/0xfbe2e53d9cede1dc900100a1d6e809a89d909746ac7b8cc011e93227af8dda8b?tab=logs
157
- // 7170069, AmpUpdateStopped, https://eth-sepolia.blockscout.com/tx/0x2ee2e1d5980013fdf1cf9c3789e0321fb598c2412db8ee8057fcfaffd1c792ab?tab=logs
158
- VaultAuxiliary: {
159
- blockNumbers: [7170034, 7170069],
160
- poolAddress: [
161
- '0xD63dB0B88dca565633fB8d70a70b9b8093d34A7E',
162
- '0xD63dB0B88dca565633fB8d70a70b9b8093d34A7E',
163
- ],
164
- },
165
- // https://sepolia.etherscan.io/tx/0x71f9879485f4e4cf97aa42381988ffe277f05a872d6b507cfa007cec1239a3f8#eventlog
166
- SwapFeePercentageChanged: {
167
- blockNumbers: [7206571],
168
- poolAddress: ['0xe69b70a86A4e1fD33dA95693A1aE12Be1c26C8ea'],
169
- },
170
- // https://sepolia.etherscan.io/tx/0xaf232ca2df59ba5fad38d74e9b54ec2ae1ad2e6abca8348f107cf3fd94c787c7#eventlog
171
- // Should remove pool from state as its paused and no longer supports swaps
172
- PoolPausedStateChanged: {
173
- blockNumbers: [7206586],
174
- poolAddress: ['0xe69b70a86A4e1fD33dA95693A1aE12Be1c26C8ea'],
175
- },
176
- // https://sepolia.etherscan.io/tx/0xa23dc10bd0fbed7ffffe867766d9b0d7670ca4a0bc352669f547bc7775644349#eventlog
177
- AggregateSwapFeePercentageChanged: {
178
- blockNumbers: [7206701],
179
- poolAddress: ['0xe69b70a86A4e1fD33dA95693A1aE12Be1c26C8ea'],
132
+
133
+ describe('Sepolia', function () {
134
+ const network = Network.SEPOLIA;
135
+ const dexHelper = new DummyDexHelper(network);
136
+ const logger = dexHelper.getLogger(dexKey);
137
+ let balancerV3Pool: BalancerV3EventPool;
138
+
139
+ // vault -> EventMappings
140
+ // TODO once we have a new test deployment add tests for: AggregateSwapFeePercentageChanged, SwapFeePercentageChanged, PoolPausedStateChanged
141
+ const eventsToTest: Record<Address, EventMappings> = {
142
+ [BalancerV3Config.BalancerV3[network].vaultAddress]: {
143
+ // https://eth-sepolia.blockscout.com/tx/0xc417d38ad6e21250c9ddded37680b40f0991cfd3f8ae2d8b5800507a58d48c44
144
+ LiquidityAdded: {
145
+ blockNumbers: [7170937],
146
+ poolAddress: ['0x2ff3b96e0057a1f25f1d62ab800554ccdb268ab8'],
147
+ },
148
+ // https://sepolia.etherscan.io/tx/0xc1596e26d51104b9236a0debc3e1946b30b82f92b8331639ad6f6aea2ff2decc
149
+ LiquidityRemoved: {
150
+ blockNumbers: [7170957],
151
+ poolAddress: ['0x2ff3b96e0057a1f25f1d62ab800554ccdb268ab8'],
152
+ },
153
+ // https://sepolia.etherscan.io/tx/0x78d18503c2dd4458c94ec916b10c088bb4e8b90059676d00dbcec83f763d8c0e
154
+ Swap: {
155
+ blockNumbers: [7175721],
156
+ poolAddress: ['0x2ff3b96e0057a1f25f1d62ab800554ccdb268ab8'],
157
+ },
158
+ // 7170034, AmpUpdateStarted, https://eth-sepolia.blockscout.com/tx/0xfbe2e53d9cede1dc900100a1d6e809a89d909746ac7b8cc011e93227af8dda8b?tab=logs
159
+ // 7170069, AmpUpdateStopped, https://eth-sepolia.blockscout.com/tx/0x2ee2e1d5980013fdf1cf9c3789e0321fb598c2412db8ee8057fcfaffd1c792ab?tab=logs
160
+ VaultAuxiliary: {
161
+ blockNumbers: [7170034, 7170069],
162
+ poolAddress: [
163
+ '0xD63dB0B88dca565633fB8d70a70b9b8093d34A7E',
164
+ '0xD63dB0B88dca565633fB8d70a70b9b8093d34A7E',
165
+ ],
166
+ },
167
+ // https://sepolia.etherscan.io/tx/0x71f9879485f4e4cf97aa42381988ffe277f05a872d6b507cfa007cec1239a3f8#eventlog
168
+ SwapFeePercentageChanged: {
169
+ blockNumbers: [7206571],
170
+ poolAddress: ['0xe69b70a86A4e1fD33dA95693A1aE12Be1c26C8ea'],
171
+ },
172
+ // https://sepolia.etherscan.io/tx/0xaf232ca2df59ba5fad38d74e9b54ec2ae1ad2e6abca8348f107cf3fd94c787c7#eventlog
173
+ // Should remove pool from state as its paused and no longer supports swaps
174
+ PoolPausedStateChanged: {
175
+ blockNumbers: [7206586],
176
+ poolAddress: ['0xe69b70a86A4e1fD33dA95693A1aE12Be1c26C8ea'],
177
+ },
178
+ // https://sepolia.etherscan.io/tx/0xa23dc10bd0fbed7ffffe867766d9b0d7670ca4a0bc352669f547bc7775644349#eventlog
179
+ AggregateSwapFeePercentageChanged: {
180
+ blockNumbers: [7206701],
181
+ poolAddress: ['0xe69b70a86A4e1fD33dA95693A1aE12Be1c26C8ea'],
182
+ },
180
183
  },
181
- },
182
- };
184
+ };
185
+
186
+ beforeEach(async () => {
187
+ balancerV3Pool = new BalancerV3EventPool(
188
+ dexKey,
189
+ network,
190
+ dexHelper,
191
+ logger,
192
+ );
193
+ });
183
194
 
184
- beforeEach(async () => {
185
- balancerV3Pool = new BalancerV3EventPool(
186
- dexKey,
187
- network,
188
- dexHelper,
189
- logger,
195
+ Object.entries(eventsToTest).forEach(
196
+ ([vaultAddress, events]: [string, EventMappings]) => {
197
+ describe(`Events for Vault: ${vaultAddress}`, () => {
198
+ Object.entries(events).forEach(
199
+ ([eventName, eventData]: [string, EventData]) => {
200
+ describe(`${eventName}`, () => {
201
+ eventData.blockNumbers.forEach((blockNumber: number, i) => {
202
+ it(`Pool: ${eventData.poolAddress[i]} State after ${blockNumber}`, async function () {
203
+ await testEventSubscriber(
204
+ balancerV3Pool,
205
+ balancerV3Pool.addressesSubscribed,
206
+ (_blockNumber: number) =>
207
+ fetchPoolState(
208
+ balancerV3Pool,
209
+ _blockNumber,
210
+ eventData.poolAddress[i],
211
+ ),
212
+ blockNumber,
213
+ `${dexKey}_${vaultAddress}`,
214
+ dexHelper.provider,
215
+ stateCompare,
216
+ );
217
+ });
218
+ });
219
+ });
220
+ },
221
+ );
222
+ });
223
+ },
190
224
  );
191
225
  });
192
226
 
193
- Object.entries(eventsToTest).forEach(
194
- ([vaultAddress, events]: [string, EventMappings]) => {
195
- describe(`Events for Vault: ${vaultAddress}`, () => {
196
- Object.entries(events).forEach(
197
- ([eventName, eventData]: [string, EventData]) => {
198
- describe(`${eventName}`, () => {
199
- eventData.blockNumbers.forEach((blockNumber: number, i) => {
200
- it(`Pool: ${eventData.poolAddress[i]} State after ${blockNumber}`, async function () {
201
- await testEventSubscriber(
202
- balancerV3Pool,
203
- balancerV3Pool.addressesSubscribed,
204
- (_blockNumber: number) =>
205
- fetchPoolState(
206
- balancerV3Pool,
207
- _blockNumber,
208
- eventData.poolAddress[i],
209
- ),
210
- blockNumber,
211
- `${dexKey}_${vaultAddress}`,
212
- dexHelper.provider,
213
- stateCompare,
214
- );
227
+ describe('Mainnet', function () {
228
+ const network = Network.MAINNET;
229
+ const dexHelper = new DummyDexHelper(network);
230
+ const logger = dexHelper.getLogger(dexKey);
231
+ let balancerV3Pool: BalancerV3EventPool;
232
+
233
+ // vault -> EventMappings
234
+ // TODO once we have a new test deployment add tests for: AggregateSwapFeePercentageChanged, SwapFeePercentageChanged, PoolPausedStateChanged
235
+ const eventsToTest: Record<Address, EventMappings> = {
236
+ [BalancerV3Config.BalancerV3[network].vaultAddress]: {
237
+ LiquidityAdded: {
238
+ blockNumbers: [21774068],
239
+ poolAddress: ['0x8523bcadcda4bd329435940dcc49a7c4c0a14d94'],
240
+ },
241
+ LiquidityRemoved: {
242
+ blockNumbers: [21788910],
243
+ poolAddress: ['0x8523bcadcda4bd329435940dcc49a7c4c0a14d94'],
244
+ },
245
+ Swap: {
246
+ blockNumbers: [21788638, 21791514, 21791514],
247
+ poolAddress: [
248
+ '0x8523bcadcda4bd329435940dcc49a7c4c0a14d94',
249
+ '0x8523bcadcda4bd329435940dcc49a7c4c0a14d94',
250
+ '0x8523bcadcda4bd329435940dcc49a7c4c0a14d94',
251
+ ],
252
+ },
253
+ },
254
+ };
255
+
256
+ beforeEach(async () => {
257
+ balancerV3Pool = new BalancerV3EventPool(
258
+ dexKey,
259
+ network,
260
+ dexHelper,
261
+ logger,
262
+ );
263
+ });
264
+
265
+ Object.entries(eventsToTest).forEach(
266
+ ([vaultAddress, events]: [string, EventMappings]) => {
267
+ describe(`Events for Vault: ${vaultAddress}`, () => {
268
+ Object.entries(events).forEach(
269
+ ([eventName, eventData]: [string, EventData]) => {
270
+ describe(`${eventName}`, () => {
271
+ eventData.blockNumbers.forEach((blockNumber: number, i) => {
272
+ it(`Pool: ${eventData.poolAddress[i]} State after ${blockNumber}`, async function () {
273
+ await testEventSubscriber(
274
+ balancerV3Pool,
275
+ balancerV3Pool.addressesSubscribed,
276
+ (_blockNumber: number) =>
277
+ fetchPoolState(
278
+ balancerV3Pool,
279
+ _blockNumber,
280
+ eventData.poolAddress[i],
281
+ ),
282
+ blockNumber,
283
+ `${dexKey}_${vaultAddress}`,
284
+ dexHelper.provider,
285
+ stateCompare,
286
+ );
287
+ });
215
288
  });
216
289
  });
217
- });
218
- },
219
- );
220
- });
221
- },
222
- );
290
+ },
291
+ );
292
+ });
293
+ },
294
+ );
295
+ });
223
296
  });
@@ -834,9 +834,9 @@ describe('BalancerV3', function () {
834
834
 
835
835
  describe('Buffer, Nested Rate', () => {
836
836
  /*
837
- The Gnosis pool, 0x272d6be442e30d7c87390edeb9b96f1e84cecd8d uses a rate provider that is nested.
838
- So unwrap rate does not equal rate between aave wsteth and eth.
839
- This particular case the rate provider accounts for growth of wsteth in terms of weth and the additional aave yield.
837
+ The Gnosis pool, 0x272d6be442e30d7c87390edeb9b96f1e84cecd8d uses a rate provider that is nested.
838
+ So unwrap rate does not equal rate between aave wsteth and eth.
839
+ This particular case the rate provider accounts for growth of wsteth in terms of weth and the additional aave yield.
840
840
  This highlighted that rateProvider can not be used for buffer wrap/unwrap which instead should use erc4626 rate.
841
841
  */
842
842
  const dexHelper = new DummyDexHelper(network);
@@ -898,10 +898,10 @@ describe('BalancerV3', function () {
898
898
  describe('Token/Underlying With Different Decimals', () => {
899
899
  /*
900
900
  Mainnet Pool, 0x5dd88b3aa3143173eb26552923922bdf33f50949 has an ERC4626 token with 18 decimals that uses a 6 decimal underlying.
901
- Note for maths: Instead of manually adding support for each ERC4626 implementation (e.g. stata with Ray maths) we always use an
901
+ Note for maths: Instead of manually adding support for each ERC4626 implementation (e.g. stata with Ray maths) we always use an
902
902
  18 decimal scaled rate and do 18 decimal maths to convert. We may end up loosing 100% accuracy but thats deemed acceptable.
903
903
  */
904
- describe.only('Buffer wrap 6decimal>18decimal', () => {
904
+ describe('Buffer wrap 6decimal>18decimal', () => {
905
905
  const dexHelper = new DummyDexHelper(network);
906
906
 
907
907
  const tokens = Tokens[network];
@@ -1060,6 +1060,102 @@ describe('BalancerV3', function () {
1060
1060
  });
1061
1061
  });
1062
1062
  });
1063
+
1064
+ describe('Base', () => {
1065
+ const network = Network.BASE;
1066
+
1067
+ describe('Stable Pool', () => {
1068
+ const dexHelper = new DummyDexHelper(network);
1069
+
1070
+ const tokens = Tokens[network];
1071
+ const srcTokenSymbol = 'wstETH';
1072
+ const destTokenSymbol = 'WETH';
1073
+
1074
+ const amountsForSell = [
1075
+ 0n,
1076
+ 1n * BI_POWS[tokens[srcTokenSymbol].decimals],
1077
+ 2n * BI_POWS[tokens[srcTokenSymbol].decimals],
1078
+ 3n * BI_POWS[tokens[srcTokenSymbol].decimals],
1079
+ 4n * BI_POWS[tokens[srcTokenSymbol].decimals],
1080
+ 5n * BI_POWS[tokens[srcTokenSymbol].decimals],
1081
+ 6n * BI_POWS[tokens[srcTokenSymbol].decimals],
1082
+ 7n * BI_POWS[tokens[srcTokenSymbol].decimals],
1083
+ 8n * BI_POWS[tokens[srcTokenSymbol].decimals],
1084
+ 9n * BI_POWS[tokens[srcTokenSymbol].decimals],
1085
+ 10n * BI_POWS[tokens[srcTokenSymbol].decimals],
1086
+ ];
1087
+
1088
+ const amountsForBuy = [
1089
+ 0n,
1090
+ 1n * BI_POWS[tokens[destTokenSymbol].decimals],
1091
+ 2n * BI_POWS[tokens[destTokenSymbol].decimals],
1092
+ 3n * BI_POWS[tokens[destTokenSymbol].decimals],
1093
+ 4n * BI_POWS[tokens[destTokenSymbol].decimals],
1094
+ 5n * BI_POWS[tokens[destTokenSymbol].decimals],
1095
+ 6n * BI_POWS[tokens[destTokenSymbol].decimals],
1096
+ 7n * BI_POWS[tokens[destTokenSymbol].decimals],
1097
+ 8n * BI_POWS[tokens[destTokenSymbol].decimals],
1098
+ 9n * BI_POWS[tokens[destTokenSymbol].decimals],
1099
+ 10n * BI_POWS[tokens[destTokenSymbol].decimals],
1100
+ ];
1101
+
1102
+ beforeAll(async () => {
1103
+ blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
1104
+ balancerV3 = new BalancerV3(network, dexKey, dexHelper);
1105
+ if (balancerV3.initializePricing) {
1106
+ await balancerV3.initializePricing(blockNumber);
1107
+ }
1108
+ });
1109
+
1110
+ it('getPoolIdentifiers and getPricesVolume SELL', async function () {
1111
+ await testPricingOnNetwork(
1112
+ balancerV3,
1113
+ network,
1114
+ dexKey,
1115
+ blockNumber,
1116
+ srcTokenSymbol,
1117
+ destTokenSymbol,
1118
+ SwapSide.SELL,
1119
+ amountsForSell,
1120
+ );
1121
+ });
1122
+
1123
+ it('getPoolIdentifiers and getPricesVolume BUY', async function () {
1124
+ await testPricingOnNetwork(
1125
+ balancerV3,
1126
+ network,
1127
+ dexKey,
1128
+ blockNumber,
1129
+ srcTokenSymbol,
1130
+ destTokenSymbol,
1131
+ SwapSide.BUY,
1132
+ amountsForBuy,
1133
+ );
1134
+ });
1135
+
1136
+ it('getTopPoolsForToken', async function () {
1137
+ // We have to check without calling initializePricing, because
1138
+ // pool-tracker is not calling that function
1139
+ const newBalancerV3 = new BalancerV3(network, dexKey, dexHelper);
1140
+ if (newBalancerV3.updatePoolState) {
1141
+ await newBalancerV3.updatePoolState();
1142
+ }
1143
+ const poolLiquidity = await newBalancerV3.getTopPoolsForToken(
1144
+ tokens[srcTokenSymbol].address,
1145
+ 10,
1146
+ );
1147
+ console.log(`${srcTokenSymbol} Top Pools:`, poolLiquidity);
1148
+
1149
+ if (!newBalancerV3.hasConstantPriceLargeAmounts) {
1150
+ checkPoolsLiquidity(
1151
+ poolLiquidity,
1152
+ Tokens[network][srcTokenSymbol].address,
1153
+ dexKey,
1154
+ );
1155
+ }
1156
+ });
1157
+ });
1158
+ });
1063
1159
  });
1064
1160
 
1065
1161
  // Add back once multicall queries are working
@@ -218,10 +218,12 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
218
218
  i < newState[poolAddress].balancesLiveScaled18.length;
219
219
  i++
220
220
  ) {
221
- newState[poolAddress].balancesLiveScaled18[i] += this.toScaled18(
222
- BigInt(event.args.amountsAddedRaw[i]),
223
- newState[poolAddress].scalingFactors[i],
224
- );
221
+ newState[poolAddress].balancesLiveScaled18[i] +=
222
+ this.toScaled18ApplyRateRoundDown(
223
+ BigInt(event.args.amountsAddedRaw[i]),
224
+ newState[poolAddress].scalingFactors[i],
225
+ newState[poolAddress].tokenRates[i] || WAD,
226
+ );
225
227
  }
226
228
  newState[poolAddress].totalSupply = BigInt(event.args.totalSupply);
227
229
 
@@ -244,10 +246,12 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
244
246
  i < newState[poolAddress].balancesLiveScaled18.length;
245
247
  i++
246
248
  ) {
247
- newState[poolAddress].balancesLiveScaled18[i] -= this.toScaled18(
248
- BigInt(event.args.amountsRemovedRaw[i]),
249
- newState[poolAddress].scalingFactors[i],
250
- );
249
+ newState[poolAddress].balancesLiveScaled18[i] -=
250
+ this.toScaled18ApplyRateRoundDown(
251
+ BigInt(event.args.amountsRemovedRaw[i]),
252
+ newState[poolAddress].scalingFactors[i],
253
+ newState[poolAddress].tokenRates[i] || WAD,
254
+ );
251
255
  }
252
256
  newState[poolAddress].totalSupply = BigInt(event.args.totalSupply);
253
257
 
@@ -275,14 +279,17 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
275
279
  this.logger.error(`swapEvent - token index not found in pool state`);
276
280
  return null;
277
281
  }
278
- newState[poolAddress].balancesLiveScaled18[tokenInIndex] += this.toScaled18(
279
- BigInt(event.args.amountIn),
280
- newState[poolAddress].scalingFactors[tokenInIndex],
281
- );
282
+ newState[poolAddress].balancesLiveScaled18[tokenInIndex] +=
283
+ this.toScaled18ApplyRateRoundDown(
284
+ BigInt(event.args.amountIn),
285
+ newState[poolAddress].scalingFactors[tokenInIndex],
286
+ newState[poolAddress].tokenRates[tokenInIndex] || WAD,
287
+ );
282
288
  newState[poolAddress].balancesLiveScaled18[tokenOutIndex] -=
283
- this.toScaled18(
289
+ this.toScaled18ApplyRateRoundDown(
284
290
  BigInt(event.args.amountOut),
285
291
  newState[poolAddress].scalingFactors[tokenOutIndex],
292
+ newState[poolAddress].tokenRates[tokenOutIndex] || WAD,
286
293
  );
287
294
 
288
295
  return newState;
@@ -697,6 +704,19 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
697
704
  }
698
705
 
699
706
  toScaled18(amount: bigint, scalingFactor: bigint): bigint {
707
+ // (amount * scalingFactor).mulUp(tokenRate);
700
708
  return (amount * scalingFactor * WAD) / WAD;
701
709
  }
710
+
711
+ toScaled18ApplyRateRoundDown(
712
+ amount: bigint,
713
+ scalingFactor: bigint,
714
+ tokenRate: bigint,
715
+ ): bigint {
716
+ return this.mulDown(amount * scalingFactor, tokenRate);
717
+ }
718
+
719
+ mulDown(a: bigint, b: bigint): bigint {
720
+ return (a * b) / WAD;
721
+ }
702
722
  }
@@ -30,7 +30,7 @@ import { Block } from '@ethersproject/abstract-provider';
30
30
 
31
31
  const MAX_UINT256 =
32
32
  '115792089237316195423570985008687907853269984665640564039457584007913129639935';
33
- const POOL_UPDATE_TTL = 5 * 60; // 5mins
33
+ const POOL_UPDATE_TTL = 1 * 60; // 1min
34
34
  const RATE_UPDATE_TTL = 1 * 60; // 1min
35
35
 
36
36
  type DeepMutable<T> = {
@@ -38,5 +38,17 @@ export const BalancerV3Config: DexConfigMap<DexParams> = {
38
38
  balancerRouterAddress: '0x5C6fb490BDFD3246EB0bB062c168DeCAF4bD9FDd',
39
39
  balancerBatchRouterAddress: '0x136f1EFcC3f8f88516B9E94110D56FDBfB1778d1',
40
40
  },
41
+ [Network.ARBITRUM]: {
42
+ vaultAddress: '0xbA1333333333a1BA1108E8412f11850A5C319bA9',
43
+ apiNetworkName: 'ARBITRUM',
44
+ balancerRouterAddress: '0x0f08eEf2C785AA5e7539684aF04755dEC1347b7c',
45
+ balancerBatchRouterAddress: '0xaD89051bEd8d96f045E8912aE1672c6C0bF8a85E',
46
+ },
47
+ [Network.BASE]: {
48
+ vaultAddress: '0xbA1333333333a1BA1108E8412f11850A5C319bA9',
49
+ apiNetworkName: 'BASE',
50
+ balancerRouterAddress: '0x76578ecf9a141296Ec657847fb45B0585bCDa3a6',
51
+ balancerBatchRouterAddress: '0x85a80afee867aDf27B50BdB7b76DA70f1E853062',
52
+ },
41
53
  },
42
54
  };
@@ -14,7 +14,7 @@ describe('Cables E2E', () => {
14
14
 
15
15
  const sideToContractMethods = new Map([
16
16
  [SwapSide.SELL, [ContractMethod.swapExactAmountIn]],
17
- [SwapSide.BUY, [ContractMethod.swapExactAmountOut]],
17
+ // [SwapSide.BUY, [ContractMethod.swapExactAmountOut]],
18
18
  ]);
19
19
 
20
20
  describe('Arbitrum', () => {
@@ -30,7 +30,7 @@ describe('Cables E2E', () => {
30
30
  [
31
31
  {
32
32
  name: 'USDC',
33
- sellAmount: '500000',
33
+ sellAmount: '50000000000000',
34
34
  buyAmount: '700000',
35
35
  },
36
36
  {
@@ -39,18 +39,18 @@ describe('Cables E2E', () => {
39
39
  buyAmount: '850000',
40
40
  },
41
41
  ],
42
- [
43
- {
44
- name: 'WETH',
45
- sellAmount: '100000000000000000',
46
- buyAmount: '200000000000000000',
47
- },
48
- {
49
- name: 'USDT',
50
- sellAmount: '6000000',
51
- buyAmount: '8000000',
52
- },
53
- ],
42
+ // [
43
+ // {
44
+ // name: 'WETH',
45
+ // sellAmount: '100000000000000000',
46
+ // buyAmount: '200000000000000000',
47
+ // },
48
+ // {
49
+ // name: 'USDT',
50
+ // sellAmount: '6000000',
51
+ // buyAmount: '8000000',
52
+ // },
53
+ // ],
54
54
  ];
55
55
 
56
56
  sideToContractMethods.forEach((contractMethods, side) =>
@@ -84,32 +84,32 @@ describe('Cables E2E', () => {
84
84
  sleepMs,
85
85
  );
86
86
  });
87
- it(`${pair[1].name} -> ${pair[0].name}`, async () => {
88
- await testE2E(
89
- side === SwapSide.SELL
90
- ? tokens[pair[1].name]
91
- : tokens[pair[0].name],
92
- side === SwapSide.SELL
93
- ? tokens[pair[0].name]
94
- : tokens[pair[1].name],
95
- side === SwapSide.SELL
96
- ? holders[pair[1].name]
97
- : holders[pair[0].name],
98
- side === SwapSide.SELL
99
- ? pair[1].sellAmount
100
- : pair[1].buyAmount,
101
- side,
102
- dexKey,
103
- contractMethod,
104
- network,
105
- provider,
106
- undefined,
107
- undefined,
108
- undefined,
109
- slippage,
110
- sleepMs,
111
- );
112
- });
87
+ // it(`${pair[1].name} -> ${pair[0].name}`, async () => {
88
+ // await testE2E(
89
+ // side === SwapSide.SELL
90
+ // ? tokens[pair[1].name]
91
+ // : tokens[pair[0].name],
92
+ // side === SwapSide.SELL
93
+ // ? tokens[pair[0].name]
94
+ // : tokens[pair[1].name],
95
+ // side === SwapSide.SELL
96
+ // ? holders[pair[1].name]
97
+ // : holders[pair[0].name],
98
+ // side === SwapSide.SELL
99
+ // ? pair[1].sellAmount
100
+ // : pair[1].buyAmount,
101
+ // side,
102
+ // dexKey,
103
+ // contractMethod,
104
+ // network,
105
+ // provider,
106
+ // undefined,
107
+ // undefined,
108
+ // undefined,
109
+ // slippage,
110
+ // sleepMs,
111
+ // );
112
+ // });
113
113
  });
114
114
  });
115
115
  });