@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.
- package/CHANGELOG.md +8 -0
- package/README.md +197 -0
- package/build/addLiquidity.d.ts +67 -0
- package/build/addLiquidity.js +269 -0
- package/build/addLiquidity.js.map +1 -0
- package/build/bisect.d.ts +1 -0
- package/build/bisect.js +62 -0
- package/build/bisect.js.map +1 -0
- package/build/index.d.ts +24 -0
- package/build/index.js +76 -0
- package/build/index.js.map +1 -0
- package/build/liquidityHistogram.d.ts +50 -0
- package/build/liquidityHistogram.js +162 -0
- package/build/liquidityHistogram.js.map +1 -0
- package/build/quote.d.ts +18 -0
- package/build/quote.js +106 -0
- package/build/quote.js.map +1 -0
- package/build/swap-v2.d.ts +20 -0
- package/build/swap-v2.js +261 -0
- package/build/swap-v2.js.map +1 -0
- package/build/swap.d.ts +15 -0
- package/build/swap.js +249 -0
- package/build/swap.js.map +1 -0
- package/build/swapLegacy.d.ts +16 -0
- package/build/swapLegacy.js +229 -0
- package/build/swapLegacy.js.map +1 -0
- package/build/swapV2.d.ts +11 -0
- package/build/swapV2.js +406 -0
- package/build/swapV2.js.map +1 -0
- package/build/types.d.ts +73 -0
- package/build/types.js +9 -0
- package/build/types.js.map +1 -0
- package/build/utils.d.ts +119 -0
- package/build/utils.js +219 -0
- package/build/utils.js.map +1 -0
- package/build/utilsV2.d.ts +88 -0
- package/build/utilsV2.js +180 -0
- package/build/utilsV2.js.map +1 -0
- package/build/withdrawLiquidity.d.ts +8 -0
- package/build/withdrawLiquidity.js +174 -0
- package/build/withdrawLiquidity.js.map +1 -0
- package/build/ytTrades.d.ts +106 -0
- package/build/ytTrades.js +292 -0
- package/build/ytTrades.js.map +1 -0
- package/build/ytTradesLegacy.d.ts +106 -0
- package/build/ytTradesLegacy.js +292 -0
- package/build/ytTradesLegacy.js.map +1 -0
- package/examples/.env.example +1 -0
- package/examples/test-histogram-simple.ts +172 -0
- package/examples/test-histogram.ts +112 -0
- package/package.json +26 -0
- package/src/addLiquidity.ts +384 -0
- package/src/bisect.ts +72 -0
- package/src/index.ts +74 -0
- package/src/liquidityHistogram.ts +192 -0
- package/src/quote.ts +128 -0
- package/src/swap.ts +299 -0
- package/src/swapLegacy.ts +272 -0
- package/src/types.ts +80 -0
- package/src/utils.ts +235 -0
- package/src/withdrawLiquidity.ts +240 -0
- package/src/ytTrades.ts +419 -0
- package/tsconfig.json +17 -0
package/build/swap-v2.js
ADDED
|
@@ -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":";;;AAAA;;;;;;;GAOG;AACH,mCAA6F;AAC7F,mCASgB;AAEhB,MAAM,WAAW,GAAG,KAAK,CAAA;AAEzB;;;;GAIG;AACH,SAAgB,YAAY,CAAC,WAA6B,EAAE,IAAc;IACxE,MAAM,EAAE,UAAU,EAAE,oBAAoB,EAAE,KAAK,EAAE,GAAG,WAAW,CAAA;IAC/D,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;IAEjF,kCAAkC;IAClC,MAAM,QAAQ,GAAG,IAAI,eAAO,CAAC,IAAA,+BAAuB,EAAC,gBAAgB,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;IAE5F,gBAAgB;IAChB,IAAI,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAA;IAC7C,IAAI,wBAAwB,GAAG,KAAK,CAAC,WAAW,CAAA;IAEhD,2EAA2E;IAC3E,IAAI,kBAAkB,GAAG,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAA;IACpD,IAAI,kBAAkB,GAAG,kBAAkB,CAAA;IAE3C,OAAO;IACP,MAAM,SAAS,GAAG,IAAA,wBAAgB,EAAC,oBAAoB,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAA;IACxF,MAAM,cAAc,GAAG,oBAAoB,CAAC,cAAc,CAAA;IAE1D,qBAAqB;IACrB,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,SAAS,KAAK,qBAAa,CAAC,MAAM,EAAE,CAAC;YAC5C,IAAI,IAAI,CAAC,cAAc,GAAG,gBAAgB,EAAE,CAAC;gBAC3C,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;YACpF,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,IAAI,CAAC,cAAc,GAAG,gBAAgB,EAAE,CAAC;gBAC3C,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;YACpF,CAAC;QACH,CAAC;IACH,CAAC;IAED,eAAe;IACf,IAAI,YAAY,GAAG,CAAC,CAAA;IACpB,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,IAAI,cAAc,GAAG,CAAC,CAAA;IACtB,IAAI,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAA;IAEhC,wCAAwC;IACxC,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,MAAM,aAAa,GAAG,IAAI,CAAA,CAAC,eAAe;IAC1C,MAAM,KAAK,GAAG,KAAK,CAAA,CAAC,4BAA4B;IAEhD,IAAI,KAAK;QAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,CAAC,SAAS,cAAc,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC9F,IAAI,KAAK;QACP,OAAO,CAAC,GAAG,CACT,wBAAwB,wBAAwB,eAAe,gBAAgB,eAAe,kBAAkB,EAAE,CACnH,CAAA;IAEH,OAAO,YAAY,GAAG,CAAC,IAAI,UAAU,GAAG,aAAa,EAAE,CAAC;QACtD,UAAU,EAAE,CAAA;QACZ,IAAI,KAAK;YAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,UAAU,kBAAkB,YAAY,MAAM,CAAC,CAAA;QAEzF,yCAAyC;QACzC,MAAM,qBAAqB,GAAG,IAAA,wBAAgB,EAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;QAC/E,IAAI,KAAK;YAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,qBAAqB,EAAE,CAAC,CAAA;QAEhE,IAAI,qBAAqB,KAAK,IAAI,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,SAAS,KAAK,qBAAa,CAAC,MAAM,EAAE,CAAC;gBAC5C,iCAAiC;gBACjC,MAAM,WAAW,GAAG,IAAA,0BAAkB,EAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;gBACvE,IAAI,WAAW,KAAK,IAAI;oBAAE,MAAK;gBAE/B,gDAAgD;gBAChD,gBAAgB,GAAG,IAAA,wBAAgB,EAAC,wBAAwB,CAAC,CAAA,CAAC,0BAA0B;gBACxF,wBAAwB,GAAG,WAAW,CAAA,CAAC,oBAAoB;gBAE3D,mEAAmE;gBACnE,MAAM,YAAY,GAAG,IAAA,gBAAQ,EAAC,KAAK,EAAE,WAAW,CAAC,CAAA;gBACjD,IAAI,YAAY,EAAE,CAAC;oBACjB,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,GAAG,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;oBACrF,kBAAkB,GAAG,kBAAkB,CAAA;gBACzC,CAAC;gBACD,SAAQ;YACV,CAAC;iBAAM,CAAC;gBACN,8BAA8B;gBAC9B,MAAK;YACP,CAAC;QACH,CAAC;QAED,MAAM,kBAAkB,GAAG,qBAAqB,CAAA;QAEhD,4CAA4C;QAC5C,MAAM,WAAW,GAAG,IAAA,wBAAgB,EAAC,wBAAwB,CAAC,CAAA;QAC9D,MAAM,YAAY,GAAG,IAAA,wBAAgB,EAAC,kBAAkB,CAAC,CAAA;QAEzD,kCAAkC;QAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAA;QAE5D,yCAAyC;QACzC,MAAM,eAAe,GAAG,IAAA,gBAAQ,EAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;QACjE,MAAM,WAAW,GAAG,eAAe,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC,CAAA;QAC1D,MAAM,WAAW,GAAG,eAAe,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC,CAAA;QAE1D,MAAM,GAAG,GAAG,oBAAoB,CAAC,YAAY,CAAA;QAE7C,gEAAgE;QAChE,0CAA0C;QAC1C,MAAM,cAAc,GAAG,QAAQ,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAA;QAC/D,MAAM,eAAe,GAAG,CAAC,kBAAkB,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC,CAAA;QAC/F,MAAM,OAAO,GAAG,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAA;QAEvE,MAAM,QAAQ,GAAG,gBAAgB,GAAG,WAAW,CAAA;QAC/C,MAAM,YAAY,GAAG,kBAAkB,GAAG,QAAQ,CAAA;QAClD,MAAM,OAAO,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAA;QAEjE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,CAAA;QAC7C,MAAM,SAAS,GAAG,kBAAkB,GAAG,KAAK,CAAA;QAE5C,IAAI,IAAI,CAAC,SAAS,KAAK,qBAAa,CAAC,MAAM,EAAE,CAAC;YAC5C,oCAAoC;YACpC,MAAM,SAAS,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;YAC9D,MAAM,YAAY,GAAG,YAAY,GAAG,gBAAgB,CAAA;YACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;YAElD,IAAI,YAAY,IAAI,GAAG,EAAE,CAAC;gBACxB,iBAAiB;gBACjB,MAAM,YAAY,GAAG,IAAA,gBAAQ,EAAC,KAAK,EAAE,kBAAkB,CAAC,CAAA;gBACxD,IAAI,YAAY,EAAE,CAAC;oBACjB,kBAAkB,IAAI,YAAY,CAAC,IAAI,CAAC,YAAY,CAAA;oBACpD,kBAAkB,GAAG,kBAAkB,CAAA;gBACzC,CAAC;gBACD,wBAAwB,GAAG,kBAAkB,CAAA;gBAC7C,gBAAgB,GAAG,YAAY,CAAA;gBAC/B,SAAQ;YACV,CAAC;YAED,+BAA+B;YAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAA;YACpD,MAAM,UAAU,GAAG,gBAAgB,GAAG,QAAQ,CAAA;YAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAA;YACtD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAA;YACtF,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;YAE3D,IAAI,iBAAiB,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,WAAW,GAAG,IAAA,wBAAgB,EAAC,iBAAiB,EAAE,SAAS,CAAC,CAAA;gBAClE,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,cAAc,CAAC,GAAG,WAAW,CAAC,CAAA;gBAC/E,MAAM,QAAQ,GAAG,WAAW,GAAG,cAAc,CAAA;gBAC7C,MAAM,QAAQ,GAAG,iBAAiB,GAAG,WAAW,CAAA;gBAEhD,YAAY,IAAI,QAAQ,CAAA;gBACxB,QAAQ,IAAI,QAAQ,CAAA;gBACpB,cAAc,IAAI,cAAc,CAAA;YAClC,CAAC;YAED,YAAY,IAAI,WAAW,CAAA;YAC3B,gBAAgB,GAAG,UAAU,CAAA;YAE7B,4BAA4B;YAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,gBAAgB,CAAC,IAAI,GAAG,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;gBACzE,MAAM,YAAY,GAAG,IAAA,gBAAQ,EAAC,KAAK,EAAE,kBAAkB,CAAC,CAAA;gBACxD,IAAI,YAAY,EAAE,CAAC;oBACjB,kBAAkB,IAAI,YAAY,CAAC,IAAI,CAAC,YAAY,CAAA;oBACpD,kBAAkB,GAAG,kBAAkB,CAAA;gBACzC,CAAC;gBACD,wBAAwB,GAAG,kBAAkB,CAAA;gBAC7C,gBAAgB,GAAG,YAAY,CAAA;YACjC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,oCAAoC;YACpC,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAA;YACxD,MAAM,aAAa,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAA;YAC1F,MAAM,oBAAoB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAA;YAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAA;YAElE,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,CAAC,GAAG,CAAC,0BAA0B,aAAa,gBAAgB,oBAAoB,EAAE,CAAC,CAAA;gBAC1F,OAAO,CAAC,GAAG,CAAC,kBAAkB,YAAY,SAAS,GAAG,WAAW,KAAK,YAAY,SAAS,EAAE,CAAC,CAAA;YAChG,CAAC;YAED,IAAI,oBAAoB,IAAI,GAAG,EAAE,CAAC;gBAChC,6BAA6B;gBAC7B,MAAM,WAAW,GAAG,IAAA,0BAAkB,EAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;gBACvE,IAAI,WAAW,KAAK,IAAI;oBAAE,MAAK;gBAE/B,mEAAmE;gBACnE,MAAM,YAAY,GAAG,IAAA,gBAAQ,EAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;gBAC9D,IAAI,YAAY,EAAE,CAAC;oBACjB,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,GAAG,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;oBACrF,kBAAkB,GAAG,kBAAkB,CAAA;gBACzC,CAAC;gBAED,gBAAgB,GAAG,IAAA,wBAAgB,EAAC,wBAAwB,CAAC,CAAA;gBAC7D,wBAAwB,GAAG,WAAW,CAAA;gBACtC,SAAQ;YACV,CAAC;YAED,wDAAwD;YACxD,MAAM,OAAO,GAAG,OAAO,GAAG,YAAY,CAAA;YACtC,MAAM,YAAY,GAAG,QAAQ,CAAC,2BAA2B,CAAC,OAAO,CAAC,CAAA;YAElE,cAAc;YACd,MAAM,YAAY,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC,CAAA;YAC5E,MAAM,KAAK,GAAG,gBAAgB,GAAG,YAAY,CAAA;YAC7C,MAAM,WAAW,GAAG,SAAS,GAAG,KAAK,CAAA;YAErC,wCAAwC;YACxC,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,CAAA;YACpE,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;YAE/C,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,CAAC,GAAG,CAAC,wBAAwB,YAAY,aAAa,OAAO,kBAAkB,YAAY,EAAE,CAAC,CAAA;gBACrG,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,iBAAiB,WAAW,mBAAmB,aAAa,EAAE,CAAC,CAAA;gBAC3F,OAAO,CAAC,GAAG,CAAC,oBAAoB,cAAc,iBAAiB,WAAW,EAAE,CAAC,CAAA;YAC/E,CAAC;YAED,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;gBACxB,mCAAmC;gBACnC,MAAM,WAAW,GAAG,IAAA,0BAAkB,EAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;gBACvE,IAAI,WAAW,KAAK,IAAI;oBAAE,MAAK;gBAE/B,0BAA0B;gBAC1B,MAAM,YAAY,GAAG,IAAA,gBAAQ,EAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;gBAC9D,IAAI,YAAY,EAAE,CAAC;oBACjB,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,GAAG,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;oBACrF,kBAAkB,GAAG,kBAAkB,CAAA;gBACzC,CAAC;gBAED,gBAAgB,GAAG,IAAA,wBAAgB,EAAC,wBAAwB,CAAC,CAAA;gBAC7D,wBAAwB,GAAG,WAAW,CAAA;gBACtC,SAAQ;YACV,CAAC;YAED,yBAAyB;YACzB,MAAM,WAAW,GAAG,IAAA,wBAAgB,EAAC,aAAa,EAAE,SAAS,CAAC,CAAA;YAC9D,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,cAAc,CAAC,GAAG,WAAW,CAAC,CAAA;YAC/E,MAAM,QAAQ,GAAG,WAAW,GAAG,cAAc,CAAA;YAC7C,MAAM,QAAQ,GAAG,aAAa,GAAG,WAAW,CAAA;YAE5C,qBAAqB;YACrB,YAAY,IAAI,QAAQ,CAAA;YACxB,QAAQ,IAAI,QAAQ,CAAA;YACpB,cAAc,IAAI,cAAc,CAAA;YAEhC,kCAAkC;YAClC,YAAY,IAAI,cAAc,CAAA;YAC9B,gBAAgB,GAAG,YAAY,CAAA;YAE/B,4BAA4B;YAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,gBAAgB,GAAG,WAAW,CAAC,IAAI,GAAG,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;gBACxE,MAAM,WAAW,GAAG,IAAA,0BAAkB,EAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;gBACvE,IAAI,WAAW,KAAK,IAAI;oBAAE,MAAK;gBAE/B,0BAA0B;gBAC1B,MAAM,YAAY,GAAG,IAAA,gBAAQ,EAAC,KAAK,EAAE,wBAAwB,CAAC,CAAA;gBAC9D,IAAI,YAAY,EAAE,CAAC;oBACjB,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,GAAG,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;oBACrF,kBAAkB,GAAG,kBAAkB,CAAA;gBACzC,CAAC;gBAED,gBAAgB,GAAG,IAAA,wBAAgB,EAAC,wBAAwB,CAAC,CAAA;gBAC7D,wBAAwB,GAAG,WAAW,CAAA;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,gBAAgB,EAAE,IAAI,CAAC,QAAQ,GAAG,YAAY;QAC9C,SAAS,EAAE,YAAY;QACvB,oBAAoB,EAAE,QAAQ;QAC9B,0BAA0B,EAAE,cAAc;QAC1C,cAAc,EAAE,gBAAgB;QAChC,cAAc,EAAE,wBAAwB;KACzC,CAAA;AACH,CAAC;AAxQD,oCAwQC;AAED;;;GAGG;AACH,SAAgB,YAAY,CAAC,WAA6B,EAAE,QAAgB,EAAE,SAAwB;IACpG,OAAO,YAAY,CAAC,WAAW,EAAE;QAC/B,SAAS;QACT,QAAQ;QACR,cAAc,EAAE,WAAW,CAAC,qBAAqB;QACjD,kBAAkB,EAAE,KAAK;KAC1B,CAAC,CAAA;AACJ,CAAC;AAPD,oCAOC"}
|
package/build/swap.d.ts
ADDED
|
@@ -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;
|