@exponent-labs/market-three-math 0.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 (63) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +197 -0
  3. package/build/addLiquidity.d.ts +67 -0
  4. package/build/addLiquidity.js +269 -0
  5. package/build/addLiquidity.js.map +1 -0
  6. package/build/bisect.d.ts +1 -0
  7. package/build/bisect.js +62 -0
  8. package/build/bisect.js.map +1 -0
  9. package/build/index.d.ts +24 -0
  10. package/build/index.js +76 -0
  11. package/build/index.js.map +1 -0
  12. package/build/liquidityHistogram.d.ts +50 -0
  13. package/build/liquidityHistogram.js +162 -0
  14. package/build/liquidityHistogram.js.map +1 -0
  15. package/build/quote.d.ts +18 -0
  16. package/build/quote.js +106 -0
  17. package/build/quote.js.map +1 -0
  18. package/build/swap-v2.d.ts +20 -0
  19. package/build/swap-v2.js +261 -0
  20. package/build/swap-v2.js.map +1 -0
  21. package/build/swap.d.ts +15 -0
  22. package/build/swap.js +249 -0
  23. package/build/swap.js.map +1 -0
  24. package/build/swapLegacy.d.ts +16 -0
  25. package/build/swapLegacy.js +229 -0
  26. package/build/swapLegacy.js.map +1 -0
  27. package/build/swapV2.d.ts +11 -0
  28. package/build/swapV2.js +406 -0
  29. package/build/swapV2.js.map +1 -0
  30. package/build/types.d.ts +73 -0
  31. package/build/types.js +9 -0
  32. package/build/types.js.map +1 -0
  33. package/build/utils.d.ts +119 -0
  34. package/build/utils.js +219 -0
  35. package/build/utils.js.map +1 -0
  36. package/build/utilsV2.d.ts +88 -0
  37. package/build/utilsV2.js +180 -0
  38. package/build/utilsV2.js.map +1 -0
  39. package/build/withdrawLiquidity.d.ts +8 -0
  40. package/build/withdrawLiquidity.js +174 -0
  41. package/build/withdrawLiquidity.js.map +1 -0
  42. package/build/ytTrades.d.ts +106 -0
  43. package/build/ytTrades.js +292 -0
  44. package/build/ytTrades.js.map +1 -0
  45. package/build/ytTradesLegacy.d.ts +106 -0
  46. package/build/ytTradesLegacy.js +292 -0
  47. package/build/ytTradesLegacy.js.map +1 -0
  48. package/examples/.env.example +1 -0
  49. package/examples/test-histogram-simple.ts +172 -0
  50. package/examples/test-histogram.ts +112 -0
  51. package/package.json +26 -0
  52. package/src/addLiquidity.ts +384 -0
  53. package/src/bisect.ts +72 -0
  54. package/src/index.ts +74 -0
  55. package/src/liquidityHistogram.ts +192 -0
  56. package/src/quote.ts +128 -0
  57. package/src/swap.ts +299 -0
  58. package/src/swapLegacy.ts +272 -0
  59. package/src/types.ts +80 -0
  60. package/src/utils.ts +235 -0
  61. package/src/withdrawLiquidity.ts +240 -0
  62. package/src/ytTrades.ts +419 -0
  63. package/tsconfig.json +17 -0
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSwapQuote = exports.simulateSwap = void 0;
4
+ /**
5
+ * CLMM Swap simulation - V2
6
+ * Updated to match the latest Rust on-chain implementation
7
+ * Key changes:
8
+ * - Uses currentPrefixSum for active liquidity
9
+ * - Implements kappa scaling for principal-limited swaps
10
+ * - Correct tick key conversions (1e6 basis)
11
+ */
12
+ const types_1 = require("./types");
13
+ const utils_1 = require("./utils");
14
+ const BASE_POINTS = 10000;
15
+ /**
16
+ * Simulate a swap on the CLMM market
17
+ * This is a pure function that does not mutate the market state
18
+ * Returns the swap outcome including amounts and final state
19
+ */
20
+ function simulateSwap(marketState, args) {
21
+ const { financials, configurationOptions, ticks } = marketState;
22
+ const secondsRemaining = Math.max(0, financials.expirationTs - Date.now() / 1000);
23
+ // Create effective price snapshot
24
+ const snapshot = new utils_1.EffSnap((0, utils_1.normalizedTimeRemaining)(secondsRemaining), args.syExchangeRate);
25
+ // Current state
26
+ let currentPriceSpot = ticks.currentSpotPrice;
27
+ let currentLeftBoundaryIndex = ticks.currentTick;
28
+ // Use currentPrefixSum if available, otherwise fall back to calculating it
29
+ let activeLiquidityU64 = ticks.currentPrefixSum ?? 0;
30
+ let activeLiquidityF64 = activeLiquidityU64;
31
+ // Fees
32
+ const lpFeeRate = (0, utils_1.calculateFeeRate)(configurationOptions.lnFeeRateRoot, secondsRemaining);
33
+ const protocolFeeBps = configurationOptions.treasuryFeeBps;
34
+ // Check price limits
35
+ if (args.priceSpotLimit !== undefined) {
36
+ if (args.direction === types_1.SwapDirection.PtToSy) {
37
+ if (args.priceSpotLimit < currentPriceSpot) {
38
+ throw new Error("Price limit violated: limit must be >= current price for PtToSy");
39
+ }
40
+ }
41
+ else {
42
+ if (args.priceSpotLimit > currentPriceSpot) {
43
+ throw new Error("Price limit violated: limit must be <= current price for SyToPt");
44
+ }
45
+ }
46
+ }
47
+ // Accumulators
48
+ let amountOutNet = 0;
49
+ let feeLpOut = 0;
50
+ let feeProtocolOut = 0;
51
+ let amountInLeft = args.amountIn;
52
+ // Main loop across contiguous intervals
53
+ let iterations = 0;
54
+ const maxIterations = 1000; // Safety limit
55
+ const debug = false; // Set to true for debugging
56
+ if (debug)
57
+ console.log(`\nSwap Debug: direction=${args.direction}, amountIn=${args.amountIn}`);
58
+ if (debug)
59
+ console.log(`Initial: currentTick=${currentLeftBoundaryIndex}, spotPrice=${currentPriceSpot}, activeLiq=${activeLiquidityU64}`);
60
+ while (amountInLeft > 0 && iterations < maxIterations) {
61
+ iterations++;
62
+ if (debug)
63
+ console.log(`\n--- Iteration ${iterations}, amountInLeft=${amountInLeft} ---`);
64
+ // Get right boundary of current interval
65
+ const rightBoundaryIndexOpt = (0, utils_1.getSuccessorTick)(ticks, currentLeftBoundaryIndex);
66
+ if (debug)
67
+ console.log(`rightBoundary=${rightBoundaryIndexOpt}`);
68
+ if (rightBoundaryIndexOpt === null) {
69
+ if (args.direction === types_1.SwapDirection.SyToPt) {
70
+ // Cross to create a new interval
71
+ const predecessor = (0, utils_1.getPredecessorTick)(ticks, currentLeftBoundaryIndex);
72
+ if (predecessor === null)
73
+ break;
74
+ // When crossing downward (SyToPt), update state
75
+ currentPriceSpot = (0, utils_1.getLnImpliedRate)(currentLeftBoundaryIndex); // Boundary we're crossing
76
+ currentLeftBoundaryIndex = predecessor; // New left boundary
77
+ // Update active liquidity by subtracting liquidity_net at boundary
78
+ const boundaryTick = (0, utils_1.findTick)(ticks, predecessor);
79
+ if (boundaryTick) {
80
+ activeLiquidityU64 = Math.max(0, activeLiquidityU64 - boundaryTick.tick.liquidityNet);
81
+ activeLiquidityF64 = activeLiquidityU64;
82
+ }
83
+ continue;
84
+ }
85
+ else {
86
+ // No more liquidity available
87
+ break;
88
+ }
89
+ }
90
+ const rightBoundaryIndex = rightBoundaryIndexOpt;
91
+ // Get anchor prices for interval boundaries
92
+ const anchorULeft = (0, utils_1.getLnImpliedRate)(currentLeftBoundaryIndex);
93
+ const anchorURight = (0, utils_1.getLnImpliedRate)(rightBoundaryIndex);
94
+ // Effective price at current spot
95
+ const cEffOld = snapshot.getEffectivePrice(currentPriceSpot);
96
+ // Get principal ledgers for the interval
97
+ const currentTickData = (0, utils_1.findTick)(ticks, currentLeftBoundaryIndex);
98
+ const principalPt = currentTickData?.tick.principalPt ?? 0;
99
+ const principalSy = currentTickData?.tick.principalSy ?? 0;
100
+ const eps = configurationOptions.epsilonClamp;
101
+ // Calculate kappa (scaling factor based on available principal)
102
+ // Y_max = (L/τ) * (C(u_old) - C(u_right))
103
+ const cEffAtBoundary = snapshot.getEffectivePrice(anchorURight);
104
+ const yMaxToBoundaryF = (activeLiquidityF64 / snapshot.timeFactor) * (cEffOld - cEffAtBoundary);
105
+ const kappaSy = yMaxToBoundaryF > 0 ? principalSy / yMaxToBoundaryF : 0;
106
+ const duToLeft = currentPriceSpot - anchorULeft;
107
+ const ptMaxToLeftF = activeLiquidityF64 * duToLeft;
108
+ const kappaPt = ptMaxToLeftF > 0 ? principalPt / ptMaxToLeftF : 0;
109
+ const kappa = Math.min(kappaPt, kappaSy, 1.0);
110
+ const lTradeF64 = activeLiquidityF64 * kappa;
111
+ if (args.direction === types_1.SwapDirection.PtToSy) {
112
+ // PT -> SY swap (buying SY with PT)
113
+ const duByInput = lTradeF64 > 0 ? amountInLeft / lTradeF64 : 0;
114
+ const duToBoundary = anchorURight - currentPriceSpot;
115
+ const duActual = Math.min(duByInput, duToBoundary);
116
+ if (duToBoundary <= eps) {
117
+ // Cross boundary
118
+ const boundaryTick = (0, utils_1.findTick)(ticks, rightBoundaryIndex);
119
+ if (boundaryTick) {
120
+ activeLiquidityU64 += boundaryTick.tick.liquidityNet;
121
+ activeLiquidityF64 = activeLiquidityU64;
122
+ }
123
+ currentLeftBoundaryIndex = rightBoundaryIndex;
124
+ currentPriceSpot = anchorURight;
125
+ continue;
126
+ }
127
+ // Token flows for this segment
128
+ const ptInSegment = Math.floor(lTradeF64 * duActual);
129
+ const anchorUNew = currentPriceSpot + duActual;
130
+ const cEffNew = snapshot.getEffectivePrice(anchorUNew);
131
+ const syOutGross = Math.floor((lTradeF64 / snapshot.timeFactor) * (cEffOld - cEffNew));
132
+ const syOutGrossClamped = Math.min(syOutGross, principalSy);
133
+ if (syOutGrossClamped > 0) {
134
+ const totalFeeOut = (0, utils_1.getFeeFromAmount)(syOutGrossClamped, lpFeeRate);
135
+ const protocolFeeOut = Math.floor((totalFeeOut * protocolFeeBps) / BASE_POINTS);
136
+ const lpFeeOut = totalFeeOut - protocolFeeOut;
137
+ const syOutNet = syOutGrossClamped - totalFeeOut;
138
+ amountOutNet += syOutNet;
139
+ feeLpOut += lpFeeOut;
140
+ feeProtocolOut += protocolFeeOut;
141
+ }
142
+ amountInLeft -= ptInSegment;
143
+ currentPriceSpot = anchorUNew;
144
+ // If we hit boundary, cross
145
+ if (Math.abs(anchorURight - currentPriceSpot) <= eps && amountInLeft > 0) {
146
+ const boundaryTick = (0, utils_1.findTick)(ticks, rightBoundaryIndex);
147
+ if (boundaryTick) {
148
+ activeLiquidityU64 += boundaryTick.tick.liquidityNet;
149
+ activeLiquidityF64 = activeLiquidityU64;
150
+ }
151
+ currentLeftBoundaryIndex = rightBoundaryIndex;
152
+ currentPriceSpot = anchorURight;
153
+ }
154
+ }
155
+ else {
156
+ // SY -> PT swap (buying PT with SY)
157
+ const cEffLeft = snapshot.getEffectivePrice(anchorULeft);
158
+ const deltaCByInput = lTradeF64 > 0 ? (snapshot.timeFactor / lTradeF64) * amountInLeft : 0;
159
+ const deltaCToLeftBoundary = Math.max(0, cEffLeft - cEffOld);
160
+ const deltaCActual = Math.min(deltaCByInput, deltaCToLeftBoundary);
161
+ if (debug) {
162
+ console.log(`SyToPt deltas: byInput=${deltaCByInput}, toBoundary=${deltaCToLeftBoundary}`);
163
+ console.log(` deltaCActual=${deltaCActual}, eps=${eps}, kappa=${kappa}, lTrade=${lTradeF64}`);
164
+ }
165
+ if (deltaCToLeftBoundary <= eps) {
166
+ // Cross boundary to the left
167
+ const predecessor = (0, utils_1.getPredecessorTick)(ticks, currentLeftBoundaryIndex);
168
+ if (predecessor === null)
169
+ break;
170
+ // Update active liquidity by subtracting liquidity_net at boundary
171
+ const boundaryTick = (0, utils_1.findTick)(ticks, currentLeftBoundaryIndex);
172
+ if (boundaryTick) {
173
+ activeLiquidityU64 = Math.max(0, activeLiquidityU64 - boundaryTick.tick.liquidityNet);
174
+ activeLiquidityF64 = activeLiquidityU64;
175
+ }
176
+ currentPriceSpot = (0, utils_1.getLnImpliedRate)(currentLeftBoundaryIndex);
177
+ currentLeftBoundaryIndex = predecessor;
178
+ continue;
179
+ }
180
+ // New effective price and spot price after consuming ΔC
181
+ const cEffNew = cEffOld + deltaCActual;
182
+ const spotPriceNew = snapshot.spotPriceFromEffectivePrice(cEffNew);
183
+ // Token flows
184
+ const syInSegmentF = (lTradeF64 / snapshot.timeFactor) * (cEffNew - cEffOld);
185
+ const duAbs = currentPriceSpot - spotPriceNew;
186
+ const ptOutGrossF = lTradeF64 * duAbs;
187
+ // Clamp gross PT by available principal
188
+ const ptOutGrossU64 = Math.min(Math.floor(ptOutGrossF), principalPt);
189
+ const syInSegmentU64 = Math.floor(syInSegmentF);
190
+ if (debug) {
191
+ console.log(`SyToPt: deltaCActual=${deltaCActual}, cEffNew=${cEffNew}, spotPriceNew=${spotPriceNew}`);
192
+ console.log(` duAbs=${duAbs}, ptOutGrossF=${ptOutGrossF}, ptOutGrossU64=${ptOutGrossU64}`);
193
+ console.log(` syInSegmentU64=${syInSegmentU64}, principalPt=${principalPt}`);
194
+ }
195
+ if (ptOutGrossU64 === 0) {
196
+ // Nothing to pay out; try to cross
197
+ const predecessor = (0, utils_1.getPredecessorTick)(ticks, currentLeftBoundaryIndex);
198
+ if (predecessor === null)
199
+ break;
200
+ // Update active liquidity
201
+ const boundaryTick = (0, utils_1.findTick)(ticks, currentLeftBoundaryIndex);
202
+ if (boundaryTick) {
203
+ activeLiquidityU64 = Math.max(0, activeLiquidityU64 - boundaryTick.tick.liquidityNet);
204
+ activeLiquidityF64 = activeLiquidityU64;
205
+ }
206
+ currentPriceSpot = (0, utils_1.getLnImpliedRate)(currentLeftBoundaryIndex);
207
+ currentLeftBoundaryIndex = predecessor;
208
+ continue;
209
+ }
210
+ // Fees in token_out (PT)
211
+ const totalFeeOut = (0, utils_1.getFeeFromAmount)(ptOutGrossU64, lpFeeRate);
212
+ const protocolFeeOut = Math.floor((totalFeeOut * protocolFeeBps) / BASE_POINTS);
213
+ const lpFeeOut = totalFeeOut - protocolFeeOut;
214
+ const ptOutNet = ptOutGrossU64 - totalFeeOut;
215
+ // Accumulate to user
216
+ amountOutNet += ptOutNet;
217
+ feeLpOut += lpFeeOut;
218
+ feeProtocolOut += protocolFeeOut;
219
+ // Consume input and advance state
220
+ amountInLeft -= syInSegmentU64;
221
+ currentPriceSpot = spotPriceNew;
222
+ // If we hit boundary, cross
223
+ if (Math.abs(currentPriceSpot - anchorULeft) <= eps && amountInLeft > 0) {
224
+ const predecessor = (0, utils_1.getPredecessorTick)(ticks, currentLeftBoundaryIndex);
225
+ if (predecessor === null)
226
+ break;
227
+ // Update active liquidity
228
+ const boundaryTick = (0, utils_1.findTick)(ticks, currentLeftBoundaryIndex);
229
+ if (boundaryTick) {
230
+ activeLiquidityU64 = Math.max(0, activeLiquidityU64 - boundaryTick.tick.liquidityNet);
231
+ activeLiquidityF64 = activeLiquidityU64;
232
+ }
233
+ currentPriceSpot = (0, utils_1.getLnImpliedRate)(currentLeftBoundaryIndex);
234
+ currentLeftBoundaryIndex = predecessor;
235
+ }
236
+ }
237
+ }
238
+ return {
239
+ amountInConsumed: args.amountIn - amountInLeft,
240
+ amountOut: amountOutNet,
241
+ lpFeeChargedOutToken: feeLpOut,
242
+ protocolFeeChargedOutToken: feeProtocolOut,
243
+ finalSpotPrice: currentPriceSpot,
244
+ finalTickIndex: currentLeftBoundaryIndex,
245
+ };
246
+ }
247
+ exports.simulateSwap = simulateSwap;
248
+ /**
249
+ * Calculate the expected output for a given input amount
250
+ * This is a convenience wrapper around simulateSwap
251
+ */
252
+ function getSwapQuote(marketState, amountIn, direction) {
253
+ return simulateSwap(marketState, {
254
+ direction,
255
+ amountIn,
256
+ syExchangeRate: marketState.currentSyExchangeRate,
257
+ isCurrentFlashSwap: false,
258
+ });
259
+ }
260
+ exports.getSwapQuote = getSwapQuote;
261
+ //# sourceMappingURL=swap-v2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap-v2.js","sourceRoot":"","sources":["../src/swap-v2.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * CLMM Swap simulation - V2
3
+ * Updated to match the latest Rust on-chain implementation
4
+ * Key changes:
5
+ * - Uses currentPrefixSum for active liquidity
6
+ * - Implements kappa scaling for principal-limited swaps
7
+ * - Correct tick key conversions (1e6 basis)
8
+ */
9
+ import { MarketThreeState, SwapArgs, SwapOutcome } from "./types";
10
+ /**
11
+ * Simulate a swap on the CLMM market
12
+ * This is a pure function that does not mutate the market state
13
+ * Returns the swap outcome including amounts and final state
14
+ */
15
+ export declare function simulateSwap(marketState: MarketThreeState, args: SwapArgs): SwapOutcome;
package/build/swap.js ADDED
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.simulateSwap = void 0;
4
+ /**
5
+ * CLMM Swap simulation - V2
6
+ * Updated to match the latest Rust on-chain implementation
7
+ * Key changes:
8
+ * - Uses currentPrefixSum for active liquidity
9
+ * - Implements kappa scaling for principal-limited swaps
10
+ * - Correct tick key conversions (1e6 basis)
11
+ */
12
+ const types_1 = require("./types");
13
+ const utils_1 = require("./utils");
14
+ const BASE_POINTS = 10000;
15
+ /**
16
+ * Simulate a swap on the CLMM market
17
+ * This is a pure function that does not mutate the market state
18
+ * Returns the swap outcome including amounts and final state
19
+ */
20
+ function simulateSwap(marketState, args) {
21
+ const { financials, configurationOptions, ticks } = marketState;
22
+ const secondsRemaining = Math.max(0, Number(financials.expirationTs) - Date.now() / 1000);
23
+ // Create effective price snapshot
24
+ const snapshot = new utils_1.EffSnap((0, utils_1.normalizedTimeRemaining)(secondsRemaining), args.syExchangeRate);
25
+ // Current state
26
+ let currentPriceSpot = ticks.currentSpotPrice;
27
+ let currentLeftBoundaryIndex = ticks.currentTick;
28
+ // Use currentPrefixSum if available, otherwise fall back to calculating it
29
+ let activeLiquidityU64 = ticks.currentPrefixSum ?? 0n;
30
+ let activeLiquidityF64 = Number(activeLiquidityU64);
31
+ // Fees
32
+ const lpFeeRate = (0, utils_1.calculateFeeRate)(configurationOptions.lnFeeRateRoot, secondsRemaining);
33
+ const protocolFeeBps = configurationOptions.treasuryFeeBps;
34
+ // Check price limits
35
+ if (args.priceSpotLimit !== undefined) {
36
+ if (args.direction === types_1.SwapDirection.PtToSy) {
37
+ if (args.priceSpotLimit < currentPriceSpot) {
38
+ throw new Error("Price limit violated: limit must be >= current price for PtToSy");
39
+ }
40
+ }
41
+ else {
42
+ if (args.priceSpotLimit > currentPriceSpot) {
43
+ throw new Error("Price limit violated: limit must be <= current price for SyToPt");
44
+ }
45
+ }
46
+ }
47
+ // Accumulators
48
+ let amountOutNet = 0;
49
+ let feeLpOut = 0;
50
+ let feeProtocolOut = 0;
51
+ let amountInLeft = args.amountIn;
52
+ // Main loop across contiguous intervals
53
+ let iterations = 0;
54
+ const MAX_ITERATIONS = 1000; // Safety limit
55
+ const debug = false; // Set to true for debugging
56
+ if (debug)
57
+ console.log(`\nSwap Debug: direction=${args.direction}, amountIn=${args.amountIn}`);
58
+ if (debug)
59
+ console.log(`Initial: currentTick=${currentLeftBoundaryIndex}, spotPrice=${currentPriceSpot}, activeLiq=${activeLiquidityU64}`);
60
+ while (amountInLeft > 0 && iterations < MAX_ITERATIONS) {
61
+ iterations++;
62
+ if (debug)
63
+ console.log(`\n--- Iteration ${iterations}, amountInLeft=${amountInLeft} ---`);
64
+ // Get right boundary of current interval
65
+ const rightBoundaryIndexOpt = (0, utils_1.findTickByKey)(ticks, (0, utils_1.getSuccessorTickKey)(ticks, currentLeftBoundaryIndex))?.index;
66
+ if (debug)
67
+ console.log(`rightBoundary=${rightBoundaryIndexOpt}`);
68
+ if (rightBoundaryIndexOpt === null) {
69
+ if (args.direction === types_1.SwapDirection.SyToPt) {
70
+ // Cross to create a new interval
71
+ const predecessor = (0, utils_1.getPredecessorTickKey)(ticks, currentLeftBoundaryIndex);
72
+ if (predecessor === null)
73
+ break;
74
+ // Update active liquidity by subtracting liquidity_net at boundary
75
+ const boundaryTick = (0, utils_1.findTickByKey)(ticks, predecessor);
76
+ // When crossing downward (SyToPt), update state
77
+ currentPriceSpot = (0, utils_1.getImpliedRate)(currentLeftBoundaryIndex); // Boundary we're crossing
78
+ currentLeftBoundaryIndex = boundaryTick.index; // New left boundary
79
+ if (boundaryTick) {
80
+ activeLiquidityU64 = (0, utils_1.bigIntMax)(0n, activeLiquidityU64 - boundaryTick.tick.liquidityNet);
81
+ activeLiquidityF64 = Number(activeLiquidityU64);
82
+ }
83
+ continue;
84
+ }
85
+ else {
86
+ // No more liquidity available
87
+ break;
88
+ }
89
+ }
90
+ const rightBoundaryIndex = rightBoundaryIndexOpt ?? 0;
91
+ // Get anchor prices for interval boundaries
92
+ const anchorULeft = (0, utils_1.getImpliedRate)((0, utils_1.findTickByIndex)(ticks, currentLeftBoundaryIndex)?.apyBasePoints ?? 0);
93
+ const anchorURight = (0, utils_1.getImpliedRate)((0, utils_1.findTickByIndex)(ticks, rightBoundaryIndex)?.apyBasePoints ?? 0);
94
+ // Effective price at current spot
95
+ const cEffOld = snapshot.getEffectivePrice(currentPriceSpot);
96
+ // Get principal ledgers for the interval
97
+ const currentTickData = (0, utils_1.findTickByIndex)(ticks, currentLeftBoundaryIndex);
98
+ const principalPt = currentTickData?.principalPt ?? 0n;
99
+ const principalSy = currentTickData?.principalSy ?? 0n;
100
+ const eps = configurationOptions.epsilonClamp;
101
+ // Calculate kappa (scaling factor based on available principal)
102
+ // Y_max = (L/τ) * (C(u_old) - C(u_right))
103
+ const cEffAtBoundary = snapshot.getEffectivePrice(anchorURight);
104
+ const yMaxToBoundaryF = activeLiquidityF64 * (cEffOld - cEffAtBoundary);
105
+ const kappaSy = yMaxToBoundaryF > 0 ? Number(principalSy) / yMaxToBoundaryF : 0;
106
+ const duToLeft = currentPriceSpot - anchorULeft;
107
+ const ptMaxToLeftF = activeLiquidityF64 * duToLeft;
108
+ const kappaPt = ptMaxToLeftF > 0 ? Number(principalPt) / ptMaxToLeftF : 0;
109
+ const kappa = Math.min(kappaPt, kappaSy);
110
+ // Boundary ΔC if we go to u_right
111
+ const lTradeF64 = activeLiquidityF64 * kappa;
112
+ if (args.direction === types_1.SwapDirection.PtToSy) {
113
+ // PT -> SY swap (buying SY with PT)
114
+ const duByInput = lTradeF64 > 0 ? amountInLeft / lTradeF64 : 0;
115
+ const duToBoundary = anchorURight - currentPriceSpot;
116
+ const duActual = Math.min(duByInput, duToBoundary);
117
+ if (duToBoundary <= eps) {
118
+ // Cross boundary
119
+ const boundaryTick = (0, utils_1.findTickByIndex)(ticks, rightBoundaryIndex);
120
+ if (boundaryTick) {
121
+ activeLiquidityU64 += boundaryTick.liquidityNet;
122
+ activeLiquidityF64 = Number(activeLiquidityU64);
123
+ }
124
+ currentLeftBoundaryIndex = rightBoundaryIndex;
125
+ currentPriceSpot = anchorURight;
126
+ continue;
127
+ }
128
+ // Token flows for this segment
129
+ const ptInSegment = Math.floor(lTradeF64 * duActual);
130
+ const anchorUNew = currentPriceSpot + duActual;
131
+ const cEffNew = snapshot.getEffectivePrice(anchorUNew);
132
+ const syOutGross = Math.floor(lTradeF64 * (cEffOld - cEffNew));
133
+ const syOutGrossClamped = Math.min(syOutGross, Number(principalSy));
134
+ if (syOutGrossClamped > 0) {
135
+ const totalFeeOut = (0, utils_1.getFeeFromAmount)(syOutGrossClamped, lpFeeRate);
136
+ const protocolFeeOut = Math.floor((totalFeeOut * protocolFeeBps) / BASE_POINTS);
137
+ const lpFeeOut = totalFeeOut - protocolFeeOut;
138
+ const syOutNet = syOutGrossClamped - totalFeeOut;
139
+ amountOutNet += syOutNet;
140
+ feeLpOut += lpFeeOut;
141
+ feeProtocolOut += protocolFeeOut;
142
+ }
143
+ amountInLeft -= ptInSegment;
144
+ currentPriceSpot = anchorUNew;
145
+ // If we hit boundary, cross
146
+ if (Math.abs(anchorURight - currentPriceSpot) <= eps && amountInLeft > 0) {
147
+ const boundaryTick = (0, utils_1.findTickByIndex)(ticks, rightBoundaryIndex);
148
+ if (boundaryTick) {
149
+ activeLiquidityU64 += boundaryTick.liquidityNet;
150
+ activeLiquidityF64 = Number(activeLiquidityU64);
151
+ }
152
+ currentLeftBoundaryIndex = rightBoundaryIndex;
153
+ currentPriceSpot = anchorURight;
154
+ }
155
+ }
156
+ else {
157
+ // SY -> PT swap (buying PT with SY)
158
+ const cEffLeft = snapshot.getEffectivePrice(anchorULeft);
159
+ const deltaCByInput = lTradeF64 > 0 ? amountInLeft / lTradeF64 : 0;
160
+ const deltaCToLeftBoundary = Math.max(0, cEffLeft - cEffOld);
161
+ const deltaCActual = Math.min(deltaCByInput, deltaCToLeftBoundary);
162
+ if (debug) {
163
+ console.log(`SyToPt deltas: byInput=${deltaCByInput}, toBoundary=${deltaCToLeftBoundary}`);
164
+ console.log(` deltaCActual=${deltaCActual}, eps=${eps}, kappa=${kappa}, lTrade=${lTradeF64}`);
165
+ }
166
+ if (deltaCToLeftBoundary <= eps) {
167
+ // Cross boundary to the left
168
+ const predecessor = (0, utils_1.getPredecessorTickKey)(ticks, currentLeftBoundaryIndex);
169
+ if (predecessor === null)
170
+ break;
171
+ // Update active liquidity by subtracting liquidity_net at boundary
172
+ const boundaryTick = (0, utils_1.findTickByIndex)(ticks, currentLeftBoundaryIndex);
173
+ if (boundaryTick) {
174
+ activeLiquidityU64 = (0, utils_1.bigIntMax)(0n, activeLiquidityU64 - boundaryTick.liquidityNet);
175
+ activeLiquidityF64 = Number(activeLiquidityU64);
176
+ }
177
+ currentPriceSpot = (0, utils_1.getImpliedRate)(currentLeftBoundaryIndex);
178
+ currentLeftBoundaryIndex = predecessor;
179
+ continue;
180
+ }
181
+ // New effective price and spot price after consuming ΔC
182
+ const cEffNew = cEffOld + deltaCActual;
183
+ const spotPriceNew = snapshot.spotPriceFromEffectivePrice(cEffNew);
184
+ // Token flows
185
+ const syInSegmentF = lTradeF64 * (cEffNew - cEffOld);
186
+ const duAbs = currentPriceSpot - spotPriceNew;
187
+ const ptOutGrossF = lTradeF64 * duAbs;
188
+ // Clamp gross PT by available principal
189
+ const ptOutGrossU64 = (0, utils_1.bigIntMin)(BigInt(Math.floor(ptOutGrossF)), principalPt);
190
+ const syInSegmentU64 = BigInt(Math.floor(syInSegmentF));
191
+ if (debug) {
192
+ console.log(`SyToPt: deltaCActual=${deltaCActual}, cEffNew=${cEffNew}, spotPriceNew=${spotPriceNew}`);
193
+ console.log(` duAbs=${duAbs}, ptOutGrossF=${ptOutGrossF}, ptOutGrossU64=${ptOutGrossU64}`);
194
+ console.log(` syInSegmentU64=${syInSegmentU64}, principalPt=${principalPt}`);
195
+ }
196
+ if (ptOutGrossU64 === 0n) {
197
+ // Nothing to pay out; try to cross
198
+ const predecessor = (0, utils_1.getPredecessorTickKey)(ticks, currentLeftBoundaryIndex);
199
+ if (predecessor === null)
200
+ break;
201
+ // Update active liquidity
202
+ const boundaryTick = (0, utils_1.findTickByIndex)(ticks, currentLeftBoundaryIndex);
203
+ if (boundaryTick) {
204
+ activeLiquidityU64 = (0, utils_1.bigIntMax)(0n, activeLiquidityU64 - boundaryTick.liquidityNet);
205
+ activeLiquidityF64 = Number(activeLiquidityU64);
206
+ }
207
+ currentPriceSpot = (0, utils_1.getImpliedRate)(currentLeftBoundaryIndex);
208
+ currentLeftBoundaryIndex = predecessor;
209
+ continue;
210
+ }
211
+ // Fees in token_out (PT)
212
+ const totalFeeOut = (0, utils_1.getFeeFromAmount)(Number(ptOutGrossU64), lpFeeRate);
213
+ const protocolFeeOut = Math.floor((totalFeeOut * protocolFeeBps) / BASE_POINTS);
214
+ const lpFeeOut = totalFeeOut - protocolFeeOut;
215
+ const ptOutNet = Number(ptOutGrossU64) - totalFeeOut;
216
+ // Accumulate to user
217
+ amountOutNet += ptOutNet;
218
+ feeLpOut += lpFeeOut;
219
+ feeProtocolOut += protocolFeeOut;
220
+ // Consume input and advance state
221
+ amountInLeft -= Number(syInSegmentU64);
222
+ currentPriceSpot = spotPriceNew;
223
+ // If we hit boundary, cross
224
+ if (Math.abs(currentPriceSpot - anchorULeft) <= eps && amountInLeft > 0) {
225
+ const predecessor = (0, utils_1.getPredecessorTickKey)(ticks, currentLeftBoundaryIndex);
226
+ if (predecessor === null)
227
+ break;
228
+ // Update active liquidity
229
+ const boundaryTick = (0, utils_1.findTickByIndex)(ticks, currentLeftBoundaryIndex);
230
+ if (boundaryTick) {
231
+ activeLiquidityU64 = (0, utils_1.bigIntMax)(0n, activeLiquidityU64 - boundaryTick.liquidityNet);
232
+ activeLiquidityF64 = Number(activeLiquidityU64);
233
+ }
234
+ currentPriceSpot = (0, utils_1.getImpliedRate)(currentLeftBoundaryIndex);
235
+ currentLeftBoundaryIndex = predecessor;
236
+ }
237
+ }
238
+ }
239
+ return {
240
+ amountInConsumed: args.amountIn - amountInLeft,
241
+ amountOut: amountOutNet,
242
+ lpFeeChargedOutToken: feeLpOut,
243
+ protocolFeeChargedOutToken: feeProtocolOut,
244
+ finalSpotPrice: currentPriceSpot,
245
+ finalTickIndex: currentLeftBoundaryIndex,
246
+ };
247
+ }
248
+ exports.simulateSwap = simulateSwap;
249
+ //# sourceMappingURL=swap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap.js","sourceRoot":"","sources":["../src/swap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * CLMM Swap simulation
3
+ * Ported from exponent_clmm/src/state/market_three/helpers/swap.rs
4
+ */
5
+ import { MarketThreeState, SwapArgs, SwapDirection, SwapOutcome } from "./types";
6
+ /**
7
+ * Simulate a swap on the CLMM market
8
+ * This is a pure function that does not mutate the market state
9
+ * Returns the swap outcome including amounts and final state
10
+ */
11
+ export declare function simulateSwap(marketState: MarketThreeState, args: SwapArgs): SwapOutcome;
12
+ /**
13
+ * Calculate the expected output for a given input amount
14
+ * This is a convenience wrapper around simulateSwap
15
+ */
16
+ export declare function getSwapQuote(marketState: MarketThreeState, amountIn: number, direction: SwapDirection): SwapOutcome;