@paraswap/dex-lib 4.8.37-native-dex-math.1 → 4.8.37

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 (305) hide show
  1. package/build/abi/pancakeswap-infinity/cl-pool-manager.json +80 -0
  2. package/build/dex/aave-gsm/config.js +2 -2
  3. package/build/dex/fluid-dex/scripts/measure-calc-time.js +178 -0
  4. package/build/dex/fluid-dex/scripts/measure-calc-time.js.map +1 -0
  5. package/build/dex/idex.d.ts +1 -1
  6. package/build/dex/index.js +2 -0
  7. package/build/dex/index.js.map +1 -1
  8. package/build/dex/{infusion → pancakeswap-infinity}/config.d.ts +2 -2
  9. package/build/dex/pancakeswap-infinity/config.js +14 -0
  10. package/build/dex/pancakeswap-infinity/config.js.map +1 -0
  11. package/build/dex/pancakeswap-infinity/encoder.d.ts +4 -0
  12. package/build/dex/pancakeswap-infinity/encoder.js +218 -0
  13. package/build/dex/pancakeswap-infinity/encoder.js.map +1 -0
  14. package/build/dex/pancakeswap-infinity/pancakeswap-infinity.d.ts +21 -0
  15. package/build/dex/pancakeswap-infinity/pancakeswap-infinity.js +102 -0
  16. package/build/dex/pancakeswap-infinity/pancakeswap-infinity.js.map +1 -0
  17. package/build/dex/pancakeswap-infinity/subgraph.d.ts +7 -0
  18. package/build/dex/pancakeswap-infinity/subgraph.js +64 -0
  19. package/build/dex/pancakeswap-infinity/subgraph.js.map +1 -0
  20. package/build/dex/pancakeswap-infinity/types.d.ts +39 -0
  21. package/build/dex/pancakeswap-infinity/types.js.map +1 -0
  22. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.d.ts +0 -2
  23. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js +0 -5
  24. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js.map +1 -1
  25. package/build/dex/pancakeswap-v3/pancakeswap-v3.d.ts +3 -6
  26. package/build/dex/pancakeswap-v3/pancakeswap-v3.js +9 -85
  27. package/build/dex/pancakeswap-v3/pancakeswap-v3.js.map +1 -1
  28. package/build/dex/solidly-v3/solidly-v3-pool.d.ts +0 -3
  29. package/build/dex/solidly-v3/solidly-v3-pool.js +0 -8
  30. package/build/dex/solidly-v3/solidly-v3-pool.js.map +1 -1
  31. package/build/dex/solidly-v3/solidly-v3.d.ts +2 -5
  32. package/build/dex/solidly-v3/solidly-v3.js +8 -84
  33. package/build/dex/solidly-v3/solidly-v3.js.map +1 -1
  34. package/build/dex/uniswap-v3/scripts/measure-calc-time.js +110 -222
  35. package/build/dex/uniswap-v3/scripts/measure-calc-time.js.map +1 -1
  36. package/build/dex/uniswap-v3/types.d.ts +0 -1
  37. package/build/dex/uniswap-v3/types.js.map +1 -1
  38. package/build/dex/uniswap-v3/uniswap-v3-pool.d.ts +0 -2
  39. package/build/dex/uniswap-v3/uniswap-v3-pool.js +0 -5
  40. package/build/dex/uniswap-v3/uniswap-v3-pool.js.map +1 -1
  41. package/build/dex/uniswap-v3/uniswap-v3.d.ts +3 -11
  42. package/build/dex/uniswap-v3/uniswap-v3.js +9 -86
  43. package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
  44. package/build/dex/uniswap-v4/api-go/compare-pricing.d.ts +1 -0
  45. package/build/dex/uniswap-v4/api-go/compare-pricing.js +187 -0
  46. package/build/dex/uniswap-v4/api-go/compare-pricing.js.map +1 -0
  47. package/build/dex/uniswap-v4/api-go/compare-states.d.ts +1 -0
  48. package/build/dex/uniswap-v4/api-go/compare-states.js +149 -0
  49. package/build/dex/uniswap-v4/api-go/compare-states.js.map +1 -0
  50. package/build/dex/uniswap-v4/api-go/fetch-pool-key.d.ts +0 -0
  51. package/build/dex/uniswap-v4/api-go/fetch-pool-key.js +140 -0
  52. package/build/dex/uniswap-v4/api-go/fetch-pool-key.js.map +1 -0
  53. package/build/dex/uniswap-v4/types.d.ts +0 -1
  54. package/build/dex/uniswap-v4/uniswap-v4-pool-manager.d.ts +0 -2
  55. package/build/dex/uniswap-v4/uniswap-v4-pool-manager.js +0 -3
  56. package/build/dex/uniswap-v4/uniswap-v4-pool-manager.js.map +1 -1
  57. package/build/dex/uniswap-v4/uniswap-v4-pool.d.ts +0 -3
  58. package/build/dex/uniswap-v4/uniswap-v4-pool.js +0 -18
  59. package/build/dex/uniswap-v4/uniswap-v4-pool.js.map +1 -1
  60. package/build/dex/uniswap-v4/uniswap-v4.d.ts +1 -3
  61. package/build/dex/uniswap-v4/uniswap-v4.js +14 -74
  62. package/build/dex/uniswap-v4/uniswap-v4.js.map +1 -1
  63. package/build/pricing-helper.d.ts +1 -1
  64. package/build/pricing-helper.js +2 -2
  65. package/build/pricing-helper.js.map +1 -1
  66. package/package.json +3 -3
  67. package/build/abi/BProtocol.json +0 -1155
  68. package/build/abi/Jarvis.json +0 -1172
  69. package/build/abi/MStableAsset.json +0 -1545
  70. package/build/abi/OneInchLp.json +0 -1304
  71. package/build/abi/Onebit.json +0 -736
  72. package/build/abi/Shell.json +0 -1294
  73. package/build/abi/TraderJoeV2Router.json +0 -50
  74. package/build/abi/idle-dao/idle-cdo-factory.json +0 -38
  75. package/build/abi/idle-dao/idle-cdo.json +0 -1245
  76. package/build/abi/infusion/InfusionFactory.json +0 -147
  77. package/build/abi/infusion/InfusionPair.json +0 -658
  78. package/build/abi/infusion/InfusionRouter.json +0 -442
  79. package/build/abi/maker-psm/pot.json +0 -322
  80. package/build/abi/maker-psm/psm.json +0 -243
  81. package/build/abi/maker-psm/vat.json +0 -363
  82. package/build/abi/nomiswap-v2/nomiswap-v2-pool.json +0 -773
  83. package/build/abi/quick-perps/fast-price-events.json +0 -70
  84. package/build/abi/quick-perps/fast-price-feed.json +0 -741
  85. package/build/abi/quick-perps/reader.json +0 -313
  86. package/build/abi/quick-perps/vault-price-feed.json +0 -323
  87. package/build/abi/quick-perps/vault.json +0 -1953
  88. package/build/abi/uniswap-v2/excalibur-pool.json +0 -881
  89. package/build/abi/uniswap-v2/mdex-factory.json +0 -759
  90. package/build/abi/wUSDM.json +0 -757
  91. package/build/abi/zrx.v2.json +0 -1967
  92. package/build/abi/zrx.v3.json +0 -3454
  93. package/build/abi/zrx.v4.json +0 -2193
  94. package/build/dex/OneInchLp.d.ts +0 -24
  95. package/build/dex/OneInchLp.js +0 -43
  96. package/build/dex/OneInchLp.js.map +0 -1
  97. package/build/dex/bProtocol/bProtocol.d.ts +0 -15
  98. package/build/dex/bProtocol/bProtocol.js +0 -56
  99. package/build/dex/bProtocol/bProtocol.js.map +0 -1
  100. package/build/dex/bProtocol/types.d.ts +0 -11
  101. package/build/dex/bProtocol/types.js +0 -8
  102. package/build/dex/bProtocol/types.js.map +0 -1
  103. package/build/dex/ekubo/pools/base-pool.d.ts +0 -47
  104. package/build/dex/ekubo/pools/base-pool.js +0 -184
  105. package/build/dex/ekubo/pools/base-pool.js.map +0 -1
  106. package/build/dex/ekubo/pools/iface.d.ts +0 -46
  107. package/build/dex/ekubo/pools/iface.js +0 -75
  108. package/build/dex/ekubo/pools/iface.js.map +0 -1
  109. package/build/dex/ekubo/pools/math/price.d.ts +0 -7
  110. package/build/dex/ekubo/pools/math/price.js +0 -112
  111. package/build/dex/ekubo/pools/math/price.js.map +0 -1
  112. package/build/dex/ekubo/pools/oracle-pool.d.ts +0 -10
  113. package/build/dex/ekubo/pools/oracle-pool.js +0 -19
  114. package/build/dex/ekubo/pools/oracle-pool.js.map +0 -1
  115. package/build/dex/ekubo/pools/pool-utils.d.ts +0 -44
  116. package/build/dex/ekubo/pools/pool-utils.js +0 -240
  117. package/build/dex/ekubo/pools/pool-utils.js.map +0 -1
  118. package/build/dex/idle-dao/config.d.ts +0 -5
  119. package/build/dex/idle-dao/config.js +0 -24
  120. package/build/dex/idle-dao/config.js.map +0 -1
  121. package/build/dex/idle-dao/idle-dao.d.ts +0 -42
  122. package/build/dex/idle-dao/idle-dao.js +0 -279
  123. package/build/dex/idle-dao/idle-dao.js.map +0 -1
  124. package/build/dex/idle-dao/token_list.d.ts +0 -4
  125. package/build/dex/idle-dao/token_list.js +0 -289
  126. package/build/dex/idle-dao/token_list.js.map +0 -1
  127. package/build/dex/idle-dao/tokens.d.ts +0 -9
  128. package/build/dex/idle-dao/tokens.js +0 -68
  129. package/build/dex/idle-dao/tokens.js.map +0 -1
  130. package/build/dex/idle-dao/types.d.ts +0 -35
  131. package/build/dex/idle-dao/types.js +0 -11
  132. package/build/dex/idle-dao/types.js.map +0 -1
  133. package/build/dex/idle-dao/utils.d.ts +0 -8
  134. package/build/dex/idle-dao/utils.js +0 -149
  135. package/build/dex/idle-dao/utils.js.map +0 -1
  136. package/build/dex/infusion/config.js +0 -20
  137. package/build/dex/infusion/config.js.map +0 -1
  138. package/build/dex/infusion/infusion-stable-pool.d.ts +0 -4
  139. package/build/dex/infusion/infusion-stable-pool.js +0 -74
  140. package/build/dex/infusion/infusion-stable-pool.js.map +0 -1
  141. package/build/dex/infusion/infusion.d.ts +0 -51
  142. package/build/dex/infusion/infusion.js +0 -500
  143. package/build/dex/infusion/infusion.js.map +0 -1
  144. package/build/dex/infusion/types.d.ts +0 -45
  145. package/build/dex/infusion/types.js.map +0 -1
  146. package/build/dex/infusion/utils/isStablePair.d.ts +0 -2
  147. package/build/dex/infusion/utils/isStablePair.js +0 -18
  148. package/build/dex/infusion/utils/isStablePair.js.map +0 -1
  149. package/build/dex/jarvis.d.ts +0 -56
  150. package/build/dex/jarvis.js +0 -163
  151. package/build/dex/jarvis.js.map +0 -1
  152. package/build/dex/mStable.d.ts +0 -44
  153. package/build/dex/mStable.js +0 -75
  154. package/build/dex/mStable.js.map +0 -1
  155. package/build/dex/maker-psm/config.d.ts +0 -11
  156. package/build/dex/maker-psm/config.js +0 -53
  157. package/build/dex/maker-psm/config.js.map +0 -1
  158. package/build/dex/maker-psm/maker-psm.d.ts +0 -103
  159. package/build/dex/maker-psm/maker-psm.js +0 -493
  160. package/build/dex/maker-psm/maker-psm.js.map +0 -1
  161. package/build/dex/maker-psm/types.d.ts +0 -39
  162. package/build/dex/maker-psm/types.js +0 -3
  163. package/build/dex/maker-psm/types.js.map +0 -1
  164. package/build/dex/onebit/onebit.d.ts +0 -16
  165. package/build/dex/onebit/onebit.js +0 -61
  166. package/build/dex/onebit/onebit.js.map +0 -1
  167. package/build/dex/onebit/types.d.ts +0 -14
  168. package/build/dex/onebit/types.js +0 -8
  169. package/build/dex/onebit/types.js.map +0 -1
  170. package/build/dex/quick-perps/config.d.ts +0 -11
  171. package/build/dex/quick-perps/config.js +0 -27
  172. package/build/dex/quick-perps/config.js.map +0 -1
  173. package/build/dex/quick-perps/fast-price-feed.d.ts +0 -26
  174. package/build/dex/quick-perps/fast-price-feed.js +0 -184
  175. package/build/dex/quick-perps/fast-price-feed.js.map +0 -1
  176. package/build/dex/quick-perps/pool.d.ts +0 -21
  177. package/build/dex/quick-perps/pool.js +0 -229
  178. package/build/dex/quick-perps/pool.js.map +0 -1
  179. package/build/dex/quick-perps/quick-perps.d.ts +0 -53
  180. package/build/dex/quick-perps/quick-perps.js +0 -247
  181. package/build/dex/quick-perps/quick-perps.js.map +0 -1
  182. package/build/dex/quick-perps/types.d.ts +0 -98
  183. package/build/dex/quick-perps/types.js +0 -3
  184. package/build/dex/quick-perps/types.js.map +0 -1
  185. package/build/dex/quick-perps/usdq.d.ts +0 -15
  186. package/build/dex/quick-perps/usdq.js +0 -62
  187. package/build/dex/quick-perps/usdq.js.map +0 -1
  188. package/build/dex/quick-perps/vault-price-feed.d.ts +0 -43
  189. package/build/dex/quick-perps/vault-price-feed.js +0 -203
  190. package/build/dex/quick-perps/vault-price-feed.js.map +0 -1
  191. package/build/dex/quick-perps/vault-utils.d.ts +0 -8
  192. package/build/dex/quick-perps/vault-utils.js +0 -42
  193. package/build/dex/quick-perps/vault-utils.js.map +0 -1
  194. package/build/dex/quick-perps/vault.d.ts +0 -46
  195. package/build/dex/quick-perps/vault.js +0 -182
  196. package/build/dex/quick-perps/vault.js.map +0 -1
  197. package/build/dex/se-vlr/config.d.ts +0 -3
  198. package/build/dex/se-vlr/config.js +0 -24
  199. package/build/dex/se-vlr/config.js.map +0 -1
  200. package/build/dex/se-vlr/se-vlr-pool.d.ts +0 -39
  201. package/build/dex/se-vlr/se-vlr-pool.js +0 -70
  202. package/build/dex/se-vlr/se-vlr-pool.js.map +0 -1
  203. package/build/dex/se-vlr/se-vlr.d.ts +0 -35
  204. package/build/dex/se-vlr/se-vlr.js +0 -131
  205. package/build/dex/se-vlr/se-vlr.js.map +0 -1
  206. package/build/dex/se-vlr/types.d.ts +0 -6
  207. package/build/dex/se-vlr/types.js +0 -3
  208. package/build/dex/se-vlr/types.js.map +0 -1
  209. package/build/dex/shell.d.ts +0 -25
  210. package/build/dex/shell.js +0 -41
  211. package/build/dex/shell.js.map +0 -1
  212. package/build/dex/solidly/forks-override/aerodrome.d.ts +0 -14
  213. package/build/dex/solidly/forks-override/aerodrome.js +0 -46
  214. package/build/dex/solidly/forks-override/aerodrome.js.map +0 -1
  215. package/build/dex/solidly/forks-override/chronos.d.ts +0 -23
  216. package/build/dex/solidly/forks-override/chronos.js +0 -141
  217. package/build/dex/solidly/forks-override/chronos.js.map +0 -1
  218. package/build/dex/solidly/forks-override/usdfi.d.ts +0 -8
  219. package/build/dex/solidly/forks-override/usdfi.js +0 -15
  220. package/build/dex/solidly/forks-override/usdfi.js.map +0 -1
  221. package/build/dex/solidly/forks-override/velocimeter.d.ts +0 -23
  222. package/build/dex/solidly/forks-override/velocimeter.js +0 -77
  223. package/build/dex/solidly/forks-override/velocimeter.js.map +0 -1
  224. package/build/dex/trader-joe-v2.d.ts +0 -40
  225. package/build/dex/trader-joe-v2.js +0 -74
  226. package/build/dex/trader-joe-v2.js.map +0 -1
  227. package/build/dex/uniswap-v2/dfyn.d.ts +0 -19
  228. package/build/dex/uniswap-v2/dfyn.js +0 -61
  229. package/build/dex/uniswap-v2/dfyn.js.map +0 -1
  230. package/build/dex/uniswap-v2/excalibur.d.ts +0 -24
  231. package/build/dex/uniswap-v2/excalibur.js +0 -47
  232. package/build/dex/uniswap-v2/excalibur.js.map +0 -1
  233. package/build/dex/uniswap-v2/mdex.d.ts +0 -24
  234. package/build/dex/uniswap-v2/mdex.js +0 -50
  235. package/build/dex/uniswap-v2/mdex.js.map +0 -1
  236. package/build/dex/uniswap-v2/nomiswap-v2.d.ts +0 -24
  237. package/build/dex/uniswap-v2/nomiswap-v2.js +0 -57
  238. package/build/dex/uniswap-v2/nomiswap-v2.js.map +0 -1
  239. package/build/dex/uniswap-v3/scripts/bench-all-dexes.js +0 -160
  240. package/build/dex/uniswap-v3/scripts/bench-all-dexes.js.map +0 -1
  241. package/build/dex/uniswap-v3/uniswap-v3-new.d.ts +0 -94
  242. package/build/dex/uniswap-v3/uniswap-v3-new.js +0 -923
  243. package/build/dex/uniswap-v3/uniswap-v3-new.js.map +0 -1
  244. package/build/dex/uniswap-v4/contract-math/Position.d.ts +0 -3
  245. package/build/dex/uniswap-v4/contract-math/Position.js +0 -10
  246. package/build/dex/uniswap-v4/contract-math/Position.js.map +0 -1
  247. package/build/dex/usual-bond/config.d.ts +0 -3
  248. package/build/dex/usual-bond/config.js +0 -13
  249. package/build/dex/usual-bond/config.js.map +0 -1
  250. package/build/dex/usual-bond/types.d.ts +0 -7
  251. package/build/dex/usual-bond/types.js +0 -3
  252. package/build/dex/usual-bond/types.js.map +0 -1
  253. package/build/dex/usual-bond/usual-bond.d.ts +0 -35
  254. package/build/dex/usual-bond/usual-bond.js +0 -176
  255. package/build/dex/usual-bond/usual-bond.js.map +0 -1
  256. package/build/dex/wusdm/config.d.ts +0 -3
  257. package/build/dex/wusdm/config.js +0 -43
  258. package/build/dex/wusdm/config.js.map +0 -1
  259. package/build/dex/wusdm/constants.d.ts +0 -2
  260. package/build/dex/wusdm/constants.js +0 -6
  261. package/build/dex/wusdm/constants.js.map +0 -1
  262. package/build/dex/wusdm/types.d.ts +0 -18
  263. package/build/dex/wusdm/types.js +0 -11
  264. package/build/dex/wusdm/types.js.map +0 -1
  265. package/build/dex/wusdm/wusdm-pool.d.ts +0 -21
  266. package/build/dex/wusdm/wusdm-pool.js +0 -74
  267. package/build/dex/wusdm/wusdm-pool.js.map +0 -1
  268. package/build/dex/wusdm/wusdm.d.ts +0 -46
  269. package/build/dex/wusdm/wusdm.js +0 -243
  270. package/build/dex/wusdm/wusdm.js.map +0 -1
  271. package/build/dex/zerox/config.d.ts +0 -2
  272. package/build/dex/zerox/config.js +0 -33
  273. package/build/dex/zerox/config.js.map +0 -1
  274. package/build/dex/zerox/index.d.ts +0 -22
  275. package/build/dex/zerox/index.js +0 -225
  276. package/build/dex/zerox/index.js.map +0 -1
  277. package/build/dex/zerox/order.d.ts +0 -88
  278. package/build/dex/zerox/order.js +0 -53
  279. package/build/dex/zerox/order.js.map +0 -1
  280. package/build/dex/zerox/types.d.ts +0 -73
  281. package/build/dex/zerox/types.js +0 -21
  282. package/build/dex/zerox/types.js.map +0 -1
  283. package/native/Cargo.lock +0 -331
  284. package/native/Cargo.toml +0 -22
  285. package/native/build.rs +0 -5
  286. package/native/package-lock.json +0 -32
  287. package/native/package.json +0 -20
  288. package/native/src/config.rs +0 -73
  289. package/native/src/lib.rs +0 -528
  290. package/native/src/math/bit_math.rs +0 -177
  291. package/native/src/math/full_math.rs +0 -217
  292. package/native/src/math/liquidity_math.rs +0 -72
  293. package/native/src/math/mod.rs +0 -10
  294. package/native/src/math/oracle.rs +0 -493
  295. package/native/src/math/sqrt_price_math.rs +0 -272
  296. package/native/src/math/swap_math.rs +0 -306
  297. package/native/src/math/tick.rs +0 -239
  298. package/native/src/math/tick_bitmap.rs +0 -312
  299. package/native/src/math/tick_math.rs +0 -321
  300. package/native/src/math/unsafe_math.rs +0 -67
  301. package/native/src/pool_state.rs +0 -41
  302. package/native/src/query_outputs.rs +0 -379
  303. package/native/src/v4_query_outputs.rs +0 -255
  304. /package/build/dex/{uniswap-v3/scripts/bench-all-dexes.d.ts → fluid-dex/scripts/measure-calc-time.d.ts} +0 -0
  305. /package/build/dex/{infusion → pancakeswap-infinity}/types.js +0 -0
@@ -1,493 +0,0 @@
1
- use ethnum::{I256, U256};
2
- use std::collections::HashMap;
3
-
4
- // 2^160 - 1: hi_128 = 0xFFFFFFFF, lo_128 = u128::MAX
5
- const MASK_160: U256 = U256::from_words(0xFFFF_FFFF, u128::MAX);
6
-
7
- /// An oracle observation.
8
- #[derive(Debug, Clone, Copy, PartialEq, Eq)]
9
- pub struct OracleObservation {
10
- pub block_timestamp: U256,
11
- pub tick_cumulative: I256,
12
- pub seconds_per_liquidity_cumulative_x128: U256,
13
- pub initialized: bool,
14
- }
15
-
16
- impl Default for OracleObservation {
17
- fn default() -> Self {
18
- OracleObservation {
19
- block_timestamp: U256::ZERO,
20
- tick_cumulative: I256::ZERO,
21
- seconds_per_liquidity_cumulative_x128: U256::ZERO,
22
- initialized: false,
23
- }
24
- }
25
- }
26
-
27
- /// Observation candidate pair used in binary search.
28
- pub struct OracleObservationCandidates {
29
- pub before_or_at: OracleObservation,
30
- pub at_or_after: OracleObservation,
31
- }
32
-
33
- /// Transforms a previous observation into a new one, given the time elapsed and the
34
- /// current tick and liquidity values.
35
- ///
36
- /// The `block_timestamp` parameter corresponds to `state.blockTimestamp` in the TS version.
37
- /// In the original TS, `transform` receives `state` and uses `state.blockTimestamp` for the
38
- /// output's blockTimestamp. Here we pass it explicitly as `block_timestamp_state`.
39
- pub fn transform(
40
- last: &OracleObservation,
41
- block_timestamp: U256,
42
- block_timestamp_state: U256,
43
- tick: I256,
44
- liquidity: U256,
45
- ) -> OracleObservation {
46
- let delta = block_timestamp - last.block_timestamp;
47
-
48
- // tickCumulative: last.tickCumulative + BigInt.asIntN(56, tick) * delta
49
- let tick_i56 = sign_extend_i56(tick);
50
- let delta_signed = delta.as_i256();
51
- let tick_cumulative = last.tick_cumulative + tick_i56 * delta_signed;
52
-
53
- // secondsPerLiquidityCumulativeX128:
54
- // last.spl + (BigInt.asUintN(160, delta) << 128) / (liquidity > 0 ? liquidity : 1)
55
- let delta_u160 = delta & MASK_160;
56
- let numerator = delta_u160 << 128;
57
- let denominator = if liquidity > U256::ZERO {
58
- liquidity
59
- } else {
60
- U256::ONE
61
- };
62
- let seconds_per_liquidity_cumulative_x128 =
63
- last.seconds_per_liquidity_cumulative_x128 + numerator / denominator;
64
-
65
- OracleObservation {
66
- block_timestamp: block_timestamp_state,
67
- tick_cumulative,
68
- seconds_per_liquidity_cumulative_x128,
69
- initialized: true,
70
- }
71
- }
72
-
73
- /// Writes an oracle observation to the array, returning the updated index and cardinality.
74
- ///
75
- /// `block_timestamp_state` is the state's block timestamp (used for comparison and as the
76
- /// new observation's timestamp).
77
- ///
78
- /// Returns `(updated_index, updated_cardinality)`.
79
- pub fn write(
80
- observations: &mut HashMap<u16, OracleObservation>,
81
- index: u16,
82
- block_timestamp: U256,
83
- block_timestamp_state: U256,
84
- tick: I256,
85
- liquidity: U256,
86
- cardinality: u16,
87
- cardinality_next: u16,
88
- ) -> (u16, u16) {
89
- let last = observations
90
- .get(&index)
91
- .copied()
92
- .expect("last observation must exist");
93
-
94
- // If the block timestamp hasn't changed, no update needed
95
- if last.block_timestamp == block_timestamp_state {
96
- return (index, cardinality);
97
- }
98
-
99
- let cardinality_updated = if cardinality_next > cardinality && index == cardinality - 1 {
100
- cardinality_next
101
- } else {
102
- cardinality
103
- };
104
-
105
- let index_updated = ((index as u32 + 1) % cardinality_updated as u32) as u16;
106
-
107
- let new_observation = transform(&last, block_timestamp, block_timestamp_state, tick, liquidity);
108
- observations.insert(index_updated, new_observation);
109
-
110
- // In the TS code, if indexUpdated !== index, the old index is deleted
111
- if index_updated != index {
112
- observations.remove(&index);
113
- }
114
-
115
- (index_updated, cardinality_updated)
116
- }
117
-
118
- /// Compares two timestamps with overflow-aware less-than-or-equal.
119
- ///
120
- /// This handles the uint32 overflow case: if both timestamps are <= time, compare normally.
121
- /// Otherwise, adjust the one that hasn't overflowed by adding 2^32.
122
- pub fn lte(time: U256, a: U256, b: U256) -> bool {
123
- if a <= time && b <= time {
124
- return a <= b;
125
- }
126
-
127
- let two_pow_32 = U256::ONE << 32;
128
- let a_adjusted = if a > time { a } else { a + two_pow_32 };
129
- let b_adjusted = if b > time { b } else { b + two_pow_32 };
130
- a_adjusted <= b_adjusted
131
- }
132
-
133
- /// Binary search for the observations surrounding a target timestamp.
134
- pub fn binary_search(
135
- observations: &HashMap<u16, OracleObservation>,
136
- time: U256,
137
- target: U256,
138
- index: u16,
139
- cardinality: u16,
140
- ) -> OracleObservationCandidates {
141
- let mut l = ((index as u32 + 1) % cardinality as u32) as u32;
142
- let mut r = l + cardinality as u32 - 1;
143
-
144
- loop {
145
- let i = (l + r) / 2;
146
- let idx = (i % cardinality as u32) as u16;
147
- let before_or_at = observations
148
- .get(&idx)
149
- .copied()
150
- .unwrap_or_default();
151
-
152
- if !before_or_at.initialized {
153
- l = i + 1;
154
- continue;
155
- }
156
-
157
- let after_idx = ((i + 1) % cardinality as u32) as u16;
158
- let at_or_after = observations
159
- .get(&after_idx)
160
- .copied()
161
- .unwrap_or_default();
162
-
163
- let target_at_or_after = lte(time, before_or_at.block_timestamp, target);
164
-
165
- if target_at_or_after && lte(time, target, at_or_after.block_timestamp) {
166
- return OracleObservationCandidates {
167
- before_or_at,
168
- at_or_after,
169
- };
170
- }
171
-
172
- if !target_at_or_after {
173
- r = i - 1;
174
- } else {
175
- l = i + 1;
176
- }
177
- }
178
- }
179
-
180
- /// Returns the observations surrounding a target timestamp.
181
- ///
182
- /// `block_timestamp_state` is the state's block timestamp used for transform.
183
- pub fn get_surrounding_observations(
184
- observations: &HashMap<u16, OracleObservation>,
185
- time: U256,
186
- target: U256,
187
- block_timestamp_state: U256,
188
- tick: I256,
189
- index: u16,
190
- liquidity: U256,
191
- cardinality: u16,
192
- ) -> OracleObservationCandidates {
193
- let before_or_at = observations
194
- .get(&index)
195
- .copied()
196
- .unwrap_or_default();
197
-
198
- if lte(time, before_or_at.block_timestamp, target) {
199
- if before_or_at.block_timestamp == target {
200
- return OracleObservationCandidates {
201
- before_or_at,
202
- at_or_after: before_or_at,
203
- };
204
- } else {
205
- let at_or_after = transform(
206
- &before_or_at,
207
- target,
208
- block_timestamp_state,
209
- tick,
210
- liquidity,
211
- );
212
- return OracleObservationCandidates {
213
- before_or_at,
214
- at_or_after,
215
- };
216
- }
217
- }
218
-
219
- let oldest_idx = ((index as u32 + 1) % cardinality as u32) as u16;
220
- let mut before_or_at = observations
221
- .get(&oldest_idx)
222
- .copied()
223
- .unwrap_or_default();
224
-
225
- if !before_or_at.initialized {
226
- before_or_at = observations.get(&0u16).copied().unwrap_or_default();
227
- }
228
-
229
- assert!(
230
- lte(time, before_or_at.block_timestamp, target),
231
- "OLD"
232
- );
233
-
234
- binary_search(observations, time, target, index, cardinality)
235
- }
236
-
237
- /// Returns the accumulator values as of `secondsAgo` seconds ago from the given time.
238
- ///
239
- /// `block_timestamp_state` is the state's block timestamp.
240
- ///
241
- /// Returns `(tick_cumulative, seconds_per_liquidity_cumulative_x128)`.
242
- pub fn observe_single(
243
- observations: &HashMap<u16, OracleObservation>,
244
- time: U256,
245
- seconds_ago: U256,
246
- block_timestamp_state: U256,
247
- tick: I256,
248
- index: u16,
249
- liquidity: U256,
250
- cardinality: u16,
251
- ) -> (I256, U256) {
252
- if seconds_ago == U256::ZERO {
253
- let mut last = observations
254
- .get(&index)
255
- .copied()
256
- .unwrap_or_default();
257
- if last.block_timestamp != time {
258
- last = transform(&last, time, block_timestamp_state, tick, liquidity);
259
- }
260
- return (
261
- last.tick_cumulative,
262
- last.seconds_per_liquidity_cumulative_x128,
263
- );
264
- }
265
-
266
- let target = time - seconds_ago;
267
-
268
- let OracleObservationCandidates {
269
- before_or_at,
270
- at_or_after,
271
- } = get_surrounding_observations(
272
- observations,
273
- time,
274
- target,
275
- block_timestamp_state,
276
- tick,
277
- index,
278
- liquidity,
279
- cardinality,
280
- );
281
-
282
- if target == before_or_at.block_timestamp {
283
- return (
284
- before_or_at.tick_cumulative,
285
- before_or_at.seconds_per_liquidity_cumulative_x128,
286
- );
287
- } else if target == at_or_after.block_timestamp {
288
- return (
289
- at_or_after.tick_cumulative,
290
- at_or_after.seconds_per_liquidity_cumulative_x128,
291
- );
292
- } else {
293
- let observation_time_delta =
294
- at_or_after.block_timestamp - before_or_at.block_timestamp;
295
- let target_delta = target - before_or_at.block_timestamp;
296
- let observation_time_delta_signed = observation_time_delta.as_i256();
297
- let target_delta_signed = target_delta.as_i256();
298
-
299
- let tick_cumulative = before_or_at.tick_cumulative
300
- + ((at_or_after.tick_cumulative - before_or_at.tick_cumulative)
301
- / observation_time_delta_signed)
302
- * target_delta_signed;
303
-
304
- // secondsPerLiquidityCumulativeX128 interpolation:
305
- // beforeOrAt.spl + BigInt.asUintN(160,
306
- // (BigInt.asUintN(256, atOrAfter.spl - beforeOrAt.spl) * targetDelta) / observationTimeDelta
307
- // )
308
- let spl_diff = at_or_after.seconds_per_liquidity_cumulative_x128
309
- .wrapping_sub(before_or_at.seconds_per_liquidity_cumulative_x128);
310
- let spl_interpolated = (spl_diff * target_delta) / observation_time_delta;
311
- let spl_masked = spl_interpolated & MASK_160;
312
- let seconds_per_liquidity_cumulative_x128 =
313
- before_or_at.seconds_per_liquidity_cumulative_x128 + spl_masked;
314
-
315
- return (tick_cumulative, seconds_per_liquidity_cumulative_x128);
316
- }
317
- }
318
-
319
- /// Sign-extend a value to signed 56-bit (equivalent to BigInt.asIntN(56, x)).
320
- fn sign_extend_i56(val: I256) -> I256 {
321
- let mask: I256 = (I256::ONE << 56) - I256::ONE;
322
- let masked = val & mask;
323
- if masked & (I256::ONE << 55) != I256::ZERO {
324
- masked | !mask
325
- } else {
326
- masked
327
- }
328
- }
329
-
330
- #[cfg(test)]
331
- mod tests {
332
- use super::*;
333
-
334
- fn make_obs(
335
- block_timestamp: u64,
336
- tick_cumulative: i64,
337
- spl: u64,
338
- initialized: bool,
339
- ) -> OracleObservation {
340
- OracleObservation {
341
- block_timestamp: U256::from(block_timestamp),
342
- tick_cumulative: I256::from(tick_cumulative),
343
- seconds_per_liquidity_cumulative_x128: U256::from(spl),
344
- initialized,
345
- }
346
- }
347
-
348
- #[test]
349
- fn test_lte_both_below_time() {
350
- assert!(lte(U256::from(100u64), U256::from(50u64), U256::from(60u64)));
351
- assert!(!lte(U256::from(100u64), U256::from(60u64), U256::from(50u64)));
352
- }
353
-
354
- #[test]
355
- fn test_lte_equal() {
356
- assert!(lte(U256::from(100u64), U256::from(50u64), U256::from(50u64)));
357
- }
358
-
359
- #[test]
360
- fn test_lte_overflow_case() {
361
- // a is past overflow, b is before overflow
362
- // time = 10, a = 5 (not overflowed), b = 15 (overflowed past time)
363
- // a <= time? yes. b <= time? no.
364
- // a_adjusted = 5 + 2^32, b_adjusted = 15
365
- // 5 + 2^32 > 15, so a is NOT <= b
366
- assert!(!lte(U256::from(10u64), U256::from(5u64), U256::from(15u64)));
367
- }
368
-
369
- #[test]
370
- fn test_transform_basic() {
371
- let last = make_obs(100, 5000, 10000, true);
372
- let result = transform(
373
- &last,
374
- U256::from(110u64), // blockTimestamp
375
- U256::from(110u64), // state.blockTimestamp
376
- I256::from(50i64), // tick
377
- U256::from(1000u64), // liquidity
378
- );
379
- assert_eq!(result.block_timestamp, U256::from(110u64));
380
- // tickCumulative = 5000 + 50 * 10 = 5500
381
- assert_eq!(result.tick_cumulative, I256::from(5500i64));
382
- assert!(result.initialized);
383
- }
384
-
385
- #[test]
386
- fn test_transform_zero_liquidity() {
387
- let last = make_obs(100, 0, 0, true);
388
- let result = transform(
389
- &last,
390
- U256::from(110u64),
391
- U256::from(110u64),
392
- I256::from(10i64),
393
- U256::ZERO, // zero liquidity => denominator becomes 1
394
- );
395
- // tickCumulative = 0 + 10 * 10 = 100
396
- assert_eq!(result.tick_cumulative, I256::from(100i64));
397
- // secondsPerLiquidity = 0 + (10 << 128) / 1 = 10 << 128
398
- let expected_spl = U256::from(10u64) << 128;
399
- assert_eq!(result.seconds_per_liquidity_cumulative_x128, expected_spl);
400
- }
401
-
402
- #[test]
403
- fn test_write_same_timestamp_noop() {
404
- let mut observations = HashMap::new();
405
- observations.insert(0u16, make_obs(100, 0, 0, true));
406
-
407
- let (idx, card) = write(
408
- &mut observations,
409
- 0, // index
410
- U256::from(100u64), // blockTimestamp
411
- U256::from(100u64), // state.blockTimestamp (same)
412
- I256::from(10i64),
413
- U256::from(1000u64),
414
- 1, // cardinality
415
- 1, // cardinalityNext
416
- );
417
- assert_eq!(idx, 0);
418
- assert_eq!(card, 1);
419
- }
420
-
421
- #[test]
422
- fn test_write_new_observation() {
423
- let mut observations = HashMap::new();
424
- observations.insert(0u16, make_obs(100, 0, 0, true));
425
-
426
- let (idx, card) = write(
427
- &mut observations,
428
- 0,
429
- U256::from(110u64),
430
- U256::from(110u64),
431
- I256::from(10i64),
432
- U256::from(1000u64),
433
- 1,
434
- 2,
435
- );
436
- // cardinality should increase because cardinalityNext > cardinality and index == cardinality - 1
437
- assert_eq!(card, 2);
438
- assert_eq!(idx, 1);
439
- assert!(observations.get(&1u16).unwrap().initialized);
440
- }
441
-
442
- #[test]
443
- fn test_observe_single_zero_seconds_ago() {
444
- let mut observations = HashMap::new();
445
- observations.insert(0u16, make_obs(100, 5000, 10000, true));
446
-
447
- let (tick_cum, spl) = observe_single(
448
- &observations,
449
- U256::from(100u64),
450
- U256::ZERO,
451
- U256::from(100u64),
452
- I256::from(50i64),
453
- 0,
454
- U256::from(1000u64),
455
- 1,
456
- );
457
- // secondsAgo == 0 and last.blockTimestamp == time, so return last values directly
458
- assert_eq!(tick_cum, I256::from(5000i64));
459
- assert_eq!(spl, U256::from(10000u64));
460
- }
461
-
462
- #[test]
463
- fn test_observe_single_transforms_when_timestamp_differs() {
464
- let mut observations = HashMap::new();
465
- observations.insert(0u16, make_obs(100, 5000, 10000, true));
466
-
467
- let (tick_cum, _spl) = observe_single(
468
- &observations,
469
- U256::from(110u64), // current time
470
- U256::ZERO, // secondsAgo = 0
471
- U256::from(110u64),
472
- I256::from(50i64), // current tick
473
- 0,
474
- U256::from(1000u64),
475
- 1,
476
- );
477
- // Should transform: tickCumulative = 5000 + 50 * 10 = 5500
478
- assert_eq!(tick_cum, I256::from(5500i64));
479
- }
480
-
481
- #[test]
482
- fn test_sign_extend_i56_positive() {
483
- let val = I256::from(42i64);
484
- assert_eq!(sign_extend_i56(val), I256::from(42i64));
485
- }
486
-
487
- #[test]
488
- fn test_sign_extend_i56_negative() {
489
- let val = I256::from(-1i64);
490
- let result = sign_extend_i56(val);
491
- assert_eq!(result, I256::from(-1i64));
492
- }
493
- }