@paraswap/dex-lib 4.1.7-pub-sub → 4.1.8

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 (360) hide show
  1. package/.idea/codeStyles/Project.xml +59 -0
  2. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  3. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  4. package/.idea/modules.xml +8 -0
  5. package/.idea/paraswap-dex-lib.iml +12 -0
  6. package/.idea/vcs.xml +6 -0
  7. package/build/dex/angle-staked-stable/angle-staked-stable.js +2 -1
  8. package/build/dex/angle-staked-stable/angle-staked-stable.js.map +1 -1
  9. package/build/dex/angle-transmuter/angle-transmuter.js.map +1 -1
  10. package/build/dex/balancer-v1/config.js +2 -1
  11. package/build/dex/balancer-v1/config.js.map +1 -1
  12. package/build/dex/generic-rfq/generic-rfq.js +2 -1
  13. package/build/dex/generic-rfq/generic-rfq.js.map +1 -1
  14. package/build/dex/generic-rfq/rate-fetcher.d.ts +1 -4
  15. package/build/dex/generic-rfq/rate-fetcher.js +20 -65
  16. package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
  17. package/build/dex/weth/weth.js +2 -1
  18. package/build/dex/weth/weth.js.map +1 -1
  19. package/build/dex/zerox/index.d.ts +1 -1
  20. package/build/dex/zerox/index.js.map +1 -1
  21. package/build/lib/pub-sub.d.ts +0 -17
  22. package/build/lib/pub-sub.js +4 -84
  23. package/build/lib/pub-sub.js.map +1 -1
  24. package/package.json +1 -1
  25. package/scripts/get-uniswap-v3-dexes.ts +64 -0
  26. package/src/abi/balancer-v3/directionalFeeHook.json +677 -677
  27. package/src/abi/balancer-v3/stableSurgeHook.json +975 -975
  28. package/src/dex/aave-gsm/aave-gsm-gas-estimation.test.ts +32 -0
  29. package/src/dex/aave-v2/aave-v2-gas-estimation.test.ts +28 -0
  30. package/src/dex/aave-v3/aave-v3-gas-estimation.test.ts +66 -0
  31. package/src/dex/aave-v3-stata/aave-v3-stata-gas-estimation.test.ts +41 -0
  32. package/src/dex/aave-v3-stata-v2/aave-v3-stata-v2-gas-estimation.test.ts +41 -0
  33. package/src/dex/angle-staked-stable/angle-staked-stable-gas-estimation.test.ts +29 -0
  34. package/src/dex/angle-staked-stable/angle-staked-stable.ts +2 -1
  35. package/src/dex/angle-transmuter/angle-transmuter-gas-estimation.test.ts +41 -0
  36. package/src/dex/angle-transmuter/angle-transmuter.ts +0 -1
  37. package/src/dex/balancer-v1/balancer-v1-gas-estimation.test.ts +29 -0
  38. package/src/dex/balancer-v1/config.ts +2 -1
  39. package/src/dex/balancer-v2/balancer-v2-gas-estimation.test.ts +98 -0
  40. package/src/dex/balancer-v3/balancer-v3-gas-estimation.test.ts +30 -0
  41. package/src/dex/bancor/bancor-gas-estimation.test.ts +30 -0
  42. package/src/dex/bebop/bebop-gas-estimation.test.ts +30 -0
  43. package/src/dex/concentrator-arusd/concentrator-arusd-gas-estimation.test.ts +29 -0
  44. package/src/dex/curve-v1/curve-v1-gas-estimation.test.ts +29 -0
  45. package/src/dex/curve-v2/curve-v2-gas-estimation.test.ts +29 -0
  46. package/src/dex/fluid-dex/fluid-dex-gas-estimation.test.ts +29 -0
  47. package/src/dex/fx-protocol-rusd/fx-protocol-rusd-gas-estimation.test.ts +29 -0
  48. package/src/dex/generic-rfq/generic-rfq.ts +6 -1
  49. package/src/dex/generic-rfq/rate-fetcher.ts +47 -112
  50. package/src/dex/hashflow/hashflow-gas-estimation.test.ts +30 -0
  51. package/src/dex/idle-dao/idle-dao--gas-estimation.test.ts +30 -0
  52. package/src/dex/lido/lido-gas-estimation.test.ts +29 -0
  53. package/src/dex/lite-psm/lite-psm-gas-estimation.test.ts +34 -0
  54. package/src/dex/maker-psm/maker-psm-gas-estimation.test.ts +34 -0
  55. package/src/dex/maverick-v1/maverick-v1-gas-estimation.test.ts +29 -0
  56. package/src/dex/maverick-v2/maverick-v2-gas-estimation.test.ts +29 -0
  57. package/src/dex/pancakeswap-v3/pancakeswap-v3-gas-estimation.test.ts +29 -0
  58. package/src/dex/polygon-migrator/polygon-migrator-gas-estimation.test.ts +41 -0
  59. package/src/dex/sky-converter/sky-converter-gas-estimation.test.ts +78 -0
  60. package/src/dex/solidly/solidly-gas-estimation.test.ts +29 -0
  61. package/src/dex/solidly-v3/solidly-v3-gas-estimation.test.ts +29 -0
  62. package/src/dex/spark/spark-gas-estimation.test.ts +29 -0
  63. package/src/dex/stader/stader-gas-estimation.test.ts +29 -0
  64. package/src/dex/stkgho/stkgho-gas-estimation.test.ts +29 -0
  65. package/src/dex/swaap-v2/swaap-v2-estimation.test.ts +29 -0
  66. package/src/dex/swell/swell-estimation.test.ts +29 -0
  67. package/src/dex/trader-joe-v2.1/trader-joe-v2.1-gas-estimation.test.ts +29 -0
  68. package/src/dex/uniswap-v2/uniswap-v2-gas-estimation.test.ts +98 -0
  69. package/src/dex/uniswap-v3/uniswap-v3-gas-estimation.test.ts +98 -0
  70. package/src/dex/usual/usual-gas-estimation.test.ts +54 -0
  71. package/src/dex/usual-pp/usual-pp-gas-estimation.test.ts +29 -0
  72. package/src/dex/weth/weth-gas-estimation.test.ts +42 -0
  73. package/src/dex/weth/weth.ts +3 -1
  74. package/src/dex/wombat/wombat-gas-estimation.test.ts +29 -0
  75. package/src/dex/wsteth/wsteth-gas-estimation.test.ts +41 -0
  76. package/src/dex/wusdm/wusdm-gas-estimation.test.ts +41 -0
  77. package/src/lib/pub-sub.ts +3 -107
  78. package/tests/constants-e2e.ts +8 -0
  79. package/tests/tenderly-simulation-new.test.ts +151 -0
  80. package/tests/tenderly-simulation-new.ts +698 -0
  81. package/tests/token-storage-slots.json +532 -0
  82. package/tests/utils-e2e.ts +137 -1
  83. package/build/abi/AaveV1_lending_pool.json +0 -27
  84. package/build/abi/Aave_GSM.json +0 -751
  85. package/build/abi/Balancer.json +0 -257
  86. package/build/abi/BalancerV2.json +0 -1179
  87. package/build/abi/RamsesV2Pool.abi.json +0 -1554
  88. package/build/abi/RamsesV2Quoter.abi.json +0 -274
  89. package/build/abi/USDM.json +0 -807
  90. package/build/abi/UniswapV2Router.json +0 -397
  91. package/build/abi/angle-transmuter/ChainlinkAccessControlledOffchainAggregator.json +0 -1246
  92. package/build/abi/angle-transmuter/ChainlinkEACAggregatorProxy.json +0 -509
  93. package/build/abi/curve-v1/CurveBUSDv2.abi.json +0 -1356
  94. package/build/abi/curve-v1/CurveTokenV1.json +0 -305
  95. package/build/abi/curve-v1/CurveTokenV2.json +0 -318
  96. package/build/abi/curve-v1/CurveV1StableNg.json +0 -1452
  97. package/build/abi/curve-v1/CurveV2Swap.json +0 -700
  98. package/build/abi/curve-v1/FactoryCryptoRegistry.json +0 -316
  99. package/build/abi/curve-v1/FactoryRegistry.json +0 -508
  100. package/build/abi/curve-v1/StableSwapAave.json +0 -1152
  101. package/build/abi/curve-v1/StableSwapBUSD.json +0 -814
  102. package/build/abi/curve-v1/StableSwapCompound.json +0 -814
  103. package/build/abi/curve-v1/StableSwapIDLE.json +0 -1253
  104. package/build/abi/curve-v1/StableSwapPax.json +0 -865
  105. package/build/abi/curve-v1/StableSwapSnow.json +0 -900
  106. package/build/abi/curve-v1/StableSwapUSDN.json +0 -1004
  107. package/build/abi/curve-v1/StableSwapUSDT.json +0 -814
  108. package/build/abi/curve-v1/StableSwapY.json +0 -814
  109. package/build/abi/inception/inception-ineth-pool.json +0 -1062
  110. package/build/abi/inception/inception-ineth.json +0 -609
  111. package/build/abi/inception/inception-ratio-feed.json +0 -329
  112. package/build/abi/inception/inception-vault.json +0 -991
  113. package/build/abi/kyberdmm/kyber-storage.abi.json +0 -824
  114. package/build/abi/kyberdmm.abi.json +0 -1148
  115. package/build/abi/maverick-v2/MaverickV2Quoter.json +0 -278
  116. package/build/abi/nerve/nerve-metapool.json +0 -790
  117. package/build/abi/platypus/asset.json +0 -490
  118. package/build/abi/platypus/avax-pool.json +0 -820
  119. package/build/abi/platypus/oracle.json +0 -119
  120. package/build/abi/platypus/pool.json +0 -677
  121. package/build/abi/smardex/all/smardex-router.json +0 -648
  122. package/build/abi/smardex/layer-1/smardex-factory.json +0 -242
  123. package/build/abi/smardex/layer-1/smardex-pool.json +0 -506
  124. package/build/abi/smardex/layer-2/smardex-factory.json +0 -185
  125. package/build/abi/smardex/layer-2/smardex-pool.json +0 -578
  126. package/build/abi/swaap-v1/pool.json +0 -1346
  127. package/build/abi/uniswap-v3/UniswapV3Quoter.abi.json +0 -193
  128. package/build/abi/velodrome-slipstream/VelodromeSlipstreamQuoterV2.abi.json +0 -267
  129. package/build/dex/aave-v1/aave-v1.d.ts +0 -34
  130. package/build/dex/aave-v1/aave-v1.js +0 -180
  131. package/build/dex/aave-v1/aave-v1.js.map +0 -1
  132. package/build/dex/aave-v1/config.d.ts +0 -11
  133. package/build/dex/aave-v1/config.js +0 -20
  134. package/build/dex/aave-v1/config.js.map +0 -1
  135. package/build/dex/aave-v1/tokens-mainnet.json +0 -134
  136. package/build/dex/aave-v1/tokens.d.ts +0 -3
  137. package/build/dex/aave-v1/tokens.js +0 -50
  138. package/build/dex/aave-v1/tokens.js.map +0 -1
  139. package/build/dex/aave-v1/types.d.ts +0 -12
  140. package/build/dex/aave-v1/types.js +0 -3
  141. package/build/dex/aave-v1/types.js.map +0 -1
  142. package/build/dex/balancer-v1/balancer-pools.json +0 -33333
  143. package/build/dex/bebop/websocket-fetcher.d.ts +0 -35
  144. package/build/dex/bebop/websocket-fetcher.js +0 -87
  145. package/build/dex/bebop/websocket-fetcher.js.map +0 -1
  146. package/build/dex/idle-dao/idle-dao-pool.d.ts +0 -56
  147. package/build/dex/idle-dao/idle-dao-pool.js +0 -176
  148. package/build/dex/idle-dao/idle-dao-pool.js.map +0 -1
  149. package/build/dex/idle-dao/idle-dao-pooling-pool.d.ts +0 -16
  150. package/build/dex/idle-dao/idle-dao-pooling-pool.js +0 -57
  151. package/build/dex/idle-dao/idle-dao-pooling-pool.js.map +0 -1
  152. package/build/dex/idle-dao/scripts.d.ts +0 -9
  153. package/build/dex/idle-dao/scripts.js +0 -552
  154. package/build/dex/idle-dao/scripts.js.map +0 -1
  155. package/build/dex/inception/config.d.ts +0 -4
  156. package/build/dex/inception/config.js +0 -109
  157. package/build/dex/inception/config.js.map +0 -1
  158. package/build/dex/inception/inception-event-pool.d.ts +0 -16
  159. package/build/dex/inception/inception-event-pool.js +0 -51
  160. package/build/dex/inception/inception-event-pool.js.map +0 -1
  161. package/build/dex/inception/inception-native.d.ts +0 -43
  162. package/build/dex/inception/inception-native.js +0 -131
  163. package/build/dex/inception/inception-native.js.map +0 -1
  164. package/build/dex/inception/inception-pool.d.ts +0 -18
  165. package/build/dex/inception/inception-pool.js +0 -32
  166. package/build/dex/inception/inception-pool.js.map +0 -1
  167. package/build/dex/inception/inception-price-feed.d.ts +0 -19
  168. package/build/dex/inception/inception-price-feed.js +0 -51
  169. package/build/dex/inception/inception-price-feed.js.map +0 -1
  170. package/build/dex/inception/inception.d.ts +0 -43
  171. package/build/dex/inception/inception.js +0 -204
  172. package/build/dex/inception/inception.js.map +0 -1
  173. package/build/dex/inception/tokens.d.ts +0 -9
  174. package/build/dex/inception/tokens.js +0 -28
  175. package/build/dex/inception/tokens.js.map +0 -1
  176. package/build/dex/inception/types.d.ts +0 -22
  177. package/build/dex/inception/types.js +0 -3
  178. package/build/dex/inception/types.js.map +0 -1
  179. package/build/dex/inception/utils.d.ts +0 -6
  180. package/build/dex/inception/utils.js +0 -37
  181. package/build/dex/inception/utils.js.map +0 -1
  182. package/build/dex/platypus/asset.d.ts +0 -14
  183. package/build/dex/platypus/asset.js +0 -97
  184. package/build/dex/platypus/asset.js.map +0 -1
  185. package/build/dex/platypus/config.d.ts +0 -11
  186. package/build/dex/platypus/config.js +0 -69
  187. package/build/dex/platypus/config.js.map +0 -1
  188. package/build/dex/platypus/platypus.d.ts +0 -63
  189. package/build/dex/platypus/platypus.js +0 -473
  190. package/build/dex/platypus/platypus.js.map +0 -1
  191. package/build/dex/platypus/pool-avax.d.ts +0 -8
  192. package/build/dex/platypus/pool-avax.js +0 -54
  193. package/build/dex/platypus/pool-avax.js.map +0 -1
  194. package/build/dex/platypus/pool-base.d.ts +0 -19
  195. package/build/dex/platypus/pool-base.js +0 -86
  196. package/build/dex/platypus/pool-base.js.map +0 -1
  197. package/build/dex/platypus/pool-pure.d.ts +0 -8
  198. package/build/dex/platypus/pool-pure.js +0 -37
  199. package/build/dex/platypus/pool-pure.js.map +0 -1
  200. package/build/dex/platypus/pool-subscriber.d.ts +0 -14
  201. package/build/dex/platypus/pool-subscriber.js +0 -167
  202. package/build/dex/platypus/pool-subscriber.js.map +0 -1
  203. package/build/dex/platypus/pool.d.ts +0 -8
  204. package/build/dex/platypus/pool.js +0 -58
  205. package/build/dex/platypus/pool.js.map +0 -1
  206. package/build/dex/platypus/types.d.ts +0 -92
  207. package/build/dex/platypus/types.js +0 -10
  208. package/build/dex/platypus/types.js.map +0 -1
  209. package/build/dex/quickswap/spiritswap-v3.d.ts +0 -6
  210. package/build/dex/quickswap/spiritswap-v3.js +0 -19
  211. package/build/dex/quickswap/spiritswap-v3.js.map +0 -1
  212. package/build/dex/smardex/config.d.ts +0 -4
  213. package/build/dex/smardex/config.js +0 -64
  214. package/build/dex/smardex/config.js.map +0 -1
  215. package/build/dex/smardex/constants.d.ts +0 -18
  216. package/build/dex/smardex/constants.js +0 -33
  217. package/build/dex/smardex/constants.js.map +0 -1
  218. package/build/dex/smardex/sdk/constants.d.ts +0 -6
  219. package/build/dex/smardex/sdk/constants.js +0 -13
  220. package/build/dex/smardex/sdk/constants.js.map +0 -1
  221. package/build/dex/smardex/sdk/core.d.ts +0 -113
  222. package/build/dex/smardex/sdk/core.js +0 -499
  223. package/build/dex/smardex/sdk/core.js.map +0 -1
  224. package/build/dex/smardex/sdk/errors.d.ts +0 -15
  225. package/build/dex/smardex/sdk/errors.js +0 -22
  226. package/build/dex/smardex/sdk/errors.js.map +0 -1
  227. package/build/dex/smardex/sdk/types.d.ts +0 -62
  228. package/build/dex/smardex/sdk/types.js +0 -3
  229. package/build/dex/smardex/sdk/types.js.map +0 -1
  230. package/build/dex/smardex/sdk/utils.d.ts +0 -44
  231. package/build/dex/smardex/sdk/utils.js +0 -133
  232. package/build/dex/smardex/sdk/utils.js.map +0 -1
  233. package/build/dex/smardex/smardex-event-pool.d.ts +0 -28
  234. package/build/dex/smardex/smardex-event-pool.js +0 -119
  235. package/build/dex/smardex/smardex-event-pool.js.map +0 -1
  236. package/build/dex/smardex/smardex.d.ts +0 -65
  237. package/build/dex/smardex/smardex.js +0 -519
  238. package/build/dex/smardex/smardex.js.map +0 -1
  239. package/build/dex/smardex/types.d.ts +0 -55
  240. package/build/dex/smardex/types.js +0 -3
  241. package/build/dex/smardex/types.js.map +0 -1
  242. package/build/dex/solidly/forks-override/cone.d.ts +0 -22
  243. package/build/dex/solidly/forks-override/cone.js +0 -53
  244. package/build/dex/solidly/forks-override/cone.js.map +0 -1
  245. package/build/dex/solidly/forks-override/solisnek.d.ts +0 -8
  246. package/build/dex/solidly/forks-override/solisnek.js +0 -15
  247. package/build/dex/solidly/forks-override/solisnek.js.map +0 -1
  248. package/build/dex/swaap-v1/config.d.ts +0 -17
  249. package/build/dex/swaap-v1/config.js +0 -56
  250. package/build/dex/swaap-v1/config.js.map +0 -1
  251. package/build/dex/swaap-v1/constants.d.ts +0 -6
  252. package/build/dex/swaap-v1/constants.js +0 -17
  253. package/build/dex/swaap-v1/constants.js.map +0 -1
  254. package/build/dex/swaap-v1/libraries/ChainlinkUtils.d.ts +0 -25
  255. package/build/dex/swaap-v1/libraries/ChainlinkUtils.js +0 -62
  256. package/build/dex/swaap-v1/libraries/ChainlinkUtils.js.map +0 -1
  257. package/build/dex/swaap-v1/libraries/Const.d.ts +0 -18
  258. package/build/dex/swaap-v1/libraries/Const.js +0 -26
  259. package/build/dex/swaap-v1/libraries/Const.js.map +0 -1
  260. package/build/dex/swaap-v1/libraries/GeometricBrownianMotion.d.ts +0 -77
  261. package/build/dex/swaap-v1/libraries/GeometricBrownianMotion.js +0 -316
  262. package/build/dex/swaap-v1/libraries/GeometricBrownianMotion.js.map +0 -1
  263. package/build/dex/swaap-v1/libraries/LogExpMath.d.ts +0 -75
  264. package/build/dex/swaap-v1/libraries/LogExpMath.js +0 -418
  265. package/build/dex/swaap-v1/libraries/LogExpMath.js.map +0 -1
  266. package/build/dex/swaap-v1/libraries/MathMMM.d.ts +0 -185
  267. package/build/dex/swaap-v1/libraries/MathMMM.js +0 -453
  268. package/build/dex/swaap-v1/libraries/MathMMM.js.map +0 -1
  269. package/build/dex/swaap-v1/libraries/Num.d.ts +0 -31
  270. package/build/dex/swaap-v1/libraries/Num.js +0 -167
  271. package/build/dex/swaap-v1/libraries/Num.js.map +0 -1
  272. package/build/dex/swaap-v1/libraries/PoolQuotations.d.ts +0 -23
  273. package/build/dex/swaap-v1/libraries/PoolQuotations.js +0 -131
  274. package/build/dex/swaap-v1/libraries/PoolQuotations.js.map +0 -1
  275. package/build/dex/swaap-v1/libraries/Struct.d.ts +0 -56
  276. package/build/dex/swaap-v1/libraries/Struct.js +0 -3
  277. package/build/dex/swaap-v1/libraries/Struct.js.map +0 -1
  278. package/build/dex/swaap-v1/swaap-v1-pool.d.ts +0 -45
  279. package/build/dex/swaap-v1/swaap-v1-pool.js +0 -656
  280. package/build/dex/swaap-v1/swaap-v1-pool.js.map +0 -1
  281. package/build/dex/swaap-v1/swaap-v1.d.ts +0 -62
  282. package/build/dex/swaap-v1/swaap-v1.js +0 -379
  283. package/build/dex/swaap-v1/swaap-v1.js.map +0 -1
  284. package/build/dex/swaap-v1/types.d.ts +0 -106
  285. package/build/dex/swaap-v1/types.js +0 -9
  286. package/build/dex/swaap-v1/types.js.map +0 -1
  287. package/build/executor/fixtures/executor01/exchange-params/price-route-multiswap-balancerv1-curvev1-eth-usdc-gusd.json +0 -16
  288. package/build/executor/fixtures/executor01/exchange-params/price-route-multiswap-balancerv1-sushiv3-wbtc-eth-sushi.json +0 -16
  289. package/build/executor/fixtures/executor01/exchange-params/price-route-multiswap-sushiv3-curvev1-eth-usdc-gusd.json +0 -16
  290. package/build/executor/fixtures/executor01/exchange-params/price-route-multiswap-sushiv3-curvev1-gusd-usdc-eth.json +0 -16
  291. package/build/executor/fixtures/executor01/exchange-params/price-route-multiswap-sushiv3-dai-usdc-eth.json +0 -16
  292. package/build/executor/fixtures/executor01/exchange-params/price-route-multiswap-sushiv3-eth-usdc-dai.json +0 -16
  293. package/build/executor/fixtures/executor01/exchange-params/price-route-multiswap-sushiv3-usdc-eth-wbtc.json +0 -16
  294. package/build/executor/fixtures/executor01/exchange-params/price-route-multiswap-sushiv3-usdt-usdc-dai.json +0 -16
  295. package/build/executor/fixtures/executor01/exchange-params/price-route-simpleSwap-balancerv1-eth-usdc.json +0 -9
  296. package/build/executor/fixtures/executor01/exchange-params/price-route-simpleSwap-balancerv1-usdc-eth.json +0 -9
  297. package/build/executor/fixtures/executor01/exchange-params/price-route-simpleSwap-balancerv1-usdc-wbtc.json +0 -9
  298. package/build/executor/fixtures/executor01/exchange-params/price-route-simpleSwap-curvev1-eth-steth.json +0 -9
  299. package/build/executor/fixtures/executor01/exchange-params/price-route-simpleSwap-curvev1-steth-eth.json +0 -9
  300. package/build/executor/fixtures/executor01/exchange-params/price-route-simpleSwap-curvev1-usdc-usdt.json +0 -9
  301. package/build/executor/fixtures/executor01/exchange-params/price-route-simpleSwap-univ3-eth-usdc.json +0 -9
  302. package/build/executor/fixtures/executor01/exchange-params/price-route-simpleSwap-univ3-usdc-eth.json +0 -9
  303. package/build/executor/fixtures/executor01/exchange-params/price-route-simpleSwap-univ3-usdc-usdt.json +0 -9
  304. package/build/executor/fixtures/executor01/maybe-weth-calldata/price-route-multiswap-balancerv1-sushiv3-wbtc-eth-sushi.json +0 -12
  305. package/build/executor/fixtures/executor01/maybe-weth-calldata/price-route-multiswap-sushiv3-curvev1-eth-usdc-gusd.json +0 -7
  306. package/build/executor/fixtures/executor01/maybe-weth-calldata/price-route-multiswap-sushiv3-curvev1-gusd-usdc-eth.json +0 -7
  307. package/build/executor/fixtures/executor01/maybe-weth-calldata/price-route-multiswap-sushiv3-dai-usdc-eth.json +0 -7
  308. package/build/executor/fixtures/executor01/maybe-weth-calldata/price-route-multiswap-sushiv3-eth-usdc-dai.json +0 -7
  309. package/build/executor/fixtures/executor01/maybe-weth-calldata/price-route-multiswap-sushiv3-usdc-eth-wbtc.json +0 -12
  310. package/build/executor/fixtures/executor01/maybe-weth-calldata/price-route-simpleSwap-univ3-eth-usdc.json +0 -7
  311. package/build/executor/fixtures/executor01/maybe-weth-calldata/price-route-simpleSwap-univ3-usdc-eth.json +0 -7
  312. package/build/executor/fixtures/executor01/routes/price-route-multiswap-balancerv1-curvev1-eth-usdc-gusd.json +0 -78
  313. package/build/executor/fixtures/executor01/routes/price-route-multiswap-balancerv1-sushiv3-wbtc-eth-sushi.json +0 -81
  314. package/build/executor/fixtures/executor01/routes/price-route-multiswap-sushiv3-curvev1-eth-usdc-gusd.json +0 -78
  315. package/build/executor/fixtures/executor01/routes/price-route-multiswap-sushiv3-curvev1-gusd-usdc-eth.json +0 -78
  316. package/build/executor/fixtures/executor01/routes/price-route-multiswap-sushiv3-dai-usdc-eth.json +0 -81
  317. package/build/executor/fixtures/executor01/routes/price-route-multiswap-sushiv3-eth-usdc-dai.json +0 -81
  318. package/build/executor/fixtures/executor01/routes/price-route-multiswap-sushiv3-usdc-eth-wbtc.json +0 -81
  319. package/build/executor/fixtures/executor01/routes/price-route-multiswap-sushiv3-usdt-usdc-dai.json +0 -81
  320. package/build/executor/fixtures/executor01/routes/price-route-simpleSwap-balancerv1-eth-usdc.json +0 -64
  321. package/build/executor/fixtures/executor01/routes/price-route-simpleSwap-balancerv1-usdc-eth.json +0 -85
  322. package/build/executor/fixtures/executor01/routes/price-route-simpleSwap-balancerv1-usdc-wbtc.json +0 -64
  323. package/build/executor/fixtures/executor01/routes/price-route-simpleSwap-curvev1-eth-steth.json +0 -52
  324. package/build/executor/fixtures/executor01/routes/price-route-simpleSwap-curvev1-steth-eth.json +0 -52
  325. package/build/executor/fixtures/executor01/routes/price-route-simpleSwap-curvev1-usdc-usdt.json +0 -52
  326. package/build/executor/fixtures/executor01/routes/price-route-simpleSwap-univ3-eth-usdc.json +0 -55
  327. package/build/executor/fixtures/executor01/routes/price-route-simpleSwap-univ3-usdc-eth.json +0 -55
  328. package/build/executor/fixtures/executor01/routes/price-route-simpleSwap-univ3-usdc-usdt.json +0 -55
  329. package/build/executor/fixtures/executor02/exchange-params/price-route-multiSwap-balancerv1-sushiv3-univ3-bal-eth-sushi.json +0 -23
  330. package/build/executor/fixtures/executor02/exchange-params/price-route-multiSwap-maverickv1-sushiv3-univ3-eth-usdc-mav.json +0 -37
  331. package/build/executor/fixtures/executor02/exchange-params/price-route-multiSwap-univ3-sushiv3-sushi-eth-wbtc.json +0 -23
  332. package/build/executor/fixtures/executor02/exchange-params/price-route-multiSwap-univ3-sushiv3-wbtc-eth-sushi.json +0 -23
  333. package/build/executor/fixtures/executor02/exchange-params/price-route-multiswap-curvev1-univ3-dai-usdc-eth.json +0 -51
  334. package/build/executor/fixtures/executor02/exchange-params/price-route-multiswap-univ3-usdt-dai-eth.json +0 -58
  335. package/build/executor/fixtures/executor02/exchange-params/price-route-simpleSwap-sushiv3-balancerv1-eth-usdc.json +0 -23
  336. package/build/executor/fixtures/executor02/exchange-params/price-route-simpleSwap-sushiv3-balancerv1-usdc-eth.json +0 -23
  337. package/build/executor/fixtures/executor02/exchange-params/price-route-simpleSwap-sushiv3-univ3-eth-sushi.json +0 -9
  338. package/build/executor/fixtures/executor02/exchange-params/price-route-simpleSwap-sushiv3-univ3-sushi-eth.json +0 -16
  339. package/build/executor/fixtures/executor02/exchange-params/price-route-simpleSwap-univ3-curvev1-usdt-dai.json +0 -23
  340. package/build/executor/fixtures/executor02/maybe-weth-calldata/price-route-multiSwap-balancerv1-sushiv3-univ3-bal-eth-sushi.json +0 -12
  341. package/build/executor/fixtures/executor02/maybe-weth-calldata/price-route-multiSwap-maverickv1-sushiv3-univ3-eth-usdc-mav.json +0 -7
  342. package/build/executor/fixtures/executor02/maybe-weth-calldata/price-route-multiSwap-univ3-sushiv3-sushi-eth-wbtc.json +0 -12
  343. package/build/executor/fixtures/executor02/maybe-weth-calldata/price-route-multiSwap-univ3-sushiv3-wbtc-eth-sushi.json +0 -12
  344. package/build/executor/fixtures/executor02/maybe-weth-calldata/price-route-multiswap-curvev1-univ3-dai-usdc-eth.json +0 -7
  345. package/build/executor/fixtures/executor02/maybe-weth-calldata/price-route-multiswap-univ3-usdt-dai-eth.json +0 -7
  346. package/build/executor/fixtures/executor02/maybe-weth-calldata/price-route-simpleSwap-sushiv3-balancerv1-eth-usdc.json +0 -7
  347. package/build/executor/fixtures/executor02/maybe-weth-calldata/price-route-simpleSwap-sushiv3-balancerv1-usdc-eth.json +0 -7
  348. package/build/executor/fixtures/executor02/maybe-weth-calldata/price-route-simpleSwap-sushiv3-univ3-eth-sushi.json +0 -7
  349. package/build/executor/fixtures/executor02/maybe-weth-calldata/price-route-simpleSwap-sushiv3-univ3-sushi-eth.json +0 -7
  350. package/build/executor/fixtures/executor02/routes/price-route-multiSwap-balancerv1-sushiv3-univ3-bal-eth-sushi.json +0 -130
  351. package/build/executor/fixtures/executor02/routes/price-route-multiSwap-maverickv1-sushiv3-univ3-eth-usdc-mav.json +0 -136
  352. package/build/executor/fixtures/executor02/routes/price-route-multiSwap-univ3-sushiv3-sushi-eth-wbtc.json +0 -100
  353. package/build/executor/fixtures/executor02/routes/price-route-multiSwap-univ3-sushiv3-wbtc-eth-sushi.json +0 -100
  354. package/build/executor/fixtures/executor02/routes/price-route-multiswap-curvev1-univ3-dai-usdc-eth.json +0 -166
  355. package/build/executor/fixtures/executor02/routes/price-route-multiswap-univ3-usdt-dai-eth.json +0 -190
  356. package/build/executor/fixtures/executor02/routes/price-route-simpleSwap-sushiv3-balancerv1-eth-usdc.json +0 -114
  357. package/build/executor/fixtures/executor02/routes/price-route-simpleSwap-sushiv3-balancerv1-usdc-eth.json +0 -114
  358. package/build/executor/fixtures/executor02/routes/price-route-simpleSwap-sushiv3-univ3-eth-sushi.json +0 -55
  359. package/build/executor/fixtures/executor02/routes/price-route-simpleSwap-sushiv3-univ3-sushi-eth.json +0 -73
  360. package/build/executor/fixtures/executor02/routes/price-route-simpleSwap-univ3-curvev1-usdt-dai.json +0 -82
@@ -0,0 +1,698 @@
1
+ /* eslint-disable no-console */
2
+ import 'dotenv/config';
3
+ import axios from 'axios';
4
+ import { ethers } from 'ethers';
5
+ import * as fs from 'fs/promises';
6
+ import * as path from 'path';
7
+ import { ETHER_ADDRESS } from '../src/constants';
8
+
9
+ const TENDERLY_TOKEN = process.env.TENDERLY_TOKEN!;
10
+ const TENDERLY_ACCOUNT_ID = process.env.TENDERLY_ACCOUNT_ID!;
11
+ const TENDERLY_PROJECT = process.env.TENDERLY_PROJECT!;
12
+
13
+ interface StateObject {
14
+ // Overrides of storage slots.
15
+ // In this mapping, the key is variable storage slot,
16
+ // and the value contains the override.
17
+ storage?: Record<string, string>; // storage slot -> value
18
+ balance?: string;
19
+ nonce?: number;
20
+ // Bytecode that will override the code associated to the given account.
21
+ code?: string;
22
+ }
23
+ export type StateOverride = Record<string, StateObject>; // contract -> storage override
24
+
25
+ interface TokenStorageSlots {
26
+ balanceSlot: string;
27
+ allowanceSlot: string;
28
+ isVyper?: boolean;
29
+ }
30
+
31
+ interface SimulateTransactionRequest {
32
+ from: string | null;
33
+ to: string | null;
34
+ value?: string;
35
+ data: string;
36
+ chainId: number;
37
+ timestamp?: number;
38
+ blockNumber?: number;
39
+ stateOverride?: StateOverride;
40
+ }
41
+
42
+ // not fully complete
43
+ interface SimulatedTransactionCall {
44
+ hash: string;
45
+ contract_name: string;
46
+ function_name: string;
47
+ function_pc: number;
48
+ function_op: string;
49
+ function_file_index: number;
50
+ function_code_start: number;
51
+ function_line_number: number;
52
+ function_code_length: number;
53
+ absolute_position: number;
54
+ caller_pc: number;
55
+ caller_op: string;
56
+ call_type: string;
57
+ address: string;
58
+ from: string;
59
+ from_balance: string;
60
+ to: string;
61
+ to_balance: string;
62
+ value: string | null;
63
+ caller: {
64
+ address: string;
65
+ balance: string;
66
+ };
67
+ block_timestamp: string;
68
+ gas: number;
69
+ gas_used: number;
70
+ intrinsic_gas: number;
71
+ storage_address: string;
72
+ input: string;
73
+ storage_slot: string[] | undefined;
74
+ calls: SimulatedTransactionCall[] | null;
75
+ }
76
+
77
+ // not fully complete
78
+ interface Simulation {
79
+ id: string;
80
+ project_id: string;
81
+ owner_id: string;
82
+ network_id: string;
83
+ block_number: number;
84
+ transaction_index: number;
85
+ from: string;
86
+ to: string;
87
+ input: string;
88
+ gas: number;
89
+ gas_price: string;
90
+ gas_used: number;
91
+ value: string;
92
+ method: string;
93
+ status: boolean;
94
+ }
95
+
96
+ // not complete, all details include a lot more info
97
+ interface SimulatedTransactionDetails {
98
+ transaction: {
99
+ hash: string;
100
+ block_hash: string;
101
+ block_number: number;
102
+ from: string;
103
+ gas: number;
104
+ gas_price: number;
105
+ gas_fee_cap: number;
106
+ gas_tip_cap: number;
107
+ cumulative_gas_used: number;
108
+ gas_used: number;
109
+ effective_gas_price: number;
110
+ input: string;
111
+ nonce: number;
112
+ to: string;
113
+ index: number;
114
+ value: string;
115
+ access_list: null;
116
+ status: boolean;
117
+ transaction_info: {
118
+ call_trace: SimulatedTransactionCall;
119
+ };
120
+ };
121
+ }
122
+
123
+ class TokenStorageSlotsCache {
124
+ private static TOKEN_STORAGE_SLOTS: Record<
125
+ number,
126
+ Record<string, TokenStorageSlots>
127
+ > | null = null;
128
+ private static readonly TOKEN_STORAGE_SLOTS_FILEPATH = path.join(
129
+ __dirname,
130
+ 'token-storage-slots.json',
131
+ );
132
+
133
+ private static async loadTokenStorageSlots(): Promise<
134
+ Record<number, Record<string, TokenStorageSlots>>
135
+ > {
136
+ return JSON.parse(
137
+ await fs.readFile(TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS_FILEPATH, {
138
+ encoding: 'utf-8',
139
+ }),
140
+ );
141
+ }
142
+
143
+ private static async saveTokenStorageSlots(): Promise<void> {
144
+ await fs.writeFile(
145
+ TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS_FILEPATH,
146
+ JSON.stringify(TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS, null, 2),
147
+ { encoding: 'utf-8' },
148
+ );
149
+ }
150
+
151
+ static async getTokenStorageSlots(
152
+ chainId: number,
153
+ token: string,
154
+ ): Promise<TokenStorageSlots | null> {
155
+ if (!TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS) {
156
+ TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS =
157
+ await TokenStorageSlotsCache.loadTokenStorageSlots();
158
+ }
159
+
160
+ return (
161
+ TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS[chainId]?.[
162
+ token.toLowerCase()
163
+ ] ?? null
164
+ );
165
+ }
166
+
167
+ static async setTokenStorageSlots(
168
+ chainId: number,
169
+ token: string,
170
+ slots: TokenStorageSlots,
171
+ ): Promise<void> {
172
+ if (!TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS) {
173
+ TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS =
174
+ await TokenStorageSlotsCache.loadTokenStorageSlots();
175
+ }
176
+
177
+ TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS ||= {};
178
+ TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS[chainId] ||= {};
179
+ TokenStorageSlotsCache.TOKEN_STORAGE_SLOTS[chainId][token.toLowerCase()] =
180
+ slots;
181
+
182
+ void TokenStorageSlotsCache.saveTokenStorageSlots();
183
+ }
184
+ }
185
+
186
+ export class TenderlySimulatorNew {
187
+ // public constants
188
+ static readonly DEFAULT_OWNER = '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
189
+ static readonly DEFAULT_SPENDER =
190
+ '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
191
+
192
+ // singleton
193
+ private static instance: TenderlySimulatorNew;
194
+
195
+ private constructor() {}
196
+
197
+ public static getInstance(): TenderlySimulatorNew {
198
+ if (!TenderlySimulatorNew.instance) {
199
+ TenderlySimulatorNew.instance = new TenderlySimulatorNew();
200
+ }
201
+
202
+ return TenderlySimulatorNew.instance;
203
+ }
204
+
205
+ public async simulateTransaction(
206
+ request: SimulateTransactionRequest,
207
+ ): Promise<Simulation> {
208
+ const data = {
209
+ network_id: request.chainId,
210
+ from: request.from,
211
+ to: request.to,
212
+ input: request.data,
213
+ value: request.value,
214
+ save: true,
215
+ save_if_fails: true,
216
+ state_objects: request.stateOverride,
217
+ };
218
+
219
+ console.log('Sending transaction simulation with params:');
220
+ console.log(JSON.stringify(data, null, 2));
221
+
222
+ const response = await axios.request({
223
+ method: 'POST',
224
+ url: `https://api.tenderly.co/api/v1/account/${TENDERLY_ACCOUNT_ID}/project/${TENDERLY_PROJECT}/simulate`,
225
+ headers: {
226
+ 'X-Access-Key': TENDERLY_TOKEN,
227
+ },
228
+ data,
229
+ });
230
+
231
+ const simulation = response.data.simulation as Simulation;
232
+ const url = `https://dashboard.tenderly.co/${TENDERLY_ACCOUNT_ID}/${TENDERLY_PROJECT}/simulator/${simulation.id}`;
233
+
234
+ console.log('Successfully simulated a transaction:');
235
+ console.log(`Simulation URL - ${url}`);
236
+
237
+ return simulation;
238
+ }
239
+
240
+ public async getSimulatedTransactionDetails(
241
+ id: string,
242
+ ): Promise<SimulatedTransactionDetails | null> {
243
+ try {
244
+ const { data } = await axios.post(
245
+ `https://api.tenderly.co/api/v1/account/${TENDERLY_ACCOUNT_ID}/project/${TENDERLY_PROJECT}/simulations/${id}`,
246
+ {},
247
+ { headers: { 'X-Access-Key': TENDERLY_TOKEN } },
248
+ );
249
+
250
+ return data;
251
+ } catch (e) {
252
+ console.error(e);
253
+ return null;
254
+ }
255
+ }
256
+
257
+ getSLOADCalls = (
258
+ callTrace: SimulatedTransactionCall,
259
+ ): SimulatedTransactionCall[] => {
260
+ const results: SimulatedTransactionCall[] = [];
261
+
262
+ if (callTrace.call_type === 'SLOAD') {
263
+ results.push(callTrace);
264
+ }
265
+
266
+ if (callTrace.calls) {
267
+ for (const call of callTrace.calls) {
268
+ results.push(...this.getSLOADCalls(call));
269
+ }
270
+ }
271
+
272
+ return results;
273
+ };
274
+
275
+ /**
276
+ *
277
+ * @param balanceOfSlot storage slot of `balanceOf` mapping
278
+ * @param owner account's address
279
+ * @param isVyper `true` if contract is written in Vyper
280
+ */
281
+ calculateAddressBalanceSlot(
282
+ balanceOfSlot: string,
283
+ owner: string,
284
+ isVyper = false,
285
+ ) {
286
+ return isVyper
287
+ ? this.calculateVyperAddressBalanceSlot(balanceOfSlot, owner)
288
+ : this.calculateSolidityAddressBalanceSlot(balanceOfSlot, owner);
289
+ }
290
+
291
+ /**
292
+ *
293
+ * @param balanceOfSlot storage slot of `balanceOf` mapping
294
+ * @param owner account's address
295
+ */
296
+ calculateSolidityAddressBalanceSlot(balanceOfSlot: string, owner: string) {
297
+ return ethers.utils.keccak256(
298
+ ethers.utils.concat([ethers.utils.hexZeroPad(owner, 32), balanceOfSlot]),
299
+ );
300
+ }
301
+
302
+ /**
303
+ *
304
+ * @param balanceOfSlot storage slot of `balanceOf` mapping
305
+ * @param owner account's address
306
+ */
307
+ calculateVyperAddressBalanceSlot(balanceOfSlot: string, owner: string) {
308
+ return ethers.utils.keccak256(
309
+ ethers.utils.concat([balanceOfSlot, ethers.utils.hexZeroPad(owner, 32)]),
310
+ );
311
+ }
312
+
313
+ /**
314
+ *
315
+ * @param allowanceSlot storage slot of `allowance` mapping
316
+ * @param owner account's address
317
+ * @param spender spender's address
318
+ * @param isVyper `true` if contract is written in Vyper
319
+ */
320
+ calculateAddressAllowanceSlot(
321
+ allowanceSlot: string,
322
+ owner: string,
323
+ spender: string,
324
+ isVyper = false,
325
+ ) {
326
+ return isVyper
327
+ ? this.calculateVyperAddressAllowanceSlot(allowanceSlot, owner, spender)
328
+ : this.calculateSolidityAddressAllowanceSlot(
329
+ allowanceSlot,
330
+ owner,
331
+ spender,
332
+ );
333
+ }
334
+
335
+ /**
336
+ *
337
+ * @param allowanceSlot storage slot of `allowance` mapping
338
+ * @param owner account's address
339
+ * @param spender spender's address
340
+ */
341
+ calculateSolidityAddressAllowanceSlot(
342
+ allowanceSlot: string,
343
+ owner: string,
344
+ spender: string,
345
+ ) {
346
+ const slotHash = ethers.utils.keccak256(
347
+ ethers.utils.concat([
348
+ ethers.utils.hexZeroPad(owner, 32),
349
+ ethers.utils.hexZeroPad(allowanceSlot, 32),
350
+ ]),
351
+ );
352
+
353
+ return ethers.utils.keccak256(
354
+ ethers.utils.concat([ethers.utils.hexZeroPad(spender, 32), slotHash]),
355
+ );
356
+ }
357
+
358
+ /**
359
+ *
360
+ * @param allowanceSlot storage slot of `allowance` mapping
361
+ * @param owner account's address
362
+ * @param spender spender's address
363
+ */
364
+ calculateVyperAddressAllowanceSlot(
365
+ allowanceSlot: string,
366
+ owner: string,
367
+ spender: string,
368
+ ) {
369
+ const slotHash = ethers.utils.keccak256(
370
+ ethers.utils.concat([
371
+ ethers.utils.hexZeroPad(allowanceSlot, 32),
372
+ ethers.utils.hexZeroPad(owner, 32),
373
+ ]),
374
+ );
375
+
376
+ return ethers.utils.keccak256(
377
+ ethers.utils.concat([slotHash, ethers.utils.hexZeroPad(spender, 32)]),
378
+ );
379
+ }
380
+
381
+ buildBalanceOfSimulationRequest(
382
+ chainId: number,
383
+ token: string,
384
+ owner: string,
385
+ ): SimulateTransactionRequest {
386
+ const iface = new ethers.utils.Interface([
387
+ 'function balanceOf(address owner) view returns (uint)',
388
+ ]);
389
+
390
+ return {
391
+ from: ethers.constants.AddressZero,
392
+ to: token,
393
+ data: iface.encodeFunctionData('balanceOf', [owner]),
394
+ chainId,
395
+ };
396
+ }
397
+
398
+ buildAllowanceSimulationRequest(
399
+ chainId: number,
400
+ token: string,
401
+ owner: string,
402
+ spender: string,
403
+ ): SimulateTransactionRequest {
404
+ const iface = new ethers.utils.Interface([
405
+ 'function allowance(address owner, address spender) view returns (uint)',
406
+ ]);
407
+
408
+ return {
409
+ from: ethers.constants.AddressZero,
410
+ to: token,
411
+ data: iface.encodeFunctionData('allowance', [owner, spender]),
412
+ chainId,
413
+ };
414
+ }
415
+
416
+ /**
417
+ * Finds the slot of the `balanceOf` mapping in given token contract's storage.
418
+ * Supports `Solidity` and `Vyper` contracts
419
+ * @param chainId token chain id
420
+ * @param token token address
421
+ */
422
+ async findTokenBalanceOfSlot(
423
+ chainId: number,
424
+ token: string,
425
+ ): Promise<{ slot: string; isVyper?: boolean }> {
426
+ const account = TenderlySimulatorNew.DEFAULT_OWNER;
427
+
428
+ const balanceOfSimulationRequest = this.buildBalanceOfSimulationRequest(
429
+ chainId,
430
+ token,
431
+ account,
432
+ );
433
+
434
+ const { id: simulationId } = await this.simulateTransaction(
435
+ balanceOfSimulationRequest,
436
+ );
437
+
438
+ const simulationDetails = await this.getSimulatedTransactionDetails(
439
+ simulationId,
440
+ );
441
+
442
+ if (!simulationDetails) {
443
+ throw `No simulation with id ${simulationId} details found`;
444
+ }
445
+
446
+ const callTrace = simulationDetails.transaction.transaction_info.call_trace;
447
+
448
+ const sloadCalls = this.getSLOADCalls(callTrace);
449
+ // token's storage slots that were read during the `balanceOf` call
450
+ const readSlots = sloadCalls
451
+ .map(call => call.storage_slot?.[0])
452
+ .filter<string>((slot): slot is string => !!slot);
453
+
454
+ const startingPoints = [
455
+ // regular contract
456
+ 0n,
457
+ // ERC20Upgradeable
458
+ BigInt(
459
+ '0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00',
460
+ ),
461
+ ];
462
+
463
+ for (const startingPoint of startingPoints) {
464
+ for (let i = startingPoint; i < startingPoint + 1_000n; i += 1n) {
465
+ const candidateSlot = ethers.utils.defaultAbiCoder.encode(
466
+ ['uint'],
467
+ [i],
468
+ );
469
+ // try solidity slot
470
+ const solitidyBalanceOfSlot = this.calculateSolidityAddressBalanceSlot(
471
+ candidateSlot,
472
+ account,
473
+ );
474
+ if (readSlots.includes(solitidyBalanceOfSlot)) {
475
+ return { slot: candidateSlot };
476
+ }
477
+ // try vyper slot
478
+ const vyperBalanceOfSlot = this.calculateVyperAddressBalanceSlot(
479
+ candidateSlot,
480
+ account,
481
+ );
482
+ if (readSlots.includes(vyperBalanceOfSlot)) {
483
+ return { slot: candidateSlot, isVyper: true };
484
+ }
485
+ }
486
+ }
487
+
488
+ throw new Error(
489
+ `Could not find a 'balanceOf' mapping slot for token ${token} on chain ${chainId}`,
490
+ );
491
+ }
492
+
493
+ /**
494
+ * Finds the slot of the `allowance` mapping in given token contract's storage
495
+ * Supports `Solidity` and `Vyper` contracts
496
+ * @param chainId token chain id
497
+ * @param token token address
498
+ */
499
+ async findTokenAllowanceSlot(
500
+ chainId: number,
501
+ token: string,
502
+ ): Promise<{ slot: string; isVyper?: boolean }> {
503
+ const account = TenderlySimulatorNew.DEFAULT_OWNER;
504
+ const spender = TenderlySimulatorNew.DEFAULT_SPENDER;
505
+
506
+ const allowanceSimulationRequest = this.buildAllowanceSimulationRequest(
507
+ chainId,
508
+ token,
509
+ account,
510
+ spender,
511
+ );
512
+
513
+ const { id: simulationId } = await this.simulateTransaction(
514
+ allowanceSimulationRequest,
515
+ );
516
+
517
+ const simulationDetails = await this.getSimulatedTransactionDetails(
518
+ simulationId,
519
+ );
520
+
521
+ if (!simulationDetails) {
522
+ throw `No simulation with id ${simulationId} details found`;
523
+ }
524
+
525
+ const callTrace = simulationDetails.transaction.transaction_info.call_trace;
526
+
527
+ const sloadCalls = this.getSLOADCalls(callTrace);
528
+ // token's storage slots that were read during the `allowance` call
529
+ const readSlots = sloadCalls
530
+ .map(call => call.storage_slot?.[0])
531
+ .filter<string>((slot): slot is string => !!slot);
532
+
533
+ const startingPoints = [
534
+ // regular contract
535
+ 0n,
536
+ // ERC20Upgradeable
537
+ BigInt(
538
+ '0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00',
539
+ ),
540
+ ];
541
+
542
+ for (const init of startingPoints) {
543
+ for (let i = init; i < init + 1000n; i += 1n) {
544
+ const candidateSlot = ethers.utils.defaultAbiCoder.encode(
545
+ ['uint'],
546
+ [i],
547
+ );
548
+ // try solidity
549
+ const solidityAllowanceSlot =
550
+ this.calculateSolidityAddressAllowanceSlot(
551
+ candidateSlot,
552
+ account,
553
+ spender,
554
+ );
555
+ if (readSlots.includes(solidityAllowanceSlot)) {
556
+ return { slot: candidateSlot };
557
+ }
558
+ // try vyper
559
+ const vyperAllowanceSlot = this.calculateVyperAddressAllowanceSlot(
560
+ candidateSlot,
561
+ account,
562
+ spender,
563
+ );
564
+ if (readSlots.includes(vyperAllowanceSlot)) {
565
+ return { slot: candidateSlot, isVyper: true };
566
+ }
567
+ }
568
+ }
569
+
570
+ throw new Error(
571
+ `Could not find a 'allowance' mapping slot for token ${token} on chain ${chainId}`,
572
+ );
573
+ }
574
+
575
+ /**
576
+ * Returns storage slots for the given token contract.
577
+ * @param chainId Token chain ID
578
+ * @param token Token address. Doesn't have to be normalized
579
+ */
580
+ async getTokenStorageSlots(
581
+ chainId: number,
582
+ token: string,
583
+ ): Promise<TokenStorageSlots> {
584
+ const normalizedToken = token.toLowerCase();
585
+
586
+ if (normalizedToken === ETHER_ADDRESS) {
587
+ throw new Error('Cannot provide storage slots for native token');
588
+ }
589
+
590
+ // check cache
591
+ const cachedSlots = await TokenStorageSlotsCache.getTokenStorageSlots(
592
+ chainId,
593
+ normalizedToken,
594
+ );
595
+
596
+ // return if cached
597
+ if (cachedSlots) {
598
+ return cachedSlots;
599
+ }
600
+
601
+ // find the slots
602
+ const [balanceSlot, allowanceSlot] = await Promise.all([
603
+ this.findTokenBalanceOfSlot(chainId, token),
604
+ this.findTokenAllowanceSlot(chainId, token),
605
+ ]);
606
+
607
+ // save the slots and return
608
+ const slots: TokenStorageSlots = {
609
+ balanceSlot: balanceSlot.slot,
610
+ allowanceSlot: allowanceSlot.slot,
611
+ isVyper: balanceSlot.isVyper,
612
+ };
613
+
614
+ // no need to await
615
+ void TokenStorageSlotsCache.setTokenStorageSlots(chainId, token, slots);
616
+
617
+ return slots;
618
+ }
619
+
620
+ /**
621
+ * Adds native balance override to an existing `StateOverride` object
622
+ * @param stateOverride object to add the override to
623
+ * @param account address to be given the balance
624
+ * @param amount token amount in wei
625
+ */
626
+ addBalanceOverride(
627
+ stateOverride: StateOverride,
628
+ account: string,
629
+ amount: bigint,
630
+ ): void {
631
+ // add the balance override
632
+ stateOverride[account] ||= {};
633
+ stateOverride[account].balance = amount.toString();
634
+ }
635
+
636
+ /**
637
+ * Adds token balance override to an existing `StateOverride` object
638
+ * @param stateOverride object to add the override to
639
+ * @param chainId token chain ID
640
+ * @param token token address
641
+ * @param account address to be given the balance
642
+ * @param amount token amount in wei
643
+ */
644
+ async addTokenBalanceOverride(
645
+ stateOverride: StateOverride,
646
+ chainId: number,
647
+ token: string,
648
+ account: string,
649
+ amount: bigint,
650
+ ): Promise<void> {
651
+ // get mapping slots
652
+ const tokenSlots = await this.getTokenStorageSlots(chainId, token);
653
+ // calculate balance slot
654
+ const slotToOverride = this.calculateAddressBalanceSlot(
655
+ tokenSlots.balanceSlot,
656
+ account,
657
+ tokenSlots.isVyper,
658
+ );
659
+ // add the balance override
660
+ stateOverride[token] ||= {};
661
+ stateOverride[token].storage ||= {};
662
+ stateOverride[token].storage[slotToOverride] =
663
+ ethers.utils.defaultAbiCoder.encode(['uint'], [amount]);
664
+ }
665
+
666
+ /**
667
+ * Adds token allowance override to an existing `StateOverride` object
668
+ * @param stateOverride object to add the override to
669
+ * @param chainId token chain ID
670
+ * @param token token address
671
+ * @param account owner address
672
+ * @param spender spender address
673
+ * @param amount token amount in wei
674
+ */
675
+ async addAllowanceOverride(
676
+ stateOverride: StateOverride,
677
+ chainId: number,
678
+ token: string,
679
+ account: string,
680
+ spender: string,
681
+ amount: bigint,
682
+ ): Promise<void> {
683
+ // get mapping slots
684
+ const tokenSlots = await this.getTokenStorageSlots(chainId, token);
685
+ // calculate allowance slot
686
+ const slotToOverride = this.calculateAddressAllowanceSlot(
687
+ tokenSlots.allowanceSlot,
688
+ account,
689
+ spender,
690
+ tokenSlots.isVyper,
691
+ );
692
+ // add the allowance override
693
+ stateOverride[token] ||= {};
694
+ stateOverride[token].storage ||= {};
695
+ stateOverride[token].storage[slotToOverride] =
696
+ ethers.utils.defaultAbiCoder.encode(['uint'], [amount]);
697
+ }
698
+ }