@paraswap/dex-lib 2.16.7 → 2.16.8-pancakeswapv3.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 (150) hide show
  1. package/build/abi/pancakeswap-v3/PancakeV3StateMulticall.abi.json +781 -0
  2. package/build/abi/pancakeswap-v3/PancakeswapV3Pool.abi.json +1039 -0
  3. package/build/abi/pancakeswap-v3/PancakeswapV3Quoter.abi.json +285 -0
  4. package/build/abi/pancakeswap-v3/PancakeswapV3Router.abi.json +583 -0
  5. package/build/dex/index.js +1 -1
  6. package/build/dex/index.js.map +1 -1
  7. package/build/dex/{test-dex → pancakeswap-v3}/config.d.ts +2 -2
  8. package/build/dex/pancakeswap-v3/config.js +62 -0
  9. package/build/dex/pancakeswap-v3/config.js.map +1 -0
  10. package/build/dex/pancakeswap-v3/constants.d.ts +23 -0
  11. package/build/dex/pancakeswap-v3/constants.js +29 -0
  12. package/build/dex/pancakeswap-v3/constants.js.map +1 -0
  13. package/build/dex/pancakeswap-v3/contract-math/BitMath.d.ts +4 -0
  14. package/build/dex/pancakeswap-v3/contract-math/BitMath.js +93 -0
  15. package/build/dex/pancakeswap-v3/contract-math/BitMath.js.map +1 -0
  16. package/build/dex/pancakeswap-v3/contract-math/FixedPoint128.d.ts +3 -0
  17. package/build/dex/pancakeswap-v3/contract-math/FixedPoint128.js +8 -0
  18. package/build/dex/pancakeswap-v3/contract-math/FixedPoint128.js.map +1 -0
  19. package/build/dex/pancakeswap-v3/contract-math/FixedPoint96.d.ts +4 -0
  20. package/build/dex/pancakeswap-v3/contract-math/FixedPoint96.js +9 -0
  21. package/build/dex/pancakeswap-v3/contract-math/FixedPoint96.js.map +1 -0
  22. package/build/dex/pancakeswap-v3/contract-math/FullMath.d.ts +4 -0
  23. package/build/dex/pancakeswap-v3/contract-math/FullMath.js +19 -0
  24. package/build/dex/pancakeswap-v3/contract-math/FullMath.js.map +1 -0
  25. package/build/dex/pancakeswap-v3/contract-math/LiquidityMath.d.ts +3 -0
  26. package/build/dex/pancakeswap-v3/contract-math/LiquidityMath.js +22 -0
  27. package/build/dex/pancakeswap-v3/contract-math/LiquidityMath.js.map +1 -0
  28. package/build/dex/pancakeswap-v3/contract-math/Oracle.d.ts +10 -0
  29. package/build/dex/pancakeswap-v3/contract-math/Oracle.js +133 -0
  30. package/build/dex/pancakeswap-v3/contract-math/Oracle.js.map +1 -0
  31. package/build/dex/pancakeswap-v3/contract-math/SqrtPriceMath.d.ts +10 -0
  32. package/build/dex/pancakeswap-v3/contract-math/SqrtPriceMath.js +91 -0
  33. package/build/dex/pancakeswap-v3/contract-math/SqrtPriceMath.js.map +1 -0
  34. package/build/dex/pancakeswap-v3/contract-math/SwapMath.d.ts +8 -0
  35. package/build/dex/pancakeswap-v3/contract-math/SwapMath.js +70 -0
  36. package/build/dex/pancakeswap-v3/contract-math/SwapMath.js.map +1 -0
  37. package/build/dex/pancakeswap-v3/contract-math/Tick.d.ts +7 -0
  38. package/build/dex/pancakeswap-v3/contract-math/Tick.js +45 -0
  39. package/build/dex/pancakeswap-v3/contract-math/Tick.js.map +1 -0
  40. package/build/dex/pancakeswap-v3/contract-math/TickBitMap.d.ts +8 -0
  41. package/build/dex/pancakeswap-v3/contract-math/TickBitMap.js +87 -0
  42. package/build/dex/pancakeswap-v3/contract-math/TickBitMap.js.map +1 -0
  43. package/build/dex/pancakeswap-v3/contract-math/TickMath.d.ts +8 -0
  44. package/build/dex/pancakeswap-v3/contract-math/TickMath.js +162 -0
  45. package/build/dex/pancakeswap-v3/contract-math/TickMath.js.map +1 -0
  46. package/build/dex/pancakeswap-v3/contract-math/UnsafeMath.d.ts +3 -0
  47. package/build/dex/pancakeswap-v3/contract-math/UnsafeMath.js +10 -0
  48. package/build/dex/pancakeswap-v3/contract-math/UnsafeMath.js.map +1 -0
  49. package/build/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.d.ts +18 -0
  50. package/build/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.js +407 -0
  51. package/build/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.js.map +1 -0
  52. package/build/dex/pancakeswap-v3/contract-math/utils.d.ts +3 -0
  53. package/build/dex/pancakeswap-v3/contract-math/utils.js +16 -0
  54. package/build/dex/pancakeswap-v3/contract-math/utils.js.map +1 -0
  55. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.d.ts +45 -0
  56. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js +340 -0
  57. package/build/dex/pancakeswap-v3/pancakeswap-v3-pool.js.map +1 -0
  58. package/build/dex/pancakeswap-v3/pancakeswap-v3.d.ts +55 -0
  59. package/build/dex/pancakeswap-v3/pancakeswap-v3.js +605 -0
  60. package/build/dex/pancakeswap-v3/pancakeswap-v3.js.map +1 -0
  61. package/build/dex/pancakeswap-v3/types.d.ts +137 -0
  62. package/build/dex/pancakeswap-v3/types.js +9 -0
  63. package/build/dex/pancakeswap-v3/types.js.map +1 -0
  64. package/build/dex/pancakeswap-v3/utils.d.ts +6 -0
  65. package/build/dex/pancakeswap-v3/utils.js +65 -0
  66. package/build/dex/pancakeswap-v3/utils.js.map +1 -0
  67. package/build/dex/uniswap-v3/config.js +0 -28
  68. package/build/dex/uniswap-v3/config.js.map +1 -1
  69. package/build/dex/uniswap-v3/uniswap-v3-pool.d.ts +1 -2
  70. package/build/dex/uniswap-v3/uniswap-v3-pool.js +2 -3
  71. package/build/dex/uniswap-v3/uniswap-v3-pool.js.map +1 -1
  72. package/build/dex/uniswap-v3/uniswap-v3.js +1 -1
  73. package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
  74. package/package.json +1 -1
  75. package/src/abi/pancakeswap-v3/PancakeV3StateMulticall.abi.json +781 -0
  76. package/src/abi/pancakeswap-v3/PancakeswapV3Pool.abi.json +1039 -0
  77. package/src/dex/index.ts +1 -1
  78. package/src/dex/pancakeswap-v3/config.ts +68 -0
  79. package/src/dex/pancakeswap-v3/constants.ts +35 -0
  80. package/src/dex/pancakeswap-v3/contract-math/BitMath.ts +90 -0
  81. package/src/dex/pancakeswap-v3/contract-math/FixedPoint128.ts +3 -0
  82. package/src/dex/pancakeswap-v3/contract-math/FixedPoint96.ts +4 -0
  83. package/src/dex/pancakeswap-v3/contract-math/FullMath.ts +30 -0
  84. package/src/dex/pancakeswap-v3/contract-math/LiquidityMath.ts +17 -0
  85. package/src/dex/pancakeswap-v3/contract-math/Oracle.ts +226 -0
  86. package/src/dex/pancakeswap-v3/contract-math/SqrtPriceMath.ts +226 -0
  87. package/src/dex/pancakeswap-v3/contract-math/SwapMath.ts +139 -0
  88. package/src/dex/pancakeswap-v3/contract-math/Tick.ts +82 -0
  89. package/src/dex/pancakeswap-v3/contract-math/TickBitMap.ts +128 -0
  90. package/src/dex/pancakeswap-v3/contract-math/TickMath.ts +211 -0
  91. package/src/dex/pancakeswap-v3/contract-math/UnsafeMath.ts +5 -0
  92. package/src/dex/pancakeswap-v3/contract-math/pancakeswap-v3-math.ts +691 -0
  93. package/src/dex/pancakeswap-v3/contract-math/utils.ts +11 -0
  94. package/src/dex/pancakeswap-v3/pancakeswap-v3-e2e.test.ts +168 -0
  95. package/src/dex/pancakeswap-v3/pancakeswap-v3-events.test.ts +124 -0
  96. package/src/dex/pancakeswap-v3/pancakeswap-v3-integration.test.ts +338 -0
  97. package/src/dex/pancakeswap-v3/pancakeswap-v3-pool.ts +554 -0
  98. package/src/dex/pancakeswap-v3/pancakeswap-v3.ts +1000 -0
  99. package/src/dex/uniswap-v3/config.ts +0 -32
  100. package/src/dex/uniswap-v3/uniswap-v3-e2e.test.ts +0 -156
  101. package/src/dex/uniswap-v3/uniswap-v3-events.test.ts +4 -0
  102. package/src/dex/uniswap-v3/uniswap-v3-pool.ts +1 -2
  103. package/src/dex/uniswap-v3/uniswap-v3.ts +0 -1
  104. package/build/abi/DirectSwap.json +0 -970
  105. package/build/abi/woo-fi/WooFeeManager.abi.json +0 -318
  106. package/build/abi/woo-fi/WooPP.abi.json +0 -548
  107. package/build/abi/woo-fi/Wooracle.abi.json +0 -260
  108. package/build/dex/aave-v3/tokens/arbitrum.json +0 -50
  109. package/build/dex/aave-v3/tokens/avalanche.json +0 -74
  110. package/build/dex/aave-v3/tokens/fantom.json +0 -62
  111. package/build/dex/aave-v3/tokens/optimism.json +0 -50
  112. package/build/dex/aave-v3/tokens/polygon.json +0 -116
  113. package/build/dex/quickswap-v3.d.ts +0 -21
  114. package/build/dex/quickswap-v3.js +0 -40
  115. package/build/dex/quickswap-v3.js.map +0 -1
  116. package/build/dex/test-dex/config.js +0 -15
  117. package/build/dex/test-dex/config.js.map +0 -1
  118. package/build/dex/test-dex/test-dex-pool.d.ts +0 -39
  119. package/build/dex/test-dex/test-dex-pool.js +0 -63
  120. package/build/dex/test-dex/test-dex-pool.js.map +0 -1
  121. package/build/dex/test-dex/test-dex.d.ts +0 -37
  122. package/build/dex/test-dex/test-dex.js +0 -126
  123. package/build/dex/test-dex/test-dex.js.map +0 -1
  124. package/build/dex/test-dex/types.d.ts +0 -6
  125. package/build/dex/test-dex/types.js +0 -3
  126. package/build/dex/test-dex/types.js.map +0 -1
  127. package/build/dex/woo-fi/config.d.ts +0 -4
  128. package/build/dex/woo-fi/config.js +0 -141
  129. package/build/dex/woo-fi/config.js.map +0 -1
  130. package/build/dex/woo-fi/constants.d.ts +0 -5
  131. package/build/dex/woo-fi/constants.js +0 -20
  132. package/build/dex/woo-fi/constants.js.map +0 -1
  133. package/build/dex/woo-fi/types.d.ts +0 -48
  134. package/build/dex/woo-fi/types.js +0 -3
  135. package/build/dex/woo-fi/types.js.map +0 -1
  136. package/build/dex/woo-fi/woo-fi-decimal-math.d.ts +0 -14
  137. package/build/dex/woo-fi/woo-fi-decimal-math.js +0 -42
  138. package/build/dex/woo-fi/woo-fi-decimal-math.js.map +0 -1
  139. package/build/dex/woo-fi/woo-fi-math.d.ts +0 -31
  140. package/build/dex/woo-fi/woo-fi-math.js +0 -300
  141. package/build/dex/woo-fi/woo-fi-math.js.map +0 -1
  142. package/build/dex/woo-fi/woo-fi.d.ts +0 -65
  143. package/build/dex/woo-fi/woo-fi.js +0 -480
  144. package/build/dex/woo-fi/woo-fi.js.map +0 -1
  145. package/build/dex/woo-fi-v2/woo-fi-math.d.ts +0 -16
  146. package/build/dex/woo-fi-v2/woo-fi-math.js +0 -137
  147. package/build/dex/woo-fi-v2/woo-fi-math.js.map +0 -1
  148. package/src/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.ts +0 -28
  149. /package/src/abi/{uniswap-v3/pancakeswap-v3/PancakeswapV3QuoterV2.abi.json → pancakeswap-v3/PancakeswapV3Quoter.abi.json} +0 -0
  150. /package/src/abi/{uniswap-v3/pancakeswap-v3 → pancakeswap-v3}/PancakeswapV3Router.abi.json +0 -0
package/src/dex/index.ts CHANGED
@@ -64,8 +64,8 @@ import { QuickSwapV3 } from './quickswap/quickswap-v3';
64
64
  import { ZyberSwapV3 } from './quickswap/zyberswap-v3';
65
65
  import { TraderJoeV2 } from './trader-joe-v2';
66
66
  import { SpiritSwapV3 } from './quickswap/spiritswap-v3';
67
- import { PancakeswapV3 } from './uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3';
68
67
  import { TraderJoeV21 } from './trader-joe-v2.1';
68
+ import { PancakeswapV3 } from './pancakeswap-v3/pancakeswap-v3';
69
69
 
70
70
  const LegacyDexes = [
71
71
  CurveV2,
@@ -0,0 +1,68 @@
1
+ import { DexParams } from '../uniswap-v3/types';
2
+ import { DexConfigMap, AdapterMappings } from '../../types';
3
+ import { Network, SwapSide } from '../../constants';
4
+ import { Address } from '../../types';
5
+
6
+ const PANCAKE_SUPPORTED_FEES = [10000n, 2500n, 500n, 100n];
7
+
8
+ // Pools that will be initialized on app startup
9
+ // They are added for testing
10
+ export const PancakeswapV3Config: DexConfigMap<DexParams> = {
11
+ PancakeswapV3: {
12
+ [Network.MAINNET]: {
13
+ factory: '0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865',
14
+ deployer: '0x41ff9AA7e16B8B1a8a8dc4f0eFacd93D02d071c9',
15
+ quoter: '0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997',
16
+ router: '0x1b81D678ffb9C0263b24A97847620C99d213eB14',
17
+ supportedFees: PANCAKE_SUPPORTED_FEES,
18
+ stateMulticall: '0x80898f80cFA3Fa3AbF410d90e69aDc432AE5D4c2',
19
+ uniswapMulticall: '0xac1cE734566f390A94b00eb9bf561c2625BF44ea',
20
+ chunksCount: 10,
21
+ initHash:
22
+ '0x6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2',
23
+ subgraphURL:
24
+ 'https://api.thegraph.com/subgraphs/name/pancakeswap/exchange-v3-eth',
25
+ },
26
+ [Network.BSC]: {
27
+ factory: '0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865',
28
+ deployer: '0x41ff9AA7e16B8B1a8a8dc4f0eFacd93D02d071c9',
29
+ quoter: '0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997',
30
+ router: '0x1b81D678ffb9C0263b24A97847620C99d213eB14',
31
+ supportedFees: PANCAKE_SUPPORTED_FEES,
32
+ stateMulticall: '0x9DAd2ED7ADc6eaacf81589Cd043579c9684E5C81',
33
+ uniswapMulticall: '0xac1cE734566f390A94b00eb9bf561c2625BF44ea',
34
+ chunksCount: 10,
35
+ initHash:
36
+ '0x6ce8eb472fa82df5469c6ab6d485f17c3ad13c8cd7af59b3d4a8026c5ce0f7e2',
37
+ subgraphURL:
38
+ 'https://api.thegraph.com/subgraphs/name/pancakeswap/exchange-v3-bsc',
39
+ },
40
+ },
41
+ };
42
+
43
+ export const Adapters: Record<number, AdapterMappings> = {
44
+ [Network.MAINNET]: {
45
+ [SwapSide.SELL]: [{ name: 'Adapter01', index: 6 }],
46
+ [SwapSide.BUY]: [{ name: 'BuyAdapter', index: 2 }],
47
+ },
48
+ [Network.BSC]: {
49
+ [SwapSide.SELL]: [{ name: 'BscAdapter02', index: 4 }],
50
+ [SwapSide.BUY]: [{ name: 'BscBuyAdapter', index: 5 }],
51
+ },
52
+ [Network.POLYGON]: {
53
+ [SwapSide.SELL]: [{ name: 'PolygonAdapter01', index: 13 }],
54
+ [SwapSide.BUY]: [{ name: 'PolygonBuyAdapter', index: 2 }],
55
+ },
56
+ [Network.ARBITRUM]: {
57
+ [SwapSide.SELL]: [{ name: 'ArbitrumAdapter01', index: 3 }],
58
+ [SwapSide.BUY]: [{ name: 'ArbitrumBuyAdapter', index: 2 }],
59
+ },
60
+ [Network.OPTIMISM]: {
61
+ [SwapSide.SELL]: [{ name: 'OptimismAdapter01', index: 3 }],
62
+ [SwapSide.BUY]: [{ name: 'OptimismBuyAdapter', index: 2 }],
63
+ },
64
+ [Network.FANTOM]: {
65
+ [SwapSide.SELL]: [{ name: 'FantomAdapter01', index: 11 }],
66
+ [SwapSide.BUY]: [{ name: 'FantomBuyAdapter', index: 3 }],
67
+ },
68
+ };
@@ -0,0 +1,35 @@
1
+ export const PANCAKESWAP3_FUNCTION_CALL_GAS_COST = 21_000; // Ceiled
2
+ export const PANCAKESWAPV3_TICK_GAS_COST = 24_000; // Ceiled
3
+
4
+ // This is used for price calculation. If out of scope, return 0n
5
+ export const TICK_BITMAP_TO_USE = 4n;
6
+
7
+ // This is used to check if the state is still valid.
8
+ export const TICK_BITMAP_BUFFER = 8n;
9
+
10
+ export const MAX_PRICING_COMPUTATION_STEPS_ALLOWED = 128;
11
+
12
+ export const PANCAKESWAPV3_SUBGRAPH_URL =
13
+ 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3';
14
+
15
+ export const PANCAKESWAPV3_EFFICIENCY_FACTOR = 3;
16
+
17
+ export const ZERO_TICK_INFO = {
18
+ liquidityGross: 0n,
19
+ liquidityNet: 0n,
20
+ tickCumulativeOutside: 0n,
21
+ secondsPerLiquidityOutsideX128: 0n,
22
+ secondsOutside: 0n,
23
+ initialized: false,
24
+ };
25
+
26
+ export const ZERO_ORACLE_OBSERVATION = {
27
+ blockTimestamp: 0n,
28
+ tickCumulative: 0n,
29
+ secondsPerLiquidityCumulativeX128: 0n,
30
+ initialized: false,
31
+ };
32
+
33
+ export const OUT_OF_RANGE_ERROR_POSTFIX = `INVALID_TICK_BIT_MAP_RANGES`;
34
+
35
+ export const DEFAULT_POOL_INIT_CODE_HASH = `0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54`;
@@ -0,0 +1,90 @@
1
+ import {
2
+ BI_MAX_UINT128,
3
+ BI_MAX_UINT16,
4
+ BI_MAX_UINT32,
5
+ BI_MAX_UINT64,
6
+ BI_MAX_UINT8,
7
+ } from '../../../bigint-constants';
8
+ import { _require } from '../../../utils';
9
+
10
+ export class BitMath {
11
+ static mostSignificantBit(x: bigint): bigint {
12
+ _require(x > 0, '', { x }, 'x > 0');
13
+ let r = 0n;
14
+
15
+ if (x >= 0x100000000000000000000000000000000n) {
16
+ x >>= 128n;
17
+ r += 128n;
18
+ }
19
+ if (x >= 0x10000000000000000n) {
20
+ x >>= 64n;
21
+ r += 64n;
22
+ }
23
+ if (x >= 0x100000000n) {
24
+ x >>= 32n;
25
+ r += 32n;
26
+ }
27
+ if (x >= 0x10000n) {
28
+ x >>= 16n;
29
+ r += 16n;
30
+ }
31
+ if (x >= 0x100n) {
32
+ x >>= 8n;
33
+ r += 8n;
34
+ }
35
+ if (x >= 0x10n) {
36
+ x >>= 4n;
37
+ r += 4n;
38
+ }
39
+ if (x >= 0x4n) {
40
+ x >>= 2n;
41
+ r += 2n;
42
+ }
43
+ if (x >= 0x2n) r += 1n;
44
+
45
+ return r;
46
+ }
47
+
48
+ static leastSignificantBit(x: bigint): bigint {
49
+ _require(x > 0, '', { x }, 'x > 0');
50
+
51
+ let r = 255n;
52
+ if ((x & BI_MAX_UINT128) > 0n) {
53
+ r -= 128n;
54
+ } else {
55
+ x >>= 128n;
56
+ }
57
+ if ((x & BI_MAX_UINT64) > 0n) {
58
+ r -= 64n;
59
+ } else {
60
+ x >>= 64n;
61
+ }
62
+ if ((x & BI_MAX_UINT32) > 0n) {
63
+ r -= 32n;
64
+ } else {
65
+ x >>= 32n;
66
+ }
67
+ if ((x & BI_MAX_UINT16) > 0n) {
68
+ r -= 16n;
69
+ } else {
70
+ x >>= 16n;
71
+ }
72
+ if ((x & BI_MAX_UINT8) > 0n) {
73
+ r -= 8n;
74
+ } else {
75
+ x >>= 8n;
76
+ }
77
+ if ((x & 0xfn) > 0n) {
78
+ r -= 4n;
79
+ } else {
80
+ x >>= 4n;
81
+ }
82
+ if ((x & 0x3n) > 0n) {
83
+ r -= 2n;
84
+ } else {
85
+ x >>= 2n;
86
+ }
87
+ if ((x & 0x1n) > 0n) r -= 1n;
88
+ return r;
89
+ }
90
+ }
@@ -0,0 +1,3 @@
1
+ export class FixedPoint128 {
2
+ static readonly Q128 = 0x100000000000000000000000000000000n;
3
+ }
@@ -0,0 +1,4 @@
1
+ export class FixedPoint96 {
2
+ static readonly RESOLUTION = 96n;
3
+ static readonly Q96 = 0x1000000000000000000000000n;
4
+ }
@@ -0,0 +1,30 @@
1
+ import { BI_MAX_UINT256 } from '../../../bigint-constants';
2
+ import { _require } from '../../../utils';
3
+
4
+ export class FullMath {
5
+ static mulDiv(a: bigint, b: bigint, denominator: bigint) {
6
+ const result = (a * b) / denominator;
7
+
8
+ _require(
9
+ result <= BI_MAX_UINT256,
10
+ '',
11
+ { result, BI_MAX_UINT: BI_MAX_UINT256 },
12
+ 'result <= BI_MAX_UINT',
13
+ );
14
+
15
+ return result;
16
+ }
17
+
18
+ static mulDivRoundingUp(a: bigint, b: bigint, denominator: bigint) {
19
+ const result = (a * b + denominator - 1n) / denominator;
20
+
21
+ _require(
22
+ result <= BI_MAX_UINT256,
23
+ '',
24
+ { result, BI_MAX_UINT: BI_MAX_UINT256 },
25
+ 'result <= BI_MAX_UINT',
26
+ );
27
+
28
+ return result;
29
+ }
30
+ }
@@ -0,0 +1,17 @@
1
+ import { _require } from '../../../utils';
2
+
3
+ export class LiquidityMath {
4
+ static addDelta(x: bigint, y: bigint): bigint {
5
+ let z;
6
+ if (y < 0) {
7
+ const _y = BigInt.asUintN(128, -y);
8
+ z = x - _y;
9
+ _require(z < x, 'LS', { z, x, y, _y }, 'z < x');
10
+ } else {
11
+ const _y = BigInt.asUintN(128, y);
12
+ z = x + _y;
13
+ _require(z >= x, 'LA', { z, x, y, _y }, 'z >= x');
14
+ }
15
+ return z;
16
+ }
17
+ }
@@ -0,0 +1,226 @@
1
+ import {
2
+ OracleObservation,
3
+ OracleObservationCandidates,
4
+ PoolState,
5
+ } from '../../uniswap-v3/types';
6
+ import { _require } from '../../../utils';
7
+ import { DeepReadonly } from 'ts-essentials';
8
+ import { ZERO_ORACLE_OBSERVATION } from '../constants';
9
+
10
+ function replaceUndefinedObservationWithZero(state: PoolState, index: number) {
11
+ if (state.observations[index] === undefined) {
12
+ state.observations[index] = { ...ZERO_ORACLE_OBSERVATION };
13
+ }
14
+ }
15
+
16
+ export class Oracle {
17
+ static transform(
18
+ state: DeepReadonly<PoolState>,
19
+ last: OracleObservation,
20
+ blockTimestamp: bigint,
21
+ tick: bigint,
22
+ liquidity: bigint,
23
+ ): OracleObservation {
24
+ const delta = blockTimestamp - last.blockTimestamp;
25
+ return {
26
+ blockTimestamp: state.blockTimestamp,
27
+ tickCumulative: last.tickCumulative + BigInt.asIntN(56, tick) * delta,
28
+ secondsPerLiquidityCumulativeX128:
29
+ last.secondsPerLiquidityCumulativeX128 +
30
+ (BigInt.asUintN(160, delta) << 128n) /
31
+ (liquidity > 0n ? liquidity : 1n),
32
+ initialized: true,
33
+ };
34
+ }
35
+
36
+ static write(
37
+ state: PoolState,
38
+ index: number,
39
+ blockTimestamp: bigint,
40
+ tick: bigint,
41
+ liquidity: bigint,
42
+ cardinality: number,
43
+ cardinalityNext: number,
44
+ ): [number, number] {
45
+ const last = state.observations[index];
46
+
47
+ if (last.blockTimestamp == state.blockTimestamp)
48
+ return [index, cardinality];
49
+
50
+ let indexUpdated = 0;
51
+ let cardinalityUpdated = 0;
52
+
53
+ if (cardinalityNext > cardinality && index == cardinality - 1) {
54
+ cardinalityUpdated = cardinalityNext;
55
+ } else {
56
+ cardinalityUpdated = cardinality;
57
+ }
58
+
59
+ indexUpdated = (index + 1) % cardinalityUpdated;
60
+
61
+ state.observations[indexUpdated] = Oracle.transform(
62
+ state,
63
+ last,
64
+ blockTimestamp,
65
+ tick,
66
+ liquidity,
67
+ );
68
+ if (indexUpdated !== index) {
69
+ delete state.observations[index];
70
+ }
71
+ return [indexUpdated, cardinalityUpdated];
72
+ }
73
+
74
+ static lte(time: bigint, a: bigint, b: bigint): boolean {
75
+ if (a <= time && b <= time) return a <= b;
76
+
77
+ const aAdjusted = a > time ? a : a + 2n ** 32n;
78
+ const bAdjusted = b > time ? b : b + 2n ** 32n;
79
+ return aAdjusted <= bAdjusted;
80
+ }
81
+
82
+ static binarySearch(
83
+ state: DeepReadonly<PoolState>,
84
+ time: bigint,
85
+ target: bigint,
86
+ index: number,
87
+ cardinality: number,
88
+ ): OracleObservationCandidates {
89
+ let l = (index + 1) % cardinality;
90
+ let r = l + cardinality - 1;
91
+ let i;
92
+
93
+ let beforeOrAt;
94
+ let atOrAfter;
95
+ while (true) {
96
+ i = (l + r) / 2;
97
+
98
+ beforeOrAt = state.observations[i % cardinality];
99
+
100
+ // we've landed on an uninitialized tick, keep searching higher (more recently)
101
+ if (!beforeOrAt.initialized) {
102
+ l = i + 1;
103
+ continue;
104
+ }
105
+
106
+ atOrAfter = state.observations[(i + 1) % cardinality];
107
+
108
+ const targetAtOrAfter = Oracle.lte(
109
+ time,
110
+ beforeOrAt.blockTimestamp,
111
+ target,
112
+ );
113
+
114
+ // check if we've found the answer!
115
+ if (targetAtOrAfter && Oracle.lte(time, target, atOrAfter.blockTimestamp))
116
+ break;
117
+
118
+ if (!targetAtOrAfter) r = i - 1;
119
+ else l = i + 1;
120
+ }
121
+ return { beforeOrAt, atOrAfter };
122
+ }
123
+
124
+ static getSurroundingObservations(
125
+ state: DeepReadonly<PoolState>,
126
+ time: bigint,
127
+ target: bigint,
128
+ tick: bigint,
129
+ index: number,
130
+ liquidity: bigint,
131
+ cardinality: number,
132
+ ): OracleObservationCandidates {
133
+ let beforeOrAt = state.observations[index];
134
+
135
+ if (Oracle.lte(time, beforeOrAt.blockTimestamp, target)) {
136
+ if (beforeOrAt.blockTimestamp === target) {
137
+ return { beforeOrAt, atOrAfter: beforeOrAt };
138
+ } else {
139
+ return {
140
+ beforeOrAt,
141
+ atOrAfter: Oracle.transform(
142
+ state,
143
+ beforeOrAt,
144
+ target,
145
+ tick,
146
+ liquidity,
147
+ ),
148
+ };
149
+ }
150
+ }
151
+
152
+ beforeOrAt = state.observations[(index + 1) % cardinality];
153
+ if (!beforeOrAt.initialized) beforeOrAt = state.observations[0];
154
+
155
+ _require(
156
+ Oracle.lte(time, beforeOrAt.blockTimestamp, target),
157
+ 'OLD',
158
+ { time, beforeOrAtBlockTimestamp: beforeOrAt.blockTimestamp, target },
159
+ 'Oracle.lte(time, beforeOrAt.blockTimestamp, target)',
160
+ );
161
+
162
+ return Oracle.binarySearch(state, time, target, index, cardinality);
163
+ }
164
+
165
+ static observeSingle(
166
+ state: DeepReadonly<PoolState>,
167
+ time: bigint,
168
+ secondsAgo: bigint,
169
+ tick: bigint,
170
+ index: number,
171
+ liquidity: bigint,
172
+ cardinality: number,
173
+ ): [bigint, bigint] {
174
+ if (secondsAgo == 0n) {
175
+ let last = state.observations[index];
176
+ if (last.blockTimestamp != time)
177
+ last = Oracle.transform(state, last, time, tick, liquidity);
178
+ return [last.tickCumulative, last.secondsPerLiquidityCumulativeX128];
179
+ }
180
+
181
+ const target = time - secondsAgo;
182
+
183
+ const { beforeOrAt, atOrAfter } = Oracle.getSurroundingObservations(
184
+ state,
185
+ time,
186
+ target,
187
+ tick,
188
+ index,
189
+ liquidity,
190
+ cardinality,
191
+ );
192
+
193
+ if (target === beforeOrAt.blockTimestamp) {
194
+ return [
195
+ beforeOrAt.tickCumulative,
196
+ beforeOrAt.secondsPerLiquidityCumulativeX128,
197
+ ];
198
+ } else if (target === atOrAfter.blockTimestamp) {
199
+ return [
200
+ atOrAfter.tickCumulative,
201
+ atOrAfter.secondsPerLiquidityCumulativeX128,
202
+ ];
203
+ } else {
204
+ const observationTimeDelta =
205
+ atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;
206
+ const targetDelta = target - beforeOrAt.blockTimestamp;
207
+ return [
208
+ beforeOrAt.tickCumulative +
209
+ ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) /
210
+ observationTimeDelta) *
211
+ targetDelta,
212
+ beforeOrAt.secondsPerLiquidityCumulativeX128 +
213
+ BigInt.asUintN(
214
+ 160,
215
+ (BigInt.asUintN(
216
+ 256,
217
+ atOrAfter.secondsPerLiquidityCumulativeX128 -
218
+ beforeOrAt.secondsPerLiquidityCumulativeX128,
219
+ ) *
220
+ targetDelta) /
221
+ observationTimeDelta,
222
+ ),
223
+ ];
224
+ }
225
+ }
226
+ }