@panoptic-eng/sdk 1.0.68 → 1.0.70
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/dist/cow/index.js +47 -2
- package/dist/cow/index.js.map +1 -1
- package/dist/{cow-CGgPXhY6.js → cow-sGuN0eas.js} +1 -1
- package/dist/{greeks-CGtgLUyh.js → greeks-DNPP24KL.js} +115 -9
- package/dist/index.d.ts +67 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +161 -62
- package/dist/index.js.map +1 -1
- package/dist/{irm-BDxwCFDm.js → irm-6RzXXa1_.js} +927 -3
- package/dist/panoptic/v2/greeks/index.d.ts +7 -4
- package/dist/panoptic/v2/greeks/index.d.ts.map +1 -1
- package/dist/panoptic/v2/greeks/index.js +74 -7
- package/dist/panoptic/v2/greeks/index.js.map +1 -1
- package/dist/panoptic/v2/index.d.ts +244 -6
- package/dist/panoptic/v2/index.d.ts.map +1 -1
- package/dist/panoptic/v2/index.js +2554 -464
- package/dist/panoptic/v2/index.js.map +1 -1
- package/dist/panoptic/v2/react-public.d.ts +258 -9
- package/dist/panoptic/v2/react-public.d.ts.map +1 -1
- package/dist/panoptic/v2/react-public.js +4655 -2909
- package/dist/panoptic/v2/react-public.js.map +1 -1
- package/dist/{providers-DubVMHWU.js → providers-CbcNt27n.js} +2 -1
- package/dist/{rates-BHS-Qiu7.js → rates-DDK4ZimJ.js} +40 -4
- package/dist/{router-BW6TqwOO.js → router-njWsLvZc.js} +969 -39
- package/dist/rpc/index.d.ts +12 -1
- package/dist/rpc/index.d.ts.map +1 -1
- package/dist/rpc/index.js +65 -5
- package/dist/rpc/index.js.map +1 -1
- package/dist/uniswap/index.js +53 -13
- package/dist/uniswap/index.js.map +1 -1
- package/dist/{v2-Dgh6JxG_.js → v2-BrG4T_Gh.js} +681 -32
- package/dist/{writes-CG612Vuk.js → writes-CI6Haer-.js} +34 -3
- package/package.json +1 -1
- package/dist/router-IDtCENST.js +0 -942
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseError, ContractFunctionExecutionError, ContractFunctionRevertedError, ExecutionRevertedError, decodeAbiParameters, decodeErrorResult, decodeEventLog, decodeFunctionData, decodeFunctionResult, encodeAbiParameters, encodeFunctionData, erc20Abi, getAbiItem, getAddress, hexToString, keccak256, parseAbi, parseEventLogs, toFunctionSelector, toHex, trim, zeroAddress } from "viem";
|
|
1
|
+
import { BaseError, ContractFunctionExecutionError, ContractFunctionRevertedError, ExecutionRevertedError, decodeAbiParameters, decodeErrorResult, decodeEventLog, decodeFunctionData, decodeFunctionResult, encodeAbiParameters, encodeFunctionData, erc20Abi, getAbiItem, getAddress, hexToString, isAddress, isAddressEqual, isHex, keccak256, parseAbi, parseEventLogs, toFunctionSelector, toHex, trim, zeroAddress } from "viem";
|
|
2
2
|
import { call, multicall } from "viem/actions";
|
|
3
3
|
import Decimal from "decimal.js";
|
|
4
4
|
|
|
@@ -94,7 +94,7 @@ const UTILIZATION_DENOMINATOR = 10000n;
|
|
|
94
94
|
|
|
95
95
|
//#endregion
|
|
96
96
|
//#region src/panoptic/v2/formatters/tick.ts
|
|
97
|
-
const Q192$
|
|
97
|
+
const Q192$8 = 1n << 192n;
|
|
98
98
|
const RAW_PRICE_PRECISION = 40n;
|
|
99
99
|
function pow10$2(exponent) {
|
|
100
100
|
if (exponent < 0n) throw new RangeError("Exponent must be non-negative");
|
|
@@ -184,7 +184,7 @@ const MAX_SQRT_PRICE_X96 = tickToSqrtPriceX96(MAX_TICK);
|
|
|
184
184
|
function getPriceRatioFromSqrtPriceX96(sqrtPriceX96) {
|
|
185
185
|
return {
|
|
186
186
|
numerator: sqrtPriceX96 * sqrtPriceX96,
|
|
187
|
-
denominator: Q192$
|
|
187
|
+
denominator: Q192$8
|
|
188
188
|
};
|
|
189
189
|
}
|
|
190
190
|
function getRawPriceRatio(tick) {
|
|
@@ -586,6 +586,9 @@ var NotMarginCalledError = class extends PanopticError {
|
|
|
586
586
|
*/
|
|
587
587
|
var NotEnoughTokensError = class extends PanopticError {
|
|
588
588
|
name = "NotEnoughTokensError";
|
|
589
|
+
get deficit() {
|
|
590
|
+
return this.assetsRequested > this.assetBalance ? this.assetsRequested - this.assetBalance : 0n;
|
|
591
|
+
}
|
|
589
592
|
constructor(tokenAddress, assetsRequested, assetBalance, cause) {
|
|
590
593
|
super(`Not enough tokens: requested=${assetsRequested}, balance=${assetBalance}, token=${tokenAddress}`, cause);
|
|
591
594
|
this.tokenAddress = tokenAddress;
|
|
@@ -9079,6 +9082,39 @@ const panopticErrorsAbi = [
|
|
|
9079
9082
|
}
|
|
9080
9083
|
]
|
|
9081
9084
|
},
|
|
9085
|
+
{
|
|
9086
|
+
type: "error",
|
|
9087
|
+
name: "NotEnoughTokens",
|
|
9088
|
+
inputs: [
|
|
9089
|
+
{
|
|
9090
|
+
name: "tokenAddress",
|
|
9091
|
+
type: "address"
|
|
9092
|
+
},
|
|
9093
|
+
{
|
|
9094
|
+
name: "account",
|
|
9095
|
+
type: "address"
|
|
9096
|
+
},
|
|
9097
|
+
{
|
|
9098
|
+
name: "assetsRequested",
|
|
9099
|
+
type: "uint256"
|
|
9100
|
+
},
|
|
9101
|
+
{
|
|
9102
|
+
name: "assetBalance",
|
|
9103
|
+
type: "uint256"
|
|
9104
|
+
}
|
|
9105
|
+
]
|
|
9106
|
+
},
|
|
9107
|
+
{
|
|
9108
|
+
type: "error",
|
|
9109
|
+
name: "ExecuteError",
|
|
9110
|
+
inputs: [{
|
|
9111
|
+
name: "callIndex",
|
|
9112
|
+
type: "uint256"
|
|
9113
|
+
}, {
|
|
9114
|
+
name: "revertData",
|
|
9115
|
+
type: "bytes"
|
|
9116
|
+
}]
|
|
9117
|
+
},
|
|
9082
9118
|
{
|
|
9083
9119
|
type: "error",
|
|
9084
9120
|
name: "NotGuardian",
|
|
@@ -9220,7 +9256,7 @@ const errorConstructors = {
|
|
|
9220
9256
|
AccountInsolvent: (args, cause) => new AccountInsolventError(args[0], args[1], cause),
|
|
9221
9257
|
NotMarginCalled: (_args, cause) => new NotMarginCalledError(cause),
|
|
9222
9258
|
CreateFail: (_args, cause) => new CreateFailError(cause),
|
|
9223
|
-
NotEnoughTokens: (args, cause) => new NotEnoughTokensError(args[0], args[1], args[2], cause),
|
|
9259
|
+
NotEnoughTokens: (args, cause) => new NotEnoughTokensError(args[0], args[args.length === 4 ? 2 : 1], args[args.length === 4 ? 3 : 2], cause),
|
|
9224
9260
|
NotEnoughLiquidityInChunk: (_args, cause) => new NotEnoughLiquidityInChunkError(cause),
|
|
9225
9261
|
InsufficientCreditLiquidity: (_args, cause) => new InsufficientCreditLiquidityError(cause),
|
|
9226
9262
|
DepositTooLarge: (_args, cause) => new DepositTooLargeError(cause),
|
|
@@ -10032,7 +10068,7 @@ function hasLoanOrCredit(tokenId) {
|
|
|
10032
10068
|
const POOL_ID_MASK$4 = (1n << 64n) - 1n;
|
|
10033
10069
|
const MAX_LEGS = TOKEN_ID_BITS.MAX_LEGS;
|
|
10034
10070
|
const MAX_OPTION_RATIO = LEG_LIMITS.MAX_RATIO;
|
|
10035
|
-
const Q192$
|
|
10071
|
+
const Q192$7 = 1n << 192n;
|
|
10036
10072
|
/**
|
|
10037
10073
|
* Floor integer square root for bigints (Newton's method). Mirrors the isqrt
|
|
10038
10074
|
* used in reads/collateralEstimate.ts (buildNeutralLeg).
|
|
@@ -10079,7 +10115,7 @@ function computeTinyCreditSignedStrike(positionSize, tickSpacing) {
|
|
|
10079
10115
|
const maxSafe = MAX_TICK - tickSpacing - 1n;
|
|
10080
10116
|
let signedStrike;
|
|
10081
10117
|
try {
|
|
10082
|
-
const sqrtKrawX96 = isqrt$1(TINY_CREDIT_TARGET_NOTIONAL_WEI * Q192$
|
|
10118
|
+
const sqrtKrawX96 = isqrt$1(TINY_CREDIT_TARGET_NOTIONAL_WEI * Q192$7 / positionSize);
|
|
10083
10119
|
signedStrike = sqrtPriceX96ToTick(sqrtKrawX96);
|
|
10084
10120
|
} catch {
|
|
10085
10121
|
signedStrike = minSafe;
|
|
@@ -10951,7 +10987,7 @@ function formatGwei(wei, precision) {
|
|
|
10951
10987
|
//#region src/panoptic/v2/tokenId/generateOverlapping.ts
|
|
10952
10988
|
const MAX_UINT64$2 = (1n << 64n) - 1n;
|
|
10953
10989
|
const MAX_UINT128$4 = (1n << 128n) - 1n;
|
|
10954
|
-
const Q192$
|
|
10990
|
+
const Q192$6 = 1n << 192n;
|
|
10955
10991
|
const MAX_TOKEN_DECIMALS = 255n;
|
|
10956
10992
|
const MAX_DECIMAL_EXPONENT = 512n;
|
|
10957
10993
|
function invalid$1(message) {
|
|
@@ -10997,7 +11033,7 @@ function quotePriceAtTick(tick, asset, assetDecimals, quoteDecimals) {
|
|
|
10997
11033
|
const orientedTick = asset === 0n ? tick : -tick;
|
|
10998
11034
|
const sqrtPriceX96 = tickToSqrtPriceX96(orientedTick);
|
|
10999
11035
|
let numerator = sqrtPriceX96 * sqrtPriceX96;
|
|
11000
|
-
let denominator = Q192$
|
|
11036
|
+
let denominator = Q192$6;
|
|
11001
11037
|
const decimalDifference = assetDecimals - quoteDecimals;
|
|
11002
11038
|
if (decimalDifference > 0n) numerator *= pow10$1(decimalDifference);
|
|
11003
11039
|
else if (decimalDifference < 0n) denominator *= pow10$1(-decimalDifference);
|
|
@@ -11017,7 +11053,7 @@ function isPriceGridStrike(strike, params, spacing, tickSpacing) {
|
|
|
11017
11053
|
}
|
|
11018
11054
|
return false;
|
|
11019
11055
|
}
|
|
11020
|
-
function ceilDiv$
|
|
11056
|
+
function ceilDiv$6(value, divisor) {
|
|
11021
11057
|
const quotient = value / divisor;
|
|
11022
11058
|
const remainder = value % divisor;
|
|
11023
11059
|
return remainder > 0n ? quotient + 1n : quotient;
|
|
@@ -11050,7 +11086,7 @@ function resolveLegs(legs) {
|
|
|
11050
11086
|
function getCandidateStrikes(params, spacing, tickSpacing, halfWidth) {
|
|
11051
11087
|
const lower = MIN_TICK + halfWidth > params.currentTick - halfWidth + 1n ? MIN_TICK + halfWidth : params.currentTick - halfWidth + 1n;
|
|
11052
11088
|
const upper = MAX_TICK - halfWidth < params.currentTick + halfWidth - 1n ? MAX_TICK - halfWidth : params.currentTick + halfWidth - 1n;
|
|
11053
|
-
const firstStrike = ceilDiv$
|
|
11089
|
+
const firstStrike = ceilDiv$6(lower, tickSpacing) * tickSpacing;
|
|
11054
11090
|
const lastStrike = floorDiv$1(upper, tickSpacing) * tickSpacing;
|
|
11055
11091
|
const strikes = [];
|
|
11056
11092
|
for (let strike = firstStrike; strike <= lastStrike; strike += tickSpacing) if (isPriceGridStrike(strike, params, spacing, tickSpacing)) strikes.push(strike);
|
|
@@ -11272,10 +11308,41 @@ function splitTokenIdByTimescale(tokenId, positionSize, targetTimescale) {
|
|
|
11272
11308
|
};
|
|
11273
11309
|
}
|
|
11274
11310
|
|
|
11311
|
+
//#endregion
|
|
11312
|
+
//#region src/panoptic/v2/tokenId/validate.ts
|
|
11313
|
+
/**
|
|
11314
|
+
* Validate a TokenId's structure using the rules of TokenId.validate.
|
|
11315
|
+
* This does not check pool registration, available liquidity, or account collateral.
|
|
11316
|
+
*/
|
|
11317
|
+
function getTokenIdValidationError(tokenId) {
|
|
11318
|
+
if (tokenId < 0n || tokenId >= 1n << 256n) return "Token ID must fit in uint256.";
|
|
11319
|
+
const legs = [];
|
|
11320
|
+
for (let index = 0n; index < TOKEN_ID_BITS.MAX_LEGS; index++) {
|
|
11321
|
+
const leg = decodeLeg(tokenId, index);
|
|
11322
|
+
if (leg.optionRatio === 0n) {
|
|
11323
|
+
const offset = TOKEN_ID_BITS.POOL_ID_SIZE + index * TOKEN_ID_BITS.LEG_SIZE;
|
|
11324
|
+
if (tokenId >> offset !== 0n) return "Position contains empty or non-contiguous legs.";
|
|
11325
|
+
break;
|
|
11326
|
+
}
|
|
11327
|
+
legs.push(leg);
|
|
11328
|
+
}
|
|
11329
|
+
if (legs.length === 0) return "Position must contain at least one leg.";
|
|
11330
|
+
const chunks = new Set();
|
|
11331
|
+
for (const leg of legs) {
|
|
11332
|
+
const chunk = `${leg.strike}:${leg.width}:${leg.tokenType}`;
|
|
11333
|
+
if (chunks.has(chunk)) return "Position contains duplicate legs sharing the same liquidity chunk.";
|
|
11334
|
+
chunks.add(chunk);
|
|
11335
|
+
if (leg.strike <= -887272n || leg.strike >= 887272n) return "Position strike must be inside the pool tick bounds.";
|
|
11336
|
+
const partner = legs[Number(leg.riskPartner)];
|
|
11337
|
+
if (!partner || partner.riskPartner !== leg.index) return "Position risk partners must reference existing legs and be mutual.";
|
|
11338
|
+
}
|
|
11339
|
+
return null;
|
|
11340
|
+
}
|
|
11341
|
+
|
|
11275
11342
|
//#endregion
|
|
11276
11343
|
//#region src/uniswap/lpDeposit.ts
|
|
11277
|
-
const Q96$
|
|
11278
|
-
const ceilDiv$
|
|
11344
|
+
const Q96$6 = 1n << 96n;
|
|
11345
|
+
const ceilDiv$5 = (n, d) => (n + d - 1n) / d;
|
|
11279
11346
|
/** Principal and separately identified funding headroom, in native token units. */
|
|
11280
11347
|
function getLpDepositBreakdown(ranges, sqrtPriceX96) {
|
|
11281
11348
|
if (sqrtPriceX96 <= 0n) throw new Error("Invalid pool price");
|
|
@@ -11286,12 +11353,12 @@ function getLpDepositBreakdown(ranges, sqrtPriceX96) {
|
|
|
11286
11353
|
const lower = tickToSqrtPriceX96(BigInt(tickLower));
|
|
11287
11354
|
const upper = tickToSqrtPriceX96(BigInt(tickUpper));
|
|
11288
11355
|
const price = sqrtPriceX96 < lower ? lower : sqrtPriceX96 > upper ? upper : sqrtPriceX96;
|
|
11289
|
-
amount0 += ceilDiv$
|
|
11290
|
-
amount1 += ceilDiv$
|
|
11356
|
+
amount0 += ceilDiv$5(liquidity * Q96$6 * (upper - price), upper * price);
|
|
11357
|
+
amount1 += ceilDiv$5(liquidity * (price - lower), Q96$6);
|
|
11291
11358
|
}
|
|
11292
11359
|
const buffer = {
|
|
11293
|
-
amount0: ceilDiv$
|
|
11294
|
-
amount1: ceilDiv$
|
|
11360
|
+
amount0: ceilDiv$5(amount0 * 5n, 100n),
|
|
11361
|
+
amount1: ceilDiv$5(amount1 * 5n, 100n)
|
|
11295
11362
|
};
|
|
11296
11363
|
return {
|
|
11297
11364
|
principal: {
|
|
@@ -11315,7 +11382,7 @@ function getUnhedgedLpRanges({ tokenId, positionSize, tickSpacing }) {
|
|
|
11315
11382
|
const lower = tickToSqrtPriceX96(tickLower);
|
|
11316
11383
|
const upper = tickToSqrtPriceX96(tickUpper);
|
|
11317
11384
|
const amount = positionSize * leg.optionRatio;
|
|
11318
|
-
const liquidity = leg.asset === 0n ? amount * (lower * upper / Q96$
|
|
11385
|
+
const liquidity = leg.asset === 0n ? amount * (lower * upper / Q96$6) / (upper - lower) : amount * Q96$6 / (upper - lower);
|
|
11319
11386
|
return liquidity <= 0n ? [] : [{
|
|
11320
11387
|
tickLower: Number(tickLower),
|
|
11321
11388
|
tickUpper: Number(tickUpper),
|
|
@@ -11336,7 +11403,7 @@ function getLpPositionFunding(params) {
|
|
|
11336
11403
|
});
|
|
11337
11404
|
const breakdown = getLpDepositBreakdown(ranges, sqrtPriceX96);
|
|
11338
11405
|
const priceSquared = valuationSqrtPriceX96 * valuationSqrtPriceX96;
|
|
11339
|
-
const value = ({ amount0, amount1 }) => quoteTokenIndex === 0 ? amount0 + ceilDiv$
|
|
11406
|
+
const value = ({ amount0, amount1 }) => quoteTokenIndex === 0 ? amount0 + ceilDiv$5(amount1 * Q96$6 * Q96$6, priceSquared) : amount1 + ceilDiv$5(amount0 * priceSquared, Q96$6 * Q96$6);
|
|
11340
11407
|
const principalInQuote = value(breakdown.principal);
|
|
11341
11408
|
const totalInQuote = value(breakdown.total);
|
|
11342
11409
|
return {
|
|
@@ -11358,7 +11425,7 @@ function getMaxLpPositionSize(params) {
|
|
|
11358
11425
|
...params,
|
|
11359
11426
|
positionSize: mid
|
|
11360
11427
|
});
|
|
11361
|
-
const minimum = params.minimumRequirement ? ceilDiv$
|
|
11428
|
+
const minimum = params.minimumRequirement ? ceilDiv$5(params.minimumRequirement.requiredInQuote * mid, params.minimumRequirement.referenceSize) : 0n;
|
|
11362
11429
|
if (funding.totalInQuote <= params.availableInQuote && minimum <= params.availableInQuote) low = mid;
|
|
11363
11430
|
else high = mid - 1n;
|
|
11364
11431
|
}
|
|
@@ -12818,7 +12885,7 @@ async function submitWriteRequest(params) {
|
|
|
12818
12885
|
* Exported so callers can display the constant; prefer {@link applyMintBuffer}
|
|
12819
12886
|
* over multiplying by it directly, which is how the rounding bug reappears.
|
|
12820
12887
|
*/
|
|
12821
|
-
const MINT_BUFFER =
|
|
12888
|
+
const MINT_BUFFER = 10750000n;
|
|
12822
12889
|
/** `RiskEngine.DECIMALS` — the denominator {@link MINT_BUFFER} is taken over. */
|
|
12823
12890
|
const MINT_BUFFER_DENOMINATOR = 10000000n;
|
|
12824
12891
|
/** The compiled-in default, matching the deployed RiskEngine. */
|
|
@@ -14547,11 +14614,76 @@ async function assertLpPositionFunded(params) {
|
|
|
14547
14614
|
return funding;
|
|
14548
14615
|
}
|
|
14549
14616
|
|
|
14617
|
+
//#endregion
|
|
14618
|
+
//#region src/uniswap/lpGreeks.ts
|
|
14619
|
+
const Q96$5 = 1n << 96n;
|
|
14620
|
+
const Q192$5 = 1n << 192n;
|
|
14621
|
+
/**
|
|
14622
|
+
* Compute the token0/token1 amounts backing `liquidity` over `[sqrtA, sqrtB]`
|
|
14623
|
+
* at the current price `sqrtP`, mirroring Uniswap's `LiquidityAmounts`
|
|
14624
|
+
* (`getAmountsForLiquidity`). All sqrt prices are X96. The current price is
|
|
14625
|
+
* clamped into the range, so out-of-range positions collapse to a single token.
|
|
14626
|
+
*/
|
|
14627
|
+
function getAmountsForLiquidity(sqrtPriceX96, sqrtRatioAX96, sqrtRatioBX96, liquidity) {
|
|
14628
|
+
const [sqrtA, sqrtB] = sqrtRatioAX96 <= sqrtRatioBX96 ? [sqrtRatioAX96, sqrtRatioBX96] : [sqrtRatioBX96, sqrtRatioAX96];
|
|
14629
|
+
const sqrtC = sqrtPriceX96 < sqrtA ? sqrtA : sqrtPriceX96 > sqrtB ? sqrtB : sqrtPriceX96;
|
|
14630
|
+
const amount0 = sqrtC < sqrtB ? liquidity * (sqrtB - sqrtC) * Q96$5 / (sqrtC * sqrtB) : 0n;
|
|
14631
|
+
const amount1 = sqrtC > sqrtA ? liquidity * (sqrtC - sqrtA) / Q96$5 : 0n;
|
|
14632
|
+
return {
|
|
14633
|
+
amount0,
|
|
14634
|
+
amount1
|
|
14635
|
+
};
|
|
14636
|
+
}
|
|
14637
|
+
|
|
14638
|
+
//#endregion
|
|
14639
|
+
//#region src/panoptic/v2/greeks/legLiquidity.ts
|
|
14640
|
+
const Q96$4 = 1n << 96n;
|
|
14641
|
+
function divCeil(numerator, denominator) {
|
|
14642
|
+
return (numerator + denominator - 1n) / denominator;
|
|
14643
|
+
}
|
|
14644
|
+
/** The Uniswap range and liquidity backing one option leg, with the contract's rounding. */
|
|
14645
|
+
function getLegLiquidityRange(leg, positionSize, tickSpacing) {
|
|
14646
|
+
const width = leg.width * tickSpacing;
|
|
14647
|
+
const lowerTick = leg.strike - width / 2n;
|
|
14648
|
+
const upperTick = leg.strike + (width + 1n) / 2n;
|
|
14649
|
+
if (lowerTick < -887272n || upperTick > 887272n || lowerTick >= upperTick) throw new RangeError("Invalid position range");
|
|
14650
|
+
const sqrtLower = tickToSqrtPriceX96(lowerTick);
|
|
14651
|
+
const sqrtUpper = tickToSqrtPriceX96(upperTick);
|
|
14652
|
+
const amount = positionSize * leg.optionRatio;
|
|
14653
|
+
const liquidity = leg.asset === 0n ? amount * (sqrtLower * sqrtUpper / Q96$4) / (sqrtUpper - sqrtLower) : amount * Q96$4 / (sqrtUpper - sqrtLower);
|
|
14654
|
+
return {
|
|
14655
|
+
lowerTick,
|
|
14656
|
+
upperTick,
|
|
14657
|
+
sqrtLower,
|
|
14658
|
+
sqrtUpper,
|
|
14659
|
+
liquidity
|
|
14660
|
+
};
|
|
14661
|
+
}
|
|
14662
|
+
/**
|
|
14663
|
+
* One option leg's signed holding of `tokenIndex` at `currentTick`: the amount
|
|
14664
|
+
* its liquidity holds minus the amount the leg moved, positive for short legs.
|
|
14665
|
+
*/
|
|
14666
|
+
function getLegTokenInventory(leg, currentTick, positionSize, tickSpacing, tokenIndex) {
|
|
14667
|
+
const { sqrtLower, sqrtUpper, liquidity } = getLegLiquidityRange(leg, positionSize, tickSpacing);
|
|
14668
|
+
const held = getAmountsForLiquidity(tickToSqrtPriceX96(currentTick), sqrtLower, sqrtUpper, liquidity);
|
|
14669
|
+
const heldAmount = tokenIndex === 0n ? held.amount0 : held.amount1;
|
|
14670
|
+
let movedAmount = 0n;
|
|
14671
|
+
if (leg.tokenType === tokenIndex) {
|
|
14672
|
+
const span = sqrtUpper - sqrtLower;
|
|
14673
|
+
if (tokenIndex === 0n) {
|
|
14674
|
+
const scaled = (liquidity << 96n) * span;
|
|
14675
|
+
movedAmount = leg.isLong ? scaled / sqrtUpper / sqrtLower : divCeil(divCeil(scaled, sqrtUpper), sqrtLower);
|
|
14676
|
+
} else movedAmount = leg.isLong ? liquidity * span / Q96$4 : divCeil(liquidity * span, Q96$4);
|
|
14677
|
+
}
|
|
14678
|
+
const net = heldAmount - movedAmount;
|
|
14679
|
+
return leg.isLong ? -net : net;
|
|
14680
|
+
}
|
|
14681
|
+
|
|
14550
14682
|
//#endregion
|
|
14551
14683
|
//#region src/panoptic/v2/greeks/index.ts
|
|
14552
14684
|
/** Fixed-point scale constants for sqrtPriceX96 arithmetic */
|
|
14553
|
-
const Q96$
|
|
14554
|
-
const Q192$
|
|
14685
|
+
const Q96$3 = 1n << 96n;
|
|
14686
|
+
const Q192$4 = 1n << 192n;
|
|
14555
14687
|
/**
|
|
14556
14688
|
* Convert tick to quote-denominated tick based on asset direction.
|
|
14557
14689
|
*
|
|
@@ -14605,7 +14737,7 @@ function computeWidth0Notional(leg, m) {
|
|
|
14605
14737
|
const signedStrike = leg.asset === 0n ? leg.strike : -leg.strike;
|
|
14606
14738
|
const sqrtKraw = tickToSqrtPriceX96(signedStrike);
|
|
14607
14739
|
const KrawX192 = sqrtKraw * sqrtKraw;
|
|
14608
|
-
return divTrunc(m * KrawX192, Q192$
|
|
14740
|
+
return divTrunc(m * KrawX192, Q192$4);
|
|
14609
14741
|
}
|
|
14610
14742
|
/**
|
|
14611
14743
|
* Calculate value for a width=0 (loan/credit) leg.
|
|
@@ -14625,7 +14757,7 @@ function getLegValueWidth0(leg, m, qCurrentTick, qStrikeTick, qMintTick, isAsset
|
|
|
14625
14757
|
const sqrtPm = tickToSqrtPriceX96(qMintTick);
|
|
14626
14758
|
const PX192 = sqrtP * sqrtP;
|
|
14627
14759
|
const PmX192 = sqrtPm * sqrtPm;
|
|
14628
|
-
return divTrunc(-notional * (PX192 - PmX192), Q192$
|
|
14760
|
+
return divTrunc(-notional * (PX192 - PmX192), Q192$4);
|
|
14629
14761
|
} else return 0n;
|
|
14630
14762
|
}
|
|
14631
14763
|
/**
|
|
@@ -14654,7 +14786,7 @@ function getLegNetValueWidth0(leg, m, qCurrentTick, qMintTick, isAssetToken0, sw
|
|
|
14654
14786
|
const sqrtPm = tickToSqrtPriceX96(qMintTick);
|
|
14655
14787
|
const PX192 = sqrtP * sqrtP;
|
|
14656
14788
|
const PmX192 = sqrtPm * sqrtPm;
|
|
14657
|
-
if (borrowsAsset) return divTrunc(-notional * (PX192 - PmX192), Q192$
|
|
14789
|
+
if (borrowsAsset) return divTrunc(-notional * (PX192 - PmX192), Q192$4);
|
|
14658
14790
|
return divTrunc(notional * PX192, PmX192) - notional;
|
|
14659
14791
|
}
|
|
14660
14792
|
/**
|
|
@@ -14676,7 +14808,7 @@ function computeOptionItm(m, qStrikeTick, qMintTick, halfWidthTick, isPut) {
|
|
|
14676
14808
|
const sqrtPm$2 = tickToSqrtPriceX96(qMintTick);
|
|
14677
14809
|
const KX192 = sqrtK$1 * sqrtK$1;
|
|
14678
14810
|
const PmX192 = sqrtPm$2 * sqrtPm$2;
|
|
14679
|
-
return divTrunc(m * (KX192 - PmX192), Q192$
|
|
14811
|
+
return divTrunc(m * (KX192 - PmX192), Q192$4);
|
|
14680
14812
|
} else if (qMintTick > qStrikeTick + halfWidthTick) return 0n;
|
|
14681
14813
|
const sqrtKR = tickToSqrtPriceX96(qStrikeTick + halfWidthTick);
|
|
14682
14814
|
const sqrtPm$1 = tickToSqrtPriceX96(qMintTick);
|
|
@@ -14684,7 +14816,7 @@ function computeOptionItm(m, qStrikeTick, qMintTick, halfWidthTick, isPut) {
|
|
|
14684
14816
|
const rX192$1 = sqrtR$1 * sqrtR$1;
|
|
14685
14817
|
const diff$1 = sqrtKR - sqrtPm$1;
|
|
14686
14818
|
const diffSqX192$1 = diff$1 * diff$1;
|
|
14687
|
-
return divTrunc(m * diffSqX192$1, rX192$1 - Q192$
|
|
14819
|
+
return divTrunc(m * diffSqX192$1, rX192$1 - Q192$4);
|
|
14688
14820
|
}
|
|
14689
14821
|
if (qMintTick < qStrikeTick - halfWidthTick) return 0n;
|
|
14690
14822
|
else if (qMintTick > qStrikeTick + halfWidthTick) {
|
|
@@ -14698,10 +14830,10 @@ function computeOptionItm(m, qStrikeTick, qMintTick, halfWidthTick, isPut) {
|
|
|
14698
14830
|
const sqrtK = tickToSqrtPriceX96(qStrikeTick);
|
|
14699
14831
|
const sqrtPm = tickToSqrtPriceX96(qMintTick);
|
|
14700
14832
|
const rX192 = sqrtR * sqrtR;
|
|
14701
|
-
const sqrtKPmX96 = divTrunc(sqrtK * Q96$
|
|
14833
|
+
const sqrtKPmX96 = divTrunc(sqrtK * Q96$3, sqrtPm);
|
|
14702
14834
|
const diff = sqrtR - sqrtKPmX96;
|
|
14703
14835
|
const diffSqX192 = diff * diff;
|
|
14704
|
-
return divTrunc(m * diffSqX192, rX192 - Q192$
|
|
14836
|
+
return divTrunc(m * diffSqX192, rX192 - Q192$4);
|
|
14705
14837
|
}
|
|
14706
14838
|
/**
|
|
14707
14839
|
* Check if leg is a call option (vs put).
|
|
@@ -14757,11 +14889,11 @@ function getLegValue(leg, currentTick, mintTick, positionSize, poolTickSpacing,
|
|
|
14757
14889
|
if (qCurrentTick < qStrikeTick - halfWidthTick) {
|
|
14758
14890
|
const sqrtP = tickToSqrtPriceX96(qCurrentTick);
|
|
14759
14891
|
const PX192 = sqrtP * sqrtP;
|
|
14760
|
-
v = divTrunc(m * PX192, Q192$
|
|
14892
|
+
v = divTrunc(m * PX192, Q192$4);
|
|
14761
14893
|
} else if (qCurrentTick > qStrikeTick + halfWidthTick) {
|
|
14762
14894
|
const sqrtK = tickToSqrtPriceX96(qStrikeTick);
|
|
14763
14895
|
const KX192 = sqrtK * sqrtK;
|
|
14764
|
-
v = divTrunc(m * KX192, Q192$
|
|
14896
|
+
v = divTrunc(m * KX192, Q192$4);
|
|
14765
14897
|
} else {
|
|
14766
14898
|
const sqrtP = tickToSqrtPriceX96(qCurrentTick);
|
|
14767
14899
|
const sqrtK = tickToSqrtPriceX96(qStrikeTick);
|
|
@@ -14770,8 +14902,8 @@ function getLegValue(leg, currentTick, mintTick, positionSize, poolTickSpacing,
|
|
|
14770
14902
|
const PX192 = sqrtP * sqrtP;
|
|
14771
14903
|
const KX192 = sqrtK * sqrtK;
|
|
14772
14904
|
const rX192 = sqrtR * sqrtR;
|
|
14773
|
-
const numerator = m * (2n * sqrtPKR * Q96$
|
|
14774
|
-
const denominator = rX192 - Q192$
|
|
14905
|
+
const numerator = m * (2n * sqrtPKR * Q96$3 - PX192 - KX192);
|
|
14906
|
+
const denominator = rX192 - Q192$4;
|
|
14775
14907
|
v = divTrunc(numerator, denominator);
|
|
14776
14908
|
}
|
|
14777
14909
|
const debt = -m;
|
|
@@ -14780,19 +14912,19 @@ function getLegValue(leg, currentTick, mintTick, positionSize, poolTickSpacing,
|
|
|
14780
14912
|
if (isPut) {
|
|
14781
14913
|
const sqrtK = tickToSqrtPriceX96(qStrikeTick);
|
|
14782
14914
|
const KX192 = sqrtK * sqrtK;
|
|
14783
|
-
const debtK = divTrunc(debt * KX192, Q192$
|
|
14915
|
+
const debtK = divTrunc(debt * KX192, Q192$4);
|
|
14784
14916
|
return debtK + v + itm;
|
|
14785
14917
|
} else {
|
|
14786
14918
|
const sqrtP = tickToSqrtPriceX96(qCurrentTick);
|
|
14787
14919
|
const PX192 = sqrtP * sqrtP;
|
|
14788
|
-
const debtP = divTrunc(debt * PX192, Q192$
|
|
14920
|
+
const debtP = divTrunc(debt * PX192, Q192$4);
|
|
14789
14921
|
if (definedRisk) {
|
|
14790
14922
|
const sqrtPm = tickToSqrtPriceX96(qMintTick);
|
|
14791
14923
|
const PmX192 = sqrtPm * sqrtPm;
|
|
14792
|
-
const itmPm = divTrunc(itm * PmX192, Q192$
|
|
14924
|
+
const itmPm = divTrunc(itm * PmX192, Q192$4);
|
|
14793
14925
|
return debtP + v + itmPm;
|
|
14794
14926
|
} else {
|
|
14795
|
-
const itmP = divTrunc(itm * PX192, Q192$
|
|
14927
|
+
const itmP = divTrunc(itm * PX192, Q192$4);
|
|
14796
14928
|
return debtP + v + itmP;
|
|
14797
14929
|
}
|
|
14798
14930
|
}
|
|
@@ -14828,7 +14960,7 @@ function getLegDelta(leg, currentTick, positionSize, poolTickSpacing, mintTick,
|
|
|
14828
14960
|
const signedStrike = leg.asset === 0n ? leg.strike : -leg.strike;
|
|
14829
14961
|
const sqrtKraw = tickToSqrtPriceX96(signedStrike);
|
|
14830
14962
|
const KrawX192 = sqrtKraw * sqrtKraw;
|
|
14831
|
-
const notional = divTrunc(m * KrawX192, Q192$
|
|
14963
|
+
const notional = divTrunc(m * KrawX192, Q192$4);
|
|
14832
14964
|
return -notional;
|
|
14833
14965
|
}
|
|
14834
14966
|
if (halfWidthTick === 0n) {
|
|
@@ -14857,8 +14989,8 @@ function getLegDelta(leg, currentTick, positionSize, poolTickSpacing, mintTick,
|
|
|
14857
14989
|
const sqrtKR = tickToSqrtPriceX96(qStrikeTick + halfWidthTick);
|
|
14858
14990
|
const sqrtR = tickToSqrtPriceX96(halfWidthTick);
|
|
14859
14991
|
const rX192 = sqrtR * sqrtR;
|
|
14860
|
-
const numerator = m * (sqrtKR - sqrtP) * Q192$
|
|
14861
|
-
const denominator = sqrtP * (rX192 - Q192$
|
|
14992
|
+
const numerator = m * (sqrtKR - sqrtP) * Q192$4;
|
|
14993
|
+
const denominator = sqrtP * (rX192 - Q192$4);
|
|
14862
14994
|
vDelta = divTrunc(numerator, denominator);
|
|
14863
14995
|
}
|
|
14864
14996
|
const isPut = !isCall(leg.tokenType, isAssetToken0);
|
|
@@ -14878,10 +15010,10 @@ function getLegDelta(leg, currentTick, positionSize, poolTickSpacing, mintTick,
|
|
|
14878
15010
|
const sqrtK = tickToSqrtPriceX96(qStrikeTick);
|
|
14879
15011
|
const sqrtPm = tickToSqrtPriceX96(qMintTick);
|
|
14880
15012
|
const rX192 = sqrtR * sqrtR;
|
|
14881
|
-
const sqrtKPmX96 = sqrtK * Q96$
|
|
15013
|
+
const sqrtKPmX96 = sqrtK * Q96$3 / sqrtPm;
|
|
14882
15014
|
const diff = sqrtR - sqrtKPmX96;
|
|
14883
15015
|
const diffSqX192 = diff * diff;
|
|
14884
|
-
return divTrunc(m * diffSqX192, rX192 - Q192$
|
|
15016
|
+
return divTrunc(m * diffSqX192, rX192 - Q192$4);
|
|
14885
15017
|
}
|
|
14886
15018
|
})();
|
|
14887
15019
|
return definedRisk ? debtDelta + vDelta : debtDelta + vDelta + itmDelta;
|
|
@@ -14890,19 +15022,21 @@ function getLegDelta(leg, currentTick, positionSize, poolTickSpacing, mintTick,
|
|
|
14890
15022
|
function toVaultFrameAtTick(delta, fromAsset, vaultAssetIndex, currentTick, flipSignOnAssetInversion = false) {
|
|
14891
15023
|
if (fromAsset === vaultAssetIndex) return delta;
|
|
14892
15024
|
const sqrtPriceX96 = tickToSqrtPriceX96(currentTick);
|
|
14893
|
-
const converted = vaultAssetIndex === 0n ? delta * Q192$
|
|
15025
|
+
const converted = vaultAssetIndex === 0n ? delta * Q192$4 / (sqrtPriceX96 * sqrtPriceX96) : delta * sqrtPriceX96 * sqrtPriceX96 / Q192$4;
|
|
14894
15026
|
return flipSignOnAssetInversion ? -converted : converted;
|
|
14895
15027
|
}
|
|
14896
15028
|
/**
|
|
14897
15029
|
* Calculate one leg's wallet-aware delta in the vault asset frame.
|
|
14898
15030
|
*
|
|
14899
15031
|
* Width-zero loans and credits must be evaluated directly in the vault frame.
|
|
14900
|
-
*
|
|
15032
|
+
* An option leg is measured as its current holding of the vault token, so
|
|
15033
|
+
* `mintTick` and `definedRisk` do not affect it. Tokens swapped at mint belong
|
|
15034
|
+
* to the account's collateral balance, not to the position: a per-position
|
|
15035
|
+
* display omits them by design, and a whole-account delta adds the balance.
|
|
14901
15036
|
*/
|
|
14902
15037
|
function getLegDeltaInVaultFrame(leg, currentTick, positionSize, poolTickSpacing, mintTick, definedRisk, vaultAssetIndex) {
|
|
14903
15038
|
if (leg.width === 0n) return getLegDelta(leg, currentTick, positionSize, poolTickSpacing, mintTick, definedRisk, vaultAssetIndex);
|
|
14904
|
-
|
|
14905
|
-
return toVaultFrameAtTick(legDelta, leg.asset, vaultAssetIndex, currentTick, true);
|
|
15039
|
+
return getLegTokenInventory(leg, currentTick, positionSize, poolTickSpacing, vaultAssetIndex);
|
|
14906
15040
|
}
|
|
14907
15041
|
/**
|
|
14908
15042
|
* Calculate the gamma (dollar gamma) of a single leg.
|
|
@@ -14937,8 +15071,8 @@ function getLegGamma(leg, currentTick, positionSize, poolTickSpacing, assetIndex
|
|
|
14937
15071
|
const sqrtKPR = tickToSqrtPriceX96(qStrikeTick + qCurrentTick + halfWidthTick);
|
|
14938
15072
|
const sqrtR = tickToSqrtPriceX96(halfWidthTick);
|
|
14939
15073
|
const rX192 = sqrtR * sqrtR;
|
|
14940
|
-
const numerator = m * sqrtKPR * Q96$
|
|
14941
|
-
const denominator = 2n * (rX192 - Q192$
|
|
15074
|
+
const numerator = m * sqrtKPR * Q96$3;
|
|
15075
|
+
const denominator = 2n * (rX192 - Q192$4);
|
|
14942
15076
|
return divTrunc(numerator, denominator);
|
|
14943
15077
|
}
|
|
14944
15078
|
/**
|
|
@@ -15001,9 +15135,9 @@ function calculatePositionDelta(input) {
|
|
|
15001
15135
|
/**
|
|
15002
15136
|
* Calculate debt-only position delta in a single target asset frame.
|
|
15003
15137
|
*
|
|
15004
|
-
* Option legs
|
|
15005
|
-
*
|
|
15006
|
-
*
|
|
15138
|
+
* Option legs contribute their current holding of the `assetIndex` token,
|
|
15139
|
+
* without any mint-time adjustment. Width-zero legs are evaluated directly in
|
|
15140
|
+
* the target frame.
|
|
15007
15141
|
*
|
|
15008
15142
|
* Width=0 loan/credit legs include only their debt obligation. The held-token
|
|
15009
15143
|
* side must be added separately from account collateral balances, preventing a
|
|
@@ -17515,7 +17649,7 @@ function buildCreditWrappedDispatch(params) {
|
|
|
17515
17649
|
|
|
17516
17650
|
//#endregion
|
|
17517
17651
|
//#region src/panoptic/v2/simulations/tokenShortfallRecovery.ts
|
|
17518
|
-
const BPS_DENOMINATOR$
|
|
17652
|
+
const BPS_DENOMINATOR$5 = 10000n;
|
|
17519
17653
|
const MAX_RECOVERY_QUOTE_ATTEMPTS = 8;
|
|
17520
17654
|
/**
|
|
17521
17655
|
* Wrap a dispatch with a temporary credit leg that sources the shortfall.
|
|
@@ -17553,21 +17687,23 @@ function getNotEnoughTokensError(error) {
|
|
|
17553
17687
|
let current = error;
|
|
17554
17688
|
while (current !== void 0 && current !== null && !visited.has(current)) {
|
|
17555
17689
|
visited.add(current);
|
|
17556
|
-
const
|
|
17690
|
+
const decoded = parsePanopticError(current);
|
|
17691
|
+
const parsed = current instanceof NotEnoughTokensError ? current : decoded?.error;
|
|
17557
17692
|
const candidate = parsed instanceof NotEnoughTokensError ? parsed : null;
|
|
17558
17693
|
if (candidate !== null) {
|
|
17559
17694
|
const args = candidate;
|
|
17560
|
-
if (args.tokenAddress
|
|
17695
|
+
if (typeof args.tokenAddress === "string" && isAddress(args.tokenAddress) && typeof args.assetsRequested === "bigint" && typeof args.assetBalance === "bigint") return candidate;
|
|
17561
17696
|
}
|
|
17562
|
-
|
|
17697
|
+
const innerData = decoded?.errorName === "ExecuteError" ? decoded.args[1] : void 0;
|
|
17698
|
+
current = typeof innerData === "string" && isHex(innerData) ? { data: innerData } : current instanceof Error && "cause" in current ? current.cause : void 0;
|
|
17563
17699
|
}
|
|
17564
17700
|
return null;
|
|
17565
17701
|
}
|
|
17566
17702
|
function maximumAmountIn(estimatedAmountIn, slippageBps) {
|
|
17567
17703
|
if (slippageBps < 0n) throw new PanopticError("slippageBps must be non-negative");
|
|
17568
|
-
return (estimatedAmountIn * (BPS_DENOMINATOR$
|
|
17704
|
+
return (estimatedAmountIn * (BPS_DENOMINATOR$5 + slippageBps) + BPS_DENOMINATOR$5 - 1n) / BPS_DENOMINATOR$5;
|
|
17569
17705
|
}
|
|
17570
|
-
function ceilDiv$
|
|
17706
|
+
function ceilDiv$4(numerator, denominator) {
|
|
17571
17707
|
return (numerator + denominator - 1n) / denominator;
|
|
17572
17708
|
}
|
|
17573
17709
|
function getInputAmount(tokenFlow, tokenInIndex) {
|
|
@@ -17590,10 +17726,10 @@ async function quoteTokenShortfallRecovery(params) {
|
|
|
17590
17726
|
reason: "invalid-shortfall",
|
|
17591
17727
|
detail: `requested=${shortfallError.assetsRequested} <= balance=${shortfallError.assetBalance}`
|
|
17592
17728
|
};
|
|
17593
|
-
if (params.slippageBps < 0n || params.slippageBps > BPS_DENOMINATOR$
|
|
17729
|
+
if (params.slippageBps < 0n || params.slippageBps > BPS_DENOMINATOR$5) return {
|
|
17594
17730
|
available: false,
|
|
17595
17731
|
reason: "invalid-slippage",
|
|
17596
|
-
detail: `slippageBps=${params.slippageBps} is outside [0, ${BPS_DENOMINATOR$
|
|
17732
|
+
detail: `slippageBps=${params.slippageBps} is outside [0, ${BPS_DENOMINATOR$5}]`
|
|
17597
17733
|
};
|
|
17598
17734
|
const targetBlockNumber = params.blockNumber ?? await params.client.getBlockNumber();
|
|
17599
17735
|
const pool = await getPool({
|
|
@@ -17672,7 +17808,7 @@ async function quoteTokenShortfallRecovery(params) {
|
|
|
17672
17808
|
const estimatedAmountIn = getInputAmount(swapSimulation.tokenFlow, tokenInIndex);
|
|
17673
17809
|
const estimatedAmountOut = getOutputAmount(swapSimulation.tokenFlow, tokenOutIndex);
|
|
17674
17810
|
if (estimatedAmountOut < requiredOutput) {
|
|
17675
|
-
creditInput = estimatedAmountOut > 0n ? ceilDiv$
|
|
17811
|
+
creditInput = estimatedAmountOut > 0n ? ceilDiv$4(creditInput * requiredOutput, estimatedAmountOut) + 1n : creditInput * 2n;
|
|
17676
17812
|
continue;
|
|
17677
17813
|
}
|
|
17678
17814
|
const recoveredDispatch = buildPrefixedExactInputRecoveryDispatch({
|
|
@@ -17727,7 +17863,7 @@ async function quoteTokenShortfallRecovery(params) {
|
|
|
17727
17863
|
};
|
|
17728
17864
|
const residual = remainingShortfall.assetsRequested - remainingShortfall.assetBalance;
|
|
17729
17865
|
requiredOutput += residual > 0n ? residual : requiredOutput;
|
|
17730
|
-
creditInput = ceilDiv$
|
|
17866
|
+
creditInput = ceilDiv$4(creditInput * requiredOutput, estimatedAmountOut) + 1n;
|
|
17731
17867
|
}
|
|
17732
17868
|
return {
|
|
17733
17869
|
available: false,
|
|
@@ -17782,7 +17918,7 @@ async function quoteTokenShortfallRecovery(params) {
|
|
|
17782
17918
|
const maxAmountIn = maximumAmountIn(estimatedAmountIn, params.slippageBps);
|
|
17783
17919
|
const swapOutput = getOutputAmount(swapSimulation.tokenFlow, tokenOutIndex);
|
|
17784
17920
|
if (swapOutput < amountOut) {
|
|
17785
|
-
creditOutSize = swapOutput > 0n ? ceilDiv$
|
|
17921
|
+
creditOutSize = swapOutput > 0n ? ceilDiv$4(creditOutSize * amountOut, swapOutput) + 1n : creditOutSize * 2n;
|
|
17786
17922
|
continue;
|
|
17787
17923
|
}
|
|
17788
17924
|
const recoverySimulation = await simulateDispatch({
|
|
@@ -17837,7 +17973,7 @@ async function quoteTokenShortfallRecovery(params) {
|
|
|
17837
17973
|
if (decodedShortfall >= shortfallError.assetsRequested - shortfallError.assetBalance) return quotePrefixedExactInput(amountOut);
|
|
17838
17974
|
const additionalAmountOut = decodedShortfall > 0n ? decodedShortfall : amountOut;
|
|
17839
17975
|
amountOut += additionalAmountOut;
|
|
17840
|
-
creditOutSize = swapOutput > 0n ? ceilDiv$
|
|
17976
|
+
creditOutSize = swapOutput > 0n ? ceilDiv$4(creditOutSize * amountOut, swapOutput) + 1n : creditOutSize * 2n;
|
|
17841
17977
|
}
|
|
17842
17978
|
return quotePrefixedExactInput(shortfallError.assetsRequested - shortfallError.assetBalance);
|
|
17843
17979
|
}
|
|
@@ -18366,10 +18502,32 @@ var UnsupportedChainError = class extends PanopticError {
|
|
|
18366
18502
|
this.chainId = chainId;
|
|
18367
18503
|
}
|
|
18368
18504
|
};
|
|
18505
|
+
/**
|
|
18506
|
+
* `tokenIn` is neither `currency0` nor `currency1` of the resolved pool.
|
|
18507
|
+
*/
|
|
18508
|
+
var InvalidSwapTokenError = class extends PanopticError {
|
|
18509
|
+
name = "InvalidSwapTokenError";
|
|
18510
|
+
constructor(token, currency0, currency1, cause) {
|
|
18511
|
+
super(`Token ${token} is not part of the pool (currency0=${currency0}, currency1=${currency1})`, cause);
|
|
18512
|
+
this.token = token;
|
|
18513
|
+
this.currency0 = currency0;
|
|
18514
|
+
this.currency1 = currency1;
|
|
18515
|
+
}
|
|
18516
|
+
};
|
|
18517
|
+
/**
|
|
18518
|
+
* The V4Quoter is not available for the chain (no fallback in v1).
|
|
18519
|
+
*/
|
|
18520
|
+
var QuoterUnavailableError = class extends PanopticError {
|
|
18521
|
+
name = "QuoterUnavailableError";
|
|
18522
|
+
constructor(chainId, cause) {
|
|
18523
|
+
super(`V4Quoter unavailable for chain ${chainId}`, cause);
|
|
18524
|
+
this.chainId = chainId;
|
|
18525
|
+
}
|
|
18526
|
+
};
|
|
18369
18527
|
|
|
18370
18528
|
//#endregion
|
|
18371
18529
|
//#region src/uniswap/v3/router/encodeSwap.ts
|
|
18372
|
-
const UINT128_MAX$
|
|
18530
|
+
const UINT128_MAX$4 = (1n << 128n) - 1n;
|
|
18373
18531
|
|
|
18374
18532
|
//#endregion
|
|
18375
18533
|
//#region src/uniswap/v3/abis/quoterV2.ts
|
|
@@ -18513,8 +18671,8 @@ function getUniswapV3Addresses(chainId, overrides) {
|
|
|
18513
18671
|
|
|
18514
18672
|
//#endregion
|
|
18515
18673
|
//#region src/uniswap/v3/router/quote.ts
|
|
18516
|
-
const BPS_DENOMINATOR$
|
|
18517
|
-
const UINT128_MAX = (1n << 128n) - 1n;
|
|
18674
|
+
const BPS_DENOMINATOR$4 = 10000n;
|
|
18675
|
+
const UINT128_MAX$3 = (1n << 128n) - 1n;
|
|
18518
18676
|
/**
|
|
18519
18677
|
* Quote an exact-in v3 swap. Returns `null` when the quote reverts (e.g. the
|
|
18520
18678
|
* pool does not exist / has no liquidity) so callers can skip that pool when
|
|
@@ -18522,8 +18680,8 @@ const UINT128_MAX = (1n << 128n) - 1n;
|
|
|
18522
18680
|
*/
|
|
18523
18681
|
async function quoteV3ExactIn(params) {
|
|
18524
18682
|
const { client, chainId, tokenIn, tokenOut, fee, amountIn, slippageBps, blockNumber } = params;
|
|
18525
|
-
if (amountIn < 0n || amountIn > UINT128_MAX) throw new PanopticError(`amountIn ${amountIn} exceeds uint128 maximum`);
|
|
18526
|
-
assertSlippageBps(slippageBps);
|
|
18683
|
+
if (amountIn < 0n || amountIn > UINT128_MAX$3) throw new PanopticError(`amountIn ${amountIn} exceeds uint128 maximum`);
|
|
18684
|
+
assertSlippageBps$1(slippageBps);
|
|
18527
18685
|
const { quoterV2 } = getUniswapV3Addresses(chainId, params.addresses);
|
|
18528
18686
|
try {
|
|
18529
18687
|
const { result } = await client.simulateContract({
|
|
@@ -18540,7 +18698,7 @@ async function quoteV3ExactIn(params) {
|
|
|
18540
18698
|
}]
|
|
18541
18699
|
});
|
|
18542
18700
|
const [amountOut, , , gasEstimate] = result;
|
|
18543
|
-
const amountOutMinimum = amountOut * (BPS_DENOMINATOR$
|
|
18701
|
+
const amountOutMinimum = amountOut * (BPS_DENOMINATOR$4 - slippageBps) / BPS_DENOMINATOR$4;
|
|
18544
18702
|
return {
|
|
18545
18703
|
amountOut,
|
|
18546
18704
|
amountOutMinimum,
|
|
@@ -18551,13 +18709,172 @@ async function quoteV3ExactIn(params) {
|
|
|
18551
18709
|
throw err;
|
|
18552
18710
|
}
|
|
18553
18711
|
}
|
|
18554
|
-
|
|
18555
|
-
|
|
18712
|
+
/**
|
|
18713
|
+
* Quote an exact-out v3 swap. Returns `null` on revert (no pool / no liquidity).
|
|
18714
|
+
*/
|
|
18715
|
+
async function quoteV3ExactOut(params) {
|
|
18716
|
+
const { client, chainId, tokenIn, tokenOut, fee, amountOut, slippageBps, blockNumber } = params;
|
|
18717
|
+
if (amountOut < 0n || amountOut > UINT128_MAX$3) throw new PanopticError(`amountOut ${amountOut} exceeds uint128 maximum`);
|
|
18718
|
+
assertSlippageBps$1(slippageBps);
|
|
18719
|
+
const { quoterV2 } = getUniswapV3Addresses(chainId, params.addresses);
|
|
18720
|
+
try {
|
|
18721
|
+
const { result } = await client.simulateContract({
|
|
18722
|
+
address: quoterV2,
|
|
18723
|
+
abi: quoterV2Abi,
|
|
18724
|
+
functionName: "quoteExactOutputSingle",
|
|
18725
|
+
blockNumber,
|
|
18726
|
+
args: [{
|
|
18727
|
+
tokenIn,
|
|
18728
|
+
tokenOut,
|
|
18729
|
+
amount: amountOut,
|
|
18730
|
+
fee: Number(fee),
|
|
18731
|
+
sqrtPriceLimitX96: 0n
|
|
18732
|
+
}]
|
|
18733
|
+
});
|
|
18734
|
+
const [amountIn, , , gasEstimate] = result;
|
|
18735
|
+
const amountInMaximum = (amountIn * (BPS_DENOMINATOR$4 + slippageBps) + BPS_DENOMINATOR$4 - 1n) / BPS_DENOMINATOR$4;
|
|
18736
|
+
return {
|
|
18737
|
+
amountIn,
|
|
18738
|
+
amountInMaximum,
|
|
18739
|
+
gasEstimate
|
|
18740
|
+
};
|
|
18741
|
+
} catch (err) {
|
|
18742
|
+
if (isRevert(err)) return null;
|
|
18743
|
+
throw err;
|
|
18744
|
+
}
|
|
18745
|
+
}
|
|
18746
|
+
function assertSlippageBps$1(slippageBps) {
|
|
18747
|
+
if (slippageBps < 0n || slippageBps > BPS_DENOMINATOR$4) throw new PanopticError(`invalid slippageBps ${slippageBps}, must be 0..10000`);
|
|
18556
18748
|
}
|
|
18557
18749
|
function isRevert(err) {
|
|
18558
18750
|
return err instanceof BaseError && err.walk((e) => e instanceof ContractFunctionRevertedError) instanceof ContractFunctionRevertedError;
|
|
18559
18751
|
}
|
|
18560
18752
|
|
|
18753
|
+
//#endregion
|
|
18754
|
+
//#region src/uniswap/v3/router/resolveRoute.ts
|
|
18755
|
+
async function resolveV3SwapRoute(params) {
|
|
18756
|
+
const { client, poolAddress, tokenIn } = params;
|
|
18757
|
+
const meta = await getPoolMetadata({
|
|
18758
|
+
client,
|
|
18759
|
+
poolAddress
|
|
18760
|
+
});
|
|
18761
|
+
if (meta.isV4) throw new PanopticError("resolveV3SwapRoute called on a v4 pool");
|
|
18762
|
+
const isToken0 = isAddressEqual(tokenIn, meta.token0Asset);
|
|
18763
|
+
const isToken1 = isAddressEqual(tokenIn, meta.token1Asset);
|
|
18764
|
+
if (!isToken0 && !isToken1) throw new InvalidSwapTokenError(tokenIn, meta.token0Asset, meta.token1Asset);
|
|
18765
|
+
const zeroForOne = isToken0;
|
|
18766
|
+
return {
|
|
18767
|
+
tokenIn,
|
|
18768
|
+
tokenOut: zeroForOne ? meta.token1Asset : meta.token0Asset,
|
|
18769
|
+
fee: meta.fee,
|
|
18770
|
+
zeroForOne
|
|
18771
|
+
};
|
|
18772
|
+
}
|
|
18773
|
+
|
|
18774
|
+
//#endregion
|
|
18775
|
+
//#region src/uniswap/v3/router/quoteViaRouter.ts
|
|
18776
|
+
const FALLBACK_META$1 = {
|
|
18777
|
+
blockNumber: 0n,
|
|
18778
|
+
blockTimestamp: 0n,
|
|
18779
|
+
blockHash: "0x0"
|
|
18780
|
+
};
|
|
18781
|
+
async function quoteSwapExactOutViaV3Router(params) {
|
|
18782
|
+
const { client, poolAddress, chainId, tokenIn, amountOut, slippageBps, blockNumber, addresses } = params;
|
|
18783
|
+
try {
|
|
18784
|
+
const targetBlockNumber = blockNumber ?? await client.getBlockNumber();
|
|
18785
|
+
const metaPromise = getBlockMeta({
|
|
18786
|
+
client,
|
|
18787
|
+
blockNumber: targetBlockNumber
|
|
18788
|
+
});
|
|
18789
|
+
metaPromise.catch(() => void 0);
|
|
18790
|
+
const route = await resolveV3SwapRoute({
|
|
18791
|
+
client,
|
|
18792
|
+
poolAddress,
|
|
18793
|
+
tokenIn
|
|
18794
|
+
});
|
|
18795
|
+
const quote = await quoteV3ExactOut({
|
|
18796
|
+
client,
|
|
18797
|
+
chainId,
|
|
18798
|
+
tokenIn: route.tokenIn,
|
|
18799
|
+
tokenOut: route.tokenOut,
|
|
18800
|
+
fee: route.fee,
|
|
18801
|
+
amountOut,
|
|
18802
|
+
slippageBps,
|
|
18803
|
+
blockNumber: targetBlockNumber,
|
|
18804
|
+
addresses
|
|
18805
|
+
});
|
|
18806
|
+
if (!quote) throw new PanopticError("v3 quote returned no result (pool may have no liquidity)");
|
|
18807
|
+
const _meta = await metaPromise;
|
|
18808
|
+
return {
|
|
18809
|
+
success: true,
|
|
18810
|
+
data: {
|
|
18811
|
+
amountIn: quote.amountIn,
|
|
18812
|
+
amountInMaximum: quote.amountInMaximum,
|
|
18813
|
+
zeroForOne: route.zeroForOne,
|
|
18814
|
+
tokenOut: route.tokenOut,
|
|
18815
|
+
gasEstimate: quote.gasEstimate
|
|
18816
|
+
},
|
|
18817
|
+
gasEstimate: quote.gasEstimate,
|
|
18818
|
+
_meta
|
|
18819
|
+
};
|
|
18820
|
+
} catch (error) {
|
|
18821
|
+
return {
|
|
18822
|
+
success: false,
|
|
18823
|
+
error: error instanceof PanopticError ? error : new PanopticError(error instanceof Error ? error.message : "Quote failed", error instanceof Error ? error : void 0),
|
|
18824
|
+
_meta: FALLBACK_META$1
|
|
18825
|
+
};
|
|
18826
|
+
}
|
|
18827
|
+
}
|
|
18828
|
+
|
|
18829
|
+
//#endregion
|
|
18830
|
+
//#region src/uniswap/v4/addresses.ts
|
|
18831
|
+
/**
|
|
18832
|
+
* Canonical Permit2, identical across all chains.
|
|
18833
|
+
*/
|
|
18834
|
+
const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
18835
|
+
/**
|
|
18836
|
+
* Verified Uniswap v4 deployment addresses keyed by chainId.
|
|
18837
|
+
*
|
|
18838
|
+
* Sourced from the official Uniswap v4 deployments. Add a chain here only after
|
|
18839
|
+
* verifying each address against the canonical Uniswap deployment listing —
|
|
18840
|
+
* Universal Router in particular is NOT the same address across chains.
|
|
18841
|
+
*/
|
|
18842
|
+
const UNISWAP_V4_ADDRESSES = {
|
|
18843
|
+
1: {
|
|
18844
|
+
universalRouter: "0x66a9893cC07D91D95644AEDD05D03f95e1dBA8Af",
|
|
18845
|
+
v4Quoter: "0x52F0E24D1c21C8A0cB1e5a5dD6198556BD9E1203",
|
|
18846
|
+
poolManager: "0x000000000004444c5dc75cB358380D2e3dE08A90",
|
|
18847
|
+
positionManager: "0xbD216513d74C8cf14cf4747E6AaA6420FF64ee9e",
|
|
18848
|
+
permit2: PERMIT2_ADDRESS
|
|
18849
|
+
},
|
|
18850
|
+
4663: {
|
|
18851
|
+
universalRouter: "0x8876789976decbfcbbbe364623c63652db8c0904",
|
|
18852
|
+
v4Quoter: "0x8dc178efb8111bb0973dd9d722ebeff267c98f94",
|
|
18853
|
+
poolManager: "0x8366a39cc670b4001a1121b8f6a443a643e40951",
|
|
18854
|
+
positionManager: "0x58daec3116aae6d93017baaea7749052e8a04fa7",
|
|
18855
|
+
permit2: PERMIT2_ADDRESS
|
|
18856
|
+
}
|
|
18857
|
+
};
|
|
18858
|
+
/**
|
|
18859
|
+
* Resolve the Uniswap v4 addresses for a chain, applying optional overrides.
|
|
18860
|
+
*
|
|
18861
|
+
* @param chainId - Target chain ID.
|
|
18862
|
+
* @param overrides - Partial override of any address (e.g. for fork tests).
|
|
18863
|
+
* @returns Fully-resolved {@link UniswapV4Addresses}.
|
|
18864
|
+
* @throws {UnsupportedChainError} when the chain is not listed and the
|
|
18865
|
+
* overrides do not supply every required address.
|
|
18866
|
+
*/
|
|
18867
|
+
function getUniswapV4Addresses(chainId, overrides) {
|
|
18868
|
+
const base = UNISWAP_V4_ADDRESSES[Number(chainId)];
|
|
18869
|
+
const merged = {
|
|
18870
|
+
...base,
|
|
18871
|
+
...overrides,
|
|
18872
|
+
permit2: overrides?.permit2 ?? base?.permit2 ?? PERMIT2_ADDRESS
|
|
18873
|
+
};
|
|
18874
|
+
if (merged.universalRouter === void 0 || merged.v4Quoter === void 0 || merged.poolManager === void 0 || merged.positionManager === void 0 || merged.permit2 === void 0) throw new UnsupportedChainError(chainId);
|
|
18875
|
+
return merged;
|
|
18876
|
+
}
|
|
18877
|
+
|
|
18561
18878
|
//#endregion
|
|
18562
18879
|
//#region src/panoptic/v2/reads/sfpm.ts
|
|
18563
18880
|
/**
|
|
@@ -20578,7 +20895,7 @@ async function getItmAmounts(params) {
|
|
|
20578
20895
|
* high-decimal amount can't masquerade as real flow.
|
|
20579
20896
|
*/
|
|
20580
20897
|
const FLOW_NEUTRAL_DUST_THRESHOLD = 1000n;
|
|
20581
|
-
const Q192$
|
|
20898
|
+
const Q192$3 = 1n << 192n;
|
|
20582
20899
|
const POOL_ID_MASK$2 = (1n << 64n) - 1n;
|
|
20583
20900
|
/**
|
|
20584
20901
|
* Floor integer square root for bigints (Newton's method). Exact for all
|
|
@@ -20614,7 +20931,7 @@ function buildNeutralLeg(tokenIndex, signedAmount, positionSize) {
|
|
|
20614
20931
|
const absAmount = signedAmount < 0n ? -signedAmount : signedAmount;
|
|
20615
20932
|
const legAsset = tokenIndex === 0n ? 1n : 0n;
|
|
20616
20933
|
const legIsLong = signedAmount < 0n;
|
|
20617
|
-
const sqrtKrawX96 = isqrt(absAmount * Q192$
|
|
20934
|
+
const sqrtKrawX96 = isqrt(absAmount * Q192$3 / positionSize);
|
|
20618
20935
|
let signedTick;
|
|
20619
20936
|
try {
|
|
20620
20937
|
signedTick = sqrtPriceX96ToTick(sqrtKrawX96);
|
|
@@ -20872,7 +21189,7 @@ async function createFlowNeutralTokenId(params) {
|
|
|
20872
21189
|
const sqrtPX96 = tickToSqrtPriceX96(tickBefore);
|
|
20873
21190
|
const valueAbs = (index, amount) => {
|
|
20874
21191
|
const abs$1 = amount < 0n ? -amount : amount;
|
|
20875
|
-
return index === 0n ? abs$1 * sqrtPX96 * sqrtPX96 / Q192$
|
|
21192
|
+
return index === 0n ? abs$1 * sqrtPX96 * sqrtPX96 / Q192$3 : abs$1;
|
|
20876
21193
|
};
|
|
20877
21194
|
const flowFor = (index) => index === 0n ? credit.creditAmount0 : credit.creditAmount1;
|
|
20878
21195
|
if (queryAddress !== void 0) {
|
|
@@ -21845,7 +22162,7 @@ async function getPoolLiquidities(params) {
|
|
|
21845
22162
|
|
|
21846
22163
|
//#endregion
|
|
21847
22164
|
//#region src/panoptic/v2/reads/accountGreeks.ts
|
|
21848
|
-
const Q192$
|
|
22165
|
+
const Q192$2 = 1n << 192n;
|
|
21849
22166
|
/**
|
|
21850
22167
|
* Calculate account-level greeks using stored position data.
|
|
21851
22168
|
*
|
|
@@ -21966,8 +22283,8 @@ async function getAccountGreeks(params) {
|
|
|
21966
22283
|
const assetBal = isAssetToken0 ? collateral.token0.assets : collateral.token1.assets;
|
|
21967
22284
|
const otherBal = isAssetToken0 ? collateral.token1.assets : collateral.token0.assets;
|
|
21968
22285
|
const sqrtPriceX96 = tickToSqrtPriceX96(BigInt(currentTick));
|
|
21969
|
-
if (isAssetToken0) collateralValue = assetBal * sqrtPriceX96 * sqrtPriceX96 / Q192$
|
|
21970
|
-
else collateralValue = assetBal * Q192$
|
|
22286
|
+
if (isAssetToken0) collateralValue = assetBal * sqrtPriceX96 * sqrtPriceX96 / Q192$2 + otherBal;
|
|
22287
|
+
else collateralValue = assetBal * Q192$2 / (sqrtPriceX96 * sqrtPriceX96) + otherBal;
|
|
21971
22288
|
collateralDelta = assetBal;
|
|
21972
22289
|
}
|
|
21973
22290
|
return {
|
|
@@ -22007,7 +22324,7 @@ function calculateAccountGreeksPure(params) {
|
|
|
22007
22324
|
const totalDelta$1 = [];
|
|
22008
22325
|
for (let i = 0; i < n; i++) {
|
|
22009
22326
|
const sqrtPriceX96 = tickToSqrtPriceX96(atTicks[i]);
|
|
22010
|
-
const assetValueInNumeraire = isAssetToken0 ? assetBal * sqrtPriceX96 * sqrtPriceX96 / Q192$
|
|
22327
|
+
const assetValueInNumeraire = isAssetToken0 ? assetBal * sqrtPriceX96 * sqrtPriceX96 / Q192$2 : assetBal * Q192$2 / (sqrtPriceX96 * sqrtPriceX96);
|
|
22011
22328
|
totalValue$1.push(assetValueInNumeraire + otherBal);
|
|
22012
22329
|
totalDelta$1.push(assetBal);
|
|
22013
22330
|
}
|
|
@@ -22057,7 +22374,7 @@ function calculateAccountGreeksPure(params) {
|
|
|
22057
22374
|
}
|
|
22058
22375
|
for (let i = 0; i < n; i++) {
|
|
22059
22376
|
const sqrtPriceX96 = tickToSqrtPriceX96(atTicks[i]);
|
|
22060
|
-
const assetValueInNumeraire = isAssetToken0 ? assetBal * sqrtPriceX96 * sqrtPriceX96 / Q192$
|
|
22377
|
+
const assetValueInNumeraire = isAssetToken0 ? assetBal * sqrtPriceX96 * sqrtPriceX96 / Q192$2 : assetBal * Q192$2 / (sqrtPriceX96 * sqrtPriceX96);
|
|
22061
22378
|
totalValue[i] += assetValueInNumeraire + otherBal;
|
|
22062
22379
|
totalDelta[i] += assetBal;
|
|
22063
22380
|
}
|
|
@@ -24472,10 +24789,10 @@ async function processClosedPositions(client, queryAddress, positions) {
|
|
|
24472
24789
|
//#endregion
|
|
24473
24790
|
//#region src/panoptic/v2/reads/hedgeCapacity.ts
|
|
24474
24791
|
const SCALE$1 = 10000000n;
|
|
24475
|
-
const FEE_SCALE = 10000n;
|
|
24476
|
-
const Q192 = 1n << 192n;
|
|
24792
|
+
const FEE_SCALE$1 = 10000n;
|
|
24793
|
+
const Q192$1 = 1n << 192n;
|
|
24477
24794
|
const MASK128$1 = (1n << 128n) - 1n;
|
|
24478
|
-
const ceilDiv$
|
|
24795
|
+
const ceilDiv$3 = (value, divisor) => (value + divisor - 1n) / divisor;
|
|
24479
24796
|
function accountHedgeDelta({ positionIds, balances, collateralDelta, tick, tickSpacing, assetIndex }) {
|
|
24480
24797
|
return positionIds.reduce((sum$1, id, index) => {
|
|
24481
24798
|
const balance = balances[index];
|
|
@@ -24495,8 +24812,8 @@ function accountHedgeDelta({ positionIds, balances, collateralDelta, tick, tickS
|
|
|
24495
24812
|
function buildCapacityHedge({ delta, assetIndex, tick, tickSpacing, poolId, notionalFee, swapFee }) {
|
|
24496
24813
|
const borrowToken = delta >= 0n ? assetIndex : assetIndex === 0n ? 1n : 0n;
|
|
24497
24814
|
const receiveToken = borrowToken === 0n ? 1n : 0n;
|
|
24498
|
-
const amount = delta >= 0n ? delta : ceilDiv$
|
|
24499
|
-
const commission = ceilDiv$
|
|
24815
|
+
const amount = delta >= 0n ? delta : ceilDiv$3((toVaultFrameAtTick(-delta, assetIndex, borrowToken, tick) + 1n) * 1000000n * FEE_SCALE$1, (1000000n - swapFee) * (FEE_SCALE$1 - notionalFee));
|
|
24816
|
+
const commission = ceilDiv$3(amount * notionalFee, FEE_SCALE$1);
|
|
24500
24817
|
const proceeds = toVaultFrameAtTick((amount - commission) * (1000000n - swapFee) / 1000000n, borrowToken, receiveToken, tick);
|
|
24501
24818
|
const tokenId = addLegToTokenId(poolId, {
|
|
24502
24819
|
index: 0n,
|
|
@@ -24528,7 +24845,7 @@ function hedgeMargin({ tokenData, balanceChanges, crossRatios, tick, buffer }) {
|
|
|
24528
24845
|
const surplus1 = balances[1] > required1 ? (balances[1] - required1) * crossRatios[1] / SCALE$1 : 0n;
|
|
24529
24846
|
const sqrt = tickToSqrtPriceX96(tick);
|
|
24530
24847
|
const price = sqrt * sqrt;
|
|
24531
|
-
const pairs = sqrt < 1n << 96n ? [[balances[0] + surplus1 * Q192 / price, required0], [balances[1] * Q192 / price + surplus0, ceilDiv$
|
|
24848
|
+
const pairs = sqrt < 1n << 96n ? [[balances[0] + surplus1 * Q192$1 / price, required0], [balances[1] * Q192$1 / price + surplus0, ceilDiv$3(required1 * Q192$1, price)]] : [[balances[0] * price / Q192$1 + surplus1, ceilDiv$3(required0 * price, Q192$1)], [balances[1] + surplus0 * price / Q192$1, required1]];
|
|
24532
24849
|
const headroom = pairs.map(([balance, required]) => balance - required);
|
|
24533
24850
|
return {
|
|
24534
24851
|
solvent: balances.every((balance) => balance >= 0n) && headroom.every((value) => value >= 0n),
|
|
@@ -24741,7 +25058,7 @@ async function getHedgeLimits({ client, poolAddress, account, positionIds, asset
|
|
|
24741
25058
|
if (hedge.amount > 0n && BigInt(legCount) >= maxLegs) return unavailable("leg-limit");
|
|
24742
25059
|
const totalAssets = hedge.borrowToken === 0n ? total0 : total1;
|
|
24743
25060
|
if (hedge.amount > 0n && (hedge.amount > MAX_SIZE || hedge.amount > borrowCapacity[Number(hedge.borrowToken)] || totalAssets === 0n)) return unavailable("capacity");
|
|
24744
|
-
const projectedUtilization = currentUtilizations.map((util, i) => hedge.amount > 0n && BigInt(i) === hedge.borrowToken ? ceilDiv$
|
|
25061
|
+
const projectedUtilization = currentUtilizations.map((util, i) => hedge.amount > 0n && BigInt(i) === hedge.borrowToken ? ceilDiv$3(util * totalAssets + hedge.amount * 10000n, totalAssets) : util);
|
|
24745
25062
|
if (hedge.amount > 0n && projectedUtilization.some((util) => util > 10000n)) return unavailable("capacity");
|
|
24746
25063
|
const global = projectedUtilization.map((util, i) => util > globalUtilizations[i] ? util : globalUtilizations[i]);
|
|
24747
25064
|
const syntheticBalance = hedge.amount | projectedUtilization[0] << 128n | projectedUtilization[1] << 144n;
|
|
@@ -24833,6 +25150,90 @@ async function getHedgeLimits({ client, poolAddress, account, positionIds, asset
|
|
|
24833
25150
|
};
|
|
24834
25151
|
}
|
|
24835
25152
|
|
|
25153
|
+
//#endregion
|
|
25154
|
+
//#region src/panoptic/v2/reads/positionMintFunding.ts
|
|
25155
|
+
const Q96$2 = 1n << 96n;
|
|
25156
|
+
const Q192 = 1n << 192n;
|
|
25157
|
+
const BPS = 10000n;
|
|
25158
|
+
const FEE_SCALE = 1000000n;
|
|
25159
|
+
const max = (a, b) => a > b ? a : b;
|
|
25160
|
+
const ceilDiv$2 = (n, d) => n > 0n ? (n + d - 1n) / d : n / d;
|
|
25161
|
+
/**
|
|
25162
|
+
* Estimate deposit-independent mint funding, including settlement and commission.
|
|
25163
|
+
* Swaps use spot conversion with fees and slippage allowance; execution still needs a live quote.
|
|
25164
|
+
* Received tokens cover post-mint margin but cannot fund the other tracker's upfront payment.
|
|
25165
|
+
* Each requiredValue is the starting balance when funding entirely in that token.
|
|
25166
|
+
*/
|
|
25167
|
+
function getPositionMintFunding(params) {
|
|
25168
|
+
const { tokenId, positionSize, sqrtPriceX96, valuationSqrtPriceX96, swapAtMint, commissionRate, swapFee, slippageBps, required0, required1 } = params;
|
|
25169
|
+
if (positionSize < 0n || sqrtPriceX96 <= 0n || valuationSqrtPriceX96 <= 0n || commissionRate < 0n || swapFee < 0n || swapFee >= FEE_SCALE || slippageBps < 0n || slippageBps >= BPS || required0 < 0n || required1 < 0n) throw new RangeError("Invalid mint funding inputs");
|
|
25170
|
+
const { legs, tickSpacing } = decodeTokenId(tokenId);
|
|
25171
|
+
const firstLeg = legs[0];
|
|
25172
|
+
if (!firstLeg || tickSpacing <= 0n) throw new RangeError("Invalid position");
|
|
25173
|
+
let paid0 = 0n;
|
|
25174
|
+
let paid1 = 0n;
|
|
25175
|
+
let itm0 = 0n;
|
|
25176
|
+
let itm1 = 0n;
|
|
25177
|
+
let notional0 = 0n;
|
|
25178
|
+
let notional1 = 0n;
|
|
25179
|
+
for (const leg of legs) {
|
|
25180
|
+
const { sqrtLower, sqrtUpper, liquidity } = getLegLiquidityRange(leg.width === 0n ? {
|
|
25181
|
+
...leg,
|
|
25182
|
+
width: 2n
|
|
25183
|
+
} : leg, positionSize, tickSpacing);
|
|
25184
|
+
const round = !leg.isLong || leg.width === 0n ? ceilDiv$2 : (n, d) => n / d;
|
|
25185
|
+
const moved0 = round((liquidity << 96n) * (sqrtUpper - sqrtLower), sqrtUpper * sqrtLower);
|
|
25186
|
+
const moved1 = round(liquidity * (sqrtUpper - sqrtLower), Q96$2);
|
|
25187
|
+
const sign = leg.isLong ? -1n : 1n;
|
|
25188
|
+
let amm0 = 0n;
|
|
25189
|
+
let amm1 = 0n;
|
|
25190
|
+
if (leg.width > 0n) {
|
|
25191
|
+
const price = max(sqrtLower, sqrtPriceX96 < sqrtUpper ? sqrtPriceX96 : sqrtUpper);
|
|
25192
|
+
amm0 = sign * round((liquidity << 96n) * (sqrtUpper - price), sqrtUpper * price);
|
|
25193
|
+
amm1 = sign * round(liquidity * (price - sqrtLower), Q96$2);
|
|
25194
|
+
itm0 += leg.tokenType === 1n ? amm0 : 0n;
|
|
25195
|
+
itm1 += leg.tokenType === 0n ? amm1 : 0n;
|
|
25196
|
+
} else {
|
|
25197
|
+
itm0 -= leg.tokenType === 0n ? sign * moved0 : 0n;
|
|
25198
|
+
itm1 -= leg.tokenType === 1n ? sign * moved1 : 0n;
|
|
25199
|
+
}
|
|
25200
|
+
paid0 += amm0 - (leg.tokenType === 0n ? sign * moved0 : 0n);
|
|
25201
|
+
paid1 += amm1 - (leg.tokenType === 1n ? sign * moved1 : 0n);
|
|
25202
|
+
notional0 += leg.tokenType === 0n ? moved0 : 0n;
|
|
25203
|
+
notional1 += leg.tokenType === 1n ? moved1 : 0n;
|
|
25204
|
+
}
|
|
25205
|
+
if (swapAtMint && (itm0 !== 0n || itm1 !== 0n)) {
|
|
25206
|
+
const swapToken0 = itm0 !== 0n && (itm1 === 0n || firstLeg.asset === 0n);
|
|
25207
|
+
const priceSquared$1 = sqrtPriceX96 * sqrtPriceX96;
|
|
25208
|
+
const itm = swapToken0 ? itm0 : itm1;
|
|
25209
|
+
const numerator = swapToken0 ? priceSquared$1 : Q192;
|
|
25210
|
+
const denominator = swapToken0 ? Q192 : priceSquared$1;
|
|
25211
|
+
const retained$1 = (FEE_SCALE - swapFee) * (BPS - slippageBps);
|
|
25212
|
+
const scale$1 = FEE_SCALE * BPS;
|
|
25213
|
+
const payment = itm > 0n ? ceilDiv$2(itm * numerator * scale$1, denominator * retained$1) : itm * numerator * retained$1 / (denominator * scale$1);
|
|
25214
|
+
paid0 += swapToken0 ? -itm : payment;
|
|
25215
|
+
paid1 += swapToken0 ? payment : -itm;
|
|
25216
|
+
}
|
|
25217
|
+
paid0 += ceilDiv$2(notional0 * commissionRate, BPS);
|
|
25218
|
+
paid1 += ceilDiv$2(notional1 * commissionRate, BPS);
|
|
25219
|
+
const priceSquared = valuationSqrtPriceX96 * valuationSqrtPriceX96;
|
|
25220
|
+
const inToken0 = (amount0, amount1) => amount0 + ceilDiv$2(amount1 * Q192, priceSquared);
|
|
25221
|
+
const inToken1 = (amount0, amount1) => amount1 + ceilDiv$2(amount0 * priceSquared, Q192);
|
|
25222
|
+
const retained = (FEE_SCALE - swapFee) * (BPS - slippageBps);
|
|
25223
|
+
const scale = FEE_SCALE * BPS;
|
|
25224
|
+
const spotSquared = sqrtPriceX96 * sqrtPriceX96;
|
|
25225
|
+
const upfront0 = max(paid0, 0n) + ceilDiv$2(max(paid1, 0n) * Q192 * scale, spotSquared * retained);
|
|
25226
|
+
const upfront1 = max(paid1, 0n) + ceilDiv$2(max(paid0, 0n) * spotSquared * scale, Q192 * retained);
|
|
25227
|
+
const requiredValue0 = upfront0 + max(0n, inToken0(required0 - max(-paid0, 0n), required1 - max(-paid1, 0n)));
|
|
25228
|
+
const requiredValue1 = upfront1 + max(0n, inToken1(required0 - max(-paid0, 0n), required1 - max(-paid1, 0n)));
|
|
25229
|
+
return {
|
|
25230
|
+
paid0,
|
|
25231
|
+
paid1,
|
|
25232
|
+
requiredValue0,
|
|
25233
|
+
requiredValue1
|
|
25234
|
+
};
|
|
25235
|
+
}
|
|
25236
|
+
|
|
24836
25237
|
//#endregion
|
|
24837
25238
|
//#region src/panoptic/v2/sync/getSyncStatus.ts
|
|
24838
25239
|
/**
|
|
@@ -28406,121 +28807,223 @@ async function simulateClosePosition(params) {
|
|
|
28406
28807
|
}
|
|
28407
28808
|
|
|
28408
28809
|
//#endregion
|
|
28409
|
-
//#region src/panoptic/v2/simulations/
|
|
28410
|
-
/**
|
|
28411
|
-
|
|
28412
|
-
|
|
28413
|
-
|
|
28414
|
-
* @returns Simulation result with exercise data or error
|
|
28415
|
-
*/
|
|
28416
|
-
async function simulateForceExercise(params) {
|
|
28417
|
-
const { client, poolAddress, account, user, positionIdListFrom, positionIdListTo, positionIdListToFinal, blockNumber } = params;
|
|
28418
|
-
const targetBlockNumber = blockNumber ?? await client.getBlockNumber();
|
|
28419
|
-
const metaPromise = getBlockMeta({
|
|
28420
|
-
client,
|
|
28421
|
-
blockNumber: targetBlockNumber
|
|
28422
|
-
});
|
|
28423
|
-
const emptyTokenFlow = {
|
|
28424
|
-
delta0: 0n,
|
|
28425
|
-
delta1: 0n,
|
|
28426
|
-
balanceBefore0: 0n,
|
|
28427
|
-
balanceBefore1: 0n,
|
|
28428
|
-
balanceAfter0: 0n,
|
|
28429
|
-
balanceAfter1: 0n,
|
|
28430
|
-
tickBefore: null,
|
|
28431
|
-
tickAfter: null
|
|
28432
|
-
};
|
|
28810
|
+
//#region src/panoptic/v2/simulations/simulateClosePremiumProtection.ts
|
|
28811
|
+
/** Estimate unfunded short premium after buyer settlement and collection of chunk fees. */
|
|
28812
|
+
async function simulateClosePremiumProtection(params) {
|
|
28813
|
+
const { client, poolAddress, account, positionIdList, closingTokenIds, targets } = params;
|
|
28814
|
+
let metaPromise;
|
|
28433
28815
|
try {
|
|
28434
|
-
const
|
|
28435
|
-
|
|
28436
|
-
|
|
28437
|
-
|
|
28438
|
-
positionIdListFrom,
|
|
28439
|
-
user,
|
|
28440
|
-
positionIdListTo,
|
|
28441
|
-
positionIdListToFinal,
|
|
28442
|
-
0n
|
|
28443
|
-
]
|
|
28816
|
+
const blockNumber = params.blockNumber ?? await client.getBlockNumber();
|
|
28817
|
+
metaPromise = getBlockMeta({
|
|
28818
|
+
client,
|
|
28819
|
+
blockNumber
|
|
28444
28820
|
});
|
|
28445
|
-
|
|
28821
|
+
metaPromise.catch(() => {});
|
|
28822
|
+
if (closingTokenIds.length === 0 || closingTokenIds.some((id) => !positionIdList.includes(id))) throw new PanopticError("Premium protection requires currently held positions to close");
|
|
28823
|
+
const positionSizes = await getCurrentPositionSizes({
|
|
28446
28824
|
client,
|
|
28447
28825
|
poolAddress,
|
|
28448
|
-
|
|
28449
|
-
|
|
28450
|
-
blockNumber
|
|
28826
|
+
account,
|
|
28827
|
+
positionIdList: closingTokenIds,
|
|
28828
|
+
blockNumber
|
|
28451
28829
|
});
|
|
28452
|
-
|
|
28453
|
-
|
|
28454
|
-
|
|
28455
|
-
|
|
28456
|
-
|
|
28457
|
-
|
|
28458
|
-
|
|
28459
|
-
|
|
28460
|
-
|
|
28461
|
-
|
|
28462
|
-
|
|
28463
|
-
|
|
28464
|
-
|
|
28465
|
-
|
|
28466
|
-
|
|
28467
|
-
|
|
28468
|
-
|
|
28469
|
-
|
|
28470
|
-
|
|
28471
|
-
|
|
28830
|
+
const { collectionDispatch } = buildProtectedSettlePlan({
|
|
28831
|
+
positionIdList: closingTokenIds,
|
|
28832
|
+
finalPositionIdList: positionIdList,
|
|
28833
|
+
positionSizes,
|
|
28834
|
+
builderCode: params.builderCode
|
|
28835
|
+
});
|
|
28836
|
+
const calls = (targets.length ? buildSettleSequenceCalls({
|
|
28837
|
+
positionIdListFrom: params.signerPositionIdList,
|
|
28838
|
+
targets
|
|
28839
|
+
}) : []).map((data) => ({
|
|
28840
|
+
to: poolAddress,
|
|
28841
|
+
data,
|
|
28842
|
+
account: params.signerAddress
|
|
28843
|
+
}));
|
|
28844
|
+
if (collectionDispatch !== void 0) {
|
|
28845
|
+
const [dispatchData] = buildSettleSequenceCalls({
|
|
28846
|
+
positionIdListFrom: positionIdList,
|
|
28847
|
+
targets: [],
|
|
28848
|
+
dispatch: collectionDispatch
|
|
28849
|
+
});
|
|
28850
|
+
if (dispatchData === void 0) throw new PanopticError("Premium protection collection dispatch is missing");
|
|
28851
|
+
calls.push({
|
|
28852
|
+
...params.buildCollectionCall(dispatchData),
|
|
28853
|
+
account: params.signerAddress
|
|
28854
|
+
});
|
|
28472
28855
|
}
|
|
28473
|
-
const
|
|
28474
|
-
|
|
28475
|
-
|
|
28476
|
-
|
|
28477
|
-
|
|
28478
|
-
|
|
28479
|
-
|
|
28856
|
+
for (const includePendingPremium of [true, false]) calls.push({
|
|
28857
|
+
to: poolAddress,
|
|
28858
|
+
account: params.signerAddress,
|
|
28859
|
+
data: encodeFunctionData({
|
|
28860
|
+
abi: panopticPoolV2Abi,
|
|
28861
|
+
functionName: "getFullPositionsData",
|
|
28862
|
+
args: [
|
|
28863
|
+
account,
|
|
28864
|
+
includePendingPremium,
|
|
28865
|
+
closingTokenIds
|
|
28866
|
+
]
|
|
28867
|
+
})
|
|
28868
|
+
});
|
|
28869
|
+
const blocks = await client.simulateBlocks({
|
|
28870
|
+
blocks: [{ calls }],
|
|
28871
|
+
blockNumber
|
|
28872
|
+
});
|
|
28873
|
+
const results = blocks[0]?.calls;
|
|
28874
|
+
if (results === void 0 || results.length !== calls.length) throw new PanopticError("Premium protection simulation returned incomplete results");
|
|
28875
|
+
for (const result$1 of results) if (result$1.status === "failure") throw result$1.error;
|
|
28876
|
+
const result = results.map((call$1) => call$1.data);
|
|
28877
|
+
const owedResult = result[result.length - 2];
|
|
28878
|
+
const availableResult = result[result.length - 1];
|
|
28879
|
+
if (owedResult === void 0 || availableResult === void 0) throw new PanopticError("Premium protection simulation returned incomplete results");
|
|
28880
|
+
const decodeShortPremium$1 = (data) => decodeLeftRightUnsigned(decodeFunctionResult({
|
|
28881
|
+
abi: panopticPoolV2Abi,
|
|
28882
|
+
functionName: "getFullPositionsData",
|
|
28883
|
+
data
|
|
28884
|
+
})[0]);
|
|
28885
|
+
const owed = decodeShortPremium$1(owedResult);
|
|
28886
|
+
const available = decodeShortPremium$1(availableResult);
|
|
28480
28887
|
return {
|
|
28481
28888
|
success: true,
|
|
28482
|
-
|
|
28483
|
-
|
|
28484
|
-
|
|
28485
|
-
|
|
28889
|
+
gasEstimate: 0n,
|
|
28890
|
+
data: {
|
|
28891
|
+
owed0: owed.right,
|
|
28892
|
+
owed1: owed.left,
|
|
28893
|
+
available0: available.right,
|
|
28894
|
+
available1: available.left,
|
|
28895
|
+
forfeit0: owed.right > available.right ? owed.right - available.right : 0n,
|
|
28896
|
+
forfeit1: owed.left > available.left ? owed.left - available.left : 0n
|
|
28897
|
+
},
|
|
28898
|
+
_meta: await metaPromise
|
|
28486
28899
|
};
|
|
28487
28900
|
} catch (error) {
|
|
28488
|
-
const
|
|
28489
|
-
|
|
28490
|
-
const isNotExercisable = errorMessage.includes("NoLegsExercisable") || errorMessage.includes("NotALongLeg");
|
|
28491
|
-
if (isNotExercisable) {
|
|
28492
|
-
const data = {
|
|
28493
|
-
exerciseFee0: 0n,
|
|
28494
|
-
exerciseFee1: 0n,
|
|
28495
|
-
canExercise: false,
|
|
28496
|
-
reason: errorMessage.includes("NoLegsExercisable") ? "No legs are exercisable (not ITM)" : "Position does not have a long leg"
|
|
28497
|
-
};
|
|
28498
|
-
return {
|
|
28499
|
-
success: true,
|
|
28500
|
-
data,
|
|
28501
|
-
gasEstimate: 0n,
|
|
28502
|
-
tokenFlow: emptyTokenFlow,
|
|
28503
|
-
_meta
|
|
28504
|
-
};
|
|
28505
|
-
}
|
|
28901
|
+
const simulationError = error instanceof PanopticError ? error : new PanopticError(String(error));
|
|
28902
|
+
if (metaPromise === void 0) throw simulationError;
|
|
28506
28903
|
return {
|
|
28507
28904
|
success: false,
|
|
28508
|
-
error:
|
|
28509
|
-
_meta
|
|
28905
|
+
error: simulationError,
|
|
28906
|
+
_meta: await metaPromise
|
|
28510
28907
|
};
|
|
28511
28908
|
}
|
|
28512
28909
|
}
|
|
28513
28910
|
|
|
28514
28911
|
//#endregion
|
|
28515
|
-
//#region src/panoptic/v2/simulations/
|
|
28912
|
+
//#region src/panoptic/v2/simulations/simulateForceExercise.ts
|
|
28516
28913
|
/**
|
|
28517
|
-
* Simulate a
|
|
28914
|
+
* Simulate a force exercise operation.
|
|
28518
28915
|
*
|
|
28519
28916
|
* @param params - Simulation parameters
|
|
28520
|
-
* @returns Simulation result with
|
|
28917
|
+
* @returns Simulation result with exercise data or error
|
|
28521
28918
|
*/
|
|
28522
|
-
async function
|
|
28523
|
-
const { client, poolAddress, account,
|
|
28919
|
+
async function simulateForceExercise(params) {
|
|
28920
|
+
const { client, poolAddress, account, user, positionIdListFrom, positionIdListTo, positionIdListToFinal, blockNumber } = params;
|
|
28921
|
+
const targetBlockNumber = blockNumber ?? await client.getBlockNumber();
|
|
28922
|
+
const metaPromise = getBlockMeta({
|
|
28923
|
+
client,
|
|
28924
|
+
blockNumber: targetBlockNumber
|
|
28925
|
+
});
|
|
28926
|
+
const emptyTokenFlow = {
|
|
28927
|
+
delta0: 0n,
|
|
28928
|
+
delta1: 0n,
|
|
28929
|
+
balanceBefore0: 0n,
|
|
28930
|
+
balanceBefore1: 0n,
|
|
28931
|
+
balanceAfter0: 0n,
|
|
28932
|
+
balanceAfter1: 0n,
|
|
28933
|
+
tickBefore: null,
|
|
28934
|
+
tickAfter: null
|
|
28935
|
+
};
|
|
28936
|
+
try {
|
|
28937
|
+
const callData = encodeFunctionData({
|
|
28938
|
+
abi: panopticPoolV2Abi,
|
|
28939
|
+
functionName: "dispatchFrom",
|
|
28940
|
+
args: [
|
|
28941
|
+
positionIdListFrom,
|
|
28942
|
+
user,
|
|
28943
|
+
positionIdListTo,
|
|
28944
|
+
positionIdListToFinal,
|
|
28945
|
+
0n
|
|
28946
|
+
]
|
|
28947
|
+
});
|
|
28948
|
+
const flowResult = await simulateWithTokenFlow({
|
|
28949
|
+
client,
|
|
28950
|
+
poolAddress,
|
|
28951
|
+
user: account,
|
|
28952
|
+
callData,
|
|
28953
|
+
blockNumber: targetBlockNumber
|
|
28954
|
+
});
|
|
28955
|
+
if (!flowResult.success || !flowResult.tokenFlow) {
|
|
28956
|
+
const errorMessage = flowResult.error || "Simulation failed";
|
|
28957
|
+
const isNotExercisable = errorMessage.includes("NoLegsExercisable") || errorMessage.includes("NotALongLeg");
|
|
28958
|
+
if (isNotExercisable) {
|
|
28959
|
+
const _meta$1 = await metaPromise;
|
|
28960
|
+
const data$1 = {
|
|
28961
|
+
exerciseFee0: 0n,
|
|
28962
|
+
exerciseFee1: 0n,
|
|
28963
|
+
canExercise: false,
|
|
28964
|
+
reason: errorMessage.includes("NoLegsExercisable") ? "No legs are exercisable (not ITM)" : "Position does not have a long leg"
|
|
28965
|
+
};
|
|
28966
|
+
return {
|
|
28967
|
+
success: true,
|
|
28968
|
+
data: data$1,
|
|
28969
|
+
gasEstimate: 0n,
|
|
28970
|
+
tokenFlow: emptyTokenFlow,
|
|
28971
|
+
_meta: _meta$1
|
|
28972
|
+
};
|
|
28973
|
+
}
|
|
28974
|
+
throw new PanopticError(errorMessage);
|
|
28975
|
+
}
|
|
28976
|
+
const _meta = await metaPromise;
|
|
28977
|
+
const tokenFlow = flowResult.tokenFlow;
|
|
28978
|
+
const data = {
|
|
28979
|
+
exerciseFee0: tokenFlow.delta0,
|
|
28980
|
+
exerciseFee1: tokenFlow.delta1,
|
|
28981
|
+
canExercise: true
|
|
28982
|
+
};
|
|
28983
|
+
return {
|
|
28984
|
+
success: true,
|
|
28985
|
+
data,
|
|
28986
|
+
gasEstimate: flowResult.gasEstimate,
|
|
28987
|
+
tokenFlow,
|
|
28988
|
+
_meta
|
|
28989
|
+
};
|
|
28990
|
+
} catch (error) {
|
|
28991
|
+
const _meta = await metaPromise;
|
|
28992
|
+
const errorMessage = error instanceof Error ? error.message : "Simulation failed";
|
|
28993
|
+
const isNotExercisable = errorMessage.includes("NoLegsExercisable") || errorMessage.includes("NotALongLeg");
|
|
28994
|
+
if (isNotExercisable) {
|
|
28995
|
+
const data = {
|
|
28996
|
+
exerciseFee0: 0n,
|
|
28997
|
+
exerciseFee1: 0n,
|
|
28998
|
+
canExercise: false,
|
|
28999
|
+
reason: errorMessage.includes("NoLegsExercisable") ? "No legs are exercisable (not ITM)" : "Position does not have a long leg"
|
|
29000
|
+
};
|
|
29001
|
+
return {
|
|
29002
|
+
success: true,
|
|
29003
|
+
data,
|
|
29004
|
+
gasEstimate: 0n,
|
|
29005
|
+
tokenFlow: emptyTokenFlow,
|
|
29006
|
+
_meta
|
|
29007
|
+
};
|
|
29008
|
+
}
|
|
29009
|
+
return {
|
|
29010
|
+
success: false,
|
|
29011
|
+
error: error instanceof PanopticError ? error : new PanopticError(errorMessage, error instanceof Error ? error : void 0),
|
|
29012
|
+
_meta
|
|
29013
|
+
};
|
|
29014
|
+
}
|
|
29015
|
+
}
|
|
29016
|
+
|
|
29017
|
+
//#endregion
|
|
29018
|
+
//#region src/panoptic/v2/simulations/simulateLiquidate.ts
|
|
29019
|
+
/**
|
|
29020
|
+
* Simulate a liquidation operation.
|
|
29021
|
+
*
|
|
29022
|
+
* @param params - Simulation parameters
|
|
29023
|
+
* @returns Simulation result with liquidation data or error
|
|
29024
|
+
*/
|
|
29025
|
+
async function simulateLiquidate(params) {
|
|
29026
|
+
const { client, poolAddress, account, liquidatee, positionIdListFrom, positionIdListTo, positionIdListToFinal, blockNumber } = params;
|
|
28524
29027
|
const targetBlockNumber = blockNumber ?? await client.getBlockNumber();
|
|
28525
29028
|
const metaPromise = getBlockMeta({
|
|
28526
29029
|
client,
|
|
@@ -29060,7 +29563,7 @@ async function simulateSwapExactIn(params) {
|
|
|
29060
29563
|
|
|
29061
29564
|
//#endregion
|
|
29062
29565
|
//#region src/panoptic/v2/simulations/oneTokenFlow.ts
|
|
29063
|
-
const BPS_DENOMINATOR$
|
|
29566
|
+
const BPS_DENOMINATOR$3 = 10000n;
|
|
29064
29567
|
/**
|
|
29065
29568
|
* Default {@link OneTokenFlowQuoteParams.minSwapRatioBps}: 0.5%.
|
|
29066
29569
|
*
|
|
@@ -29077,7 +29580,7 @@ function abs(value) {
|
|
|
29077
29580
|
return value < 0n ? -value : value;
|
|
29078
29581
|
}
|
|
29079
29582
|
function padForSlippage(amount, slippageBps) {
|
|
29080
|
-
return (amount * (BPS_DENOMINATOR$
|
|
29583
|
+
return (amount * (BPS_DENOMINATOR$3 + slippageBps) + BPS_DENOMINATOR$3 - 1n) / BPS_DENOMINATOR$3;
|
|
29081
29584
|
}
|
|
29082
29585
|
/**
|
|
29083
29586
|
* Quote a dispatch wrapped so its net flow lands in `targetTokenIndex` only.
|
|
@@ -29097,10 +29600,10 @@ async function quoteOneTokenFlow(params) {
|
|
|
29097
29600
|
reason: "invalid-target-token",
|
|
29098
29601
|
detail: `targetTokenIndex=${targetTokenIndex} is neither 0 nor 1`
|
|
29099
29602
|
};
|
|
29100
|
-
if (params.slippageBps < 0n || params.slippageBps > BPS_DENOMINATOR$
|
|
29603
|
+
if (params.slippageBps < 0n || params.slippageBps > BPS_DENOMINATOR$3) return {
|
|
29101
29604
|
available: false,
|
|
29102
29605
|
reason: "invalid-slippage",
|
|
29103
|
-
detail: `slippageBps=${params.slippageBps} is outside [0, ${BPS_DENOMINATOR$
|
|
29606
|
+
detail: `slippageBps=${params.slippageBps} is outside [0, ${BPS_DENOMINATOR$3}]`
|
|
29104
29607
|
};
|
|
29105
29608
|
const tickLimitLow = params.tickLimitLow ?? MIN_TICK;
|
|
29106
29609
|
const tickLimitHigh = params.tickLimitHigh ?? MAX_TICK;
|
|
@@ -29190,7 +29693,7 @@ async function quoteOneTokenFlow(params) {
|
|
|
29190
29693
|
if (minSwapRatioBps > 0n) {
|
|
29191
29694
|
const residualInTargetTerms = convertToTokenIndex(abs(recovery.quote.netTokenOutChange), otherTokenIndex, targetTokenIndex, pool.sqrtPriceX96);
|
|
29192
29695
|
const settledInTargetTerms = abs(recovery.quote.netTokenInChange) + residualInTargetTerms;
|
|
29193
|
-
if (residualInTargetTerms * BPS_DENOMINATOR$
|
|
29696
|
+
if (residualInTargetTerms * BPS_DENOMINATOR$3 >= minSwapRatioBps * settledInTargetTerms) return {
|
|
29194
29697
|
available: false,
|
|
29195
29698
|
reason: "residual-not-single-token",
|
|
29196
29699
|
detail: `covering the shortfall leaves ${recovery.quote.netTokenOutChange} of the other token (${residualInTargetTerms} in target token terms) against a target flow of ${recovery.quote.netTokenInChange}`
|
|
@@ -29219,7 +29722,7 @@ async function quoteOneTokenFlow(params) {
|
|
|
29219
29722
|
}
|
|
29220
29723
|
if (baseTargetDelta !== null && minSwapRatioBps > 0n) {
|
|
29221
29724
|
const swapInTargetTerms = convertToTokenIndex(swapAmount, otherTokenIndex, targetTokenIndex, pool.sqrtPriceX96);
|
|
29222
|
-
if (swapInTargetTerms * BPS_DENOMINATOR$
|
|
29725
|
+
if (swapInTargetTerms * BPS_DENOMINATOR$3 < minSwapRatioBps * abs(baseTargetDelta)) return {
|
|
29223
29726
|
available: false,
|
|
29224
29727
|
reason: "below-threshold",
|
|
29225
29728
|
detail: `non-target flow ${swapInTargetTerms} (in target token terms) is below ${minSwapRatioBps}bps of the target flow ${abs(baseTargetDelta)}`
|
|
@@ -29305,6 +29808,251 @@ async function quoteOneTokenFlow(params) {
|
|
|
29305
29808
|
};
|
|
29306
29809
|
}
|
|
29307
29810
|
|
|
29811
|
+
//#endregion
|
|
29812
|
+
//#region src/uniswap/v4/router/encodeSwap.ts
|
|
29813
|
+
const UINT128_MAX$2 = (1n << 128n) - 1n;
|
|
29814
|
+
|
|
29815
|
+
//#endregion
|
|
29816
|
+
//#region src/uniswap/v4/router/permit2.ts
|
|
29817
|
+
/** uint160 max — the largest Permit2 allowance amount. */
|
|
29818
|
+
const UINT160_MAX = (1n << 160n) - 1n;
|
|
29819
|
+
/** uint48 max — the largest Permit2 expiration. */
|
|
29820
|
+
const UINT48_MAX = (1n << 48n) - 1n;
|
|
29821
|
+
|
|
29822
|
+
//#endregion
|
|
29823
|
+
//#region src/uniswap/v4/abis/v4Quoter.ts
|
|
29824
|
+
/**
|
|
29825
|
+
* Minimal V4Quoter ABI (`quoteExactInputSingle`, `quoteExactOutputSingle`).
|
|
29826
|
+
*
|
|
29827
|
+
* Note: neither function is `view` — they mutate state internally and are
|
|
29828
|
+
* intended to be called via `eth_call` / viem `simulateContract`, never
|
|
29829
|
+
* `readContract`.
|
|
29830
|
+
*
|
|
29831
|
+
* @module uniswap/v4/abis/v4Quoter
|
|
29832
|
+
*/
|
|
29833
|
+
const quoteExactSingleParams = {
|
|
29834
|
+
name: "params",
|
|
29835
|
+
type: "tuple",
|
|
29836
|
+
components: [
|
|
29837
|
+
{
|
|
29838
|
+
name: "poolKey",
|
|
29839
|
+
type: "tuple",
|
|
29840
|
+
components: [
|
|
29841
|
+
{
|
|
29842
|
+
name: "currency0",
|
|
29843
|
+
type: "address"
|
|
29844
|
+
},
|
|
29845
|
+
{
|
|
29846
|
+
name: "currency1",
|
|
29847
|
+
type: "address"
|
|
29848
|
+
},
|
|
29849
|
+
{
|
|
29850
|
+
name: "fee",
|
|
29851
|
+
type: "uint24"
|
|
29852
|
+
},
|
|
29853
|
+
{
|
|
29854
|
+
name: "tickSpacing",
|
|
29855
|
+
type: "int24"
|
|
29856
|
+
},
|
|
29857
|
+
{
|
|
29858
|
+
name: "hooks",
|
|
29859
|
+
type: "address"
|
|
29860
|
+
}
|
|
29861
|
+
]
|
|
29862
|
+
},
|
|
29863
|
+
{
|
|
29864
|
+
name: "zeroForOne",
|
|
29865
|
+
type: "bool"
|
|
29866
|
+
},
|
|
29867
|
+
{
|
|
29868
|
+
name: "exactAmount",
|
|
29869
|
+
type: "uint128"
|
|
29870
|
+
},
|
|
29871
|
+
{
|
|
29872
|
+
name: "hookData",
|
|
29873
|
+
type: "bytes"
|
|
29874
|
+
}
|
|
29875
|
+
]
|
|
29876
|
+
};
|
|
29877
|
+
const v4QuoterAbi = [{
|
|
29878
|
+
type: "function",
|
|
29879
|
+
name: "quoteExactInputSingle",
|
|
29880
|
+
stateMutability: "nonpayable",
|
|
29881
|
+
inputs: [quoteExactSingleParams],
|
|
29882
|
+
outputs: [{
|
|
29883
|
+
name: "amountOut",
|
|
29884
|
+
type: "uint256"
|
|
29885
|
+
}, {
|
|
29886
|
+
name: "gasEstimate",
|
|
29887
|
+
type: "uint256"
|
|
29888
|
+
}]
|
|
29889
|
+
}, {
|
|
29890
|
+
type: "function",
|
|
29891
|
+
name: "quoteExactOutputSingle",
|
|
29892
|
+
stateMutability: "nonpayable",
|
|
29893
|
+
inputs: [quoteExactSingleParams],
|
|
29894
|
+
outputs: [{
|
|
29895
|
+
name: "amountIn",
|
|
29896
|
+
type: "uint256"
|
|
29897
|
+
}, {
|
|
29898
|
+
name: "gasEstimate",
|
|
29899
|
+
type: "uint256"
|
|
29900
|
+
}]
|
|
29901
|
+
}];
|
|
29902
|
+
|
|
29903
|
+
//#endregion
|
|
29904
|
+
//#region src/uniswap/v4/router/resolvePoolKey.ts
|
|
29905
|
+
/**
|
|
29906
|
+
* Resolve the PoolKey, swap direction, and output token metadata for a swap.
|
|
29907
|
+
*
|
|
29908
|
+
* @throws {InvalidSwapTokenError} when `tokenIn` is not part of the pool.
|
|
29909
|
+
*/
|
|
29910
|
+
async function resolveSwapRoute(params) {
|
|
29911
|
+
const { client, poolAddress, chainId, tokenIn, blockNumber } = params;
|
|
29912
|
+
const pool = await getPool({
|
|
29913
|
+
client,
|
|
29914
|
+
poolAddress,
|
|
29915
|
+
chainId,
|
|
29916
|
+
blockNumber
|
|
29917
|
+
});
|
|
29918
|
+
const { poolKey } = pool;
|
|
29919
|
+
const isCurrency0 = isAddressEqual(tokenIn, poolKey.currency0);
|
|
29920
|
+
const isCurrency1 = isAddressEqual(tokenIn, poolKey.currency1);
|
|
29921
|
+
if (!isCurrency0 && !isCurrency1) throw new InvalidSwapTokenError(tokenIn, poolKey.currency0, poolKey.currency1);
|
|
29922
|
+
const zeroForOne = isCurrency0;
|
|
29923
|
+
const tokenOut = zeroForOne ? poolKey.currency1 : poolKey.currency0;
|
|
29924
|
+
const outTracker = zeroForOne ? pool.collateralTracker1 : pool.collateralTracker0;
|
|
29925
|
+
return {
|
|
29926
|
+
poolKey,
|
|
29927
|
+
zeroForOne,
|
|
29928
|
+
tokenOut,
|
|
29929
|
+
tokenOutDecimals: outTracker.decimals,
|
|
29930
|
+
tokenOutSymbol: outTracker.symbol
|
|
29931
|
+
};
|
|
29932
|
+
}
|
|
29933
|
+
|
|
29934
|
+
//#endregion
|
|
29935
|
+
//#region src/uniswap/v4/router/quote.ts
|
|
29936
|
+
const BPS_DENOMINATOR$2 = 10000n;
|
|
29937
|
+
const UINT128_MAX$1 = (1n << 128n) - 1n;
|
|
29938
|
+
/** Reject out-of-range slippage so the min/max amount math can't underflow/overflow. */
|
|
29939
|
+
function assertSlippageBps(slippageBps) {
|
|
29940
|
+
if (slippageBps < 0n || slippageBps > BPS_DENOMINATOR$2) throw new PanopticError(`invalid slippageBps ${slippageBps}, must be 0..10000`);
|
|
29941
|
+
}
|
|
29942
|
+
const FALLBACK_META = {
|
|
29943
|
+
blockNumber: 0n,
|
|
29944
|
+
blockTimestamp: 0n,
|
|
29945
|
+
blockHash: "0x0"
|
|
29946
|
+
};
|
|
29947
|
+
/**
|
|
29948
|
+
* Quote an exact-out spot swap against the underlying Uniswap v4 pool.
|
|
29949
|
+
*
|
|
29950
|
+
* Uses the V4Quoter `quoteExactOutputSingle` via `eth_call` (the quoter is
|
|
29951
|
+
* state-mutating / revert-based, so it must be simulated, not read). Returns a
|
|
29952
|
+
* `SimulationResult` so failures carry a structured error rather than throwing.
|
|
29953
|
+
*/
|
|
29954
|
+
async function quoteSwapExactOutViaRouter(params) {
|
|
29955
|
+
const { client, poolAddress, chainId, tokenIn, amountOut, slippageBps, blockNumber, addresses } = params;
|
|
29956
|
+
try {
|
|
29957
|
+
if (amountOut < 0n || amountOut > UINT128_MAX$1) throw new PanopticError(`amountOut ${amountOut} exceeds uint128 maximum`);
|
|
29958
|
+
assertSlippageBps(slippageBps);
|
|
29959
|
+
const targetBlockNumber = blockNumber ?? await client.getBlockNumber();
|
|
29960
|
+
const metaPromise = getBlockMeta({
|
|
29961
|
+
client,
|
|
29962
|
+
blockNumber: targetBlockNumber
|
|
29963
|
+
});
|
|
29964
|
+
const { v4Quoter } = getUniswapV4Addresses(chainId, addresses);
|
|
29965
|
+
if (v4Quoter === zeroAddress) throw new QuoterUnavailableError(chainId);
|
|
29966
|
+
const route = await resolveSwapRoute({
|
|
29967
|
+
client,
|
|
29968
|
+
poolAddress,
|
|
29969
|
+
chainId,
|
|
29970
|
+
tokenIn,
|
|
29971
|
+
blockNumber: targetBlockNumber
|
|
29972
|
+
});
|
|
29973
|
+
const { result } = await client.simulateContract({
|
|
29974
|
+
address: v4Quoter,
|
|
29975
|
+
abi: v4QuoterAbi,
|
|
29976
|
+
functionName: "quoteExactOutputSingle",
|
|
29977
|
+
blockNumber: targetBlockNumber,
|
|
29978
|
+
args: [{
|
|
29979
|
+
poolKey: {
|
|
29980
|
+
currency0: route.poolKey.currency0,
|
|
29981
|
+
currency1: route.poolKey.currency1,
|
|
29982
|
+
fee: Number(route.poolKey.fee),
|
|
29983
|
+
tickSpacing: Number(route.poolKey.tickSpacing),
|
|
29984
|
+
hooks: route.poolKey.hooks
|
|
29985
|
+
},
|
|
29986
|
+
zeroForOne: route.zeroForOne,
|
|
29987
|
+
exactAmount: amountOut,
|
|
29988
|
+
hookData: "0x"
|
|
29989
|
+
}]
|
|
29990
|
+
});
|
|
29991
|
+
const [amountIn, gasEstimate] = result;
|
|
29992
|
+
const amountInMaximum = (amountIn * (BPS_DENOMINATOR$2 + slippageBps) + BPS_DENOMINATOR$2 - 1n) / BPS_DENOMINATOR$2;
|
|
29993
|
+
const _meta = await metaPromise;
|
|
29994
|
+
return {
|
|
29995
|
+
success: true,
|
|
29996
|
+
data: {
|
|
29997
|
+
amountIn,
|
|
29998
|
+
amountInMaximum,
|
|
29999
|
+
zeroForOne: route.zeroForOne,
|
|
30000
|
+
tokenOut: route.tokenOut,
|
|
30001
|
+
poolKey: route.poolKey,
|
|
30002
|
+
gasEstimate
|
|
30003
|
+
},
|
|
30004
|
+
gasEstimate,
|
|
30005
|
+
_meta
|
|
30006
|
+
};
|
|
30007
|
+
} catch (error) {
|
|
30008
|
+
return {
|
|
30009
|
+
success: false,
|
|
30010
|
+
error: error instanceof PanopticError ? error : new PanopticError(error instanceof Error ? error.message : "Quote failed", error instanceof Error ? error : void 0),
|
|
30011
|
+
_meta: FALLBACK_META
|
|
30012
|
+
};
|
|
30013
|
+
}
|
|
30014
|
+
}
|
|
30015
|
+
|
|
30016
|
+
//#endregion
|
|
30017
|
+
//#region src/uniswap/v4/router/quoteByPoolKey.ts
|
|
30018
|
+
const UINT128_MAX = (1n << 128n) - 1n;
|
|
30019
|
+
|
|
30020
|
+
//#endregion
|
|
30021
|
+
//#region src/panoptic/v2/simulations/quoteTokenShortfallSwap.ts
|
|
30022
|
+
/** Quote the opposite pool token needed to buy the deficit in a NotEnoughTokens revert. */
|
|
30023
|
+
async function quoteTokenShortfallSwap({ client, chainId, poolAddress, error, slippageBps = 50n }) {
|
|
30024
|
+
const shortfall = getNotEnoughTokensError(error);
|
|
30025
|
+
if (shortfall === null || shortfall.deficit === 0n) return null;
|
|
30026
|
+
const metadata = await getPoolMetadata({
|
|
30027
|
+
client,
|
|
30028
|
+
poolAddress
|
|
30029
|
+
});
|
|
30030
|
+
const matches0 = [metadata.token0Asset, metadata.collateralToken0Address].some((address) => isAddressEqual(address, shortfall.tokenAddress));
|
|
30031
|
+
const matches1 = [metadata.token1Asset, metadata.collateralToken1Address].some((address) => isAddressEqual(address, shortfall.tokenAddress));
|
|
30032
|
+
if (matches0 === matches1) return null;
|
|
30033
|
+
const tokenIn = matches0 ? metadata.token1Asset : metadata.token0Asset;
|
|
30034
|
+
const quote = await (metadata.isV4 ? quoteSwapExactOutViaRouter : quoteSwapExactOutViaV3Router)({
|
|
30035
|
+
client,
|
|
30036
|
+
chainId,
|
|
30037
|
+
poolAddress,
|
|
30038
|
+
tokenIn,
|
|
30039
|
+
amountOut: shortfall.deficit,
|
|
30040
|
+
slippageBps
|
|
30041
|
+
});
|
|
30042
|
+
return {
|
|
30043
|
+
deficit: shortfall.deficit,
|
|
30044
|
+
outputSymbol: matches0 ? metadata.token0Symbol : metadata.token1Symbol,
|
|
30045
|
+
outputDecimals: matches0 ? metadata.token0Decimals : metadata.token1Decimals,
|
|
30046
|
+
inputSymbol: matches0 ? metadata.token1Symbol : metadata.token0Symbol,
|
|
30047
|
+
inputDecimals: matches0 ? metadata.token1Decimals : metadata.token0Decimals,
|
|
30048
|
+
tokenIn,
|
|
30049
|
+
slippageBps,
|
|
30050
|
+
poolFeePips: metadata.fee <= 1000000n ? metadata.fee : null,
|
|
30051
|
+
estimatedPoolFee: quote.success && metadata.fee <= 1000000n ? (quote.data.amountIn * metadata.fee + 999999n) / 1000000n : null,
|
|
30052
|
+
quote: quote.success ? quote.data : null
|
|
30053
|
+
};
|
|
30054
|
+
}
|
|
30055
|
+
|
|
29308
30056
|
//#endregion
|
|
29309
30057
|
//#region src/panoptic/v2/simulations/temporaryLoanRecovery.ts
|
|
29310
30058
|
const BPS_DENOMINATOR$1 = 10000n;
|
|
@@ -30407,7 +31155,7 @@ const DEFAULT_INTERVAL_MS = 12000n;
|
|
|
30407
31155
|
/**
|
|
30408
31156
|
* Default maximum block range per poll.
|
|
30409
31157
|
*/
|
|
30410
|
-
const DEFAULT_MAX_BLOCK_RANGE = 1000n;
|
|
31158
|
+
const DEFAULT_MAX_BLOCK_RANGE$1 = 1000n;
|
|
30411
31159
|
/**
|
|
30412
31160
|
* Create an HTTP polling-based event fetcher.
|
|
30413
31161
|
*
|
|
@@ -30444,7 +31192,7 @@ const DEFAULT_MAX_BLOCK_RANGE = 1000n;
|
|
|
30444
31192
|
* ```
|
|
30445
31193
|
*/
|
|
30446
31194
|
function createEventPoller(params) {
|
|
30447
|
-
const { client, poolAddress, collateralTracker0, collateralTracker1, riskEngineAddress, sfpmAddress, poolManagerAddress, eventTypes, onLogs, onError, intervalMs = DEFAULT_INTERVAL_MS, maxBlockRange = DEFAULT_MAX_BLOCK_RANGE, fromBlock } = params;
|
|
31195
|
+
const { client, poolAddress, collateralTracker0, collateralTracker1, riskEngineAddress, sfpmAddress, poolManagerAddress, eventTypes, onLogs, onError, intervalMs = DEFAULT_INTERVAL_MS, maxBlockRange = DEFAULT_MAX_BLOCK_RANGE$1, fromBlock } = params;
|
|
30448
31196
|
let isRunning = false;
|
|
30449
31197
|
let lastPolledBlock = fromBlock ?? 0n;
|
|
30450
31198
|
let pollTimeout = null;
|
|
@@ -30633,272 +31381,1621 @@ function createEventPoller(params) {
|
|
|
30633
31381
|
}
|
|
30634
31382
|
|
|
30635
31383
|
//#endregion
|
|
30636
|
-
//#region src/
|
|
30637
|
-
|
|
30638
|
-
|
|
30639
|
-
|
|
30640
|
-
|
|
30641
|
-
|
|
30642
|
-
|
|
30643
|
-
|
|
30644
|
-
|
|
30645
|
-
|
|
30646
|
-
|
|
30647
|
-
|
|
30648
|
-
|
|
30649
|
-
|
|
30650
|
-
|
|
30651
|
-
|
|
30652
|
-
|
|
30653
|
-
|
|
30654
|
-
|
|
30655
|
-
|
|
30656
|
-
|
|
30657
|
-
|
|
30658
|
-
|
|
30659
|
-
|
|
30660
|
-
|
|
30661
|
-
|
|
30662
|
-
|
|
30663
|
-
|
|
30664
|
-
|
|
30665
|
-
|
|
30666
|
-
|
|
30667
|
-
|
|
30668
|
-
|
|
30669
|
-
|
|
30670
|
-
|
|
30671
|
-
|
|
30672
|
-
|
|
30673
|
-
|
|
30674
|
-
|
|
30675
|
-
|
|
30676
|
-
|
|
30677
|
-
|
|
30678
|
-
|
|
30679
|
-
|
|
30680
|
-
|
|
30681
|
-
|
|
30682
|
-
|
|
30683
|
-
|
|
30684
|
-
|
|
30685
|
-
}
|
|
30686
|
-
|
|
30687
|
-
|
|
30688
|
-
|
|
30689
|
-
|
|
30690
|
-
|
|
30691
|
-
|
|
30692
|
-
|
|
30693
|
-
|
|
30694
|
-
|
|
30695
|
-
|
|
30696
|
-
|
|
30697
|
-
|
|
30698
|
-
|
|
30699
|
-
|
|
30700
|
-
|
|
30701
|
-
|
|
30702
|
-
|
|
30703
|
-
|
|
30704
|
-
|
|
30705
|
-
|
|
30706
|
-
|
|
30707
|
-
|
|
30708
|
-
|
|
30709
|
-
|
|
30710
|
-
|
|
30711
|
-
|
|
30712
|
-
|
|
30713
|
-
|
|
30714
|
-
|
|
30715
|
-
|
|
30716
|
-
|
|
30717
|
-
|
|
30718
|
-
|
|
30719
|
-
|
|
30720
|
-
|
|
30721
|
-
|
|
30722
|
-
|
|
30723
|
-
|
|
30724
|
-
|
|
30725
|
-
|
|
30726
|
-
|
|
30727
|
-
|
|
30728
|
-
|
|
30729
|
-
|
|
30730
|
-
|
|
30731
|
-
|
|
30732
|
-
|
|
30733
|
-
|
|
30734
|
-
|
|
30735
|
-
|
|
30736
|
-
|
|
30737
|
-
|
|
30738
|
-
|
|
30739
|
-
|
|
30740
|
-
|
|
30741
|
-
|
|
30742
|
-
|
|
30743
|
-
|
|
30744
|
-
|
|
30745
|
-
|
|
30746
|
-
|
|
30747
|
-
|
|
30748
|
-
|
|
30749
|
-
|
|
30750
|
-
|
|
30751
|
-
|
|
30752
|
-
|
|
30753
|
-
|
|
30754
|
-
|
|
30755
|
-
}
|
|
30756
|
-
|
|
30757
|
-
|
|
30758
|
-
|
|
30759
|
-
|
|
30760
|
-
|
|
30761
|
-
|
|
30762
|
-
|
|
30763
|
-
|
|
30764
|
-
|
|
30765
|
-
|
|
30766
|
-
|
|
30767
|
-
|
|
30768
|
-
|
|
30769
|
-
|
|
30770
|
-
|
|
30771
|
-
|
|
30772
|
-
|
|
30773
|
-
|
|
30774
|
-
|
|
30775
|
-
|
|
30776
|
-
|
|
30777
|
-
|
|
30778
|
-
|
|
30779
|
-
|
|
30780
|
-
|
|
30781
|
-
|
|
30782
|
-
|
|
30783
|
-
|
|
30784
|
-
|
|
30785
|
-
|
|
30786
|
-
|
|
30787
|
-
|
|
30788
|
-
|
|
30789
|
-
|
|
30790
|
-
|
|
30791
|
-
|
|
30792
|
-
|
|
30793
|
-
|
|
30794
|
-
|
|
30795
|
-
|
|
30796
|
-
|
|
30797
|
-
|
|
30798
|
-
|
|
30799
|
-
|
|
30800
|
-
|
|
30801
|
-
|
|
30802
|
-
|
|
30803
|
-
|
|
30804
|
-
|
|
30805
|
-
|
|
30806
|
-
|
|
30807
|
-
|
|
30808
|
-
|
|
30809
|
-
|
|
30810
|
-
|
|
30811
|
-
|
|
30812
|
-
|
|
30813
|
-
|
|
30814
|
-
|
|
30815
|
-
|
|
30816
|
-
|
|
30817
|
-
|
|
30818
|
-
|
|
30819
|
-
|
|
30820
|
-
|
|
30821
|
-
|
|
30822
|
-
|
|
30823
|
-
|
|
30824
|
-
|
|
30825
|
-
|
|
30826
|
-
|
|
30827
|
-
|
|
30828
|
-
|
|
30829
|
-
|
|
30830
|
-
|
|
30831
|
-
|
|
30832
|
-
|
|
30833
|
-
|
|
30834
|
-
}
|
|
30835
|
-
|
|
30836
|
-
|
|
30837
|
-
|
|
30838
|
-
|
|
30839
|
-
|
|
30840
|
-
|
|
30841
|
-
|
|
30842
|
-
|
|
30843
|
-
|
|
30844
|
-
|
|
30845
|
-
|
|
30846
|
-
|
|
30847
|
-
|
|
30848
|
-
|
|
30849
|
-
|
|
30850
|
-
|
|
30851
|
-
|
|
30852
|
-
|
|
30853
|
-
|
|
30854
|
-
|
|
30855
|
-
|
|
30856
|
-
|
|
30857
|
-
|
|
30858
|
-
|
|
30859
|
-
|
|
30860
|
-
|
|
30861
|
-
}
|
|
30862
|
-
|
|
30863
|
-
|
|
30864
|
-
|
|
30865
|
-
|
|
30866
|
-
|
|
30867
|
-
|
|
30868
|
-
|
|
30869
|
-
|
|
30870
|
-
|
|
30871
|
-
|
|
30872
|
-
|
|
30873
|
-
|
|
30874
|
-
|
|
30875
|
-
|
|
30876
|
-
|
|
30877
|
-
|
|
30878
|
-
|
|
30879
|
-
|
|
30880
|
-
|
|
30881
|
-
|
|
30882
|
-
|
|
30883
|
-
|
|
30884
|
-
|
|
30885
|
-
|
|
30886
|
-
|
|
30887
|
-
|
|
30888
|
-
|
|
30889
|
-
|
|
30890
|
-
|
|
30891
|
-
|
|
30892
|
-
|
|
30893
|
-
|
|
30894
|
-
|
|
30895
|
-
|
|
30896
|
-
|
|
30897
|
-
|
|
30898
|
-
|
|
30899
|
-
|
|
30900
|
-
|
|
30901
|
-
|
|
31384
|
+
//#region src/abis/UniswapV3Pool.ts
|
|
31385
|
+
const UniswapV3PoolAbi = [
|
|
31386
|
+
{
|
|
31387
|
+
inputs: [],
|
|
31388
|
+
stateMutability: "payable",
|
|
31389
|
+
type: "constructor"
|
|
31390
|
+
},
|
|
31391
|
+
{
|
|
31392
|
+
anonymous: false,
|
|
31393
|
+
inputs: [
|
|
31394
|
+
{
|
|
31395
|
+
indexed: true,
|
|
31396
|
+
internalType: "address",
|
|
31397
|
+
name: "owner",
|
|
31398
|
+
type: "address"
|
|
31399
|
+
},
|
|
31400
|
+
{
|
|
31401
|
+
indexed: true,
|
|
31402
|
+
internalType: "int24",
|
|
31403
|
+
name: "tickLower",
|
|
31404
|
+
type: "int24"
|
|
31405
|
+
},
|
|
31406
|
+
{
|
|
31407
|
+
indexed: true,
|
|
31408
|
+
internalType: "int24",
|
|
31409
|
+
name: "tickUpper",
|
|
31410
|
+
type: "int24"
|
|
31411
|
+
},
|
|
31412
|
+
{
|
|
31413
|
+
indexed: false,
|
|
31414
|
+
internalType: "uint128",
|
|
31415
|
+
name: "amount",
|
|
31416
|
+
type: "uint128"
|
|
31417
|
+
},
|
|
31418
|
+
{
|
|
31419
|
+
indexed: false,
|
|
31420
|
+
internalType: "uint256",
|
|
31421
|
+
name: "amount0",
|
|
31422
|
+
type: "uint256"
|
|
31423
|
+
},
|
|
31424
|
+
{
|
|
31425
|
+
indexed: false,
|
|
31426
|
+
internalType: "uint256",
|
|
31427
|
+
name: "amount1",
|
|
31428
|
+
type: "uint256"
|
|
31429
|
+
}
|
|
31430
|
+
],
|
|
31431
|
+
name: "Burn",
|
|
31432
|
+
type: "event"
|
|
31433
|
+
},
|
|
31434
|
+
{
|
|
31435
|
+
anonymous: false,
|
|
31436
|
+
inputs: [
|
|
31437
|
+
{
|
|
31438
|
+
indexed: true,
|
|
31439
|
+
internalType: "address",
|
|
31440
|
+
name: "owner",
|
|
31441
|
+
type: "address"
|
|
31442
|
+
},
|
|
31443
|
+
{
|
|
31444
|
+
indexed: false,
|
|
31445
|
+
internalType: "address",
|
|
31446
|
+
name: "recipient",
|
|
31447
|
+
type: "address"
|
|
31448
|
+
},
|
|
31449
|
+
{
|
|
31450
|
+
indexed: true,
|
|
31451
|
+
internalType: "int24",
|
|
31452
|
+
name: "tickLower",
|
|
31453
|
+
type: "int24"
|
|
31454
|
+
},
|
|
31455
|
+
{
|
|
31456
|
+
indexed: true,
|
|
31457
|
+
internalType: "int24",
|
|
31458
|
+
name: "tickUpper",
|
|
31459
|
+
type: "int24"
|
|
31460
|
+
},
|
|
31461
|
+
{
|
|
31462
|
+
indexed: false,
|
|
31463
|
+
internalType: "uint128",
|
|
31464
|
+
name: "amount0",
|
|
31465
|
+
type: "uint128"
|
|
31466
|
+
},
|
|
31467
|
+
{
|
|
31468
|
+
indexed: false,
|
|
31469
|
+
internalType: "uint128",
|
|
31470
|
+
name: "amount1",
|
|
31471
|
+
type: "uint128"
|
|
31472
|
+
}
|
|
31473
|
+
],
|
|
31474
|
+
name: "Collect",
|
|
31475
|
+
type: "event"
|
|
31476
|
+
},
|
|
31477
|
+
{
|
|
31478
|
+
anonymous: false,
|
|
31479
|
+
inputs: [
|
|
31480
|
+
{
|
|
31481
|
+
indexed: true,
|
|
31482
|
+
internalType: "address",
|
|
31483
|
+
name: "sender",
|
|
31484
|
+
type: "address"
|
|
31485
|
+
},
|
|
31486
|
+
{
|
|
31487
|
+
indexed: true,
|
|
31488
|
+
internalType: "address",
|
|
31489
|
+
name: "recipient",
|
|
31490
|
+
type: "address"
|
|
31491
|
+
},
|
|
31492
|
+
{
|
|
31493
|
+
indexed: false,
|
|
31494
|
+
internalType: "uint128",
|
|
31495
|
+
name: "amount0",
|
|
31496
|
+
type: "uint128"
|
|
31497
|
+
},
|
|
31498
|
+
{
|
|
31499
|
+
indexed: false,
|
|
31500
|
+
internalType: "uint128",
|
|
31501
|
+
name: "amount1",
|
|
31502
|
+
type: "uint128"
|
|
31503
|
+
}
|
|
31504
|
+
],
|
|
31505
|
+
name: "CollectProtocol",
|
|
31506
|
+
type: "event"
|
|
31507
|
+
},
|
|
31508
|
+
{
|
|
31509
|
+
anonymous: false,
|
|
31510
|
+
inputs: [
|
|
31511
|
+
{
|
|
31512
|
+
indexed: true,
|
|
31513
|
+
internalType: "address",
|
|
31514
|
+
name: "sender",
|
|
31515
|
+
type: "address"
|
|
31516
|
+
},
|
|
31517
|
+
{
|
|
31518
|
+
indexed: true,
|
|
31519
|
+
internalType: "address",
|
|
31520
|
+
name: "recipient",
|
|
31521
|
+
type: "address"
|
|
31522
|
+
},
|
|
31523
|
+
{
|
|
31524
|
+
indexed: false,
|
|
31525
|
+
internalType: "uint256",
|
|
31526
|
+
name: "amount0",
|
|
31527
|
+
type: "uint256"
|
|
31528
|
+
},
|
|
31529
|
+
{
|
|
31530
|
+
indexed: false,
|
|
31531
|
+
internalType: "uint256",
|
|
31532
|
+
name: "amount1",
|
|
31533
|
+
type: "uint256"
|
|
31534
|
+
},
|
|
31535
|
+
{
|
|
31536
|
+
indexed: false,
|
|
31537
|
+
internalType: "uint256",
|
|
31538
|
+
name: "paid0",
|
|
31539
|
+
type: "uint256"
|
|
31540
|
+
},
|
|
31541
|
+
{
|
|
31542
|
+
indexed: false,
|
|
31543
|
+
internalType: "uint256",
|
|
31544
|
+
name: "paid1",
|
|
31545
|
+
type: "uint256"
|
|
31546
|
+
}
|
|
31547
|
+
],
|
|
31548
|
+
name: "Flash",
|
|
31549
|
+
type: "event"
|
|
31550
|
+
},
|
|
31551
|
+
{
|
|
31552
|
+
anonymous: false,
|
|
31553
|
+
inputs: [{
|
|
31554
|
+
indexed: false,
|
|
31555
|
+
internalType: "uint16",
|
|
31556
|
+
name: "observationCardinalityNextOld",
|
|
31557
|
+
type: "uint16"
|
|
31558
|
+
}, {
|
|
31559
|
+
indexed: false,
|
|
31560
|
+
internalType: "uint16",
|
|
31561
|
+
name: "observationCardinalityNextNew",
|
|
31562
|
+
type: "uint16"
|
|
31563
|
+
}],
|
|
31564
|
+
name: "IncreaseObservationCardinalityNext",
|
|
31565
|
+
type: "event"
|
|
31566
|
+
},
|
|
31567
|
+
{
|
|
31568
|
+
anonymous: false,
|
|
31569
|
+
inputs: [{
|
|
31570
|
+
indexed: false,
|
|
31571
|
+
internalType: "uint160",
|
|
31572
|
+
name: "sqrtPriceX96",
|
|
31573
|
+
type: "uint160"
|
|
31574
|
+
}, {
|
|
31575
|
+
indexed: false,
|
|
31576
|
+
internalType: "int24",
|
|
31577
|
+
name: "tick",
|
|
31578
|
+
type: "int24"
|
|
31579
|
+
}],
|
|
31580
|
+
name: "Initialize",
|
|
31581
|
+
type: "event"
|
|
31582
|
+
},
|
|
31583
|
+
{
|
|
31584
|
+
anonymous: false,
|
|
31585
|
+
inputs: [
|
|
31586
|
+
{
|
|
31587
|
+
indexed: false,
|
|
31588
|
+
internalType: "address",
|
|
31589
|
+
name: "sender",
|
|
31590
|
+
type: "address"
|
|
31591
|
+
},
|
|
31592
|
+
{
|
|
31593
|
+
indexed: true,
|
|
31594
|
+
internalType: "address",
|
|
31595
|
+
name: "owner",
|
|
31596
|
+
type: "address"
|
|
31597
|
+
},
|
|
31598
|
+
{
|
|
31599
|
+
indexed: true,
|
|
31600
|
+
internalType: "int24",
|
|
31601
|
+
name: "tickLower",
|
|
31602
|
+
type: "int24"
|
|
31603
|
+
},
|
|
31604
|
+
{
|
|
31605
|
+
indexed: true,
|
|
31606
|
+
internalType: "int24",
|
|
31607
|
+
name: "tickUpper",
|
|
31608
|
+
type: "int24"
|
|
31609
|
+
},
|
|
31610
|
+
{
|
|
31611
|
+
indexed: false,
|
|
31612
|
+
internalType: "uint128",
|
|
31613
|
+
name: "amount",
|
|
31614
|
+
type: "uint128"
|
|
31615
|
+
},
|
|
31616
|
+
{
|
|
31617
|
+
indexed: false,
|
|
31618
|
+
internalType: "uint256",
|
|
31619
|
+
name: "amount0",
|
|
31620
|
+
type: "uint256"
|
|
31621
|
+
},
|
|
31622
|
+
{
|
|
31623
|
+
indexed: false,
|
|
31624
|
+
internalType: "uint256",
|
|
31625
|
+
name: "amount1",
|
|
31626
|
+
type: "uint256"
|
|
31627
|
+
}
|
|
31628
|
+
],
|
|
31629
|
+
name: "Mint",
|
|
31630
|
+
type: "event"
|
|
31631
|
+
},
|
|
31632
|
+
{
|
|
31633
|
+
anonymous: false,
|
|
31634
|
+
inputs: [
|
|
31635
|
+
{
|
|
31636
|
+
indexed: false,
|
|
31637
|
+
internalType: "uint8",
|
|
31638
|
+
name: "feeProtocol0Old",
|
|
31639
|
+
type: "uint8"
|
|
31640
|
+
},
|
|
31641
|
+
{
|
|
31642
|
+
indexed: false,
|
|
31643
|
+
internalType: "uint8",
|
|
31644
|
+
name: "feeProtocol1Old",
|
|
31645
|
+
type: "uint8"
|
|
31646
|
+
},
|
|
31647
|
+
{
|
|
31648
|
+
indexed: false,
|
|
31649
|
+
internalType: "uint8",
|
|
31650
|
+
name: "feeProtocol0New",
|
|
31651
|
+
type: "uint8"
|
|
31652
|
+
},
|
|
31653
|
+
{
|
|
31654
|
+
indexed: false,
|
|
31655
|
+
internalType: "uint8",
|
|
31656
|
+
name: "feeProtocol1New",
|
|
31657
|
+
type: "uint8"
|
|
31658
|
+
}
|
|
31659
|
+
],
|
|
31660
|
+
name: "SetFeeProtocol",
|
|
31661
|
+
type: "event"
|
|
31662
|
+
},
|
|
31663
|
+
{
|
|
31664
|
+
anonymous: false,
|
|
31665
|
+
inputs: [
|
|
31666
|
+
{
|
|
31667
|
+
indexed: true,
|
|
31668
|
+
internalType: "address",
|
|
31669
|
+
name: "sender",
|
|
31670
|
+
type: "address"
|
|
31671
|
+
},
|
|
31672
|
+
{
|
|
31673
|
+
indexed: true,
|
|
31674
|
+
internalType: "address",
|
|
31675
|
+
name: "recipient",
|
|
31676
|
+
type: "address"
|
|
31677
|
+
},
|
|
31678
|
+
{
|
|
31679
|
+
indexed: false,
|
|
31680
|
+
internalType: "int256",
|
|
31681
|
+
name: "amount0",
|
|
31682
|
+
type: "int256"
|
|
31683
|
+
},
|
|
31684
|
+
{
|
|
31685
|
+
indexed: false,
|
|
31686
|
+
internalType: "int256",
|
|
31687
|
+
name: "amount1",
|
|
31688
|
+
type: "int256"
|
|
31689
|
+
},
|
|
31690
|
+
{
|
|
31691
|
+
indexed: false,
|
|
31692
|
+
internalType: "uint160",
|
|
31693
|
+
name: "sqrtPriceX96",
|
|
31694
|
+
type: "uint160"
|
|
31695
|
+
},
|
|
31696
|
+
{
|
|
31697
|
+
indexed: false,
|
|
31698
|
+
internalType: "uint128",
|
|
31699
|
+
name: "liquidity",
|
|
31700
|
+
type: "uint128"
|
|
31701
|
+
},
|
|
31702
|
+
{
|
|
31703
|
+
indexed: false,
|
|
31704
|
+
internalType: "int24",
|
|
31705
|
+
name: "tick",
|
|
31706
|
+
type: "int24"
|
|
31707
|
+
}
|
|
31708
|
+
],
|
|
31709
|
+
name: "Swap",
|
|
31710
|
+
type: "event"
|
|
31711
|
+
},
|
|
31712
|
+
{
|
|
31713
|
+
inputs: [
|
|
31714
|
+
{
|
|
31715
|
+
internalType: "int24",
|
|
31716
|
+
name: "tickLower",
|
|
31717
|
+
type: "int24"
|
|
31718
|
+
},
|
|
31719
|
+
{
|
|
31720
|
+
internalType: "int24",
|
|
31721
|
+
name: "tickUpper",
|
|
31722
|
+
type: "int24"
|
|
31723
|
+
},
|
|
31724
|
+
{
|
|
31725
|
+
internalType: "uint128",
|
|
31726
|
+
name: "amount",
|
|
31727
|
+
type: "uint128"
|
|
31728
|
+
}
|
|
31729
|
+
],
|
|
31730
|
+
name: "burn",
|
|
31731
|
+
outputs: [{
|
|
31732
|
+
internalType: "uint256",
|
|
31733
|
+
name: "amount0",
|
|
31734
|
+
type: "uint256"
|
|
31735
|
+
}, {
|
|
31736
|
+
internalType: "uint256",
|
|
31737
|
+
name: "amount1",
|
|
31738
|
+
type: "uint256"
|
|
31739
|
+
}],
|
|
31740
|
+
stateMutability: "payable",
|
|
31741
|
+
type: "function"
|
|
31742
|
+
},
|
|
31743
|
+
{
|
|
31744
|
+
inputs: [
|
|
31745
|
+
{
|
|
31746
|
+
internalType: "address",
|
|
31747
|
+
name: "recipient",
|
|
31748
|
+
type: "address"
|
|
31749
|
+
},
|
|
31750
|
+
{
|
|
31751
|
+
internalType: "int24",
|
|
31752
|
+
name: "tickLower",
|
|
31753
|
+
type: "int24"
|
|
31754
|
+
},
|
|
31755
|
+
{
|
|
31756
|
+
internalType: "int24",
|
|
31757
|
+
name: "tickUpper",
|
|
31758
|
+
type: "int24"
|
|
31759
|
+
},
|
|
31760
|
+
{
|
|
31761
|
+
internalType: "uint128",
|
|
31762
|
+
name: "amount0Requested",
|
|
31763
|
+
type: "uint128"
|
|
31764
|
+
},
|
|
31765
|
+
{
|
|
31766
|
+
internalType: "uint128",
|
|
31767
|
+
name: "amount1Requested",
|
|
31768
|
+
type: "uint128"
|
|
31769
|
+
}
|
|
31770
|
+
],
|
|
31771
|
+
name: "collect",
|
|
31772
|
+
outputs: [{
|
|
31773
|
+
internalType: "uint128",
|
|
31774
|
+
name: "amount0",
|
|
31775
|
+
type: "uint128"
|
|
31776
|
+
}, {
|
|
31777
|
+
internalType: "uint128",
|
|
31778
|
+
name: "amount1",
|
|
31779
|
+
type: "uint128"
|
|
31780
|
+
}],
|
|
31781
|
+
stateMutability: "payable",
|
|
31782
|
+
type: "function"
|
|
31783
|
+
},
|
|
31784
|
+
{
|
|
31785
|
+
inputs: [
|
|
31786
|
+
{
|
|
31787
|
+
internalType: "address",
|
|
31788
|
+
name: "recipient",
|
|
31789
|
+
type: "address"
|
|
31790
|
+
},
|
|
31791
|
+
{
|
|
31792
|
+
internalType: "uint128",
|
|
31793
|
+
name: "amount0Requested",
|
|
31794
|
+
type: "uint128"
|
|
31795
|
+
},
|
|
31796
|
+
{
|
|
31797
|
+
internalType: "uint128",
|
|
31798
|
+
name: "amount1Requested",
|
|
31799
|
+
type: "uint128"
|
|
31800
|
+
}
|
|
31801
|
+
],
|
|
31802
|
+
name: "collectProtocol",
|
|
31803
|
+
outputs: [{
|
|
31804
|
+
internalType: "uint128",
|
|
31805
|
+
name: "amount0",
|
|
31806
|
+
type: "uint128"
|
|
31807
|
+
}, {
|
|
31808
|
+
internalType: "uint128",
|
|
31809
|
+
name: "amount1",
|
|
31810
|
+
type: "uint128"
|
|
31811
|
+
}],
|
|
31812
|
+
stateMutability: "payable",
|
|
31813
|
+
type: "function"
|
|
31814
|
+
},
|
|
31815
|
+
{
|
|
31816
|
+
inputs: [],
|
|
31817
|
+
name: "factory",
|
|
31818
|
+
outputs: [{
|
|
31819
|
+
internalType: "address",
|
|
31820
|
+
name: "",
|
|
31821
|
+
type: "address"
|
|
31822
|
+
}],
|
|
31823
|
+
stateMutability: "view",
|
|
31824
|
+
type: "function"
|
|
31825
|
+
},
|
|
31826
|
+
{
|
|
31827
|
+
inputs: [],
|
|
31828
|
+
name: "fee",
|
|
31829
|
+
outputs: [{
|
|
31830
|
+
internalType: "uint24",
|
|
31831
|
+
name: "",
|
|
31832
|
+
type: "uint24"
|
|
31833
|
+
}],
|
|
31834
|
+
stateMutability: "view",
|
|
31835
|
+
type: "function"
|
|
31836
|
+
},
|
|
31837
|
+
{
|
|
31838
|
+
inputs: [],
|
|
31839
|
+
name: "feeGrowthGlobal0X128",
|
|
31840
|
+
outputs: [{
|
|
31841
|
+
internalType: "uint256",
|
|
31842
|
+
name: "",
|
|
31843
|
+
type: "uint256"
|
|
31844
|
+
}],
|
|
31845
|
+
stateMutability: "view",
|
|
31846
|
+
type: "function"
|
|
31847
|
+
},
|
|
31848
|
+
{
|
|
31849
|
+
inputs: [],
|
|
31850
|
+
name: "feeGrowthGlobal1X128",
|
|
31851
|
+
outputs: [{
|
|
31852
|
+
internalType: "uint256",
|
|
31853
|
+
name: "",
|
|
31854
|
+
type: "uint256"
|
|
31855
|
+
}],
|
|
31856
|
+
stateMutability: "view",
|
|
31857
|
+
type: "function"
|
|
31858
|
+
},
|
|
31859
|
+
{
|
|
31860
|
+
inputs: [
|
|
31861
|
+
{
|
|
31862
|
+
internalType: "address",
|
|
31863
|
+
name: "recipient",
|
|
31864
|
+
type: "address"
|
|
31865
|
+
},
|
|
31866
|
+
{
|
|
31867
|
+
internalType: "uint256",
|
|
31868
|
+
name: "amount0",
|
|
31869
|
+
type: "uint256"
|
|
31870
|
+
},
|
|
31871
|
+
{
|
|
31872
|
+
internalType: "uint256",
|
|
31873
|
+
name: "amount1",
|
|
31874
|
+
type: "uint256"
|
|
31875
|
+
},
|
|
31876
|
+
{
|
|
31877
|
+
internalType: "bytes",
|
|
31878
|
+
name: "data",
|
|
31879
|
+
type: "bytes"
|
|
31880
|
+
}
|
|
31881
|
+
],
|
|
31882
|
+
name: "flash",
|
|
31883
|
+
outputs: [],
|
|
31884
|
+
stateMutability: "payable",
|
|
31885
|
+
type: "function"
|
|
31886
|
+
},
|
|
31887
|
+
{
|
|
31888
|
+
inputs: [{
|
|
31889
|
+
internalType: "uint16",
|
|
31890
|
+
name: "observationCardinalityNext",
|
|
31891
|
+
type: "uint16"
|
|
31892
|
+
}],
|
|
31893
|
+
name: "increaseObservationCardinalityNext",
|
|
31894
|
+
outputs: [],
|
|
31895
|
+
stateMutability: "payable",
|
|
31896
|
+
type: "function"
|
|
31897
|
+
},
|
|
31898
|
+
{
|
|
31899
|
+
inputs: [{
|
|
31900
|
+
internalType: "uint160",
|
|
31901
|
+
name: "sqrtPriceX96",
|
|
31902
|
+
type: "uint160"
|
|
31903
|
+
}],
|
|
31904
|
+
name: "initialize",
|
|
31905
|
+
outputs: [],
|
|
31906
|
+
stateMutability: "payable",
|
|
31907
|
+
type: "function"
|
|
31908
|
+
},
|
|
31909
|
+
{
|
|
31910
|
+
inputs: [],
|
|
31911
|
+
name: "liquidity",
|
|
31912
|
+
outputs: [{
|
|
31913
|
+
internalType: "uint128",
|
|
31914
|
+
name: "",
|
|
31915
|
+
type: "uint128"
|
|
31916
|
+
}],
|
|
31917
|
+
stateMutability: "view",
|
|
31918
|
+
type: "function"
|
|
31919
|
+
},
|
|
31920
|
+
{
|
|
31921
|
+
inputs: [],
|
|
31922
|
+
name: "maxLiquidityPerTick",
|
|
31923
|
+
outputs: [{
|
|
31924
|
+
internalType: "uint128",
|
|
31925
|
+
name: "",
|
|
31926
|
+
type: "uint128"
|
|
31927
|
+
}],
|
|
31928
|
+
stateMutability: "view",
|
|
31929
|
+
type: "function"
|
|
31930
|
+
},
|
|
31931
|
+
{
|
|
31932
|
+
inputs: [
|
|
31933
|
+
{
|
|
31934
|
+
internalType: "address",
|
|
31935
|
+
name: "recipient",
|
|
31936
|
+
type: "address"
|
|
31937
|
+
},
|
|
31938
|
+
{
|
|
31939
|
+
internalType: "int24",
|
|
31940
|
+
name: "tickLower",
|
|
31941
|
+
type: "int24"
|
|
31942
|
+
},
|
|
31943
|
+
{
|
|
31944
|
+
internalType: "int24",
|
|
31945
|
+
name: "tickUpper",
|
|
31946
|
+
type: "int24"
|
|
31947
|
+
},
|
|
31948
|
+
{
|
|
31949
|
+
internalType: "uint128",
|
|
31950
|
+
name: "amount",
|
|
31951
|
+
type: "uint128"
|
|
31952
|
+
},
|
|
31953
|
+
{
|
|
31954
|
+
internalType: "bytes",
|
|
31955
|
+
name: "data",
|
|
31956
|
+
type: "bytes"
|
|
31957
|
+
}
|
|
31958
|
+
],
|
|
31959
|
+
name: "mint",
|
|
31960
|
+
outputs: [{
|
|
31961
|
+
internalType: "uint256",
|
|
31962
|
+
name: "amount0",
|
|
31963
|
+
type: "uint256"
|
|
31964
|
+
}, {
|
|
31965
|
+
internalType: "uint256",
|
|
31966
|
+
name: "amount1",
|
|
31967
|
+
type: "uint256"
|
|
31968
|
+
}],
|
|
31969
|
+
stateMutability: "payable",
|
|
31970
|
+
type: "function"
|
|
31971
|
+
},
|
|
31972
|
+
{
|
|
31973
|
+
inputs: [{
|
|
31974
|
+
internalType: "uint256",
|
|
31975
|
+
name: "",
|
|
31976
|
+
type: "uint256"
|
|
31977
|
+
}],
|
|
31978
|
+
name: "observations",
|
|
31979
|
+
outputs: [
|
|
31980
|
+
{
|
|
31981
|
+
internalType: "uint32",
|
|
31982
|
+
name: "blockTimestamp",
|
|
31983
|
+
type: "uint32"
|
|
31984
|
+
},
|
|
31985
|
+
{
|
|
31986
|
+
internalType: "int56",
|
|
31987
|
+
name: "tickCumulative",
|
|
31988
|
+
type: "int56"
|
|
31989
|
+
},
|
|
31990
|
+
{
|
|
31991
|
+
internalType: "uint160",
|
|
31992
|
+
name: "secondsPerLiquidityCumulativeX128",
|
|
31993
|
+
type: "uint160"
|
|
31994
|
+
},
|
|
31995
|
+
{
|
|
31996
|
+
internalType: "bool",
|
|
31997
|
+
name: "initialized",
|
|
31998
|
+
type: "bool"
|
|
31999
|
+
}
|
|
32000
|
+
],
|
|
32001
|
+
stateMutability: "view",
|
|
32002
|
+
type: "function"
|
|
32003
|
+
},
|
|
32004
|
+
{
|
|
32005
|
+
inputs: [{
|
|
32006
|
+
internalType: "uint32[]",
|
|
32007
|
+
name: "secondsAgos",
|
|
32008
|
+
type: "uint32[]"
|
|
32009
|
+
}],
|
|
32010
|
+
name: "observe",
|
|
32011
|
+
outputs: [{
|
|
32012
|
+
internalType: "int56[]",
|
|
32013
|
+
name: "tickCumulatives",
|
|
32014
|
+
type: "int56[]"
|
|
32015
|
+
}, {
|
|
32016
|
+
internalType: "uint160[]",
|
|
32017
|
+
name: "secondsPerLiquidityCumulativeX128s",
|
|
32018
|
+
type: "uint160[]"
|
|
32019
|
+
}],
|
|
32020
|
+
stateMutability: "view",
|
|
32021
|
+
type: "function"
|
|
32022
|
+
},
|
|
32023
|
+
{
|
|
32024
|
+
inputs: [{
|
|
32025
|
+
internalType: "bytes32",
|
|
32026
|
+
name: "",
|
|
32027
|
+
type: "bytes32"
|
|
32028
|
+
}],
|
|
32029
|
+
name: "positions",
|
|
32030
|
+
outputs: [
|
|
32031
|
+
{
|
|
32032
|
+
internalType: "uint128",
|
|
32033
|
+
name: "liquidity",
|
|
32034
|
+
type: "uint128"
|
|
32035
|
+
},
|
|
32036
|
+
{
|
|
32037
|
+
internalType: "uint256",
|
|
32038
|
+
name: "feeGrowthInside0LastX128",
|
|
32039
|
+
type: "uint256"
|
|
32040
|
+
},
|
|
32041
|
+
{
|
|
32042
|
+
internalType: "uint256",
|
|
32043
|
+
name: "feeGrowthInside1LastX128",
|
|
32044
|
+
type: "uint256"
|
|
32045
|
+
},
|
|
32046
|
+
{
|
|
32047
|
+
internalType: "uint128",
|
|
32048
|
+
name: "tokensOwed0",
|
|
32049
|
+
type: "uint128"
|
|
32050
|
+
},
|
|
32051
|
+
{
|
|
32052
|
+
internalType: "uint128",
|
|
32053
|
+
name: "tokensOwed1",
|
|
32054
|
+
type: "uint128"
|
|
32055
|
+
}
|
|
32056
|
+
],
|
|
32057
|
+
stateMutability: "view",
|
|
32058
|
+
type: "function"
|
|
32059
|
+
},
|
|
32060
|
+
{
|
|
32061
|
+
inputs: [],
|
|
32062
|
+
name: "protocolFees",
|
|
32063
|
+
outputs: [{
|
|
32064
|
+
internalType: "uint128",
|
|
32065
|
+
name: "token0",
|
|
32066
|
+
type: "uint128"
|
|
32067
|
+
}, {
|
|
32068
|
+
internalType: "uint128",
|
|
32069
|
+
name: "token1",
|
|
32070
|
+
type: "uint128"
|
|
32071
|
+
}],
|
|
32072
|
+
stateMutability: "view",
|
|
32073
|
+
type: "function"
|
|
32074
|
+
},
|
|
32075
|
+
{
|
|
32076
|
+
inputs: [{
|
|
32077
|
+
internalType: "uint8",
|
|
32078
|
+
name: "feeProtocol0",
|
|
32079
|
+
type: "uint8"
|
|
32080
|
+
}, {
|
|
32081
|
+
internalType: "uint8",
|
|
32082
|
+
name: "feeProtocol1",
|
|
32083
|
+
type: "uint8"
|
|
32084
|
+
}],
|
|
32085
|
+
name: "setFeeProtocol",
|
|
32086
|
+
outputs: [],
|
|
32087
|
+
stateMutability: "payable",
|
|
32088
|
+
type: "function"
|
|
32089
|
+
},
|
|
32090
|
+
{
|
|
32091
|
+
inputs: [],
|
|
32092
|
+
name: "slot0",
|
|
32093
|
+
outputs: [
|
|
32094
|
+
{
|
|
32095
|
+
internalType: "uint160",
|
|
32096
|
+
name: "sqrtPriceX96",
|
|
32097
|
+
type: "uint160"
|
|
32098
|
+
},
|
|
32099
|
+
{
|
|
32100
|
+
internalType: "int24",
|
|
32101
|
+
name: "tick",
|
|
32102
|
+
type: "int24"
|
|
32103
|
+
},
|
|
32104
|
+
{
|
|
32105
|
+
internalType: "uint16",
|
|
32106
|
+
name: "observationIndex",
|
|
32107
|
+
type: "uint16"
|
|
32108
|
+
},
|
|
32109
|
+
{
|
|
32110
|
+
internalType: "uint16",
|
|
32111
|
+
name: "observationCardinality",
|
|
32112
|
+
type: "uint16"
|
|
32113
|
+
},
|
|
32114
|
+
{
|
|
32115
|
+
internalType: "uint16",
|
|
32116
|
+
name: "observationCardinalityNext",
|
|
32117
|
+
type: "uint16"
|
|
32118
|
+
},
|
|
32119
|
+
{
|
|
32120
|
+
internalType: "uint8",
|
|
32121
|
+
name: "feeProtocol",
|
|
32122
|
+
type: "uint8"
|
|
32123
|
+
},
|
|
32124
|
+
{
|
|
32125
|
+
internalType: "bool",
|
|
32126
|
+
name: "unlocked",
|
|
32127
|
+
type: "bool"
|
|
32128
|
+
}
|
|
32129
|
+
],
|
|
32130
|
+
stateMutability: "view",
|
|
32131
|
+
type: "function"
|
|
32132
|
+
},
|
|
32133
|
+
{
|
|
32134
|
+
inputs: [{
|
|
32135
|
+
internalType: "int24",
|
|
32136
|
+
name: "tickLower",
|
|
32137
|
+
type: "int24"
|
|
32138
|
+
}, {
|
|
32139
|
+
internalType: "int24",
|
|
32140
|
+
name: "tickUpper",
|
|
32141
|
+
type: "int24"
|
|
32142
|
+
}],
|
|
32143
|
+
name: "snapshotCumulativesInside",
|
|
32144
|
+
outputs: [
|
|
32145
|
+
{
|
|
32146
|
+
internalType: "int56",
|
|
32147
|
+
name: "tickCumulativeInside",
|
|
32148
|
+
type: "int56"
|
|
32149
|
+
},
|
|
32150
|
+
{
|
|
32151
|
+
internalType: "uint160",
|
|
32152
|
+
name: "secondsPerLiquidityInsideX128",
|
|
32153
|
+
type: "uint160"
|
|
32154
|
+
},
|
|
32155
|
+
{
|
|
32156
|
+
internalType: "uint32",
|
|
32157
|
+
name: "secondsInside",
|
|
32158
|
+
type: "uint32"
|
|
32159
|
+
}
|
|
32160
|
+
],
|
|
32161
|
+
stateMutability: "view",
|
|
32162
|
+
type: "function"
|
|
32163
|
+
},
|
|
32164
|
+
{
|
|
32165
|
+
inputs: [
|
|
32166
|
+
{
|
|
32167
|
+
internalType: "address",
|
|
32168
|
+
name: "recipient",
|
|
32169
|
+
type: "address"
|
|
32170
|
+
},
|
|
32171
|
+
{
|
|
32172
|
+
internalType: "bool",
|
|
32173
|
+
name: "zeroForOne",
|
|
32174
|
+
type: "bool"
|
|
32175
|
+
},
|
|
32176
|
+
{
|
|
32177
|
+
internalType: "int256",
|
|
32178
|
+
name: "amountSpecified",
|
|
32179
|
+
type: "int256"
|
|
32180
|
+
},
|
|
32181
|
+
{
|
|
32182
|
+
internalType: "uint160",
|
|
32183
|
+
name: "sqrtPriceLimitX96",
|
|
32184
|
+
type: "uint160"
|
|
32185
|
+
},
|
|
32186
|
+
{
|
|
32187
|
+
internalType: "bytes",
|
|
32188
|
+
name: "data",
|
|
32189
|
+
type: "bytes"
|
|
32190
|
+
}
|
|
32191
|
+
],
|
|
32192
|
+
name: "swap",
|
|
32193
|
+
outputs: [{
|
|
32194
|
+
internalType: "int256",
|
|
32195
|
+
name: "amount0",
|
|
32196
|
+
type: "int256"
|
|
32197
|
+
}, {
|
|
32198
|
+
internalType: "int256",
|
|
32199
|
+
name: "amount1",
|
|
32200
|
+
type: "int256"
|
|
32201
|
+
}],
|
|
32202
|
+
stateMutability: "payable",
|
|
32203
|
+
type: "function"
|
|
32204
|
+
},
|
|
32205
|
+
{
|
|
32206
|
+
inputs: [{
|
|
32207
|
+
internalType: "int16",
|
|
32208
|
+
name: "",
|
|
32209
|
+
type: "int16"
|
|
32210
|
+
}],
|
|
32211
|
+
name: "tickBitmap",
|
|
32212
|
+
outputs: [{
|
|
32213
|
+
internalType: "uint256",
|
|
32214
|
+
name: "",
|
|
32215
|
+
type: "uint256"
|
|
32216
|
+
}],
|
|
32217
|
+
stateMutability: "view",
|
|
32218
|
+
type: "function"
|
|
32219
|
+
},
|
|
32220
|
+
{
|
|
32221
|
+
inputs: [],
|
|
32222
|
+
name: "tickSpacing",
|
|
32223
|
+
outputs: [{
|
|
32224
|
+
internalType: "int24",
|
|
32225
|
+
name: "",
|
|
32226
|
+
type: "int24"
|
|
32227
|
+
}],
|
|
32228
|
+
stateMutability: "view",
|
|
32229
|
+
type: "function"
|
|
32230
|
+
},
|
|
32231
|
+
{
|
|
32232
|
+
inputs: [{
|
|
32233
|
+
internalType: "int24",
|
|
32234
|
+
name: "",
|
|
32235
|
+
type: "int24"
|
|
32236
|
+
}],
|
|
32237
|
+
name: "ticks",
|
|
32238
|
+
outputs: [
|
|
32239
|
+
{
|
|
32240
|
+
internalType: "uint128",
|
|
32241
|
+
name: "liquidityGross",
|
|
32242
|
+
type: "uint128"
|
|
32243
|
+
},
|
|
32244
|
+
{
|
|
32245
|
+
internalType: "int128",
|
|
32246
|
+
name: "liquidityNet",
|
|
32247
|
+
type: "int128"
|
|
32248
|
+
},
|
|
32249
|
+
{
|
|
32250
|
+
internalType: "uint256",
|
|
32251
|
+
name: "feeGrowthOutside0X128",
|
|
32252
|
+
type: "uint256"
|
|
32253
|
+
},
|
|
32254
|
+
{
|
|
32255
|
+
internalType: "uint256",
|
|
32256
|
+
name: "feeGrowthOutside1X128",
|
|
32257
|
+
type: "uint256"
|
|
32258
|
+
},
|
|
32259
|
+
{
|
|
32260
|
+
internalType: "int56",
|
|
32261
|
+
name: "tickCumulativeOutside",
|
|
32262
|
+
type: "int56"
|
|
32263
|
+
},
|
|
32264
|
+
{
|
|
32265
|
+
internalType: "uint160",
|
|
32266
|
+
name: "secondsPerLiquidityOutsideX128",
|
|
32267
|
+
type: "uint160"
|
|
32268
|
+
},
|
|
32269
|
+
{
|
|
32270
|
+
internalType: "uint32",
|
|
32271
|
+
name: "secondsOutside",
|
|
32272
|
+
type: "uint32"
|
|
32273
|
+
},
|
|
32274
|
+
{
|
|
32275
|
+
internalType: "bool",
|
|
32276
|
+
name: "initialized",
|
|
32277
|
+
type: "bool"
|
|
32278
|
+
}
|
|
32279
|
+
],
|
|
32280
|
+
stateMutability: "view",
|
|
32281
|
+
type: "function"
|
|
32282
|
+
},
|
|
32283
|
+
{
|
|
32284
|
+
inputs: [],
|
|
32285
|
+
name: "token0",
|
|
32286
|
+
outputs: [{
|
|
32287
|
+
internalType: "address",
|
|
32288
|
+
name: "",
|
|
32289
|
+
type: "address"
|
|
32290
|
+
}],
|
|
32291
|
+
stateMutability: "view",
|
|
32292
|
+
type: "function"
|
|
32293
|
+
},
|
|
32294
|
+
{
|
|
32295
|
+
inputs: [],
|
|
32296
|
+
name: "token1",
|
|
32297
|
+
outputs: [{
|
|
32298
|
+
internalType: "address",
|
|
32299
|
+
name: "",
|
|
32300
|
+
type: "address"
|
|
32301
|
+
}],
|
|
32302
|
+
stateMutability: "view",
|
|
32303
|
+
type: "function"
|
|
32304
|
+
}
|
|
32305
|
+
];
|
|
32306
|
+
|
|
32307
|
+
//#endregion
|
|
32308
|
+
//#region src/panoptic/v2/events/poolSwapStream.ts
|
|
32309
|
+
const DEFAULT_POLL_INTERVAL_MS$1 = 3e3;
|
|
32310
|
+
const FAILURE_WINDOW_MS = 3e4;
|
|
32311
|
+
const FAILURES_BEFORE_POLL = 3;
|
|
32312
|
+
const STREAM_RETRY_MIN_MS = 15e3;
|
|
32313
|
+
const STREAM_RETRY_MAX_MS = 3e5;
|
|
32314
|
+
const RESYNC_JITTER_MS = 2e3;
|
|
32315
|
+
const EVENT_SOURCE_CLOSED = 2;
|
|
32316
|
+
function parseRecord(data) {
|
|
32317
|
+
const value = JSON.parse(data);
|
|
32318
|
+
if (typeof value !== "object" || value === null) throw new Error("Malformed stream frame");
|
|
32319
|
+
return value;
|
|
32320
|
+
}
|
|
32321
|
+
function bigintField(record, field) {
|
|
32322
|
+
const value = record[field];
|
|
32323
|
+
if (typeof value !== "string") throw new Error(`Stream frame is missing ${field}`);
|
|
32324
|
+
return BigInt(value);
|
|
32325
|
+
}
|
|
32326
|
+
function numberField(record, field) {
|
|
32327
|
+
const value = record[field];
|
|
32328
|
+
if (typeof value !== "number") throw new Error(`Stream frame is missing ${field}`);
|
|
32329
|
+
return value;
|
|
32330
|
+
}
|
|
32331
|
+
function parseStreamedKey(data) {
|
|
32332
|
+
const record = parseRecord(data);
|
|
32333
|
+
return {
|
|
32334
|
+
blockNumber: bigintField(record, "blockNumber"),
|
|
32335
|
+
logIndex: numberField(record, "logIndex")
|
|
32336
|
+
};
|
|
32337
|
+
}
|
|
32338
|
+
function parseStreamedSwap(data) {
|
|
32339
|
+
const record = parseRecord(data);
|
|
32340
|
+
const transactionHash = record.transactionHash;
|
|
32341
|
+
if (typeof transactionHash !== "string") throw new Error("Stream frame is missing transactionHash");
|
|
32342
|
+
return {
|
|
32343
|
+
...parseStreamedKey(data),
|
|
32344
|
+
timestamp: bigintField(record, "timestamp"),
|
|
32345
|
+
transactionHash,
|
|
32346
|
+
tick: numberField(record, "tick"),
|
|
32347
|
+
amount0: bigintField(record, "amount0"),
|
|
32348
|
+
amount1: bigintField(record, "amount1"),
|
|
32349
|
+
sqrtPriceX96: bigintField(record, "sqrtPriceX96"),
|
|
32350
|
+
liquidity: bigintField(record, "liquidity")
|
|
32351
|
+
};
|
|
32352
|
+
}
|
|
32353
|
+
function parseHead(data) {
|
|
32354
|
+
return bigintField(parseRecord(data ?? ""), "head");
|
|
32355
|
+
}
|
|
32356
|
+
function defaultEventSource() {
|
|
32357
|
+
const EventSourceCtor = globalThis.EventSource;
|
|
32358
|
+
return EventSourceCtor && ((url) => new EventSourceCtor(url));
|
|
32359
|
+
}
|
|
32360
|
+
function toError$1(error) {
|
|
32361
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
32362
|
+
}
|
|
32363
|
+
/**
|
|
32364
|
+
* Stream a pool's swaps from the relay at `streamUrl`.
|
|
32365
|
+
*
|
|
32366
|
+
* Every `ready`/`resync` frame carries the relay's head; swaps from the cursor up
|
|
32367
|
+
* to that head are fetched over HTTP so nothing is lost across reconnects. A
|
|
32368
|
+
* stream that closes, or errors three times in 30 s, is replaced by HTTP polling
|
|
32369
|
+
* and retried with backoff; one that closes before ever opening is not retried.
|
|
32370
|
+
*/
|
|
32371
|
+
function streamPoolSwaps(params) {
|
|
32372
|
+
const { client, pool, fromBlock, pollIntervalMs = DEFAULT_POLL_INTERVAL_MS$1, maxBlockRange = DEFAULT_MAX_BLOCK_RANGE, streamUrl, onSwaps, onError, onRemoved, onTransport, eventSource = defaultEventSource() } = params;
|
|
32373
|
+
let running = true;
|
|
32374
|
+
let cursor = fromBlock === void 0 ? void 0 : fromBlock - 1n;
|
|
32375
|
+
let transport = "off";
|
|
32376
|
+
let failures = [];
|
|
32377
|
+
let source;
|
|
32378
|
+
let poller;
|
|
32379
|
+
let retryTimer;
|
|
32380
|
+
let retryDelayMs = STREAM_RETRY_MIN_MS;
|
|
32381
|
+
let catchUpTimer;
|
|
32382
|
+
let catchUpTarget;
|
|
32383
|
+
let catchingUp = false;
|
|
32384
|
+
let everOpened = false;
|
|
32385
|
+
const setTransport = (next) => {
|
|
32386
|
+
if (next === transport) return;
|
|
32387
|
+
transport = next;
|
|
32388
|
+
onTransport?.(next);
|
|
32389
|
+
};
|
|
32390
|
+
const advance = (block) => {
|
|
32391
|
+
if (block !== void 0 && (cursor === void 0 || block > cursor)) cursor = block;
|
|
32392
|
+
};
|
|
32393
|
+
const report = (error) => {
|
|
32394
|
+
if (running) onError?.(toError$1(error));
|
|
32395
|
+
};
|
|
32396
|
+
const catchUpPending = () => catchingUp || catchUpTarget !== void 0;
|
|
32397
|
+
const runCatchUp = async () => {
|
|
32398
|
+
catchingUp = true;
|
|
32399
|
+
while (running && catchUpTarget !== void 0) {
|
|
32400
|
+
const head = catchUpTarget;
|
|
32401
|
+
catchUpTarget = void 0;
|
|
32402
|
+
if (cursor === void 0) {
|
|
32403
|
+
cursor = head;
|
|
32404
|
+
continue;
|
|
32405
|
+
}
|
|
32406
|
+
try {
|
|
32407
|
+
const { swaps } = await fetchPoolSwaps(client, pool, cursor + 1n, head, maxBlockRange);
|
|
32408
|
+
if (!running) break;
|
|
32409
|
+
const first = swaps[0];
|
|
32410
|
+
const last = swaps[swaps.length - 1];
|
|
32411
|
+
if (first && last) onSwaps(swaps, {
|
|
32412
|
+
fromBlock: first.blockNumber,
|
|
32413
|
+
toBlock: last.blockNumber
|
|
32414
|
+
});
|
|
32415
|
+
advance(head);
|
|
32416
|
+
} catch (error) {
|
|
32417
|
+
report(error);
|
|
32418
|
+
if (catchUpTarget === void 0 || catchUpTarget < head) catchUpTarget = head;
|
|
32419
|
+
catchingUp = false;
|
|
32420
|
+
catchUpTimer = setTimeout(() => void runCatchUp(), pollIntervalMs);
|
|
32421
|
+
return;
|
|
32422
|
+
}
|
|
32423
|
+
}
|
|
32424
|
+
catchingUp = false;
|
|
32425
|
+
};
|
|
32426
|
+
const catchUp = (head, delayMs = 0) => {
|
|
32427
|
+
if (catchUpTarget === void 0 || head > catchUpTarget) catchUpTarget = head;
|
|
32428
|
+
if (catchingUp) return;
|
|
32429
|
+
if (catchUpTimer !== void 0) clearTimeout(catchUpTimer);
|
|
32430
|
+
catchUpTimer = setTimeout(() => {
|
|
32431
|
+
catchUpTimer = void 0;
|
|
32432
|
+
runCatchUp();
|
|
32433
|
+
}, delayMs);
|
|
32434
|
+
};
|
|
32435
|
+
const startPolling = () => {
|
|
32436
|
+
if (poller) return;
|
|
32437
|
+
poller = watchPoolSwaps({
|
|
32438
|
+
client,
|
|
32439
|
+
pool,
|
|
32440
|
+
fromBlock: cursor === void 0 ? void 0 : cursor + 1n,
|
|
32441
|
+
pollIntervalMs,
|
|
32442
|
+
maxBlockRange,
|
|
32443
|
+
onSwaps,
|
|
32444
|
+
onError
|
|
32445
|
+
});
|
|
32446
|
+
setTransport("poll");
|
|
32447
|
+
};
|
|
32448
|
+
const stopPolling = () => {
|
|
32449
|
+
if (!poller) return;
|
|
32450
|
+
advance(poller.lastScannedBlock());
|
|
32451
|
+
poller.stop();
|
|
32452
|
+
poller = void 0;
|
|
32453
|
+
};
|
|
32454
|
+
const closeStream = () => {
|
|
32455
|
+
source?.close();
|
|
32456
|
+
source = void 0;
|
|
32457
|
+
};
|
|
32458
|
+
const scheduleStreamRetry = () => {
|
|
32459
|
+
retryTimer = setTimeout(() => {
|
|
32460
|
+
retryTimer = void 0;
|
|
32461
|
+
if (running) openStream();
|
|
32462
|
+
}, retryDelayMs);
|
|
32463
|
+
retryDelayMs = Math.min(retryDelayMs * 2, STREAM_RETRY_MAX_MS);
|
|
32464
|
+
};
|
|
32465
|
+
const openStream = () => {
|
|
32466
|
+
if (!eventSource) {
|
|
32467
|
+
startPolling();
|
|
32468
|
+
return;
|
|
32469
|
+
}
|
|
32470
|
+
const es = eventSource(streamUrl);
|
|
32471
|
+
source = es;
|
|
32472
|
+
failures = [];
|
|
32473
|
+
let opened = false;
|
|
32474
|
+
const listen = (type, handle) => es.addEventListener(type, (event) => {
|
|
32475
|
+
if (!running || source !== es) return;
|
|
32476
|
+
try {
|
|
32477
|
+
handle(event.data);
|
|
32478
|
+
} catch (error) {
|
|
32479
|
+
report(error);
|
|
32480
|
+
}
|
|
32481
|
+
});
|
|
32482
|
+
listen("open", () => {
|
|
32483
|
+
opened = true;
|
|
32484
|
+
everOpened = true;
|
|
32485
|
+
failures = [];
|
|
32486
|
+
retryDelayMs = STREAM_RETRY_MIN_MS;
|
|
32487
|
+
});
|
|
32488
|
+
listen("ready", (data) => {
|
|
32489
|
+
const head = parseHead(data);
|
|
32490
|
+
stopPolling();
|
|
32491
|
+
setTransport("stream");
|
|
32492
|
+
catchUp(head);
|
|
32493
|
+
});
|
|
32494
|
+
listen("resync", (data) => {
|
|
32495
|
+
catchUp(parseHead(data), Math.random() * RESYNC_JITTER_MS);
|
|
32496
|
+
});
|
|
32497
|
+
listen("swap", (data) => {
|
|
32498
|
+
const swap = parseStreamedSwap(data ?? "");
|
|
32499
|
+
onSwaps([swap], {
|
|
32500
|
+
fromBlock: swap.blockNumber,
|
|
32501
|
+
toBlock: swap.blockNumber
|
|
32502
|
+
});
|
|
32503
|
+
if (!catchUpPending()) advance(swap.blockNumber);
|
|
32504
|
+
});
|
|
32505
|
+
listen("removed", (data) => {
|
|
32506
|
+
onRemoved?.(parseStreamedKey(data ?? ""));
|
|
32507
|
+
});
|
|
32508
|
+
listen("error", () => {
|
|
32509
|
+
const now = Date.now();
|
|
32510
|
+
failures = failures.filter((at) => now - at < FAILURE_WINDOW_MS);
|
|
32511
|
+
failures.push(now);
|
|
32512
|
+
const closed = es.readyState === EVENT_SOURCE_CLOSED;
|
|
32513
|
+
if (!closed && failures.length < FAILURES_BEFORE_POLL) return;
|
|
32514
|
+
closeStream();
|
|
32515
|
+
startPolling();
|
|
32516
|
+
if (closed && !opened && !everOpened) return;
|
|
32517
|
+
scheduleStreamRetry();
|
|
32518
|
+
});
|
|
32519
|
+
};
|
|
32520
|
+
openStream();
|
|
32521
|
+
return {
|
|
32522
|
+
stop() {
|
|
32523
|
+
running = false;
|
|
32524
|
+
closeStream();
|
|
32525
|
+
stopPolling();
|
|
32526
|
+
if (retryTimer !== void 0) clearTimeout(retryTimer);
|
|
32527
|
+
if (catchUpTimer !== void 0) clearTimeout(catchUpTimer);
|
|
32528
|
+
setTransport("off");
|
|
32529
|
+
},
|
|
32530
|
+
lastScannedBlock: () => cursor,
|
|
32531
|
+
transport: () => transport
|
|
32532
|
+
};
|
|
32533
|
+
}
|
|
32534
|
+
|
|
32535
|
+
//#endregion
|
|
32536
|
+
//#region src/panoptic/v2/events/poolSwaps.ts
|
|
32537
|
+
const DEFAULT_POLL_INTERVAL_MS = 3e3;
|
|
32538
|
+
const DEFAULT_MAX_BLOCK_RANGE = 2000n;
|
|
32539
|
+
const SHARED_BUFFER_LIMIT = 4096;
|
|
32540
|
+
/**
|
|
32541
|
+
* Parse a decoded v3 `UniswapV3Pool.Swap` or v4 `PoolManager.Swap` log.
|
|
32542
|
+
*/
|
|
32543
|
+
function parseSwapLog(log, timestamp) {
|
|
32544
|
+
if (log.blockNumber === null || log.logIndex === null || log.transactionHash === null) throw new Error("Cannot parse a pending Swap log");
|
|
32545
|
+
const args = log.args;
|
|
32546
|
+
return {
|
|
32547
|
+
blockNumber: log.blockNumber,
|
|
32548
|
+
logIndex: log.logIndex,
|
|
32549
|
+
timestamp,
|
|
32550
|
+
transactionHash: log.transactionHash,
|
|
32551
|
+
tick: Number(args.tick),
|
|
32552
|
+
amount0: args.amount0,
|
|
32553
|
+
amount1: args.amount1,
|
|
32554
|
+
sqrtPriceX96: args.sqrtPriceX96,
|
|
32555
|
+
liquidity: args.liquidity
|
|
32556
|
+
};
|
|
32557
|
+
}
|
|
32558
|
+
function toError(error) {
|
|
32559
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
32560
|
+
}
|
|
32561
|
+
async function fetchSwapLogs(client, pool, fromBlock, toBlock) {
|
|
32562
|
+
if (pool.version === "v3") return client.getContractEvents({
|
|
32563
|
+
address: pool.poolAddress,
|
|
32564
|
+
abi: UniswapV3PoolAbi,
|
|
32565
|
+
eventName: "Swap",
|
|
32566
|
+
fromBlock,
|
|
32567
|
+
toBlock
|
|
32568
|
+
});
|
|
32569
|
+
return client.getContractEvents({
|
|
32570
|
+
address: pool.poolManager,
|
|
32571
|
+
abi: poolManagerAbi,
|
|
32572
|
+
eventName: "Swap",
|
|
32573
|
+
args: { id: pool.poolId },
|
|
32574
|
+
fromBlock,
|
|
32575
|
+
toBlock
|
|
32576
|
+
});
|
|
32577
|
+
}
|
|
32578
|
+
async function fetchSwaps(client, pool, fromBlock, toBlock) {
|
|
32579
|
+
const logs = await fetchSwapLogs(client, pool, fromBlock, toBlock);
|
|
32580
|
+
if (logs.length === 0) return [];
|
|
32581
|
+
const blockNumbers = [...new Set(logs.flatMap((log) => log.blockNumber === null ? [] : [log.blockNumber]))];
|
|
32582
|
+
const blocks = await Promise.all(blockNumbers.map((blockNumber) => client.getBlock({ blockNumber })));
|
|
32583
|
+
const timestamps = new Map(blocks.map((block, i) => [blockNumbers[i], block.timestamp]));
|
|
32584
|
+
return logs.map((log) => parseSwapLog(log, timestamps.get(log.blockNumber ?? -1n) ?? 0n)).sort((a, b) => a.blockNumber === b.blockNumber ? a.logIndex - b.logIndex : a.blockNumber < b.blockNumber ? -1 : 1);
|
|
32585
|
+
}
|
|
32586
|
+
/**
|
|
32587
|
+
* Fetch a pool's swaps in `[fromBlock, toBlock]` (default: the current head), in
|
|
32588
|
+
* chain order. Returns no swaps when `fromBlock > toBlock`.
|
|
32589
|
+
*/
|
|
32590
|
+
async function fetchPoolSwaps(client, pool, fromBlock, toBlock, maxBlockRange = DEFAULT_MAX_BLOCK_RANGE) {
|
|
32591
|
+
const end = toBlock ?? await client.getBlockNumber();
|
|
32592
|
+
const swaps = [];
|
|
32593
|
+
for (let from = fromBlock; from <= end; from += maxBlockRange) {
|
|
32594
|
+
const to = from + maxBlockRange - 1n < end ? from + maxBlockRange - 1n : end;
|
|
32595
|
+
swaps.push(...await fetchSwaps(client, pool, from, to));
|
|
32596
|
+
}
|
|
32597
|
+
return {
|
|
32598
|
+
swaps,
|
|
32599
|
+
toBlock: end
|
|
32600
|
+
};
|
|
32601
|
+
}
|
|
32602
|
+
/**
|
|
32603
|
+
* Poll a single pool's `Swap` logs with `eth_getLogs`, timestamped by block.
|
|
32604
|
+
*
|
|
32605
|
+
* Works over plain HTTP (no filters or websockets). A chunk that fails is retried on
|
|
32606
|
+
* the next tick; errors never stop the loop.
|
|
32607
|
+
*/
|
|
32608
|
+
function watchPoolSwaps(params) {
|
|
32609
|
+
const { client, pool, fromBlock, pollIntervalMs = DEFAULT_POLL_INTERVAL_MS, maxBlockRange = DEFAULT_MAX_BLOCK_RANGE, onSwaps, onError } = params;
|
|
32610
|
+
let running = true;
|
|
32611
|
+
let lastScanned;
|
|
32612
|
+
let timer;
|
|
32613
|
+
const poll = async () => {
|
|
32614
|
+
try {
|
|
32615
|
+
const head = await client.getBlockNumber();
|
|
32616
|
+
let from = lastScanned !== void 0 ? lastScanned + 1n : fromBlock ?? head;
|
|
32617
|
+
while (running && from <= head) {
|
|
32618
|
+
const to = from + maxBlockRange - 1n < head ? from + maxBlockRange - 1n : head;
|
|
32619
|
+
const swaps = await fetchSwaps(client, pool, from, to);
|
|
32620
|
+
if (!running) return;
|
|
32621
|
+
if (swaps.length > 0) onSwaps(swaps, {
|
|
32622
|
+
fromBlock: from,
|
|
32623
|
+
toBlock: to
|
|
32624
|
+
});
|
|
32625
|
+
lastScanned = to;
|
|
32626
|
+
from = to + 1n;
|
|
32627
|
+
}
|
|
32628
|
+
} catch (error) {
|
|
32629
|
+
if (running) onError?.(toError(error));
|
|
32630
|
+
}
|
|
32631
|
+
if (running) timer = setTimeout(() => void poll(), pollIntervalMs);
|
|
32632
|
+
};
|
|
32633
|
+
poll();
|
|
32634
|
+
return {
|
|
32635
|
+
stop() {
|
|
32636
|
+
running = false;
|
|
32637
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
32638
|
+
},
|
|
32639
|
+
lastScannedBlock: () => lastScanned
|
|
32640
|
+
};
|
|
32641
|
+
}
|
|
32642
|
+
const sharedWatchers = new Map();
|
|
32643
|
+
function swapKey(key) {
|
|
32644
|
+
return `${key.blockNumber}:${key.logIndex}`;
|
|
32645
|
+
}
|
|
32646
|
+
/**
|
|
32647
|
+
* Ref-counted pool swap feed: subscribers with the same `key` share one watcher
|
|
32648
|
+
* (relay stream when `streamUrl` is set, else HTTP polling), duplicates are
|
|
32649
|
+
* dropped, late subscribers first receive the swaps already seen, and the watcher
|
|
32650
|
+
* stops when the last subscriber unsubscribes.
|
|
32651
|
+
*/
|
|
32652
|
+
function subscribePoolSwaps(params) {
|
|
32653
|
+
const { key, streamUrl, onSwaps, onError, onRemoved, onTransport,...watchParams } = params;
|
|
32654
|
+
const listener = {
|
|
32655
|
+
onSwaps,
|
|
32656
|
+
onError,
|
|
32657
|
+
onRemoved,
|
|
32658
|
+
onTransport
|
|
32659
|
+
};
|
|
32660
|
+
const existing = sharedWatchers.get(key);
|
|
32661
|
+
if (existing) {
|
|
32662
|
+
existing.listeners.add(listener);
|
|
32663
|
+
const buffered = [...existing.buffer.values()];
|
|
32664
|
+
const first = buffered[0];
|
|
32665
|
+
const last = buffered[buffered.length - 1];
|
|
32666
|
+
if (first && last) onSwaps(buffered, {
|
|
32667
|
+
fromBlock: first.blockNumber,
|
|
32668
|
+
toBlock: last.blockNumber
|
|
32669
|
+
});
|
|
32670
|
+
onTransport?.(existing.transport);
|
|
32671
|
+
} else {
|
|
32672
|
+
const listeners = new Set([listener]);
|
|
32673
|
+
const buffer = new Map();
|
|
32674
|
+
const entry = {
|
|
32675
|
+
watcher: {
|
|
32676
|
+
stop: () => void 0,
|
|
32677
|
+
lastScannedBlock: () => void 0
|
|
32678
|
+
},
|
|
32679
|
+
listeners,
|
|
32680
|
+
buffer,
|
|
32681
|
+
transport: "off"
|
|
32682
|
+
};
|
|
32683
|
+
const setTransport = (transport) => {
|
|
32684
|
+
entry.transport = transport;
|
|
32685
|
+
for (const l of listeners) l.onTransport?.(transport);
|
|
32686
|
+
};
|
|
32687
|
+
const callbacks = {
|
|
32688
|
+
onSwaps: (swaps, range) => {
|
|
32689
|
+
const fresh = swaps.filter((swap) => !buffer.has(swapKey(swap)));
|
|
32690
|
+
if (fresh.length === 0) return;
|
|
32691
|
+
for (const swap of fresh) buffer.set(swapKey(swap), swap);
|
|
32692
|
+
for (const k of buffer.keys()) {
|
|
32693
|
+
if (buffer.size <= SHARED_BUFFER_LIMIT) break;
|
|
32694
|
+
buffer.delete(k);
|
|
32695
|
+
}
|
|
32696
|
+
for (const l of listeners) l.onSwaps(fresh, range);
|
|
32697
|
+
},
|
|
32698
|
+
onError: (error) => {
|
|
32699
|
+
for (const l of listeners) l.onError?.(error);
|
|
32700
|
+
}
|
|
32701
|
+
};
|
|
32702
|
+
sharedWatchers.set(key, entry);
|
|
32703
|
+
if (streamUrl !== void 0) entry.watcher = streamPoolSwaps({
|
|
32704
|
+
...watchParams,
|
|
32705
|
+
...callbacks,
|
|
32706
|
+
streamUrl,
|
|
32707
|
+
onRemoved: (removed) => {
|
|
32708
|
+
buffer.delete(swapKey(removed));
|
|
32709
|
+
for (const l of listeners) l.onRemoved?.(removed);
|
|
32710
|
+
},
|
|
32711
|
+
onTransport: setTransport
|
|
32712
|
+
});
|
|
32713
|
+
else {
|
|
32714
|
+
entry.watcher = watchPoolSwaps({
|
|
32715
|
+
...watchParams,
|
|
32716
|
+
...callbacks
|
|
32717
|
+
});
|
|
32718
|
+
setTransport("poll");
|
|
32719
|
+
}
|
|
32720
|
+
}
|
|
32721
|
+
return () => {
|
|
32722
|
+
const entry = sharedWatchers.get(key);
|
|
32723
|
+
if (!entry) return;
|
|
32724
|
+
entry.listeners.delete(listener);
|
|
32725
|
+
if (entry.listeners.size === 0) {
|
|
32726
|
+
entry.watcher.stop();
|
|
32727
|
+
sharedWatchers.delete(key);
|
|
32728
|
+
}
|
|
32729
|
+
};
|
|
32730
|
+
}
|
|
32731
|
+
|
|
32732
|
+
//#endregion
|
|
32733
|
+
//#region src/panoptic/v2/strike/ladder.ts
|
|
32734
|
+
/** Target number of rungs across a leg's full range (lower tick → upper tick). */
|
|
32735
|
+
const STRIKE_LADDER_TARGET_STRIKES = 16n;
|
|
32736
|
+
/** Nice increment mantissas, in tenths (1, 2.5, 5) × 10ⁿ. */
|
|
32737
|
+
const NICE_MANTISSAS_TENTHS = [
|
|
32738
|
+
10n,
|
|
32739
|
+
25n,
|
|
32740
|
+
50n
|
|
32741
|
+
];
|
|
32742
|
+
/** Upper bound on rung hops when searching for a tick-changing step. */
|
|
32743
|
+
const MAX_STEP_ITERATIONS = 512;
|
|
32744
|
+
/** Decimal precision used when rendering exact tick prices as strings. */
|
|
32745
|
+
const PRICE_PRECISION = 30n;
|
|
32746
|
+
function floorDiv(a, b) {
|
|
32747
|
+
const q = a / b;
|
|
32748
|
+
return a % b !== 0n && a < 0n !== b < 0n ? q - 1n : q;
|
|
32749
|
+
}
|
|
32750
|
+
function floorMod(a, b) {
|
|
32751
|
+
return a - floorDiv(a, b) * b;
|
|
32752
|
+
}
|
|
32753
|
+
function ceilDiv(a, b) {
|
|
32754
|
+
return -floorDiv(-a, b);
|
|
32755
|
+
}
|
|
32756
|
+
/** round(a / b) to nearest, ties up. */
|
|
32757
|
+
function roundDiv(a, b) {
|
|
32758
|
+
return floorDiv(2n * a + b, 2n * b);
|
|
32759
|
+
}
|
|
32760
|
+
function pow10(exp) {
|
|
32761
|
+
let result = 1n;
|
|
32762
|
+
for (let i = 0n; i < exp; i++) result *= 10n;
|
|
32763
|
+
return result;
|
|
32764
|
+
}
|
|
32765
|
+
function gcd(a, b) {
|
|
32766
|
+
a = a < 0n ? -a : a;
|
|
32767
|
+
b = b < 0n ? -b : b;
|
|
32768
|
+
while (b !== 0n) [a, b] = [b, a % b];
|
|
32769
|
+
return a;
|
|
32770
|
+
}
|
|
32771
|
+
function reduce(f) {
|
|
32772
|
+
const g = gcd(f.numerator, f.denominator);
|
|
32773
|
+
return g <= 1n ? f : {
|
|
32774
|
+
numerator: f.numerator / g,
|
|
32775
|
+
denominator: f.denominator / g
|
|
32776
|
+
};
|
|
32777
|
+
}
|
|
32778
|
+
function fromBigint(n) {
|
|
32779
|
+
return {
|
|
32780
|
+
numerator: n,
|
|
32781
|
+
denominator: 1n
|
|
32782
|
+
};
|
|
32783
|
+
}
|
|
32784
|
+
function mul(a, b) {
|
|
32785
|
+
return reduce({
|
|
32786
|
+
numerator: a.numerator * b.numerator,
|
|
32787
|
+
denominator: a.denominator * b.denominator
|
|
32788
|
+
});
|
|
32789
|
+
}
|
|
32790
|
+
function add(a, b) {
|
|
32791
|
+
return reduce({
|
|
32792
|
+
numerator: a.numerator * b.denominator + b.numerator * a.denominator,
|
|
32793
|
+
denominator: a.denominator * b.denominator
|
|
32794
|
+
});
|
|
32795
|
+
}
|
|
32796
|
+
function sub(a, b) {
|
|
32797
|
+
return add(a, {
|
|
32798
|
+
numerator: -b.numerator,
|
|
32799
|
+
denominator: b.denominator
|
|
32800
|
+
});
|
|
32801
|
+
}
|
|
32802
|
+
/** -1 | 0 | 1 comparing a to b. */
|
|
32803
|
+
function cmp(a, b) {
|
|
32804
|
+
const l = a.numerator * b.denominator;
|
|
32805
|
+
const r = b.numerator * a.denominator;
|
|
32806
|
+
return l === r ? 0 : l < r ? -1 : 1;
|
|
32807
|
+
}
|
|
32808
|
+
const LADDER_MIN = fromBigint(1n);
|
|
32809
|
+
/** Largest normalised price on the ladder. Prices above are "outside". */
|
|
32810
|
+
const LADDER_MAX = fromBigint(1000000n);
|
|
32811
|
+
function parseDecimal(value) {
|
|
32812
|
+
const trimmed = value.trim();
|
|
32813
|
+
const [basePart, exponentPart] = trimmed.toLowerCase().split("e");
|
|
32814
|
+
const [integerStr, fractionalStr = ""] = basePart.split(".");
|
|
32815
|
+
let numerator = BigInt(`${integerStr === "" ? "0" : integerStr}${fractionalStr}`);
|
|
32816
|
+
let denominator = pow10(BigInt(fractionalStr.length));
|
|
32817
|
+
if (exponentPart !== void 0 && exponentPart !== "") {
|
|
32818
|
+
const exponent = BigInt(exponentPart);
|
|
32819
|
+
if (exponent > 0n) numerator *= pow10(exponent);
|
|
32820
|
+
else if (exponent < 0n) denominator *= pow10(-exponent);
|
|
32821
|
+
}
|
|
32822
|
+
if (numerator <= 0n) throw new Error("Price must be positive");
|
|
32823
|
+
return reduce({
|
|
32824
|
+
numerator,
|
|
32825
|
+
denominator
|
|
32826
|
+
});
|
|
32827
|
+
}
|
|
32828
|
+
/** Render a positive fraction as a decimal string with trailing zeros trimmed. */
|
|
32829
|
+
function fractionToDecimal(f, precision) {
|
|
32830
|
+
const scaled = f.numerator * pow10(precision) / f.denominator;
|
|
32831
|
+
const digits = scaled.toString().padStart(Number(precision) + 1, "0");
|
|
32832
|
+
const intPart = digits.slice(0, digits.length - Number(precision));
|
|
32833
|
+
const fracPart = digits.slice(digits.length - Number(precision)).replace(/0+$/, "");
|
|
32834
|
+
return fracPart.length === 0 ? intPart : `${intPart}.${fracPart}`;
|
|
32835
|
+
}
|
|
32836
|
+
/** 10^k as an exact fraction, k may be negative. */
|
|
32837
|
+
function powerOfTen(k) {
|
|
32838
|
+
return k >= 0n ? fromBigint(pow10(k)) : {
|
|
32839
|
+
numerator: 1n,
|
|
32840
|
+
denominator: pow10(-k)
|
|
32841
|
+
};
|
|
32842
|
+
}
|
|
32843
|
+
/** floor(log10(f)) for a positive fraction. */
|
|
32844
|
+
function floorLog10(f) {
|
|
32845
|
+
let e = BigInt(f.numerator.toString().length - f.denominator.toString().length);
|
|
32846
|
+
while (cmp(f, powerOfTen(e)) < 0) e -= 1n;
|
|
32847
|
+
while (cmp(f, powerOfTen(e + 1n)) >= 0) e += 1n;
|
|
32848
|
+
return e;
|
|
32849
|
+
}
|
|
32850
|
+
function orientTick(tick, orient) {
|
|
32851
|
+
return orient.asset === 0n ? tick : -tick;
|
|
32852
|
+
}
|
|
32853
|
+
/** Exact-enough price of `tick` in the caller's orientation. */
|
|
32854
|
+
function tickToOrientedPrice(tick, orient) {
|
|
32855
|
+
const price = tickToPriceDecimalScaled(orientTick(tick, orient), orient.assetDecimals, orient.quoteDecimals, PRICE_PRECISION);
|
|
32856
|
+
return parseDecimal(price);
|
|
32857
|
+
}
|
|
32858
|
+
/** Nearest integer tick for a caller-oriented decimal price. */
|
|
32859
|
+
function orientedPriceToTick(price, orient) {
|
|
32860
|
+
const t = priceToTick(price, orient.assetDecimals, orient.quoteDecimals);
|
|
32861
|
+
return orientTick(t, orient);
|
|
32862
|
+
}
|
|
32863
|
+
/**
|
|
32864
|
+
* Relative rung step for a leg: `1.0001^(round(width·tickSpacing / TARGET)) − 1`.
|
|
32865
|
+
* Rungs scale with price (they are multiples of a price-proportional increment), so
|
|
32866
|
+
* spacing them by the range's TARGET-th root yields ≈TARGET rungs across the range
|
|
32867
|
+
* regardless of how wide it is.
|
|
32868
|
+
*/
|
|
32869
|
+
function relativeStep(width, tickSpacing) {
|
|
32870
|
+
validateGeometry(width, tickSpacing);
|
|
32871
|
+
const ticks = roundDiv(width * tickSpacing, STRIKE_LADDER_TARGET_STRIKES);
|
|
32872
|
+
const ratio = parseDecimal(tickToPriceDecimalScaled(ticks < 1n ? 1n : ticks, 0n, 0n, PRICE_PRECISION));
|
|
32873
|
+
return sub(ratio, fromBigint(1n));
|
|
32874
|
+
}
|
|
32875
|
+
/** Nice increment `m × 10ⁿ` (m ∈ {1, 2.5, 5}) with the smallest log-distance to `raw`. */
|
|
32876
|
+
function niceIncrement(raw) {
|
|
32877
|
+
const e = floorLog10(raw);
|
|
32878
|
+
const scale = (tenths) => mul(fromBigint(tenths), powerOfTen(e - 1n));
|
|
32879
|
+
const candidates = [...NICE_MANTISSAS_TENTHS.map(scale), scale(100n)];
|
|
32880
|
+
let lo = candidates[0] ?? powerOfTen(e);
|
|
32881
|
+
for (const hi of candidates.slice(1)) {
|
|
32882
|
+
if (cmp(raw, hi) < 0) return cmp(mul(raw, raw), mul(lo, hi)) <= 0 ? lo : hi;
|
|
32883
|
+
lo = hi;
|
|
32884
|
+
}
|
|
32885
|
+
return lo;
|
|
32886
|
+
}
|
|
32887
|
+
/** Rung increment at normalised price `p` for the given relative step. */
|
|
32888
|
+
function incrementAt(p, rf) {
|
|
32889
|
+
return niceIncrement(mul(p, rf));
|
|
32890
|
+
}
|
|
32891
|
+
/** Normalise a price to `max(p, 1/p)` and remember whether it was inverted. */
|
|
32892
|
+
function normalise(price) {
|
|
32893
|
+
if (price.numerator >= price.denominator) return {
|
|
32894
|
+
value: price,
|
|
32895
|
+
reciprocal: false
|
|
32896
|
+
};
|
|
32897
|
+
return {
|
|
32898
|
+
value: {
|
|
32899
|
+
numerator: price.denominator,
|
|
32900
|
+
denominator: price.numerator
|
|
32901
|
+
},
|
|
32902
|
+
reciprocal: true
|
|
32903
|
+
};
|
|
32904
|
+
}
|
|
32905
|
+
/** Is `r` a multiple of `inc`? */
|
|
32906
|
+
function isMultiple(r, inc) {
|
|
32907
|
+
return r.numerator * inc.denominator % (r.denominator * inc.numerator) === 0n;
|
|
32908
|
+
}
|
|
32909
|
+
/** Smallest multiple of `inc` strictly greater than `x`. */
|
|
32910
|
+
function ceilMultipleStrict(x, inc) {
|
|
32911
|
+
const k = floorDiv(x.numerator * inc.denominator, x.denominator * inc.numerator) + 1n;
|
|
32912
|
+
return mul(fromBigint(k), inc);
|
|
32913
|
+
}
|
|
32914
|
+
/** Largest multiple of `inc` strictly smaller than `x`. */
|
|
32915
|
+
function floorMultipleStrict(x, inc) {
|
|
32916
|
+
const k = ceilDiv(x.numerator * inc.denominator, x.denominator * inc.numerator) - 1n;
|
|
32917
|
+
return mul(fromBigint(k), inc);
|
|
32918
|
+
}
|
|
32919
|
+
/**
|
|
32920
|
+
* The rung set is `{ r : r is a multiple of incrementAt(r) }`. Because the
|
|
32921
|
+
* increment grows with price, a multiple of a finer increment can land inside a
|
|
32922
|
+
* coarser band where it is no longer a rung; these helpers push such a candidate
|
|
32923
|
+
* up/down until it is a multiple of its own band's increment.
|
|
32924
|
+
*/
|
|
32925
|
+
function isRung(r, rf) {
|
|
32926
|
+
return r.numerator > 0n && isMultiple(r, incrementAt(r, rf));
|
|
32927
|
+
}
|
|
32928
|
+
function fixUp(c, rf) {
|
|
32929
|
+
for (let i = 0; i < 64 && !isRung(c, rf); i++) c = ceilMultipleStrict(c, incrementAt(c, rf));
|
|
32930
|
+
return c;
|
|
32931
|
+
}
|
|
32932
|
+
function fixDown(c, rf) {
|
|
32933
|
+
for (let i = 0; i < 64 && c.numerator > 0n && !isRung(c, rf); i++) c = floorMultipleStrict(c, incrementAt(c, rf));
|
|
32934
|
+
return c;
|
|
32935
|
+
}
|
|
32936
|
+
/** Smallest rung strictly above `x` (may exceed the ladder top). */
|
|
32937
|
+
function nextRungAbove(x, rf) {
|
|
32938
|
+
const incHere = incrementAt(x, rf);
|
|
32939
|
+
const incs = [incHere, incrementAt(add(x, incHere), rf)];
|
|
32940
|
+
let best = null;
|
|
32941
|
+
for (const inc of incs) {
|
|
32942
|
+
const c = fixUp(ceilMultipleStrict(x, inc), rf);
|
|
32943
|
+
if (cmp(c, x) > 0 && (best === null || cmp(c, best) < 0)) best = c;
|
|
32944
|
+
}
|
|
32945
|
+
if (best === null) throw new PanopticValidationError("No ladder rung above price");
|
|
32946
|
+
return best;
|
|
32947
|
+
}
|
|
32948
|
+
/** Largest rung strictly below `x` (may fall below the ladder floor). */
|
|
32949
|
+
function prevRungBelow(x, rf) {
|
|
32950
|
+
const incHere = incrementAt(x, rf);
|
|
32951
|
+
const finer = incrementAt(sub(x, incHere), rf);
|
|
32952
|
+
let best = null;
|
|
32953
|
+
for (const inc of [incHere, finer]) {
|
|
32954
|
+
const c = fixDown(floorMultipleStrict(x, inc), rf);
|
|
32955
|
+
if (c.numerator > 0n && cmp(c, x) < 0 && (best === null || cmp(c, best) > 0)) best = c;
|
|
32956
|
+
}
|
|
32957
|
+
return best ?? fromBigint(0n);
|
|
32958
|
+
}
|
|
32959
|
+
/** Nearest rung price to a normalised price, or null when above the ladder. */
|
|
32960
|
+
function nearestRungPrice(normalised, rf) {
|
|
32961
|
+
let rung;
|
|
32962
|
+
if (isRung(normalised, rf)) rung = normalised;
|
|
32963
|
+
else {
|
|
32964
|
+
const up = nextRungAbove(normalised, rf);
|
|
32965
|
+
const down = prevRungBelow(normalised, rf);
|
|
32966
|
+
if (down.numerator <= 0n) rung = up;
|
|
32967
|
+
else rung = cmp(sub(normalised, down), sub(up, normalised)) <= 0 ? down : up;
|
|
32968
|
+
}
|
|
32969
|
+
if (cmp(rung, LADDER_MIN) < 0) rung = LADDER_MIN;
|
|
32970
|
+
if (cmp(rung, LADDER_MAX) > 0) return null;
|
|
32971
|
+
return rung;
|
|
32972
|
+
}
|
|
32973
|
+
/** Step one rung up (+1) or down (-1) on the normalised ladder. Null when leaving it. */
|
|
32974
|
+
function stepRungPrice(rung, direction, rf) {
|
|
32975
|
+
const next = direction > 0n ? nextRungAbove(rung, rf) : prevRungBelow(rung, rf);
|
|
32976
|
+
if (cmp(next, LADDER_MIN) < 0 || cmp(next, LADDER_MAX) > 0) return null;
|
|
32977
|
+
return next;
|
|
32978
|
+
}
|
|
32979
|
+
/** Nominal caller-oriented price of a rung as an exact fraction. */
|
|
32980
|
+
function rungToPrice(rung) {
|
|
32981
|
+
return rung.reciprocal ? {
|
|
32982
|
+
numerator: rung.price.denominator,
|
|
32983
|
+
denominator: rung.price.numerator
|
|
32984
|
+
} : rung.price;
|
|
32985
|
+
}
|
|
32986
|
+
function rungToPriceString(rung) {
|
|
32987
|
+
return fractionToDecimal(rungToPrice(rung), PRICE_PRECISION);
|
|
32988
|
+
}
|
|
32989
|
+
function nearestRung(price, rf) {
|
|
32990
|
+
const { value, reciprocal } = normalise(price);
|
|
32991
|
+
const p = nearestRungPrice(value, rf);
|
|
32992
|
+
return p === null ? null : {
|
|
32993
|
+
price: p,
|
|
32994
|
+
reciprocal
|
|
32995
|
+
};
|
|
32996
|
+
}
|
|
32997
|
+
/**
|
|
32998
|
+
* Step a rung in the caller's price direction. For reciprocal quotes a higher
|
|
30902
32999
|
* caller price is a lower normalised price, so the direction flips.
|
|
30903
33000
|
*/
|
|
30904
33001
|
function stepRung(rung, direction, rf) {
|
|
@@ -32055,14 +34152,7 @@ function preparePositionGamma({ tokenId, positionSize, quoteIsToken0, quoteDecim
|
|
|
32055
34152
|
const decoded = decodeTokenId(tokenId);
|
|
32056
34153
|
const chunks = decoded.legs.flatMap((leg) => {
|
|
32057
34154
|
if (leg.width === 0n) return [];
|
|
32058
|
-
const
|
|
32059
|
-
const lowerTick = leg.strike - width / 2n;
|
|
32060
|
-
const upperTick = leg.strike + (width + 1n) / 2n;
|
|
32061
|
-
if (lowerTick < -887272n || upperTick > 887272n || lowerTick >= upperTick) throw new RangeError("Invalid position range");
|
|
32062
|
-
const lower = tickToSqrtPriceX96(lowerTick);
|
|
32063
|
-
const upper = tickToSqrtPriceX96(upperTick);
|
|
32064
|
-
const amount = positionSize * leg.optionRatio;
|
|
32065
|
-
const liquidity = leg.asset === 0n ? amount * (lower * upper / Q96) / (upper - lower) : amount * Q96 / (upper - lower);
|
|
34155
|
+
const { lowerTick, upperTick, liquidity } = getLegLiquidityRange(leg, positionSize, decoded.tickSpacing);
|
|
32066
34156
|
if (liquidity >= 1n << 128n) throw new RangeError("Liquidity exceeds uint128");
|
|
32067
34157
|
return [{
|
|
32068
34158
|
lowerTick: Number(lowerTick),
|
|
@@ -32116,7 +34206,7 @@ function calculatePositionVolatilityMetrics({ observations, netPremium, baseFees
|
|
|
32116
34206
|
for (const point of points) if (!point.price.isFinite() || point.price.lte(0) || !point.gamma.isFinite() || point.rangeGammas.some((gamma) => !gamma.isFinite())) throw new RangeError("Invalid price or gamma observation");
|
|
32117
34207
|
const quantum = new Precision(10).pow(-quoteDecimals);
|
|
32118
34208
|
const gammas = points.flatMap((point) => [point.gamma, ...point.rangeGammas]);
|
|
32119
|
-
const peak = gammas.reduce((max, gamma) => Precision.max(max, gamma.abs()), new Precision(0));
|
|
34209
|
+
const peak = gammas.reduce((max$1, gamma) => Precision.max(max$1, gamma.abs()), new Precision(0));
|
|
32120
34210
|
const tolerance = Precision.max(quantum, peak.mul("1e-12"));
|
|
32121
34211
|
const positive = gammas.some((gamma) => gamma.gt(tolerance));
|
|
32122
34212
|
const negative = gammas.some((gamma) => gamma.lt(tolerance.neg()));
|
|
@@ -32587,5 +34677,5 @@ async function getPositionVolatilityHistory({ client, poolAddress, account, toke
|
|
|
32587
34677
|
}
|
|
32588
34678
|
|
|
32589
34679
|
//#endregion
|
|
32590
|
-
export { AccountInsolventError, AlreadyInitializedError, BORROW_INDEX_BITS, BPS_DENOMINATOR, BPS_SCALE, BatchValidationError, BelowMinimumRedemptionError, CastingError, ChunkHasZeroLiquidityError, ChunkLimitError, CrossPoolError, DEFAULT_MAX_SPREAD, DEFAULT_MINT_BUFFER, DEFAULT_MIN_SWAP_RATIO_BPS, DEFAULT_RECONNECT_CONFIG, DEFAULT_VEGOID, DepositTooLargeError, DuplicateTokenIdError, EffectiveLiquidityAboveThresholdError, ExceedsMaximumRedemptionError, InputListFailError, InsufficientCreditLiquidityError, InvalidBuilderCodeError, InvalidHistoryRangeError, InvalidTickBoundError, InvalidTickError, InvalidTokenIdParameterError, InvalidUniswapCallbackError, LEG_BITS, LEG_LIMITS, LEG_MASKS, LengthMismatchError, LiquidityTooHighError, LoanSlotExhaustedError, MARKET_EPOCH_BITS, MARKET_EPOCH_SHIFT, MARKET_INDICATOR_PERIODS, MAX_TICK, MAX_TRACKED_CHUNKS, MINT_BUFFER, MINT_BUFFER_DENOMINATOR, MIN_TICK, MaxRetriesExceededError, MissingPositionIdsError, NO_LOWER_LIQUIDATION_TICK, NO_UPPER_LIQUIDATION_TICK, NetLiquidityZeroError, NetworkMismatchError, NoLegsExercisableError, NotALongLegError, NotBuilderError, NotEnoughLiquidityInChunkError, NotEnoughTokensError, NotGuardianError, NotMarginCalledError, NotPanopticPoolError, ORACLE_EPOCH_SECONDS, OracleRateLimitedError, PanopticError, PanopticHelperNotDeployedError, PanopticValidationError, PoolNotInitializedError, PositionCountNotZeroError, PositionNotOwnedError, PositionSnapshotNotFoundError, PositionTooLargeError, PriceBoundFailError, PriceImpactTooLargeError, ProviderLagError, RATE_AT_TARGET_BITS, REORG_DEPTH, REQUIRED_BASE_ERROR_SENTINEL, ReentrancyError, RpcError, RpcResponseError, SCHEMA_VERSION, SECONDS_PER_YEAR, STANDARD_TICK_WIDTHS, STORAGE_PREFIX, STRIKE_LADDER_TARGET_STRIKES, SafeModeError, StaleDataError, StaleOracleError, SwapTokenMismatchError, SyncTimeoutError, TOKEN_ID_BITS, TokenIdHasZeroLegsError, TooManyLegsOpenError, TransferFailedError, UNREALIZED_INTEREST_BITS, UTILIZATION_DENOMINATOR, UnauthorizedUniswapCallbackError, UnderOverFlowError, UnhealthyPoolError, UnsafePremiumSettlementError, VARIANCE_RATIO_LAG, WAD, WrongPoolIdError, WrongUniswapPoolError, ZERO_COLLATERAL, ZERO_VALUATION, ZeroAddressError, ZeroCollateralRequirementError, addLegToTokenId, addPendingPosition, addTrackedChunks, annualizePerSecondRateWad, applyMintBuffer, applyMintBufferPerToken, apportion, approve, approveAndWait, approvePool, assertCanBurn, assertCanForceExercise, assertCanLiquidate, assertCanMint, assertFresh, assertHealthy, assertLpPositionFunded, assertTradeable, borrow, borrowAndWait, buildBatchDispatchArgs, buildCreditSwapCall, buildCreditWrappedDispatch, buildOpenPositionCalldata, buildProtectedSettleDispatch, buildProtectedSettlePlan, buildSettleSequenceCalls, buildSfpmSwapCalldata, buildSfpmSwapPlan, buildTemporaryLoanRecoveryDispatch, buildTokenShortfallRecoveryDispatch, buildUniqueCredit, buildUniqueLoan, buildUniqueWidthZeroLeg, calculateAccountGreeksPure, calculateMarketIndicator, calculatePortfolioDelta, calculatePortfolioGamma, calculatePortfolioGreeks, calculatePortfolioValue, calculatePositionDelta, calculatePositionDeltaDebtOnly, calculatePositionDeltaWithSwap, calculatePositionGamma, calculatePositionGreeks, calculatePositionValue, calculatePositionValues, calculatePositionVolatilityMetrics, calculateResyncBlock, calculateSpreadWad, calculateVarianceProfile, cancelTransaction, checkApproval, checkCollateralAcrossTicks, classifyStrategyGroups, classifyStrike, cleanupStalePendingPositions, clearCheckpoint, clearPendingPositions, clearTrackedChunks, clearTrackedPositions, clearTradeHistory, closePosition, closePositionAndWait, collateralCurveTicks, collateralRuleKindFor, collateralTrackerV2Abi, computeV4PoolId, confirmPendingPosition, convertToAssets, convertToShares, countLegs, createEventPoller, createEventSubscription, createFileStorage, createFlowNeutralTokenId, createMemoryStorage, createNonceManager, createPoolFormatters, createTokenIdBuilder, decodeAllDispatchCalldata, decodeAllLegs, decodeDispatchCalldata, decodeLeftRightSigned, decodeLeftRightUnsigned, decodeLeg, decodeOraclePack, decodeOracleRiskParameters, decodeOracleTiming, decodePanopticTokenURI, decodePoolId, decodeTickSpacing, decodeTokenId, decodeVegoid, deployNewPool, deployNewPoolAndWait, deposit, depositAndWait, deriveSupplyRatePerSecWad, deriveUniqueTokenId, detectReorg, diagnoseOracleSafeMode, dispatch, dispatchAndWait, emptyLiquidateParams, encodeLeg, encodePoolId, encodePoolKeyBytes, encodeV3PoolKeyBytes, encodeV4PoolId, ensureSfpmV3PoolInitialized, estimateBlockNumbers, estimateCloseZapSwap, estimateCollateralBreakdown, estimateCollateralRequired, executeBatchDispatch, executeBatchDispatchAndWait, executeSettleSequence, executeSettleSequenceAndWait, failPendingPosition, feeGrowthInsideX128, feesFromFeeGrowthDelta, fetchPoolId, fetchSfpmV3PoolId, fetchUniswapFeeData, forceExercise, forceExerciseAndWait, formatBlockNumber, formatBps, formatCompact, formatDatetime, formatDuration, formatDurationSeconds, formatFeeTier, formatGas, formatGwei, formatPerSecondRateWadAsAprPct, formatPerSecondRateWadAsApyPct, formatPoolIdHex, formatPriceRange, formatRateWad, formatRatioPercent, formatTick, formatTickRange, formatTimestamp, formatTimestampLocale, formatTokenAmount, formatTokenAmountSigned, formatTokenDelta, formatTokenFlow, formatTokenIdHex, formatTokenIdShort, formatTxHash, formatUtilization, formatWad, formatWadPercent, formatWadSigned, formatWei, generateOverlappingTokenIds, getAccountBuyingPower, getAccountCollateral, getAccountGreeks, getAccountHistory, getAccountPremia, getAccountSummaryBasic, getAccountSummaryRisk, getAssetIndex, getBlockMeta, getChainDeployment, getChunkLiquidities, getChunkSpreads, getClosePositionTransferEstimate, getClosedPositions, getClosedPositionsKey, getCollateralAddresses, getCollateralCurve, getCollateralCurveInputs, getCollateralData, getCollateralRequiredBase, getCollateralSharePrices, getCollateralTotalAssetsBatch, getCurrentRates, getDeltaHedgeParams, getEnforcedTickLimits, getExecutableLpMaxSize, getFactoryConstructMetadata, getFactoryOwnerOf, getFactoryTokenURI, getForfeitablePremium, getGuardianUnlockState, getHedgeLimits, getInterestState, getIrmCurrent, getIrmCurve, getItmAmounts, getLegDelta, getLegDeltaInVaultFrame, getLegGamma, getLegNetValueWidth0, getLegValue, getLiquidationPrices, getMarginBuffer, getMaxPositionSize, getMaxRedeem, getMaxWithdrawable, getNativeTokenPrice, getNetLiquidationValue, getNetLiquidationValues, getNotEnoughTokensError, getOpenPositionIds, getOpenPositionPreview, getOracleRiskParameters, getOracleState, getPanopticPoolAddress, getPanopticPoolFromPoolId, getPendingPositions, getPendingPositionsKey, getPool, getPoolCurrentTick, getPoolDeploymentBlock, getPoolDisplayId, getPoolLiquidities, getPoolMetaKey, getPoolMetadata, getPoolPrefix, getPortfolioValue, getPosition, getPositionChunkData, getPositionDeltaMetrics, getPositionEnrichmentData, getPositionGreeks, getPositionMetaKey, getPositionValueCurve, getPositionVolatilityHistory, getPositions, getPositionsKey, getPositionsWithPremia, getPriceHistory, getPricesAtTick, getRealizedPnL, getRequiredCreditForITM, getRiskParameters, getSafeMode, getSchemaVersionKey, getSimpleLoanTokenIndex, getStreamiaHistory, getSyncCheckpointKey, getSyncStatus, getTickSpacing, getTokenListId, getTrackedChunks, getTrackedChunksKey, getTrackedPositionIds, getTradeHistory, getUniswapFeeHistory, getUniswapV3LpPositionState, getUniswapV3PoolFromId, getUniswapV3PoolInfo, getUniswapV3PoolLiquidities, getUniswapV4LpPositionState, getUniswapV4PoolBasicState, getUniswapV4PoolInfo, getUniswapV4PoolKeyFromId, getUniswapV4PoolLiquidities, getUtilization, hasLoanOrCredit, hasLongLeg, interpolateBlocks, isCall, isCredit, isCreditLeg, isDefinedRisk, isGasError, isInputListFailError, isLiquidatable, isLoan, isLoanLeg, isNonceError, isPanopticErrorType, isPositionTracked, isRetryableRpcError, isShortOnly, isSpread, isSupportedChain, isolateGroupTokenId, jsonSerializer, ladderStrikeSequence, liquidate, liquidateAndWait, loadCheckpoint, logReturns, marketPnlInQuote, marketRiskFromValues, marketScenario, minePoolAddress, mint, mintAndWait, mintableAfterBuffer, multicallRead, netLiquidationValueInQuote, openPosition, openPositionAndWait, optimizeTokenIdRiskPartners, oracleEpochAt, orderListForSettle, packMarketState, panopticLiquidatorAbi, panopticPoolV2Abi, panopticQueryAbi, parseBps, parseCollateralLog, parsePanopticError, parsePoolLog, parseTokenAmount, parseTokenListId, parseWad, planDeriveStrategy, pokeOracle, pokeOracleAndWait, positionValueKey, positionValueTicks, prepareIndicatorCandles, prepareLiquidityGamma, preparePositionGamma, preparePositionValue, preparePositionValueCurve, previewBorrow, previewDeposit, previewMint, previewRedeem, previewRepay, previewUnwrap, previewWithdraw, previewWrap, priceToTick, publicBroadcaster, quoteLiquidation, quoteOneTokenFlow, quoteSfpmSwap, quoteTemporaryLoanRecovery, quoteTokenShortfallRecovery, quoteV3ExactIn, ratePerSecWadToAprPct, realizedBeta, reconstructFromEvents, recoverSnapshot, recoverSnapshotFromTx, redeem, redeemAndWait, removeTrackedChunks, repay, repayAndWait, requireChainDeployment, resolveBlockNumbers, resolveLadderStrike, resolvePanopticPoolFromPoolId, resolveTokenIndex, resolveUniswapV4PoolKey, riskEngineAbi, rollPosition, rollPositionAndWait, roundToTickSpacing, saveCheckpoint, saveClosedPosition, scaleCollateralRequired, scanChunks, screenAccountExact, selectDispatchForAccount, settleAccumulatedPremia, settleAccumulatedPremiaAndWait, settlePremiumFrom, settlePremiumFromAndWait, simulateBatchDispatch, simulateClosePosition, simulateDeployNewPool, simulateDeposit, simulateDispatch, simulateForceExercise, simulateLiquidate, simulateOpenPosition, simulateSFPMBurn, simulateSFPMMint, simulateSettle, simulateSettlePremiumBatch, simulateSettlePremiumFrom, simulateSettleSequence, simulateSwapExactIn, simulateSwapExactOut, simulateWithTokenFlow, simulateWithdraw, slippageBpsToTickDistance, smartRepay, smartRepayAndWait, speedUpTransaction, splitTokenIdByTimescale, sqrtPriceX96ToPriceDecimalScaled, sqrtPriceX96ToTick, supply, supplyAndWait, swapExactIn, swapExactInAndWait, swapExactOut, swapExactOutAndWait, syncPositions, tickLimits, tickToPrice, tickToPriceDecimalScaled, tickToSqrtPriceX96, toVaultFrameAtTick, truncateAddress, unsupply, unsupplyAndWait, unwrapWeth, unwrapWethAndWait, unwrapXstock, unwrapXstockAndWait, utilizationBpsToWad, utilizationPctToWad, validateBatch, validateBuilderCode, validatePoolId, valuePositionAccrual, verifyBlockContinuity, watchEvents, wethWrapAbi, withdraw, withdrawAndWait, withdrawWithPositions, withdrawWithPositionsAndWait, wrapEth, wrapEthAndWait, wrapXstock, wrapXstockAndWait, xstockWrapperAbi };
|
|
34680
|
+
export { AccountInsolventError, AlreadyInitializedError, BORROW_INDEX_BITS, BPS_DENOMINATOR, BPS_SCALE, BatchValidationError, BelowMinimumRedemptionError, CastingError, ChunkHasZeroLiquidityError, ChunkLimitError, CrossPoolError, DEFAULT_MAX_SPREAD, DEFAULT_MINT_BUFFER, DEFAULT_MIN_SWAP_RATIO_BPS, DEFAULT_RECONNECT_CONFIG, DEFAULT_VEGOID, DepositTooLargeError, DuplicateTokenIdError, EffectiveLiquidityAboveThresholdError, ExceedsMaximumRedemptionError, InputListFailError, InsufficientCreditLiquidityError, InvalidBuilderCodeError, InvalidHistoryRangeError, InvalidTickBoundError, InvalidTickError, InvalidTokenIdParameterError, InvalidUniswapCallbackError, LEG_BITS, LEG_LIMITS, LEG_MASKS, LengthMismatchError, LiquidityTooHighError, LoanSlotExhaustedError, MARKET_EPOCH_BITS, MARKET_EPOCH_SHIFT, MARKET_INDICATOR_PERIODS, MAX_TICK, MAX_TRACKED_CHUNKS, MINT_BUFFER, MINT_BUFFER_DENOMINATOR, MIN_TICK, MaxRetriesExceededError, MissingPositionIdsError, NO_LOWER_LIQUIDATION_TICK, NO_UPPER_LIQUIDATION_TICK, NetLiquidityZeroError, NetworkMismatchError, NoLegsExercisableError, NotALongLegError, NotBuilderError, NotEnoughLiquidityInChunkError, NotEnoughTokensError, NotGuardianError, NotMarginCalledError, NotPanopticPoolError, ORACLE_EPOCH_SECONDS, OracleRateLimitedError, PanopticError, PanopticHelperNotDeployedError, PanopticValidationError, PoolNotInitializedError, PositionCountNotZeroError, PositionNotOwnedError, PositionSnapshotNotFoundError, PositionTooLargeError, PriceBoundFailError, PriceImpactTooLargeError, ProviderLagError, RATE_AT_TARGET_BITS, REORG_DEPTH, REQUIRED_BASE_ERROR_SENTINEL, ReentrancyError, RpcError, RpcResponseError, SCHEMA_VERSION, SECONDS_PER_YEAR, STANDARD_TICK_WIDTHS, STORAGE_PREFIX, STRIKE_LADDER_TARGET_STRIKES, SafeModeError, StaleDataError, StaleOracleError, SwapTokenMismatchError, SyncTimeoutError, TOKEN_ID_BITS, TokenIdHasZeroLegsError, TooManyLegsOpenError, TransferFailedError, UNREALIZED_INTEREST_BITS, UTILIZATION_DENOMINATOR, UnauthorizedUniswapCallbackError, UnderOverFlowError, UnhealthyPoolError, UnsafePremiumSettlementError, VARIANCE_RATIO_LAG, WAD, WrongPoolIdError, WrongUniswapPoolError, ZERO_COLLATERAL, ZERO_VALUATION, ZeroAddressError, ZeroCollateralRequirementError, addLegToTokenId, addPendingPosition, addTrackedChunks, annualizePerSecondRateWad, applyMintBuffer, applyMintBufferPerToken, apportion, approve, approveAndWait, approvePool, assertCanBurn, assertCanForceExercise, assertCanLiquidate, assertCanMint, assertFresh, assertHealthy, assertLpPositionFunded, assertTradeable, borrow, borrowAndWait, buildBatchDispatchArgs, buildCreditSwapCall, buildCreditWrappedDispatch, buildOpenPositionCalldata, buildProtectedSettleDispatch, buildProtectedSettlePlan, buildSettleSequenceCalls, buildSfpmSwapCalldata, buildSfpmSwapPlan, buildTemporaryLoanRecoveryDispatch, buildTokenShortfallRecoveryDispatch, buildUniqueCredit, buildUniqueLoan, buildUniqueWidthZeroLeg, calculateAccountGreeksPure, calculateMarketIndicator, calculatePortfolioDelta, calculatePortfolioGamma, calculatePortfolioGreeks, calculatePortfolioValue, calculatePositionDelta, calculatePositionDeltaDebtOnly, calculatePositionDeltaWithSwap, calculatePositionGamma, calculatePositionGreeks, calculatePositionValue, calculatePositionValues, calculatePositionVolatilityMetrics, calculateResyncBlock, calculateSpreadWad, calculateVarianceProfile, cancelTransaction, checkApproval, checkCollateralAcrossTicks, classifyStrategyGroups, classifyStrike, cleanupStalePendingPositions, clearCheckpoint, clearPendingPositions, clearTrackedChunks, clearTrackedPositions, clearTradeHistory, closePosition, closePositionAndWait, collateralCurveTicks, collateralRuleKindFor, collateralTrackerV2Abi, computeV4PoolId, confirmPendingPosition, convertToAssets, convertToShares, countLegs, createEventPoller, createEventSubscription, createFileStorage, createFlowNeutralTokenId, createMemoryStorage, createNonceManager, createPoolFormatters, createTokenIdBuilder, decodeAllDispatchCalldata, decodeAllLegs, decodeDispatchCalldata, decodeLeftRightSigned, decodeLeftRightUnsigned, decodeLeg, decodeOraclePack, decodeOracleRiskParameters, decodeOracleTiming, decodePanopticTokenURI, decodePoolId, decodeTickSpacing, decodeTokenId, decodeVegoid, deployNewPool, deployNewPoolAndWait, deposit, depositAndWait, deriveSupplyRatePerSecWad, deriveUniqueTokenId, detectReorg, diagnoseOracleSafeMode, dispatch, dispatchAndWait, emptyLiquidateParams, encodeLeg, encodePoolId, encodePoolKeyBytes, encodeV3PoolKeyBytes, encodeV4PoolId, ensureSfpmV3PoolInitialized, estimateBlockNumbers, estimateCloseZapSwap, estimateCollateralBreakdown, estimateCollateralRequired, executeBatchDispatch, executeBatchDispatchAndWait, executeSettleSequence, executeSettleSequenceAndWait, failPendingPosition, feeGrowthInsideX128, feesFromFeeGrowthDelta, fetchPoolId, fetchPoolSwaps, fetchSfpmV3PoolId, fetchUniswapFeeData, forceExercise, forceExerciseAndWait, formatBlockNumber, formatBps, formatCompact, formatDatetime, formatDuration, formatDurationSeconds, formatFeeTier, formatGas, formatGwei, formatPerSecondRateWadAsAprPct, formatPerSecondRateWadAsApyPct, formatPoolIdHex, formatPriceRange, formatRateWad, formatRatioPercent, formatTick, formatTickRange, formatTimestamp, formatTimestampLocale, formatTokenAmount, formatTokenAmountSigned, formatTokenDelta, formatTokenFlow, formatTokenIdHex, formatTokenIdShort, formatTxHash, formatUtilization, formatWad, formatWadPercent, formatWadSigned, formatWei, generateOverlappingTokenIds, getAccountBuyingPower, getAccountCollateral, getAccountGreeks, getAccountHistory, getAccountPremia, getAccountSummaryBasic, getAccountSummaryRisk, getAssetIndex, getBlockMeta, getChainDeployment, getChunkLiquidities, getChunkSpreads, getClosePositionTransferEstimate, getClosedPositions, getClosedPositionsKey, getCollateralAddresses, getCollateralCurve, getCollateralCurveInputs, getCollateralData, getCollateralRequiredBase, getCollateralSharePrices, getCollateralTotalAssetsBatch, getCurrentRates, getDeltaHedgeParams, getEnforcedTickLimits, getExecutableLpMaxSize, getFactoryConstructMetadata, getFactoryOwnerOf, getFactoryTokenURI, getForfeitablePremium, getGuardianUnlockState, getHedgeLimits, getInterestState, getIrmCurrent, getIrmCurve, getItmAmounts, getLegDelta, getLegDeltaInVaultFrame, getLegGamma, getLegNetValueWidth0, getLegValue, getLiquidationPrices, getMarginBuffer, getMaxPositionSize, getMaxRedeem, getMaxWithdrawable, getNativeTokenPrice, getNetLiquidationValue, getNetLiquidationValues, getNotEnoughTokensError, getOpenPositionIds, getOpenPositionPreview, getOracleRiskParameters, getOracleState, getPanopticPoolAddress, getPanopticPoolFromPoolId, getPendingPositions, getPendingPositionsKey, getPool, getPoolCurrentTick, getPoolDeploymentBlock, getPoolDisplayId, getPoolLiquidities, getPoolMetaKey, getPoolMetadata, getPoolPrefix, getPortfolioValue, getPosition, getPositionChunkData, getPositionDeltaMetrics, getPositionEnrichmentData, getPositionGreeks, getPositionMetaKey, getPositionMintFunding, getPositionValueCurve, getPositionVolatilityHistory, getPositions, getPositionsKey, getPositionsWithPremia, getPriceHistory, getPricesAtTick, getRealizedPnL, getRequiredCreditForITM, getRiskParameters, getSafeMode, getSchemaVersionKey, getSimpleLoanTokenIndex, getStreamiaHistory, getSyncCheckpointKey, getSyncStatus, getTickSpacing, getTokenIdValidationError, getTokenListId, getTrackedChunks, getTrackedChunksKey, getTrackedPositionIds, getTradeHistory, getUniswapFeeHistory, getUniswapV3LpPositionState, getUniswapV3PoolFromId, getUniswapV3PoolInfo, getUniswapV3PoolLiquidities, getUniswapV4LpPositionState, getUniswapV4PoolBasicState, getUniswapV4PoolInfo, getUniswapV4PoolKeyFromId, getUniswapV4PoolLiquidities, getUtilization, hasLoanOrCredit, hasLongLeg, interpolateBlocks, isCall, isCredit, isCreditLeg, isDefinedRisk, isGasError, isInputListFailError, isLiquidatable, isLoan, isLoanLeg, isNonceError, isPanopticErrorType, isPositionTracked, isRetryableRpcError, isShortOnly, isSpread, isSupportedChain, isolateGroupTokenId, jsonSerializer, ladderStrikeSequence, liquidate, liquidateAndWait, loadCheckpoint, logReturns, marketPnlInQuote, marketRiskFromValues, marketScenario, minePoolAddress, mint, mintAndWait, mintableAfterBuffer, multicallRead, netLiquidationValueInQuote, openPosition, openPositionAndWait, optimizeTokenIdRiskPartners, oracleEpochAt, orderListForSettle, packMarketState, panopticLiquidatorAbi, panopticPoolV2Abi, panopticQueryAbi, parseBps, parseCollateralLog, parsePanopticError, parsePoolLog, parseStreamedKey, parseStreamedSwap, parseSwapLog, parseTokenAmount, parseTokenListId, parseWad, planDeriveStrategy, pokeOracle, pokeOracleAndWait, positionValueKey, positionValueTicks, prepareIndicatorCandles, prepareLiquidityGamma, preparePositionGamma, preparePositionValue, preparePositionValueCurve, previewBorrow, previewDeposit, previewMint, previewRedeem, previewRepay, previewUnwrap, previewWithdraw, previewWrap, priceToTick, publicBroadcaster, quoteLiquidation, quoteOneTokenFlow, quoteSfpmSwap, quoteTemporaryLoanRecovery, quoteTokenShortfallRecovery, quoteTokenShortfallSwap, quoteV3ExactIn, ratePerSecWadToAprPct, realizedBeta, reconstructFromEvents, recoverSnapshot, recoverSnapshotFromTx, redeem, redeemAndWait, removeTrackedChunks, repay, repayAndWait, requireChainDeployment, resolveBlockNumbers, resolveLadderStrike, resolvePanopticPoolFromPoolId, resolveTokenIndex, resolveUniswapV4PoolKey, riskEngineAbi, rollPosition, rollPositionAndWait, roundToTickSpacing, saveCheckpoint, saveClosedPosition, scaleCollateralRequired, scanChunks, screenAccountExact, selectDispatchForAccount, settleAccumulatedPremia, settleAccumulatedPremiaAndWait, settlePremiumFrom, settlePremiumFromAndWait, simulateBatchDispatch, simulateClosePosition, simulateClosePremiumProtection, simulateDeployNewPool, simulateDeposit, simulateDispatch, simulateForceExercise, simulateLiquidate, simulateOpenPosition, simulateSFPMBurn, simulateSFPMMint, simulateSettle, simulateSettlePremiumBatch, simulateSettlePremiumFrom, simulateSettleSequence, simulateSwapExactIn, simulateSwapExactOut, simulateWithTokenFlow, simulateWithdraw, slippageBpsToTickDistance, smartRepay, smartRepayAndWait, speedUpTransaction, splitTokenIdByTimescale, sqrtPriceX96ToPriceDecimalScaled, sqrtPriceX96ToTick, streamPoolSwaps, subscribePoolSwaps, supply, supplyAndWait, swapExactIn, swapExactInAndWait, swapExactOut, swapExactOutAndWait, syncPositions, tickLimits, tickToPrice, tickToPriceDecimalScaled, tickToSqrtPriceX96, toVaultFrameAtTick, truncateAddress, unsupply, unsupplyAndWait, unwrapWeth, unwrapWethAndWait, unwrapXstock, unwrapXstockAndWait, utilizationBpsToWad, utilizationPctToWad, validateBatch, validateBuilderCode, validatePoolId, valuePositionAccrual, verifyBlockContinuity, watchEvents, watchPoolSwaps, wethWrapAbi, withdraw, withdrawAndWait, withdrawWithPositions, withdrawWithPositionsAndWait, wrapEth, wrapEthAndWait, wrapXstock, wrapXstockAndWait, xstockWrapperAbi };
|
|
32591
34681
|
//# sourceMappingURL=index.js.map
|