@paraswap/dex-lib 4.0.22 → 4.0.24-bal-v3-nested-erc4626.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 (197) hide show
  1. package/.idea/aws.xml +17 -0
  2. package/.idea/codeStyles/Project.xml +19 -0
  3. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  4. package/.idea/misc.xml +6 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/paraswap-dex-lib.iml +9 -0
  7. package/.idea/prettier.xml +7 -0
  8. package/.idea/vcs.xml +6 -0
  9. package/build/abi/integral/factory.json +333 -0
  10. package/build/abi/integral/oracle.json +501 -0
  11. package/build/abi/{inception/inception-ineth-pool.json → integral/pool.json} +522 -543
  12. package/build/abi/{wombat/pool.json → integral/relayer.json} +720 -473
  13. package/build/dex/aave-v1/aave-v1.d.ts +1 -2
  14. package/build/dex/aave-v1/aave-v1.js +0 -23
  15. package/build/dex/aave-v1/aave-v1.js.map +1 -1
  16. package/build/dex/balancer-v2/config.js +1 -1
  17. package/build/dex/balancer-v2/config.js.map +1 -1
  18. package/build/dex/balancer-v3/balancer-v3-pool.d.ts +8 -2
  19. package/build/dex/balancer-v3/balancer-v3-pool.js +118 -72
  20. package/build/dex/balancer-v3/balancer-v3-pool.js.map +1 -1
  21. package/build/dex/balancer-v3/balancer-v3.js +12 -2
  22. package/build/dex/balancer-v3/balancer-v3.js.map +1 -1
  23. package/build/dex/balancer-v3/getGasCost.js +15 -11
  24. package/build/dex/balancer-v3/getGasCost.js.map +1 -1
  25. package/build/dex/balancer-v3/getOnChainState.js +10 -1
  26. package/build/dex/balancer-v3/getOnChainState.js.map +1 -1
  27. package/build/dex/balancer-v3/getPoolsApi.js +2 -0
  28. package/build/dex/balancer-v3/getPoolsApi.js.map +1 -1
  29. package/build/dex/balancer-v3/getTopPoolsApi.d.ts +1 -0
  30. package/build/dex/balancer-v3/getTopPoolsApi.js +1 -0
  31. package/build/dex/balancer-v3/getTopPoolsApi.js.map +1 -1
  32. package/build/dex/balancer-v3/types.d.ts +8 -4
  33. package/build/dex/balancer-v3/types.js +7 -0
  34. package/build/dex/balancer-v3/types.js.map +1 -1
  35. package/build/dex/fluid-dex/fluid-dex-generate-pool.d.ts +49 -0
  36. package/build/dex/fluid-dex/fluid-dex-generate-pool.js +104 -0
  37. package/build/dex/fluid-dex/fluid-dex-generate-pool.js.map +1 -0
  38. package/build/dex/generic-rfq/e2e-test-config.js +3 -3
  39. package/build/dex/generic-rfq/e2e-test-config.js.map +1 -1
  40. package/build/dex/integral/config.d.ts +4 -0
  41. package/build/dex/integral/config.js +20 -0
  42. package/build/dex/integral/config.js.map +1 -0
  43. package/build/dex/integral/context.d.ts +40 -0
  44. package/build/dex/integral/context.js +158 -0
  45. package/build/dex/integral/context.js.map +1 -0
  46. package/build/dex/integral/integral-factory.d.ts +24 -0
  47. package/build/dex/integral/integral-factory.js +95 -0
  48. package/build/dex/integral/integral-factory.js.map +1 -0
  49. package/build/dex/integral/integral-pool.d.ts +50 -0
  50. package/build/dex/integral/integral-pool.js +149 -0
  51. package/build/dex/integral/integral-pool.js.map +1 -0
  52. package/build/dex/integral/integral-pricing.d.ts +18 -0
  53. package/build/dex/integral/integral-pricing.js +114 -0
  54. package/build/dex/integral/integral-pricing.js.map +1 -0
  55. package/build/dex/integral/integral-relayer.d.ts +42 -0
  56. package/build/dex/integral/integral-relayer.js +192 -0
  57. package/build/dex/integral/integral-relayer.js.map +1 -0
  58. package/build/dex/integral/integral-token.d.ts +27 -0
  59. package/build/dex/integral/integral-token.js +59 -0
  60. package/build/dex/integral/integral-token.js.map +1 -0
  61. package/build/dex/integral/integral.d.ts +41 -0
  62. package/build/dex/integral/integral.js +376 -0
  63. package/build/dex/integral/integral.js.map +1 -0
  64. package/build/dex/integral/types.d.ts +85 -0
  65. package/build/dex/integral/types.js +9 -0
  66. package/build/dex/integral/types.js.map +1 -0
  67. package/build/dex/integral/utils-e2e.d.ts +9 -0
  68. package/build/dex/integral/utils-e2e.js +131 -0
  69. package/build/dex/integral/utils-e2e.js.map +1 -0
  70. package/build/dex/integral/utils.d.ts +17 -0
  71. package/build/dex/integral/utils.js +94 -0
  72. package/build/dex/integral/utils.js.map +1 -0
  73. package/build/dex/jarvis.d.ts +1 -2
  74. package/build/dex/jarvis.js +0 -58
  75. package/build/dex/jarvis.js.map +1 -1
  76. package/build/dex/maverick-v1/config.js +1 -1
  77. package/build/dex/maverick-v1/config.js.map +1 -1
  78. package/build/dex/platypus/platypus.d.ts +1 -2
  79. package/build/dex/platypus/platypus.js +0 -45
  80. package/build/dex/platypus/platypus.js.map +1 -1
  81. package/build/dex/stable-pool.js +8 -1
  82. package/build/dex/stable-pool.js.map +1 -1
  83. package/build/dex/swaap-v1/swaap-v1.d.ts +1 -2
  84. package/build/dex/swaap-v1/swaap-v1.js +0 -14
  85. package/build/dex/swaap-v1/swaap-v1.js.map +1 -1
  86. package/build/dex/trader-joe-v2.1/optimizer.d.ts +2 -0
  87. package/build/dex/trader-joe-v2.1/optimizer.js +47 -0
  88. package/build/dex/trader-joe-v2.1/optimizer.js.map +1 -0
  89. package/build/dex/uniswap-v3/config.js +1 -1
  90. package/build/dex/uniswap-v3/config.js.map +1 -1
  91. package/build/dex/zerox/index.d.ts +26 -4
  92. package/build/dex/zerox/index.js +42 -50
  93. package/build/dex/zerox/index.js.map +1 -1
  94. package/build/dex/zerox/types.d.ts +0 -29
  95. package/build/dex/zerox/types.js +1 -8
  96. package/build/dex/zerox/types.js.map +1 -1
  97. package/package.json +1 -1
  98. package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +165 -102
  99. package/src/dex/balancer-v2/balancer-v2-integration.test.ts +238 -80
  100. package/src/dex/balancer-v2/config.ts +1 -2
  101. package/src/dex/balancer-v3/balancer-v3-integration.test.ts +135 -2
  102. package/src/dex/balancer-v3/balancer-v3-pool.ts +161 -80
  103. package/src/dex/balancer-v3/balancer-v3.ts +13 -2
  104. package/src/dex/balancer-v3/getGasCost.ts +14 -9
  105. package/src/dex/balancer-v3/getOnChainState.ts +16 -3
  106. package/src/dex/balancer-v3/getPoolsApi.ts +5 -0
  107. package/src/dex/balancer-v3/getTopPoolsApi.ts +2 -0
  108. package/src/dex/balancer-v3/types.ts +9 -4
  109. package/src/dex/generic-rfq/e2e-test-config.ts +3 -3
  110. package/src/dex/generic-rfq/generic-rfq-e2e.test.ts +2 -2
  111. package/src/dex/maverick-v1/config.ts +1 -2
  112. package/src/dex/uniswap-v3/config.ts +1 -2
  113. package/tests/constants-e2e.ts +16 -1
  114. package/tests/smart-tokens.ts +1 -3
  115. package/tests/tenderly-simulation.ts +149 -84
  116. package/tests/utils-e2e.ts +5 -2
  117. package/.vscode/launch.json +0 -53
  118. package/.vscode/settings.json +0 -2
  119. package/.vscode/tasks.json +0 -15
  120. package/build/abi/inception/inception-ratio-feed.json +0 -329
  121. package/build/abi/inception/inception-vault.json +0 -991
  122. package/build/abi/uniswap-v3/AlienBaseV3Router.abi.json +0 -52
  123. package/build/abi/usual-m-smart-m/usualM.abi.json +0 -483
  124. package/build/dex/aave-v2/tokens-avalanche.json +0 -44
  125. package/build/dex/aave-v2/tokens-mainnet.json +0 -188
  126. package/build/dex/aave-v2/tokens-polygon.json +0 -44
  127. package/build/dex/balancer-v3/abi/balancerBatchRouter.d.ts +0 -729
  128. package/build/dex/balancer-v3/abi/balancerBatchRouter.js +0 -732
  129. package/build/dex/balancer-v3/abi/balancerBatchRouter.js.map +0 -1
  130. package/build/dex/balancer-v3/abi/balancerRouter.d.ts +0 -1406
  131. package/build/dex/balancer-v3/abi/balancerRouter.js +0 -1175
  132. package/build/dex/balancer-v3/abi/balancerRouter.js.map +0 -1
  133. package/build/dex/balancer-v3/abi/vaultExtension.V3.d.ts +0 -2081
  134. package/build/dex/balancer-v3/abi/vaultExtension.V3.js +0 -1851
  135. package/build/dex/balancer-v3/abi/vaultExtension.V3.js.map +0 -1
  136. package/build/dex/balancer-v3/balancer-v3-sepolia-pools.d.ts +0 -34
  137. package/build/dex/balancer-v3/balancer-v3-sepolia-pools.js +0 -406
  138. package/build/dex/balancer-v3/balancer-v3-sepolia-pools.js.map +0 -1
  139. package/build/dex/inception/config.d.ts +0 -4
  140. package/build/dex/inception/config.js +0 -109
  141. package/build/dex/inception/config.js.map +0 -1
  142. package/build/dex/inception/inception-event-pool.d.ts +0 -16
  143. package/build/dex/inception/inception-event-pool.js +0 -49
  144. package/build/dex/inception/inception-event-pool.js.map +0 -1
  145. package/build/dex/inception/inception.d.ts +0 -43
  146. package/build/dex/inception/inception.js +0 -180
  147. package/build/dex/inception/inception.js.map +0 -1
  148. package/build/dex/inception/tokens.d.ts +0 -9
  149. package/build/dex/inception/tokens.js +0 -28
  150. package/build/dex/inception/tokens.js.map +0 -1
  151. package/build/dex/inception/types.d.ts +0 -22
  152. package/build/dex/inception/types.js +0 -3
  153. package/build/dex/inception/types.js.map +0 -1
  154. package/build/dex/inception/utils.d.ts +0 -7
  155. package/build/dex/inception/utils.js +0 -58
  156. package/build/dex/inception/utils.js.map +0 -1
  157. package/build/dex/maker-psm/scripts/gem.abi.json +0 -136
  158. package/build/dex/maker-psm/scripts/validate-state.d.ts +0 -0
  159. package/build/dex/maker-psm/scripts/validate-state.js +0 -185
  160. package/build/dex/maker-psm/scripts/validate-state.js.map +0 -1
  161. package/build/dex/maker-psm/scripts/vat.abi.json +0 -243
  162. package/build/dex/solidly-v3/scripts/check-event-pool-event.d.ts +0 -1
  163. package/build/dex/solidly-v3/scripts/check-event-pool-event.js +0 -53
  164. package/build/dex/solidly-v3/scripts/check-event-pool-event.js.map +0 -1
  165. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.d.ts +0 -17
  166. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js +0 -64
  167. package/build/dex/uniswap-v3/forks/alien-base-v3/alien-base-v3.js.map +0 -1
  168. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.d.ts +0 -17
  169. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js +0 -79
  170. package/build/dex/uniswap-v3/forks/alien-v3/alien-v3.js.map +0 -1
  171. package/build/dex/uniswap-v3/uniswap-v3-pricing.d.ts +0 -4
  172. package/build/dex/uniswap-v3/uniswap-v3-pricing.js +0 -43
  173. package/build/dex/uniswap-v3/uniswap-v3-pricing.js.map +0 -1
  174. package/build/dex/uniswap-v3/uniswap-v3-worker.d.ts +0 -1
  175. package/build/dex/uniswap-v3/uniswap-v3-worker.js +0 -10
  176. package/build/dex/uniswap-v3/uniswap-v3-worker.js.map +0 -1
  177. package/build/dex/usual/usual-m-smart-m.d.ts +0 -17
  178. package/build/dex/usual/usual-m-smart-m.js +0 -50
  179. package/build/dex/usual/usual-m-smart-m.js.map +0 -1
  180. package/build/dex/usual-m-smart-m/config.d.ts +0 -3
  181. package/build/dex/usual-m-smart-m/config.js +0 -13
  182. package/build/dex/usual-m-smart-m/config.js.map +0 -1
  183. package/build/dex/usual-m-smart-m/types.d.ts +0 -7
  184. package/build/dex/usual-m-smart-m/types.js +0 -3
  185. package/build/dex/usual-m-smart-m/types.js.map +0 -1
  186. package/build/dex/usual-m-smart-m/usual-m-smart-m.d.ts +0 -35
  187. package/build/dex/usual-m-smart-m/usual-m-smart-m.js +0 -161
  188. package/build/dex/usual-m-smart-m/usual-m-smart-m.js.map +0 -1
  189. package/build/dex/usual-m-usd0/config.d.ts +0 -3
  190. package/build/dex/usual-m-usd0/config.js +0 -14
  191. package/build/dex/usual-m-usd0/config.js.map +0 -1
  192. package/build/dex/usual-m-usd0/types.d.ts +0 -8
  193. package/build/dex/usual-m-usd0/types.js +0 -3
  194. package/build/dex/usual-m-usd0/types.js.map +0 -1
  195. package/build/dex/usual-m-usd0/usual-m-usd0.d.ts +0 -35
  196. package/build/dex/usual-m-usd0/usual-m-usd0.js +0 -159
  197. package/build/dex/usual-m-usd0/usual-m-usd0.js.map +0 -1
@@ -11,6 +11,7 @@ import {
11
11
  StableMutableState,
12
12
  Step,
13
13
  TokenInfo,
14
+ TokenType,
14
15
  } from './types';
15
16
  import { getPoolsApi } from './getPoolsApi';
16
17
  import vaultExtensionAbi_V3 from '../../abi/balancer-v3/vault-extension.json';
@@ -543,11 +544,8 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
543
544
  );
544
545
  if (tokenIndex !== -1) {
545
546
  return {
546
- isBoosted: false,
547
- mainToken: tokenAddress,
548
- underlyingToken: null,
549
547
  index: tokenIndex,
550
- rate: poolState.tokenRates[tokenIndex],
548
+ type: TokenType.MainToken,
551
549
  };
552
550
  }
553
551
 
@@ -558,18 +556,23 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
558
556
  address && address.toLowerCase() === tokenAddress.toLowerCase(),
559
557
  );
560
558
  if (tokenIndex !== -1) {
561
- if (poolState.erc4626Rates[tokenIndex] === null) {
562
- this.logger.error(
563
- `missing erc4626 token rate ${poolState.tokens[tokenIndex]}`,
564
- );
565
- return null;
566
- }
567
559
  return {
568
- isBoosted: true,
569
- mainToken: poolState.tokens[tokenIndex],
570
- underlyingToken: tokenAddress,
571
560
  index: tokenIndex,
572
- rate: poolState.erc4626Rates[tokenIndex]!,
561
+ type: TokenType.ERC4626,
562
+ };
563
+ }
564
+ }
565
+
566
+ // Check in nested underlying tokens if available
567
+ if (poolState.tokensNestedERC4626Underlying) {
568
+ tokenIndex = poolState.tokensNestedERC4626Underlying.findIndex(
569
+ address =>
570
+ address && address.toLowerCase() === tokenAddress.toLowerCase(),
571
+ );
572
+ if (tokenIndex !== -1) {
573
+ return {
574
+ index: tokenIndex,
575
+ type: TokenType.ERC4626Nested,
573
576
  };
574
577
  }
575
578
  }
@@ -593,104 +596,182 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
593
596
  * https://docs-v3.balancer.fi/concepts/vault/buffer.html
594
597
  */
595
598
  getSteps(pool: PoolState, tokenIn: TokenInfo, tokenOut: TokenInfo): Step[] {
596
- if (tokenIn.isBoosted && tokenOut.isBoosted) {
597
- return [
598
- // Wrap tokenIn underlying to main token
599
- this.getWrapStep(tokenIn),
600
- // Swap main > main
601
- this.getSwapStep(pool, tokenIn, tokenOut),
602
- // Unwrap tokenOut main to underlying token
603
- this.getUnwrapStep(tokenOut),
604
- ];
605
- } else if (tokenIn.isBoosted) {
606
- if (
607
- tokenIn.mainToken.toLowerCase() === tokenOut.mainToken.toLowerCase()
608
- ) {
609
- // wrap, token > erc4626
610
- // tokenIn is boosted, e.g. isn't pool token and must be wrapped
611
- return [this.getWrapStep(tokenIn)];
599
+ // This is a single buffer wrap/unwrap
600
+ if (tokenIn.index === tokenOut.index) {
601
+ return this.singleBufferStep(pool, tokenIn, tokenOut);
602
+ }
603
+
604
+ // Create steps based on token types
605
+ const steps: Step[] = [];
606
+
607
+ // Handle input token wrapping if needed
608
+ if (this.needsBuffer(tokenIn)) {
609
+ if (tokenIn.type === TokenType.ERC4626Nested) {
610
+ steps.push(this.getWrapStepNested(pool, tokenIn));
612
611
  }
613
- return [
614
- // Wrap tokenIn underlying to main token
615
- this.getWrapStep(tokenIn),
616
- // Swap main > main
617
- this.getSwapStep(pool, tokenIn, tokenOut),
618
- ];
619
- } else if (tokenOut.isBoosted) {
620
- if (
621
- tokenIn.mainToken.toLowerCase() === tokenOut.mainToken.toLowerCase()
622
- ) {
623
- // unwrap, stata > token
624
- // token out is boosted, e.g. isn't pool token
625
- return [this.getUnwrapStep(tokenOut)];
612
+ steps.push(this.getWrapStep(pool, tokenIn));
613
+ }
614
+
615
+ // Add main swap step
616
+ steps.push(this.getSwapStep(pool, tokenIn, tokenOut));
617
+
618
+ // Handle output token unwrapping if needed
619
+ if (this.needsBuffer(tokenOut)) {
620
+ steps.push(this.getUnwrapStep(pool, tokenOut));
621
+ if (tokenOut.type === TokenType.ERC4626Nested) {
622
+ steps.push(this.getUnwrapStepNested(pool, tokenOut));
626
623
  }
627
- return [
628
- // Swap main > main
629
- this.getSwapStep(pool, tokenIn, tokenOut),
630
- // Unwrap tokenOut main to underlying token
631
- this.getUnwrapStep(tokenOut),
632
- ];
633
- } else {
634
- return [
635
- // Swap main > main
636
- this.getSwapStep(pool, tokenIn, tokenOut),
637
- ];
638
624
  }
625
+
626
+ return steps;
627
+ }
628
+
629
+ private singleBufferStep(
630
+ pool: PoolState,
631
+ tokenIn: TokenInfo,
632
+ tokenOut: TokenInfo,
633
+ ): Step[] {
634
+ if (tokenIn.type === TokenType.ERC4626) {
635
+ // wrap, token > erc4626
636
+ // tokenIn is boosted, e.g. isn't pool token and must be wrapped
637
+ return [this.getWrapStep(pool, tokenIn)];
638
+ }
639
+ if (tokenOut.type === TokenType.ERC4626) {
640
+ // unwrap, erc4626 > token
641
+ // tokenOut is boosted, e.g. isn't pool token and must be unwrapped
642
+ return [this.getUnwrapStep(pool, tokenOut)];
643
+ }
644
+ throw new Error(`Error get step with same token index`);
645
+ }
646
+
647
+ private needsBuffer(token: TokenInfo): boolean {
648
+ return (
649
+ token.type === TokenType.ERC4626 || token.type === TokenType.ERC4626Nested
650
+ );
639
651
  }
640
652
 
641
- getWrapStep(token: TokenInfo): Step {
642
- if (!token.underlyingToken)
653
+ private validateUnderlyingToken(pool: PoolState, tokenIndex: number): void {
654
+ if (!pool.tokensUnderlying[tokenIndex] || !pool.erc4626Rates[tokenIndex]) {
643
655
  throw new Error(
644
- `Buffer wrap: token has no underlying. ${token.mainToken}`,
656
+ `Underlying Token Error: token at index ${tokenIndex}. ${pool.tokensUnderlying[tokenIndex]} ${pool.erc4626Rates[tokenIndex]}`,
645
657
  );
646
- // Vault expects pool to be the ERC4626 wrapped token, e.g. aUSDC
658
+ }
659
+ }
660
+
661
+ private validateNestedUnderlyingToken(
662
+ pool: PoolState,
663
+ tokenIndex: number,
664
+ ): void {
665
+ if (
666
+ !pool.tokensUnderlying[tokenIndex] ||
667
+ !pool.tokensNestedERC4626Underlying[tokenIndex] ||
668
+ !pool.erc4626NestedRates[tokenIndex]
669
+ ) {
670
+ throw new Error(
671
+ `NestedUnderlying Token Error: token at index ${tokenIndex}. ${pool.tokensUnderlying[tokenIndex]} ${pool.tokensNestedERC4626Underlying[tokenIndex]} ${pool.erc4626NestedRates[tokenIndex]}`,
672
+ );
673
+ }
674
+ }
675
+
676
+ getWrapStepNested(pool: PoolState, token: TokenInfo): Step {
677
+ this.validateNestedUnderlyingToken(pool, token.index);
678
+
679
+ const underlyingToken = pool.tokensUnderlying[token.index] as string;
680
+ const nestedUnderlyingToken = pool.tokensNestedERC4626Underlying[
681
+ token.index
682
+ ] as string;
683
+
647
684
  return {
648
- pool: token.mainToken,
685
+ pool: underlyingToken,
649
686
  isBuffer: true,
650
687
  swapInput: {
651
- tokenIn: token.underlyingToken,
652
- tokenOut: token.mainToken,
688
+ tokenIn: nestedUnderlyingToken,
689
+ tokenOut: underlyingToken,
653
690
  },
654
691
  poolState: {
655
692
  poolType: 'Buffer',
656
- rate: token.rate,
657
- poolAddress: token.mainToken,
658
- tokens: [token.mainToken, token.underlyingToken], // staticToken & underlying
693
+ rate: pool.erc4626NestedRates[token.index] as bigint,
694
+ poolAddress: underlyingToken,
695
+ tokens: [nestedUnderlyingToken, underlyingToken],
659
696
  },
660
697
  };
661
698
  }
662
699
 
663
- getUnwrapStep(token: TokenInfo): Step {
664
- if (!token.underlyingToken)
665
- throw new Error(
666
- `Buffer unwrap: token has no underlying. ${token.mainToken}`,
667
- );
668
- // Vault expects pool to be the ERC4626 wrapped token, e.g. aUSDC
700
+ getWrapStep(pool: PoolState, token: TokenInfo): Step {
701
+ this.validateUnderlyingToken(pool, token.index);
702
+
703
+ const wrappedToken = pool.tokens[token.index];
704
+ const underlyingToken = pool.tokensUnderlying[token.index] as string;
705
+
706
+ return {
707
+ pool: wrappedToken,
708
+ isBuffer: true,
709
+ swapInput: {
710
+ tokenIn: underlyingToken,
711
+ tokenOut: wrappedToken,
712
+ },
713
+ poolState: {
714
+ poolType: 'Buffer',
715
+ rate: pool.erc4626Rates[token.index] as bigint,
716
+ poolAddress: wrappedToken,
717
+ tokens: [wrappedToken, underlyingToken],
718
+ },
719
+ };
720
+ }
721
+
722
+ getUnwrapStepNested(pool: PoolState, token: TokenInfo): Step {
723
+ this.validateNestedUnderlyingToken(pool, token.index);
724
+
725
+ const underlyingToken = pool.tokensUnderlying[token.index] as string;
726
+ const nestedUnderlyingToken = pool.tokensNestedERC4626Underlying[
727
+ token.index
728
+ ] as string;
729
+
730
+ return {
731
+ pool: underlyingToken,
732
+ isBuffer: true,
733
+ swapInput: {
734
+ tokenIn: underlyingToken,
735
+ tokenOut: nestedUnderlyingToken,
736
+ },
737
+ poolState: {
738
+ poolType: 'Buffer',
739
+ rate: pool.erc4626NestedRates[token.index] as bigint,
740
+ poolAddress: underlyingToken,
741
+ tokens: [nestedUnderlyingToken, underlyingToken],
742
+ },
743
+ };
744
+ }
745
+
746
+ getUnwrapStep(pool: PoolState, token: TokenInfo): Step {
747
+ this.validateUnderlyingToken(pool, token.index);
748
+
749
+ const wrappedToken = pool.tokens[token.index];
750
+ const underlyingToken = pool.tokensUnderlying[token.index] as string;
751
+
669
752
  return {
670
- pool: token.mainToken,
753
+ pool: wrappedToken,
671
754
  isBuffer: true,
672
755
  swapInput: {
673
- tokenIn: token.mainToken,
674
- tokenOut: token.underlyingToken,
756
+ tokenIn: wrappedToken,
757
+ tokenOut: underlyingToken,
675
758
  },
676
759
  poolState: {
677
760
  poolType: 'Buffer',
678
- // TODO: for ERC4626 fetch the wrap/unwrap rate
679
- rate: token.rate,
680
- poolAddress: token.mainToken,
681
- tokens: [token.mainToken, token.underlyingToken], // staticToken & underlying
761
+ rate: pool.erc4626Rates[token.index] as bigint,
762
+ poolAddress: wrappedToken,
763
+ tokens: [wrappedToken, underlyingToken],
682
764
  },
683
765
  };
684
766
  }
685
767
 
686
768
  getSwapStep(pool: PoolState, tokenIn: TokenInfo, tokenOut: TokenInfo): Step {
687
- // A normal swap between two tokens in a pool
688
769
  return {
689
770
  pool: pool.poolAddress,
690
771
  isBuffer: false,
691
772
  swapInput: {
692
- tokenIn: tokenIn.mainToken,
693
- tokenOut: tokenOut.mainToken,
773
+ tokenIn: pool.tokens[tokenIn.index],
774
+ tokenOut: pool.tokens[tokenOut.index],
694
775
  },
695
776
  poolState: pool,
696
777
  };
@@ -177,7 +177,9 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
177
177
  hasTokens(pool: DeepReadonly<PoolState>, tokens: string[]): boolean {
178
178
  return tokens.every(
179
179
  token =>
180
- pool.tokens.includes(token) || pool.tokensUnderlying.includes(token),
180
+ pool.tokens.includes(token) ||
181
+ pool.tokensUnderlying.includes(token) ||
182
+ pool.tokensNestedERC4626Underlying.includes(token),
181
183
  );
182
184
  }
183
185
 
@@ -586,11 +588,20 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
586
588
  .filter(t => !!t)
587
589
  .filter(t => t?.address !== tokenAddress) as Token[];
588
590
 
591
+ const nestedUnderlyingTokens = pool.poolTokens
592
+ .map(t => ({
593
+ address: t.underlyingToken?.underlyingTokenAddress,
594
+ decimals: t.underlyingToken?.decimals,
595
+ }))
596
+ .filter(item => !!item.address) as Token[];
597
+
589
598
  return {
590
599
  exchange: this.dexKey,
591
600
  address: pool.address,
592
601
  liquidityUSD: parseFloat(pool.dynamicData.totalLiquidity),
593
- connectorTokens: tokens.concat(underlyingTokens),
602
+ connectorTokens: tokens
603
+ .concat(underlyingTokens)
604
+ .concat(nestedUnderlyingTokens),
594
605
  };
595
606
  });
596
607
  }
@@ -14,15 +14,7 @@ const PARTIAL_BOOSTED_SWAP_GAS_COST = 259815;
14
14
  const BUFFER_WRAP_UNWRAP_GAS_COST = 155921;
15
15
 
16
16
  export function getGasCost(steps: Step[]): number {
17
- if (steps.length === 2) {
18
- // Partial boosted/buffer swap:
19
- // token[wrap]wrappedToken[swap]wrappedToken or
20
- // wrappedToken[swap]wrappedToken[unwrap]token
21
- return PARTIAL_BOOSTED_SWAP_GAS_COST;
22
- } else if (steps.length === 3) {
23
- // Full boosted/buffer swap: token[wrap]wrappedToken[swap]wrappedToken[unwrap]token
24
- return FULL_BOOSTED_SWAP_GAS_COST;
25
- } else {
17
+ if (steps.length === 1) {
26
18
  switch (steps[0].poolState.poolType) {
27
19
  case 'WEIGHTED':
28
20
  return WEIGHTED_GAS_COST;
@@ -33,5 +25,18 @@ export function getGasCost(steps: Step[]): number {
33
25
  default:
34
26
  return WEIGHTED_GAS_COST;
35
27
  }
28
+ } else if (steps.length === 2) {
29
+ // Partial boosted/buffer swap:
30
+ // token[wrap]wrappedToken[swap]wrappedToken or
31
+ // wrappedToken[swap]wrappedToken[unwrap]token
32
+ return PARTIAL_BOOSTED_SWAP_GAS_COST;
33
+ } else if (steps.length === 3) {
34
+ // Full boosted/buffer swap: token[wrap]wrappedToken[swap]wrappedToken[unwrap]token
35
+ return FULL_BOOSTED_SWAP_GAS_COST;
36
+ } else {
37
+ return (
38
+ FULL_BOOSTED_SWAP_GAS_COST +
39
+ (steps.length - 3) * BUFFER_WRAP_UNWRAP_GAS_COST
40
+ );
36
41
  }
37
42
  }
@@ -86,7 +86,7 @@ const poolOnChain: Record<
86
86
  poolAddress: string,
87
87
  data: any,
88
88
  startIndex: number,
89
- ): Omit<CommonMutableState, 'erc4626Rates'> => {
89
+ ): Omit<CommonMutableState, 'erc4626Rates' | 'erc4626NestedRates'> => {
90
90
  const resultTokenRates = decodeThrowError(
91
91
  contractInterface,
92
92
  'getPoolTokenRates',
@@ -267,8 +267,17 @@ export function getErc4626MultiCallData(
267
267
  // We want to query rate for each unique ERC4626 token
268
268
  const uniqueErc4626Tokens = Array.from(
269
269
  new Set(
270
- Object.values(immutablePoolStateMap).flatMap(pool =>
271
- pool.tokens.filter((_, index) => pool.tokensUnderlying[index] !== null),
270
+ Object.values(immutablePoolStateMap).flatMap(
271
+ pool =>
272
+ [
273
+ // Get tokens with corresponding non-null tokensUnderlying
274
+ ...pool.tokens.filter(
275
+ (_, index) => pool.tokensUnderlying[index] !== null,
276
+ ),
277
+ ...pool.tokensUnderlying.filter(
278
+ (_, index) => pool.tokensNestedERC4626Underlying[index] !== null,
279
+ ),
280
+ ] as string[],
272
281
  ),
273
282
  ),
274
283
  );
@@ -392,6 +401,10 @@ export async function getOnChainState(
392
401
  if (!tokensWithRates[t]) return null;
393
402
  return tokensWithRates[t];
394
403
  }),
404
+ erc4626NestedRates: pool.tokensUnderlying.map(t => {
405
+ if (!t || !tokensWithRates[t]) return null;
406
+ return tokensWithRates[t];
407
+ }),
395
408
  },
396
409
  ];
397
410
  }),
@@ -14,6 +14,7 @@ interface PoolToken {
14
14
  isErc4626: boolean;
15
15
  underlyingToken: {
16
16
  address: string;
17
+ underlyingTokenAddress: string | null;
17
18
  } | null;
18
19
  }
19
20
 
@@ -67,6 +68,7 @@ function createQuery(
67
68
  isErc4626
68
69
  underlyingToken {
69
70
  address
71
+ underlyingTokenAddress
70
72
  }
71
73
  }
72
74
  }
@@ -82,6 +84,9 @@ function toImmutablePoolStateMap(pools: Pool[]): ImmutablePoolStateMap {
82
84
  tokensUnderlying: pool.poolTokens.map(t =>
83
85
  t.underlyingToken ? t.underlyingToken.address : null,
84
86
  ),
87
+ tokensNestedERC4626Underlying: pool.poolTokens.map(t =>
88
+ t.underlyingToken ? t.underlyingToken.underlyingTokenAddress : null,
89
+ ),
85
90
  weights: pool.poolTokens.map(t =>
86
91
  t.weight ? parseUnits(t.weight, 18).toBigInt() : 0n,
87
92
  ),
@@ -7,6 +7,7 @@ interface PoolToken {
7
7
  underlyingToken?: {
8
8
  address: string;
9
9
  decimals: number;
10
+ underlyingTokenAddress: string;
10
11
  };
11
12
  }
12
13
 
@@ -63,6 +64,7 @@ function createQuery(
63
64
  underlyingToken {
64
65
  address
65
66
  decimals
67
+ underlyingTokenAddress
66
68
  }
67
69
  }
68
70
  dynamicData {
@@ -9,6 +9,7 @@ export type CommonImmutablePoolState = {
9
9
  tokens: string[];
10
10
  // For boosted pools underlying is the unwrapped token, e.g. USDC/DAI
11
11
  tokensUnderlying: (string | null)[];
12
+ tokensNestedERC4626Underlying: (string | null)[];
12
13
  weights: bigint[];
13
14
  // TODO re-introduce this once added to API
14
15
  // scalingFactors: bigint[];
@@ -19,6 +20,7 @@ export type CommonImmutablePoolState = {
19
20
  export interface CommonMutableState {
20
21
  tokenRates: bigint[];
21
22
  erc4626Rates: (bigint | null)[];
23
+ erc4626NestedRates: (bigint | null)[];
22
24
  balancesLiveScaled18: bigint[];
23
25
  swapFee: bigint;
24
26
  aggregateSwapFee: bigint;
@@ -78,10 +80,13 @@ export type DexParams = {
78
80
  balancerBatchRouterAddress: string;
79
81
  };
80
82
 
83
+ export enum TokenType {
84
+ MainToken = 1,
85
+ ERC4626,
86
+ ERC4626Nested,
87
+ }
88
+
81
89
  export type TokenInfo = {
82
- isBoosted: boolean;
83
- underlyingToken: string | null;
84
- mainToken: string;
85
90
  index: number;
86
- rate: bigint;
91
+ type: TokenType;
87
92
  };
@@ -8,16 +8,16 @@ export const testConfig: {
8
8
  amount: string;
9
9
  }>;
10
10
  } = {
11
- [Network.ARBITRUM]: [
11
+ [Network.MAINNET]: [
12
12
  {
13
- srcToken: 'WETH',
13
+ srcToken: 'USDT',
14
14
  destToken: 'USDC',
15
15
  amount: '10000',
16
16
  swapSide: SwapSide.BUY,
17
17
  },
18
18
  {
19
19
  srcToken: 'USDC',
20
- destToken: 'WETH',
20
+ destToken: 'USDT',
21
21
  amount: '10000',
22
22
  swapSide: SwapSide.SELL,
23
23
  },
@@ -115,8 +115,8 @@ describe(`GenericRFQ ${dexKey} E2E`, () => {
115
115
  `Please add "addBalance" and "addAllowance" functions for ${testCase.destToken} on ${Network[network]} (in constants-e2e.ts).`,
116
116
  );
117
117
  }
118
- srcToken = smartTokens[testCase.srcToken];
119
- destToken = smartTokens[testCase.destToken];
118
+ srcToken = new SmartToken(tokens[testCase.srcToken]);
119
+ destToken = new SmartToken(tokens[testCase.destToken]);
120
120
 
121
121
  srcToken.addBalance(testAccount.address, MAX_UINT);
122
122
  srcToken.addAllowance(
@@ -14,8 +14,7 @@ export const MaverickV1Config: DexConfigMap<DexParams> = {
14
14
  poolInspectorAddress: '0xaA5BF61a664109e959D69C38734d4EA7dF74e456',
15
15
  },
16
16
  [Network.BASE]: {
17
- subgraphURL:
18
- 'https://api.studio.thegraph.com/query/42519/maverick-base/version/latest',
17
+ subgraphURL: 'CSxkHjxpG1TxTBQMn55uG1DWpdD4Lsix4RNX4RTLvK4T',
19
18
  routerAddress: '0x32AED3Bce901DA12ca8489788F3A99fCe1056e14',
20
19
  poolInspectorAddress: '0x65A3AD03Be97619284bA7AA1E3Ca05638B9d6364',
21
20
  },
@@ -117,8 +117,7 @@ export const UniswapV3Config: DexConfigMap<DexParams> = {
117
117
  chunksCount: 10,
118
118
  initRetryFrequency: 10,
119
119
  initHash: `0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54`,
120
- subgraphURL:
121
- 'https://api.studio.thegraph.com/query/48211/uniswap-v3-base/version/latest',
120
+ subgraphURL: 'GqzP4Xaehti8KSfQmv3ZctFSjnSUYZ4En5NRsiTbvZpz',
122
121
  },
123
122
  },
124
123
  SushiSwapV3: {
@@ -128,7 +128,7 @@ export const Tokens: {
128
128
  address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
129
129
  decimals: 6,
130
130
  symbol: 'USDC',
131
- addBalance: balancesFn,
131
+ addBalance: balanceAndBlacklistStatesFn,
132
132
  addAllowance: allowedFn,
133
133
  },
134
134
  INST: {
@@ -581,6 +581,21 @@ export const Tokens: {
581
581
  decimals: 6,
582
582
  symbol: 'USUALM',
583
583
  },
584
+ USDL: {
585
+ address: '0xbdC7c08592Ee4aa51D06C27Ee23D5087D65aDbcD',
586
+ decimals: 18,
587
+ symbol: 'USDL',
588
+ },
589
+ csUSDL: {
590
+ address: '0xbEeFc011e94f43b8B7b455eBaB290C7Ab4E216f1',
591
+ decimals: 18,
592
+ symbol: 'csUSDL',
593
+ },
594
+ csUSDC: {
595
+ address: '0x7204b7dbf9412567835633b6f00c3edc3a8d6330',
596
+ decimals: 18,
597
+ symbol: 'csUSDC',
598
+ },
584
599
  },
585
600
  [Network.POLYGON]: {
586
601
  jGBP: {
@@ -5,9 +5,7 @@ export type StateOverride = {
5
5
  };
6
6
 
7
7
  export type StateSimulateApiOverride = {
8
- storage: {
9
- value: Record<string, string>;
10
- };
8
+ storage: Record<string, string>;
11
9
  };
12
10
 
13
11
  export type StateOverrides = {