@paraswap/dex-lib 2.16.8-pancakeswapv3.0 → 2.17.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 (198) 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/vcs.xml +6 -0
  8. package/build/abi/woo-fi/WooFeeManager.abi.json +318 -0
  9. package/build/abi/woo-fi/WooPP.abi.json +548 -0
  10. package/build/abi/woo-fi/Wooracle.abi.json +260 -0
  11. package/build/config.js +4 -4
  12. package/build/dex/aave-v3/tokens/arbitrum.json +50 -0
  13. package/build/dex/aave-v3/tokens/avalanche.json +74 -0
  14. package/build/dex/aave-v3/tokens/fantom.json +62 -0
  15. package/build/dex/aave-v3/tokens/optimism.json +50 -0
  16. package/build/dex/aave-v3/tokens/polygon.json +116 -0
  17. package/build/dex/balancer-v2/balancer-v2.d.ts +14 -19
  18. package/build/dex/balancer-v2/balancer-v2.js +27 -22
  19. package/build/dex/balancer-v2/balancer-v2.js.map +1 -1
  20. package/build/dex/balancer-v2/config.d.ts +2 -7
  21. package/build/dex/balancer-v2/config.js +20 -30
  22. package/build/dex/balancer-v2/config.js.map +1 -1
  23. package/build/dex/balancer-v2/pools/balancer-v2-pool.d.ts +25 -0
  24. package/build/dex/balancer-v2/pools/balancer-v2-pool.js +107 -0
  25. package/build/dex/balancer-v2/pools/balancer-v2-pool.js.map +1 -0
  26. package/build/dex/balancer-v2/pools/linear/LinearMath.d.ts +20 -0
  27. package/build/dex/balancer-v2/pools/linear/LinearMath.js +179 -0
  28. package/build/dex/balancer-v2/pools/linear/LinearMath.js.map +1 -0
  29. package/build/dex/balancer-v2/pools/linear/LinearPool.d.ts +50 -0
  30. package/build/dex/balancer-v2/pools/linear/LinearPool.js +458 -0
  31. package/build/dex/balancer-v2/pools/linear/LinearPool.js.map +1 -0
  32. package/build/dex/balancer-v2/pools/phantom-stable/PhantomStableMath.d.ts +10 -0
  33. package/build/dex/balancer-v2/pools/phantom-stable/PhantomStableMath.js +314 -0
  34. package/build/dex/balancer-v2/pools/phantom-stable/PhantomStableMath.js.map +1 -0
  35. package/build/dex/balancer-v2/pools/phantom-stable/PhantomStablePool.d.ts +50 -0
  36. package/build/dex/balancer-v2/pools/phantom-stable/PhantomStablePool.js +367 -0
  37. package/build/dex/balancer-v2/pools/phantom-stable/PhantomStablePool.js.map +1 -0
  38. package/build/dex/balancer-v2/pools/stable/StableMath.d.ts +7 -0
  39. package/build/dex/balancer-v2/pools/stable/StableMath.js +111 -0
  40. package/build/dex/balancer-v2/pools/stable/StableMath.js.map +1 -0
  41. package/build/dex/balancer-v2/pools/stable/StablePool.d.ts +30 -0
  42. package/build/dex/balancer-v2/pools/stable/StablePool.js +129 -0
  43. package/build/dex/balancer-v2/pools/stable/StablePool.js.map +1 -0
  44. package/build/dex/balancer-v2/pools/weighted/WeightedMath.d.ts +6 -0
  45. package/build/dex/balancer-v2/pools/weighted/WeightedMath.js +61 -0
  46. package/build/dex/balancer-v2/pools/weighted/WeightedMath.js.map +1 -0
  47. package/build/dex/balancer-v2/pools/weighted/WeightedPool.d.ts +30 -0
  48. package/build/dex/balancer-v2/pools/weighted/WeightedPool.js +112 -0
  49. package/build/dex/balancer-v2/pools/weighted/WeightedPool.js.map +1 -0
  50. package/build/dex/balancer-v2/types.d.ts +1 -0
  51. package/build/dex/balancer-v2/types.js.map +1 -1
  52. package/build/dex/balancer-v2/utils.d.ts +3 -2
  53. package/build/dex/balancer-v2/utils.js +6 -4
  54. package/build/dex/balancer-v2/utils.js.map +1 -1
  55. package/build/dex/index.js +1 -1
  56. package/build/dex/index.js.map +1 -1
  57. package/build/dex/quickswap-v3.d.ts +21 -0
  58. package/build/dex/quickswap-v3.js +40 -0
  59. package/build/dex/quickswap-v3.js.map +1 -0
  60. package/build/dex/uniswap-v3/config.js +28 -0
  61. package/build/dex/uniswap-v3/config.js.map +1 -1
  62. package/build/dex/uniswap-v3/uniswap-v3-pool.d.ts +2 -1
  63. package/build/dex/uniswap-v3/uniswap-v3-pool.js +3 -2
  64. package/build/dex/uniswap-v3/uniswap-v3-pool.js.map +1 -1
  65. package/build/dex/uniswap-v3/uniswap-v3.js +1 -1
  66. package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
  67. package/build/dex/{pancakeswap-v3 → woo-fi}/config.d.ts +2 -2
  68. package/build/dex/woo-fi/config.js +141 -0
  69. package/build/dex/woo-fi/config.js.map +1 -0
  70. package/build/dex/woo-fi/constants.d.ts +5 -0
  71. package/build/dex/woo-fi/constants.js +20 -0
  72. package/build/dex/woo-fi/constants.js.map +1 -0
  73. package/build/dex/woo-fi/types.d.ts +48 -0
  74. package/build/dex/woo-fi/types.js +3 -0
  75. package/build/dex/woo-fi/types.js.map +1 -0
  76. package/build/dex/woo-fi/woo-fi-decimal-math.d.ts +14 -0
  77. package/build/dex/woo-fi/woo-fi-decimal-math.js +42 -0
  78. package/build/dex/woo-fi/woo-fi-decimal-math.js.map +1 -0
  79. package/build/dex/woo-fi/woo-fi-math.d.ts +31 -0
  80. package/build/dex/woo-fi/woo-fi-math.js +300 -0
  81. package/build/dex/woo-fi/woo-fi-math.js.map +1 -0
  82. package/build/dex/woo-fi/woo-fi.d.ts +65 -0
  83. package/build/dex/woo-fi/woo-fi.js +480 -0
  84. package/build/dex/woo-fi/woo-fi.js.map +1 -0
  85. package/package.json +1 -1
  86. package/src/config.ts +4 -4
  87. package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +538 -225
  88. package/src/dex/balancer-v2/balancer-v2-integration.test.ts +305 -122
  89. package/src/dex/balancer-v2/balancer-v2.ts +60 -56
  90. package/src/dex/balancer-v2/config.ts +23 -35
  91. package/src/dex/balancer-v2/pools/balancer-v2-pool.ts +274 -0
  92. package/src/dex/balancer-v2/{LinearMath.ts → pools/linear/LinearMath.ts} +11 -10
  93. package/src/dex/balancer-v2/{LinearPool.ts → pools/linear/LinearPool.ts} +210 -6
  94. package/src/dex/balancer-v2/{StableMath.ts → pools/phantom-stable/PhantomStableMath.ts} +101 -21
  95. package/src/dex/balancer-v2/{PhantomStablePool.ts → pools/phantom-stable/PhantomStablePool.ts} +167 -12
  96. package/src/dex/balancer-v2/pools/stable/StableMath.ts +204 -0
  97. package/src/dex/balancer-v2/pools/stable/StablePool.ts +221 -0
  98. package/src/dex/balancer-v2/pools/weighted/WeightedMath.ts +84 -0
  99. package/src/dex/balancer-v2/pools/weighted/WeightedPool.ts +189 -0
  100. package/src/dex/balancer-v2/types.ts +1 -0
  101. package/src/dex/balancer-v2/utils.ts +7 -1
  102. package/src/dex/index.ts +1 -1
  103. package/src/dex/uniswap-v3/config.ts +32 -0
  104. package/src/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.ts +28 -0
  105. package/src/dex/uniswap-v3/uniswap-v3-e2e.test.ts +156 -0
  106. package/src/dex/uniswap-v3/uniswap-v3-events.test.ts +0 -4
  107. package/src/dex/uniswap-v3/uniswap-v3-pool.ts +2 -1
  108. package/src/dex/uniswap-v3/uniswap-v3.ts +1 -0
  109. package/tests/constants-e2e.ts +33 -8
  110. package/build/abi/pancakeswap-v3/PancakeV3StateMulticall.abi.json +0 -781
  111. package/build/abi/pancakeswap-v3/PancakeswapV3Pool.abi.json +0 -1039
  112. package/build/abi/pancakeswap-v3/PancakeswapV3Quoter.abi.json +0 -285
  113. package/build/abi/pancakeswap-v3/PancakeswapV3Router.abi.json +0 -583
  114. package/build/dex/pancakeswap-v3/config.js +0 -62
  115. package/build/dex/pancakeswap-v3/config.js.map +0 -1
  116. package/build/dex/pancakeswap-v3/constants.d.ts +0 -23
  117. package/build/dex/pancakeswap-v3/constants.js +0 -29
  118. package/build/dex/pancakeswap-v3/constants.js.map +0 -1
  119. package/build/dex/pancakeswap-v3/contract-math/BitMath.d.ts +0 -4
  120. package/build/dex/pancakeswap-v3/contract-math/BitMath.js +0 -93
  121. package/build/dex/pancakeswap-v3/contract-math/BitMath.js.map +0 -1
  122. package/build/dex/pancakeswap-v3/contract-math/FixedPoint128.d.ts +0 -3
  123. package/build/dex/pancakeswap-v3/contract-math/FixedPoint128.js +0 -8
  124. package/build/dex/pancakeswap-v3/contract-math/FixedPoint128.js.map +0 -1
  125. package/build/dex/pancakeswap-v3/contract-math/FixedPoint96.d.ts +0 -4
  126. package/build/dex/pancakeswap-v3/contract-math/FixedPoint96.js +0 -9
  127. package/build/dex/pancakeswap-v3/contract-math/FixedPoint96.js.map +0 -1
  128. package/build/dex/pancakeswap-v3/contract-math/FullMath.d.ts +0 -4
  129. package/build/dex/pancakeswap-v3/contract-math/FullMath.js +0 -19
  130. package/build/dex/pancakeswap-v3/contract-math/FullMath.js.map +0 -1
  131. package/build/dex/pancakeswap-v3/contract-math/LiquidityMath.d.ts +0 -3
  132. package/build/dex/pancakeswap-v3/contract-math/LiquidityMath.js +0 -22
  133. package/build/dex/pancakeswap-v3/contract-math/LiquidityMath.js.map +0 -1
  134. package/build/dex/pancakeswap-v3/contract-math/Oracle.d.ts +0 -10
  135. package/build/dex/pancakeswap-v3/contract-math/Oracle.js +0 -133
  136. package/build/dex/pancakeswap-v3/contract-math/Oracle.js.map +0 -1
  137. package/build/dex/pancakeswap-v3/contract-math/SqrtPriceMath.d.ts +0 -10
  138. package/build/dex/pancakeswap-v3/contract-math/SqrtPriceMath.js +0 -91
  139. package/build/dex/pancakeswap-v3/contract-math/SqrtPriceMath.js.map +0 -1
  140. package/build/dex/pancakeswap-v3/contract-math/SwapMath.d.ts +0 -8
  141. package/build/dex/pancakeswap-v3/contract-math/SwapMath.js +0 -70
  142. package/build/dex/pancakeswap-v3/contract-math/SwapMath.js.map +0 -1
  143. package/build/dex/pancakeswap-v3/contract-math/Tick.d.ts +0 -7
  144. package/build/dex/pancakeswap-v3/contract-math/Tick.js +0 -45
  145. package/build/dex/pancakeswap-v3/contract-math/Tick.js.map +0 -1
  146. package/build/dex/pancakeswap-v3/contract-math/TickBitMap.d.ts +0 -8
  147. package/build/dex/pancakeswap-v3/contract-math/TickBitMap.js +0 -87
  148. package/build/dex/pancakeswap-v3/contract-math/TickBitMap.js.map +0 -1
  149. package/build/dex/pancakeswap-v3/contract-math/TickMath.d.ts +0 -8
  150. package/build/dex/pancakeswap-v3/contract-math/TickMath.js +0 -162
  151. package/build/dex/pancakeswap-v3/contract-math/TickMath.js.map +0 -1
  152. package/build/dex/pancakeswap-v3/contract-math/UnsafeMath.d.ts +0 -3
  153. package/build/dex/pancakeswap-v3/contract-math/UnsafeMath.js +0 -10
  154. package/build/dex/pancakeswap-v3/contract-math/UnsafeMath.js.map +0 -1
  155. package/build/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.d.ts +0 -18
  156. package/build/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.js +0 -407
  157. package/build/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.js.map +0 -1
  158. package/build/dex/pancakeswap-v3/contract-math/utils.d.ts +0 -3
  159. package/build/dex/pancakeswap-v3/contract-math/utils.js +0 -16
  160. package/build/dex/pancakeswap-v3/contract-math/utils.js.map +0 -1
  161. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.d.ts +0 -45
  162. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js +0 -340
  163. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js.map +0 -1
  164. package/build/dex/pancakeswap-v3/pancakeswap-v3.d.ts +0 -55
  165. package/build/dex/pancakeswap-v3/pancakeswap-v3.js +0 -605
  166. package/build/dex/pancakeswap-v3/pancakeswap-v3.js.map +0 -1
  167. package/build/dex/pancakeswap-v3/types.d.ts +0 -137
  168. package/build/dex/pancakeswap-v3/types.js +0 -9
  169. package/build/dex/pancakeswap-v3/types.js.map +0 -1
  170. package/build/dex/pancakeswap-v3/utils.d.ts +0 -6
  171. package/build/dex/pancakeswap-v3/utils.js +0 -65
  172. package/build/dex/pancakeswap-v3/utils.js.map +0 -1
  173. package/src/abi/pancakeswap-v3/PancakeV3StateMulticall.abi.json +0 -781
  174. package/src/abi/pancakeswap-v3/PancakeswapV3Pool.abi.json +0 -1039
  175. package/src/dex/balancer-v2/balancer-v2-pool.ts +0 -744
  176. package/src/dex/pancakeswap-v3/config.ts +0 -68
  177. package/src/dex/pancakeswap-v3/constants.ts +0 -35
  178. package/src/dex/pancakeswap-v3/contract-math/BitMath.ts +0 -90
  179. package/src/dex/pancakeswap-v3/contract-math/FixedPoint128.ts +0 -3
  180. package/src/dex/pancakeswap-v3/contract-math/FixedPoint96.ts +0 -4
  181. package/src/dex/pancakeswap-v3/contract-math/FullMath.ts +0 -30
  182. package/src/dex/pancakeswap-v3/contract-math/LiquidityMath.ts +0 -17
  183. package/src/dex/pancakeswap-v3/contract-math/Oracle.ts +0 -226
  184. package/src/dex/pancakeswap-v3/contract-math/SqrtPriceMath.ts +0 -226
  185. package/src/dex/pancakeswap-v3/contract-math/SwapMath.ts +0 -139
  186. package/src/dex/pancakeswap-v3/contract-math/Tick.ts +0 -82
  187. package/src/dex/pancakeswap-v3/contract-math/TickBitMap.ts +0 -128
  188. package/src/dex/pancakeswap-v3/contract-math/TickMath.ts +0 -211
  189. package/src/dex/pancakeswap-v3/contract-math/UnsafeMath.ts +0 -5
  190. package/src/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.ts +0 -691
  191. package/src/dex/pancakeswap-v3/contract-math/utils.ts +0 -11
  192. package/src/dex/pancakeswap-v3/pancakeswap-v3-e2e.test.ts +0 -168
  193. package/src/dex/pancakeswap-v3/pancakeswap-v3-events.test.ts +0 -124
  194. package/src/dex/pancakeswap-v3/pancakeswap-v3-integration.test.ts +0 -338
  195. package/src/dex/pancakeswap-v3/pancakeswap-v3-pool.ts +0 -554
  196. package/src/dex/pancakeswap-v3/pancakeswap-v3.ts +0 -1000
  197. /package/src/abi/{pancakeswap-v3/PancakeswapV3Quoter.abi.json → uniswap-v3/pancakeswap-v3/PancakeswapV3QuoterV2.abi.json} +0 -0
  198. /package/src/abi/{pancakeswap-v3 → uniswap-v3/pancakeswap-v3}/PancakeswapV3Router.abi.json +0 -0
@@ -1,691 +0,0 @@
1
- import _ from 'lodash';
2
- import {
3
- OutputResult,
4
- PoolState,
5
- Slot0,
6
- TickInfo,
7
- } from '../../uniswap-v3/types';
8
- import { LiquidityMath } from './LiquidityMath';
9
- import { Oracle } from './Oracle';
10
- import { SqrtPriceMath } from './SqrtPriceMath';
11
- import { SwapMath } from './SwapMath';
12
- import { Tick } from './Tick';
13
- import { TickBitMap } from './TickBitMap';
14
- import { TickMath } from './TickMath';
15
- import { _require } from '../../../utils';
16
- import { DeepReadonly } from 'ts-essentials';
17
- import { NumberAsString, SwapSide } from '@paraswap/core';
18
- import { BI_MAX_INT } from '../../../bigint-constants';
19
- import {
20
- MAX_PRICING_COMPUTATION_STEPS_ALLOWED,
21
- OUT_OF_RANGE_ERROR_POSTFIX,
22
- } from '../constants';
23
- import { FullMath } from './FullMath';
24
- import { FixedPoint128 } from './FixedPoint128';
25
-
26
- type ModifyPositionParams = {
27
- tickLower: bigint;
28
- tickUpper: bigint;
29
- liquidityDelta: bigint;
30
- };
31
-
32
- type PriceComputationState = {
33
- amountSpecifiedRemaining: bigint;
34
- amountCalculated: bigint;
35
- sqrtPriceX96: bigint;
36
- tick: bigint;
37
- protocolFee: bigint;
38
- liquidity: bigint;
39
- isFirstCycleState: boolean;
40
- };
41
-
42
- type PriceComputationCache = {
43
- liquidityStart: bigint;
44
- blockTimestamp: bigint;
45
- feeProtocol: bigint;
46
- secondsPerLiquidityCumulativeX128: bigint;
47
- tickCumulative: bigint;
48
- computedLatestObservation: boolean;
49
- tickCount: number;
50
- };
51
-
52
- const PROTOCOL_FEE_SP = 65536n;
53
-
54
- const PROTOCOL_FEE_DENOMINATOR = 10000n;
55
-
56
- function _updatePriceComputationObjects<
57
- T extends PriceComputationState | PriceComputationCache,
58
- >(toUpdate: T, updateBy: T) {
59
- for (const k of Object.keys(updateBy) as (keyof T)[]) {
60
- toUpdate[k] = updateBy[k];
61
- }
62
- }
63
-
64
- function _priceComputationCycles(
65
- poolState: DeepReadonly<PoolState>,
66
- ticksCopy: Record<NumberAsString, TickInfo>,
67
- slot0Start: Slot0,
68
- state: PriceComputationState,
69
- cache: PriceComputationCache,
70
- sqrtPriceLimitX96: bigint,
71
- zeroForOne: boolean,
72
- exactInput: boolean,
73
- ): [
74
- // result
75
- PriceComputationState,
76
- // Latest calculated full cycle state we can use for bigger amounts
77
- {
78
- latestFullCycleState: PriceComputationState;
79
- latestFullCycleCache: PriceComputationCache;
80
- },
81
- ] {
82
- const latestFullCycleState: PriceComputationState = { ...state };
83
-
84
- if (cache.tickCount == 0) {
85
- cache.tickCount = 1;
86
- }
87
- const latestFullCycleCache: PriceComputationCache = { ...cache };
88
-
89
- // We save tick before any change. Later we use this to restore
90
- // state before last step
91
- let lastTicksCopy: { index: number; tick: TickInfo } | undefined;
92
-
93
- let i = 0;
94
- for (
95
- ;
96
- state.amountSpecifiedRemaining !== 0n &&
97
- state.sqrtPriceX96 !== sqrtPriceLimitX96;
98
- ++i
99
- ) {
100
- if (
101
- latestFullCycleCache.tickCount + i >
102
- MAX_PRICING_COMPUTATION_STEPS_ALLOWED
103
- ) {
104
- state.amountSpecifiedRemaining = 0n;
105
- state.amountCalculated = 0n;
106
- break;
107
- }
108
-
109
- const step = {
110
- sqrtPriceStartX96: 0n,
111
- tickNext: 0n,
112
- initialized: false,
113
- sqrtPriceNextX96: 0n,
114
- amountIn: 0n,
115
- amountOut: 0n,
116
- feeAmount: 0n,
117
- };
118
-
119
- step.sqrtPriceStartX96 = state.sqrtPriceX96;
120
-
121
- try {
122
- [step.tickNext, step.initialized] =
123
- TickBitMap.nextInitializedTickWithinOneWord(
124
- poolState,
125
- state.tick,
126
- poolState.tickSpacing,
127
- zeroForOne,
128
- true,
129
- );
130
- } catch (e) {
131
- if (
132
- e instanceof Error &&
133
- e.message.endsWith(OUT_OF_RANGE_ERROR_POSTFIX)
134
- ) {
135
- state.amountSpecifiedRemaining = 0n;
136
- state.amountCalculated = 0n;
137
- break;
138
- }
139
- throw e;
140
- }
141
-
142
- if (step.tickNext < TickMath.MIN_TICK) {
143
- //TODO in contract
144
- step.tickNext = TickMath.MIN_TICK;
145
- } else if (step.tickNext > TickMath.MAX_TICK) {
146
- step.tickNext = TickMath.MAX_TICK;
147
- }
148
-
149
- step.sqrtPriceNextX96 = TickMath.getSqrtRatioAtTick(step.tickNext);
150
-
151
- const swapStepResult = SwapMath.computeSwapStep(
152
- //TODO check if fee changes
153
- state.sqrtPriceX96, //TODO in contract
154
- (
155
- zeroForOne
156
- ? step.sqrtPriceNextX96 < sqrtPriceLimitX96
157
- : step.sqrtPriceNextX96 > sqrtPriceLimitX96
158
- )
159
- ? sqrtPriceLimitX96
160
- : step.sqrtPriceNextX96,
161
- state.liquidity,
162
- state.amountSpecifiedRemaining,
163
- poolState.fee,
164
- );
165
-
166
- state.sqrtPriceX96 = swapStepResult.sqrtRatioNextX96;
167
- step.amountIn = swapStepResult.amountIn;
168
- step.amountOut = swapStepResult.amountOut;
169
- step.feeAmount = swapStepResult.feeAmount;
170
-
171
- if (exactInput) {
172
- //TODO in contract
173
- state.amountSpecifiedRemaining -= step.amountIn + step.feeAmount;
174
- state.amountCalculated = state.amountCalculated - step.amountOut;
175
- } else {
176
- state.amountSpecifiedRemaining += step.amountOut;
177
- state.amountCalculated =
178
- state.amountCalculated + step.amountIn + step.feeAmount;
179
- }
180
-
181
- if (cache.feeProtocol > 0n) {
182
- const delta =
183
- (step.feeAmount * cache.feeProtocol) / PROTOCOL_FEE_DENOMINATOR;
184
- step.feeAmount -= delta;
185
- state.protocolFee += delta;
186
- }
187
-
188
- if (state.sqrtPriceX96 === step.sqrtPriceNextX96) {
189
- if (step.initialized) {
190
- if (!cache.computedLatestObservation) {
191
- [cache.tickCumulative, cache.secondsPerLiquidityCumulativeX128] =
192
- Oracle.observeSingle(
193
- poolState,
194
- cache.blockTimestamp,
195
- 0n,
196
- slot0Start.tick,
197
- slot0Start.observationIndex,
198
- cache.liquidityStart,
199
- slot0Start.observationCardinality,
200
- );
201
- cache.computedLatestObservation = true;
202
- }
203
-
204
- if (state.amountSpecifiedRemaining === 0n) {
205
- const castTickNext = Number(step.tickNext);
206
- lastTicksCopy = {
207
- index: castTickNext,
208
- tick: { ...ticksCopy[castTickNext] },
209
- };
210
- }
211
-
212
- let liquidityNet = Tick.cross(
213
- ticksCopy,
214
- step.tickNext,
215
- cache.secondsPerLiquidityCumulativeX128,
216
- cache.tickCumulative,
217
- cache.blockTimestamp,
218
- );
219
- if (zeroForOne) liquidityNet = -liquidityNet;
220
-
221
- state.liquidity = LiquidityMath.addDelta(state.liquidity, liquidityNet);
222
- }
223
-
224
- state.tick = zeroForOne ? step.tickNext - 1n : step.tickNext;
225
- } else if (state.sqrtPriceX96 != step.sqrtPriceStartX96) {
226
- state.tick = TickMath.getTickAtSqrtRatio(state.sqrtPriceX96);
227
- }
228
-
229
- if (state.amountSpecifiedRemaining !== 0n) {
230
- _updatePriceComputationObjects(latestFullCycleState, state);
231
- _updatePriceComputationObjects(latestFullCycleCache, cache);
232
- // If it last cycle, check if ticks were changed and then restore previous state
233
- // for next calculations
234
- } else if (lastTicksCopy !== undefined) {
235
- ticksCopy[lastTicksCopy.index] = lastTicksCopy.tick;
236
- }
237
- }
238
-
239
- if (i > 1) {
240
- latestFullCycleCache.tickCount += i - 1;
241
- }
242
-
243
- if (state.amountSpecifiedRemaining !== 0n) {
244
- state.amountSpecifiedRemaining = 0n;
245
- state.amountCalculated = 0n;
246
- }
247
-
248
- return [state, { latestFullCycleState, latestFullCycleCache }];
249
- }
250
-
251
- class PancakeswapV3Math {
252
- queryOutputs(
253
- poolState: DeepReadonly<PoolState>,
254
- // Amounts must increase
255
- amounts: bigint[],
256
- zeroForOne: boolean,
257
- side: SwapSide,
258
- ): OutputResult {
259
- const slot0Start = poolState.slot0;
260
-
261
- const isSell = side === SwapSide.SELL;
262
-
263
- // While calculating, ticks are changing, so to not change the actual state,
264
- // we use copy
265
- const ticksCopy = _.cloneDeep(poolState.ticks);
266
-
267
- const sqrtPriceLimitX96 = zeroForOne
268
- ? TickMath.MIN_SQRT_RATIO + 1n
269
- : TickMath.MAX_SQRT_RATIO - 1n;
270
-
271
- const cache: PriceComputationCache = {
272
- liquidityStart: poolState.liquidity,
273
- blockTimestamp: this._blockTimestamp(poolState),
274
- feeProtocol: zeroForOne
275
- ? slot0Start.feeProtocol % PROTOCOL_FEE_SP
276
- : slot0Start.feeProtocol >> 16n,
277
- secondsPerLiquidityCumulativeX128: 0n,
278
- tickCumulative: 0n,
279
- computedLatestObservation: false,
280
- tickCount: 0, // what is this
281
- };
282
-
283
- const state: PriceComputationState = {
284
- // Will be overwritten later
285
- amountSpecifiedRemaining: 0n,
286
- amountCalculated: 0n,
287
- sqrtPriceX96: slot0Start.sqrtPriceX96,
288
- tick: slot0Start.tick,
289
- protocolFee: 0n,
290
- liquidity: cache.liquidityStart,
291
- isFirstCycleState: true,
292
- };
293
-
294
- let isOutOfRange = false;
295
- let previousAmount = 0n;
296
-
297
- const outputs = new Array(amounts.length);
298
- const tickCounts = new Array(amounts.length);
299
- for (const [i, amount] of amounts.entries()) {
300
- if (amount === 0n) {
301
- outputs[i] = 0n;
302
- tickCounts[i] = 0;
303
- continue;
304
- }
305
-
306
- const amountSpecified = isSell
307
- ? BigInt.asIntN(256, amount)
308
- : -BigInt.asIntN(256, amount);
309
-
310
- if (state.isFirstCycleState) {
311
- // TODO what is this
312
- // Set first non zero amount
313
- state.amountSpecifiedRemaining = amountSpecified;
314
- state.isFirstCycleState = false;
315
- } else {
316
- state.amountSpecifiedRemaining =
317
- amountSpecified - (previousAmount - state.amountSpecifiedRemaining);
318
- }
319
-
320
- const exactInput = amountSpecified > 0n;
321
-
322
- _require(
323
- zeroForOne
324
- ? sqrtPriceLimitX96 < slot0Start.sqrtPriceX96 &&
325
- sqrtPriceLimitX96 > TickMath.MIN_SQRT_RATIO
326
- : sqrtPriceLimitX96 > slot0Start.sqrtPriceX96 &&
327
- sqrtPriceLimitX96 < TickMath.MAX_SQRT_RATIO,
328
- 'SPL',
329
- { zeroForOne, sqrtPriceLimitX96, slot0Start },
330
- 'zeroForOne ? sqrtPriceLimitX96 < slot0Start.sqrtPriceX96 && sqrtPriceLimitX96 > TickMath.MIN_SQRT_RATIO : sqrtPriceLimitX96 > slot0Start.sqrtPriceX96 && sqrtPriceLimitX96 < TickMath.MAX_SQRT_RATIO',
331
- );
332
-
333
- if (!isOutOfRange) {
334
- const [finalState, { latestFullCycleState, latestFullCycleCache }] =
335
- _priceComputationCycles(
336
- poolState,
337
- ticksCopy,
338
- slot0Start,
339
- state,
340
- cache,
341
- sqrtPriceLimitX96,
342
- zeroForOne,
343
- exactInput,
344
- );
345
- if (
346
- finalState.amountSpecifiedRemaining === 0n &&
347
- finalState.amountCalculated === 0n
348
- ) {
349
- isOutOfRange = true;
350
- outputs[i] = 0n;
351
- tickCounts[i] = 0;
352
- continue;
353
- }
354
-
355
- // We use it on next step to correct state.amountSpecifiedRemaining
356
- previousAmount = amountSpecified;
357
-
358
- // First extract calculated values
359
- const [amount0, amount1] =
360
- zeroForOne === exactInput
361
- ? [
362
- amountSpecified - finalState.amountSpecifiedRemaining,
363
- finalState.amountCalculated,
364
- ]
365
- : [
366
- finalState.amountCalculated,
367
- amountSpecified - finalState.amountSpecifiedRemaining,
368
- ];
369
-
370
- // Update for next amount
371
- _updatePriceComputationObjects(state, latestFullCycleState);
372
- _updatePriceComputationObjects(cache, latestFullCycleCache);
373
-
374
- if (isSell) {
375
- outputs[i] = BigInt.asUintN(256, -(zeroForOne ? amount1 : amount0));
376
- tickCounts[i] = latestFullCycleCache.tickCount;
377
- continue;
378
- } else {
379
- outputs[i] = zeroForOne
380
- ? BigInt.asUintN(256, amount0)
381
- : BigInt.asUintN(256, amount1);
382
- tickCounts[i] = latestFullCycleCache.tickCount;
383
- continue;
384
- }
385
- } else {
386
- outputs[i] = 0n;
387
- tickCounts[i] = 0;
388
- }
389
- }
390
-
391
- return {
392
- outputs,
393
- tickCounts,
394
- };
395
- }
396
-
397
- swapFromEvent(
398
- poolState: PoolState,
399
- newSqrtPriceX96: bigint,
400
- newTick: bigint,
401
- newLiquidity: bigint,
402
- zeroForOne: boolean,
403
- ): void {
404
- const slot0Start = poolState.slot0;
405
-
406
- const cache = {
407
- liquidityStart: poolState.liquidity,
408
- blockTimestamp: this._blockTimestamp(poolState),
409
- feeProtocol: zeroForOne
410
- ? slot0Start.feeProtocol % PROTOCOL_FEE_SP
411
- : slot0Start.feeProtocol >> 16n,
412
- secondsPerLiquidityCumulativeX128: 0n,
413
- tickCumulative: 0n,
414
- computedLatestObservation: false,
415
- };
416
-
417
- const state = {
418
- // Because I don't have the exact amount user used, set this number to MAX_NUMBER to proceed
419
- // with calculations. I think it is not a problem since in loop I don't rely on this value
420
- amountSpecifiedRemaining: BI_MAX_INT,
421
- amountCalculated: 0n,
422
- sqrtPriceX96: slot0Start.sqrtPriceX96,
423
- tick: slot0Start.tick,
424
- protocolFee: 0n,
425
- liquidity: cache.liquidityStart,
426
- };
427
-
428
- // Because I didn't have all variables, adapted loop stop with state.tick !== newTick
429
- // condition. This cycle need only to calculate Tick.cross() function values
430
- // It means that we are interested in cycling only if state.tick !== newTick
431
- // When they become equivalent, we proceed with state updating part as normal
432
- // And if assumptions regarding this cycle are correct, we don't need to process
433
- // the last cycle when state.tick === newTick
434
- while (state.tick !== newTick && state.sqrtPriceX96 !== newSqrtPriceX96) {
435
- const step = {
436
- sqrtPriceStartX96: 0n,
437
- tickNext: 0n,
438
- initialized: false,
439
- sqrtPriceNextX96: 0n,
440
- amountIn: 0n,
441
- amountOut: 0n,
442
- feeAmount: 0n,
443
- };
444
-
445
- step.sqrtPriceStartX96 = state.sqrtPriceX96;
446
-
447
- [step.tickNext, step.initialized] =
448
- TickBitMap.nextInitializedTickWithinOneWord(
449
- poolState,
450
- state.tick,
451
- poolState.tickSpacing,
452
- zeroForOne,
453
- false,
454
- );
455
-
456
- if (step.tickNext < TickMath.MIN_TICK) {
457
- step.tickNext = TickMath.MIN_TICK;
458
- } else if (step.tickNext > TickMath.MAX_TICK) {
459
- step.tickNext = TickMath.MAX_TICK;
460
- }
461
-
462
- step.sqrtPriceNextX96 = TickMath.getSqrtRatioAtTick(step.tickNext);
463
-
464
- const swapStepResult = SwapMath.computeSwapStep(
465
- state.sqrtPriceX96,
466
- (
467
- zeroForOne
468
- ? step.sqrtPriceNextX96 < newSqrtPriceX96
469
- : step.sqrtPriceNextX96 > newSqrtPriceX96
470
- )
471
- ? newSqrtPriceX96
472
- : step.sqrtPriceNextX96,
473
- state.liquidity,
474
- state.amountSpecifiedRemaining,
475
- poolState.fee,
476
- );
477
-
478
- state.sqrtPriceX96 = swapStepResult.sqrtRatioNextX96;
479
-
480
- if (cache.feeProtocol > 0) {
481
- const delta =
482
- (step.feeAmount * cache.feeProtocol) / PROTOCOL_FEE_DENOMINATOR;
483
- step.feeAmount -= delta;
484
- state.protocolFee += delta;
485
- }
486
-
487
- if (state.sqrtPriceX96 == step.sqrtPriceNextX96) {
488
- if (step.initialized) {
489
- if (!cache.computedLatestObservation) {
490
- [cache.tickCumulative, cache.secondsPerLiquidityCumulativeX128] =
491
- Oracle.observeSingle(
492
- poolState,
493
- cache.blockTimestamp,
494
- 0n,
495
- slot0Start.tick,
496
- slot0Start.observationIndex,
497
- cache.liquidityStart,
498
- slot0Start.observationCardinality,
499
- );
500
- cache.computedLatestObservation = true;
501
- }
502
-
503
- let liquidityNet = Tick.cross(
504
- poolState.ticks,
505
- step.tickNext,
506
- cache.secondsPerLiquidityCumulativeX128,
507
- cache.tickCumulative,
508
- cache.blockTimestamp,
509
- );
510
-
511
- if (zeroForOne) liquidityNet = -liquidityNet;
512
-
513
- state.liquidity = LiquidityMath.addDelta(
514
- state.liquidity,
515
- liquidityNet,
516
- );
517
- }
518
-
519
- state.tick = zeroForOne ? step.tickNext - 1n : step.tickNext;
520
- } else if (state.sqrtPriceX96 != step.sqrtPriceStartX96) {
521
- state.tick = TickMath.getTickAtSqrtRatio(state.sqrtPriceX96);
522
- }
523
- }
524
-
525
- if (slot0Start.tick !== newTick) {
526
- const [observationIndex, observationCardinality] = Oracle.write(
527
- poolState,
528
- slot0Start.observationIndex,
529
- this._blockTimestamp(poolState),
530
- slot0Start.tick,
531
- poolState.liquidity,
532
- slot0Start.observationCardinality,
533
- slot0Start.observationCardinalityNext,
534
- );
535
-
536
- [
537
- poolState.slot0.sqrtPriceX96,
538
- poolState.slot0.tick,
539
- poolState.slot0.observationIndex,
540
- poolState.slot0.observationCardinality,
541
- ] = [newSqrtPriceX96, newTick, observationIndex, observationCardinality];
542
- } else {
543
- poolState.slot0.sqrtPriceX96 = newSqrtPriceX96;
544
- }
545
-
546
- if (poolState.liquidity !== newLiquidity)
547
- poolState.liquidity = newLiquidity;
548
- }
549
-
550
- _modifyPosition(
551
- state: PoolState,
552
- params: ModifyPositionParams,
553
- ): [bigint, bigint] {
554
- const _slot0 = state.slot0;
555
-
556
- this._updatePosition(
557
- state,
558
- params.tickLower,
559
- params.tickUpper,
560
- params.liquidityDelta,
561
- _slot0.tick,
562
- );
563
-
564
- let amount0 = 0n;
565
- let amount1 = 0n;
566
- if (params.liquidityDelta !== 0n) {
567
- if (_slot0.tick < params.tickLower) {
568
- amount0 = SqrtPriceMath._getAmount0DeltaO(
569
- TickMath.getSqrtRatioAtTick(params.tickLower),
570
- TickMath.getSqrtRatioAtTick(params.tickUpper),
571
- params.liquidityDelta,
572
- );
573
- } else if (_slot0.tick < params.tickUpper) {
574
- const liquidityBefore = state.liquidity;
575
-
576
- [state.slot0.observationIndex, state.slot0.observationCardinality] =
577
- Oracle.write(
578
- state,
579
- _slot0.observationIndex,
580
- this._blockTimestamp(state),
581
- _slot0.tick,
582
- liquidityBefore,
583
- _slot0.observationCardinality,
584
- _slot0.observationCardinalityNext,
585
- );
586
-
587
- amount0 = SqrtPriceMath._getAmount0DeltaO(
588
- _slot0.sqrtPriceX96,
589
- TickMath.getSqrtRatioAtTick(params.tickUpper),
590
- params.liquidityDelta,
591
- );
592
- amount1 = SqrtPriceMath._getAmount1DeltaO(
593
- TickMath.getSqrtRatioAtTick(params.tickLower),
594
- _slot0.sqrtPriceX96,
595
- params.liquidityDelta,
596
- );
597
-
598
- state.liquidity = LiquidityMath.addDelta(
599
- liquidityBefore,
600
- params.liquidityDelta,
601
- );
602
- } else {
603
- amount1 = SqrtPriceMath._getAmount1DeltaO(
604
- TickMath.getSqrtRatioAtTick(params.tickLower),
605
- TickMath.getSqrtRatioAtTick(params.tickUpper),
606
- params.liquidityDelta,
607
- );
608
- }
609
- }
610
- return [amount0, amount1];
611
- }
612
-
613
- private _isTickToProcess(state: PoolState, tick: bigint): boolean {
614
- return tick >= state.lowestKnownTick && tick <= state.highestKnownTick;
615
- }
616
-
617
- private _updatePosition(
618
- state: PoolState,
619
- tickLower: bigint,
620
- tickUpper: bigint,
621
- liquidityDelta: bigint,
622
- tick: bigint,
623
- ): void {
624
- // if we need to update the ticks, do it
625
- let flippedLower = false;
626
- let flippedUpper = false;
627
- if (liquidityDelta !== 0n) {
628
- const time = this._blockTimestamp(state);
629
- const [tickCumulative, secondsPerLiquidityCumulativeX128] =
630
- Oracle.observeSingle(
631
- state,
632
- time,
633
- 0n,
634
- state.slot0.tick,
635
- state.slot0.observationIndex,
636
- state.liquidity,
637
- state.slot0.observationCardinality,
638
- );
639
-
640
- if (this._isTickToProcess(state, tickLower)) {
641
- flippedLower = Tick.update(
642
- state,
643
- tickLower,
644
- tick,
645
- liquidityDelta,
646
- secondsPerLiquidityCumulativeX128,
647
- tickCumulative,
648
- time,
649
- false,
650
- state.maxLiquidityPerTick,
651
- );
652
- }
653
- if (this._isTickToProcess(state, tickUpper)) {
654
- flippedUpper = Tick.update(
655
- state,
656
- tickUpper,
657
- tick,
658
- liquidityDelta,
659
- secondsPerLiquidityCumulativeX128,
660
- tickCumulative,
661
- time,
662
- true,
663
- state.maxLiquidityPerTick,
664
- );
665
- }
666
-
667
- if (flippedLower) {
668
- TickBitMap.flipTick(state, tickLower, state.tickSpacing);
669
- }
670
- if (flippedUpper) {
671
- TickBitMap.flipTick(state, tickUpper, state.tickSpacing);
672
- }
673
- }
674
-
675
- // clear any tick data that is no longer needed
676
- if (liquidityDelta < 0n) {
677
- if (flippedLower) {
678
- Tick.clear(state, tickLower);
679
- }
680
- if (flippedUpper) {
681
- Tick.clear(state, tickUpper);
682
- }
683
- }
684
- }
685
-
686
- private _blockTimestamp(state: DeepReadonly<PoolState>) {
687
- return BigInt.asUintN(32, state.blockTimestamp);
688
- }
689
- }
690
-
691
- export const pancakeswapV3Math = new PancakeswapV3Math();
@@ -1,11 +0,0 @@
1
- export function _mulmod(x: bigint, y: bigint, m: bigint): bigint {
2
- return m === 0n ? 0n : (x * y) % m;
3
- }
4
-
5
- export function _lt(x: bigint, y: bigint) {
6
- return x < y ? 1n : 0n;
7
- }
8
-
9
- export function _gt(x: bigint, y: bigint) {
10
- return x > y ? 1n : 0n;
11
- }