@1inch/swap-vm-sdk 0.1.2-rc.6 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/index.js +454 -135
  2. package/dist/index.mjs +455 -136
  3. package/dist/swap-vm/instructions/concentrate/concentrate-liquidity-calculator/types.d.mts +9 -21
  4. package/dist/swap-vm/instructions/concentrate/concentrate-liquidity-calculator/types.d.ts +9 -21
  5. package/dist/swap-vm/instructions/concentrate/index.d.mts +8 -3
  6. package/dist/swap-vm/instructions/concentrate/index.d.ts +8 -3
  7. package/dist/swap-vm/instructions/concentrate/price/index.d.mts +3 -0
  8. package/dist/swap-vm/instructions/concentrate/price/index.d.ts +3 -0
  9. package/dist/swap-vm/instructions/concentrate/price/price.d.mts +45 -0
  10. package/dist/swap-vm/instructions/concentrate/price/price.d.ts +45 -0
  11. package/dist/swap-vm/instructions/concentrate/price/types.d.mts +21 -0
  12. package/dist/swap-vm/instructions/concentrate/price/types.d.ts +21 -0
  13. package/dist/swap-vm/instructions/concentrate/price-range/index.d.mts +2 -0
  14. package/dist/swap-vm/instructions/concentrate/price-range/index.d.ts +2 -0
  15. package/dist/swap-vm/instructions/concentrate/price-range/price-range.d.mts +18 -0
  16. package/dist/swap-vm/instructions/concentrate/price-range/price-range.d.ts +18 -0
  17. package/dist/swap-vm/instructions/concentrate/price-range/types.d.mts +26 -0
  18. package/dist/swap-vm/instructions/concentrate/price-range/types.d.ts +26 -0
  19. package/dist/swap-vm/instructions/concentrate/token-reserve/index.d.mts +2 -0
  20. package/dist/swap-vm/instructions/concentrate/token-reserve/index.d.ts +2 -0
  21. package/dist/swap-vm/instructions/concentrate/token-reserve/token-reserve.d.mts +10 -0
  22. package/dist/swap-vm/instructions/concentrate/token-reserve/token-reserve.d.ts +10 -0
  23. package/dist/swap-vm/instructions/concentrate/token-reserve/types.d.mts +10 -0
  24. package/dist/swap-vm/instructions/concentrate/token-reserve/types.d.ts +10 -0
  25. package/dist/swap-vm/instructions/index.d.mts +1 -0
  26. package/dist/swap-vm/instructions/index.d.ts +1 -0
  27. package/dist/swap-vm/instructions/pegged-swap/index.d.mts +4 -0
  28. package/dist/swap-vm/instructions/pegged-swap/index.d.ts +4 -0
  29. package/dist/swap-vm/instructions/pegged-swap/pegged-swap-calculator/index.d.mts +2 -0
  30. package/dist/swap-vm/instructions/pegged-swap/pegged-swap-calculator/index.d.ts +2 -0
  31. package/dist/swap-vm/instructions/pegged-swap/pegged-swap-calculator/pegged-swap-calculator.d.mts +16 -0
  32. package/dist/swap-vm/instructions/pegged-swap/pegged-swap-calculator/pegged-swap-calculator.d.ts +16 -0
  33. package/dist/swap-vm/instructions/pegged-swap/pegged-swap-calculator/types.d.mts +9 -0
  34. package/dist/swap-vm/instructions/pegged-swap/pegged-swap-calculator/types.d.ts +9 -0
  35. package/dist/swap-vm/instructions/pegged-swap/pegged-swap-math/pegged-swap-math.d.mts +18 -0
  36. package/dist/swap-vm/instructions/pegged-swap/pegged-swap-math/pegged-swap-math.d.ts +18 -0
  37. package/dist/swap-vm/instructions/pegged-swap/price/index.d.mts +2 -0
  38. package/dist/swap-vm/instructions/pegged-swap/price/index.d.ts +2 -0
  39. package/dist/swap-vm/instructions/pegged-swap/price/pegged-price.d.mts +28 -0
  40. package/dist/swap-vm/instructions/pegged-swap/price/pegged-price.d.ts +28 -0
  41. package/dist/swap-vm/instructions/pegged-swap/price/types.d.mts +30 -0
  42. package/dist/swap-vm/instructions/pegged-swap/price/types.d.ts +30 -0
  43. package/dist/swap-vm/instructions/utils/index.d.mts +2 -0
  44. package/dist/swap-vm/instructions/utils/index.d.ts +2 -0
  45. package/dist/swap-vm/instructions/utils/truncate-human-decimal-string.d.mts +9 -0
  46. package/dist/swap-vm/instructions/utils/truncate-human-decimal-string.d.ts +9 -0
  47. package/package.json +4 -4
  48. package/dist/swap-vm/instructions/concentrate/concentrate-liquidity-calculator/concentrate-liquidity-calculator.d.mts +0 -61
  49. package/dist/swap-vm/instructions/concentrate/concentrate-liquidity-calculator/concentrate-liquidity-calculator.d.ts +0 -61
  50. /package/dist/swap-vm/instructions/{concentrate → utils}/bigint-sqrt.d.mts +0 -0
  51. /package/dist/swap-vm/instructions/{concentrate → utils}/bigint-sqrt.d.ts +0 -0
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { decodeAbiParameters, decodeEventLog, encodeAbiParameters, encodeFunctionData, hashTypedData, keccak256 } from "viem";
1
+ import { decodeAbiParameters, decodeEventLog, encodeAbiParameters, encodeFunctionData, formatUnits, hashTypedData, keccak256, parseUnits } from "viem";
2
2
  import { Address, Address as Address$1, AddressHalf, HexString, HexString as HexString$1, Interaction, NetworkEnum, NetworkEnum as NetworkEnum$1 } from "@1inch/sdk-core";
3
3
  import { BN, BitMask, BytesBuilder, BytesIter, UINT_16_MAX, UINT_24_MAX, UINT_256_MAX, UINT_32_MAX, UINT_40_MAX, UINT_64_MAX, UINT_8_MAX, UINT_96_MAX, add0x, trim0x } from "@1inch/byte-utils";
4
4
  import assert from "assert";
@@ -1847,7 +1847,7 @@ var ConcentrateGrowLiquidity2DArgsCoder = class {
1847
1847
  };
1848
1848
 
1849
1849
  //#endregion
1850
- //#region src/swap-vm/instructions/concentrate/bigint-sqrt.ts
1850
+ //#region src/swap-vm/instructions/utils/bigint-sqrt.ts
1851
1851
  function bigintSqrt(value) {
1852
1852
  if (value < 0n) throw new Error("square root of negative numbers is not supported");
1853
1853
  if (value < 2n) return value;
@@ -1863,7 +1863,7 @@ function bigintSqrt(value) {
1863
1863
 
1864
1864
  //#endregion
1865
1865
  //#region src/swap-vm/instructions/concentrate/concentrate-grow-liquidity-2d-args.ts
1866
- const ONE_E18 = 10n ** 18n;
1866
+ const ONE_E18$1 = 10n ** 18n;
1867
1867
  /**
1868
1868
  * Arguments for concentrateGrowLiquidity2D instruction
1869
1869
  * Contract encodes sqrtPriceMin and sqrtPriceMax (2 × uint256, 64 bytes)
@@ -1891,8 +1891,8 @@ var ConcentrateGrowLiquidity2DArgs = class ConcentrateGrowLiquidity2DArgs {
1891
1891
  * Computes sqrtPrice = sqrt(P * 1e18) so that (sqrtPrice/1e18)^2 = P/1e18.
1892
1892
  **/
1893
1893
  static fromRawPrices(rawPriceMin, rawPriceMax) {
1894
- const sqrtPriceMin = bigintSqrt(rawPriceMin * ONE_E18);
1895
- const sqrtPriceMax = bigintSqrt(rawPriceMax * ONE_E18);
1894
+ const sqrtPriceMin = bigintSqrt(rawPriceMin * ONE_E18$1);
1895
+ const sqrtPriceMax = bigintSqrt(rawPriceMax * ONE_E18$1);
1896
1896
  return new ConcentrateGrowLiquidity2DArgs(sqrtPriceMin, sqrtPriceMax);
1897
1897
  }
1898
1898
  /**
@@ -1936,8 +1936,8 @@ const ONE = 10n ** 18n;
1936
1936
  */
1937
1937
  function computeLiquidityFromAmounts(availableLt, availableGt, sqrtPspot, sqrtPmin, sqrtPmax) {
1938
1938
  if (sqrtPmin >= sqrtPmax) throw new Error("sqrtPmax should be greater than sqrtPmin");
1939
- const lFromLt = sqrtPmax > sqrtPspot ? mulDiv(availableLt, mulDiv(sqrtPmax, sqrtPspot, ONE), sqrtPmax - sqrtPspot) : UINT_256_MAX;
1940
- const lFromGt = sqrtPspot > sqrtPmin ? mulDiv(availableGt, ONE, sqrtPspot - sqrtPmin) : UINT_256_MAX;
1939
+ const lFromLt = sqrtPmax > sqrtPspot ? mulDiv$1(availableLt, mulDiv$1(sqrtPmax, sqrtPspot, ONE), sqrtPmax - sqrtPspot) : UINT_256_MAX;
1940
+ const lFromGt = sqrtPspot > sqrtPmin ? mulDiv$1(availableGt, ONE, sqrtPspot - sqrtPmin) : UINT_256_MAX;
1941
1941
  const targetL = lFromLt < lFromGt ? lFromLt : lFromGt;
1942
1942
  const { bLt: actualLt, bGt: actualGt } = computeBalances(targetL, sqrtPspot, sqrtPmin, sqrtPmax);
1943
1943
  return {
@@ -1961,8 +1961,8 @@ function computeLiquidityFromAmounts(availableLt, availableGt, sqrtPspot, sqrtPm
1961
1961
  */
1962
1962
  function computeBalances(targetL, sqrtPspot, sqrtPmin, sqrtPmax) {
1963
1963
  if (sqrtPmin >= sqrtPmax) throw new Error("sqrtPmax should be greater than sqrtPmin");
1964
- const bLt = sqrtPmax > sqrtPspot ? mulDiv(targetL, sqrtPmax - sqrtPspot, mulDiv(sqrtPmax, sqrtPspot, ONE)) : 0n;
1965
- const bGt = sqrtPspot > sqrtPmin ? mulDiv(targetL, sqrtPspot - sqrtPmin, ONE) : 0n;
1964
+ const bLt = sqrtPmax > sqrtPspot ? mulDiv$1(targetL, sqrtPmax - sqrtPspot, mulDiv$1(sqrtPmax, sqrtPspot, ONE)) : 0n;
1965
+ const bGt = sqrtPspot > sqrtPmin ? mulDiv$1(targetL, sqrtPspot - sqrtPmin, ONE) : 0n;
1966
1966
  return {
1967
1967
  bLt,
1968
1968
  bGt
@@ -1981,9 +1981,9 @@ function computeBalances(targetL, sqrtPspot, sqrtPmin, sqrtPmax) {
1981
1981
  */
1982
1982
  function computeLiquidityAndPrice(balanceLt, balanceGt, sqrtPriceMin, sqrtPriceMax) {
1983
1983
  const liquidity = computeL(balanceLt, balanceGt, sqrtPriceMin, sqrtPriceMax);
1984
- const virtualLt = balanceLt + mulDiv(liquidity, ONE, sqrtPriceMax);
1985
- const virtualGt = balanceGt + mulDiv(liquidity, sqrtPriceMin, ONE);
1986
- const sqrtPriceSpot = bigintSqrt(mulDiv(virtualGt, ONE * ONE, virtualLt));
1984
+ const virtualLt = balanceLt + mulDiv$1(liquidity, ONE, sqrtPriceMax);
1985
+ const virtualGt = balanceGt + mulDiv$1(liquidity, sqrtPriceMin, ONE);
1986
+ const sqrtPriceSpot = bigintSqrt(mulDiv$1(virtualGt, ONE * ONE, virtualLt));
1987
1987
  return {
1988
1988
  liquidity,
1989
1989
  sqrtPriceSpot
@@ -1994,161 +1994,299 @@ function computeLiquidityAndPrice(balanceLt, balanceGt, sqrtPriceMin, sqrtPriceM
1994
1994
  * Mirrors XYCConcentrateArgsBuilder._computeL in XYCConcentrate.sol.
1995
1995
  */
1996
1996
  function computeL(bLt, bGt, sqrtPriceMin, sqrtPriceMax) {
1997
- const alpha = ONE - mulDiv(sqrtPriceMin, ONE, sqrtPriceMax);
1998
- const beta = mulDiv(bLt, sqrtPriceMin, ONE) + mulDiv(bGt, ONE, sqrtPriceMax);
1999
- const fourAC = mulDiv(4n * alpha, bLt, ONE) * bGt;
1997
+ const alpha = ONE - mulDiv$1(sqrtPriceMin, ONE, sqrtPriceMax);
1998
+ const beta = mulDiv$1(bLt, sqrtPriceMin, ONE) + mulDiv$1(bGt, ONE, sqrtPriceMax);
1999
+ const fourAC = mulDiv$1(4n * alpha, bLt, ONE) * bGt;
2000
2000
  const disc = beta * beta + fourAC;
2001
- return mulDiv(beta + bigintSqrt(disc), ONE, 2n * alpha);
2001
+ return mulDiv$1(beta + bigintSqrt(disc), ONE, 2n * alpha);
2002
2002
  }
2003
- function mulDiv(a, b, c) {
2003
+ function mulDiv$1(a, b, c) {
2004
2004
  if (c === 0n) throw new Error("mulDiv: division by zero");
2005
2005
  return a * b / c;
2006
2006
  }
2007
2007
 
2008
2008
  //#endregion
2009
- //#region src/swap-vm/instructions/concentrate/concentrate-liquidity-calculator/concentrate-liquidity-calculator.ts
2009
+ //#region src/swap-vm/instructions/utils/truncate-human-decimal-string.ts
2010
2010
  /**
2011
- * Calculator for concentrated liquidity: given two tokens and a price range (min, spot, max),
2012
- * computes sqrt prices and token reserves for "max allocation" (use all available balances)
2013
- * or "fixed allocation" (fix one token amount and solve for the other).
2011
+ * Round a decimal string to `maxFrac` fractional digits (half-up: if the first dropped digit
2012
+ * is `5`–`9`, round the last kept digit up), then strip trailing zeros after the dot.
2014
2013
  *
2015
- * Token ordering follows the pool convention: token0 = lower address, token1 = higher address.
2016
- * Prices are supplied as ScaledPrices with scale 10^(token0Decimals + token1Decimals); they are
2017
- * converted internally to P = token1/token0 in 1e18 and then to sqrt(P * 1e18) for the math.
2014
+ * @param s Decimal string as produced by e.g. `formatUnits` (no scientific notation).
2015
+ * @param maxFrac Maximum number of digits after `.`; `0` means integer only (round using the
2016
+ * first fractional digit).
2018
2017
  */
2019
- var ConcentrateLiquidityCalculator = class ConcentrateLiquidityCalculator {
2020
- static ONE_E18 = 10n ** 18n;
2021
- constructor(tokenA, tokenB) {
2022
- this.tokenA = tokenA;
2023
- this.tokenB = tokenB;
2018
+ function truncateHumanDecimalString(s, maxFrac) {
2019
+ if (maxFrac < 0) throw new Error("maxFrac must be non-negative");
2020
+ const dot = s.indexOf(".");
2021
+ if (dot === -1) return s;
2022
+ const intPartStr = s.slice(0, dot) || "0";
2023
+ const fracFull = s.slice(dot + 1);
2024
+ if (maxFrac === 0) {
2025
+ let intPart = BigInt(intPartStr);
2026
+ const first = fracFull[0];
2027
+ if (first !== void 0 && first >= "5" && first <= "9") intPart += 1n;
2028
+ return intPart.toString();
2029
+ }
2030
+ const fracPadded = (fracFull + "0".repeat(maxFrac)).slice(0, maxFrac);
2031
+ const nextDigit = fracFull.length > maxFrac ? fracFull[maxFrac] : void 0;
2032
+ const roundUp = nextDigit !== void 0 && nextDigit >= "5" && nextDigit <= "9";
2033
+ const scale = 10n ** BigInt(maxFrac);
2034
+ let scaled = BigInt(intPartStr) * scale + BigInt(fracPadded || "0");
2035
+ if (roundUp) scaled += 1n;
2036
+ const intOut = scaled / scale;
2037
+ let fracOut = (scaled % scale).toString().padStart(maxFrac, "0");
2038
+ fracOut = fracOut.replace(/0+$/, "");
2039
+ return fracOut.length > 0 ? `${intOut}.${fracOut}` : intOut.toString();
2040
+ }
2041
+
2042
+ //#endregion
2043
+ //#region src/swap-vm/instructions/concentrate/price/price.ts
2044
+ const ONE_E18$2 = 10n ** 18n;
2045
+ var Price = class Price {
2046
+ constructor(sqrtP, token0, token1) {
2047
+ this.sqrtP = sqrtP;
2048
+ this.token0 = token0;
2049
+ this.token1 = token1;
2050
+ assert(sqrtP > 0n, "sqrt price must be positive");
2051
+ assert(!token0.address.equal(token1.address), "price tokens should be different");
2052
+ }
2053
+ /**
2054
+ * Fixed-point sqrt price as used on-chain (`sqrt(P * 1e18)`).
2055
+ */
2056
+ static fromSqrt(price, pair) {
2057
+ const zeroForOne = pair.tokenA.address.lt(pair.tokenB.address);
2058
+ const token0 = zeroForOne ? pair.tokenA : pair.tokenB;
2059
+ const token1 = zeroForOne ? pair.tokenB : pair.tokenA;
2060
+ return new Price(price, token0, token1);
2024
2061
  }
2025
2062
  /**
2026
- * Token with the smaller address (token0 in pool convention; "Lt" in the math).
2063
+ * Human decimal string for **quote per 1 base**`.
2027
2064
  */
2028
- get token0() {
2029
- return this.tokenA.address.lt(this.tokenB.address) ? this.tokenA : this.tokenB;
2065
+ static fromHuman(price, pair) {
2066
+ assert(!pair.quoteToken.address.equal(pair.baseToken.address), "quote and base must be different tokens");
2067
+ const zeroForOne = pair.quoteToken.address.lt(pair.baseToken.address);
2068
+ const t0 = zeroForOne ? pair.quoteToken : pair.baseToken;
2069
+ const t1 = zeroForOne ? pair.baseToken : pair.quoteToken;
2070
+ const d0 = t0.decimals;
2071
+ const d1 = t1.decimals;
2072
+ const scale = d0 + d1;
2073
+ if (scale > BigInt(Number.MAX_SAFE_INTEGER)) throw new Error("decimals sum too large for parseUnits");
2074
+ const scaledRaw = parseUnits(price.trim(), Number(scale));
2075
+ if (pair.quoteToken.address.equal(t0.address)) {
2076
+ const numerator = 10n ** (d1 + d1) * ONE_E18$2;
2077
+ return new Price(bigintSqrt(numerator * ONE_E18$2 / scaledRaw), t0, t1);
2078
+ }
2079
+ if (pair.quoteToken.address.equal(t1.address)) {
2080
+ const denominator = 10n ** (d0 + d0);
2081
+ return new Price(bigintSqrt(scaledRaw * ONE_E18$2 * ONE_E18$2 / denominator), t0, t1);
2082
+ }
2083
+ throw new Error("quote token must be one of the two pair tokens");
2084
+ }
2085
+ static fromJSON(input) {
2086
+ const token0 = {
2087
+ address: new Address$1(input.token0.address),
2088
+ decimals: BigInt(input.token0.decimals)
2089
+ };
2090
+ const token1 = {
2091
+ address: new Address$1(input.token1.address),
2092
+ decimals: BigInt(input.token1.decimals)
2093
+ };
2094
+ assert(token0.address.lt(token1.address), "token0 address must be less than token1 (canonical order)");
2095
+ return new Price(BigInt(input.sqrtP), token0, token1);
2096
+ }
2097
+ equals(other) {
2098
+ return this.sqrtP === other.sqrtP && this.token0.address.equal(other.token0.address) && this.token1.address.equal(other.token1.address) && this.token0.decimals === other.token0.decimals && this.token1.decimals === other.token1.decimals;
2099
+ }
2100
+ lt(other) {
2101
+ assert(this.isSamePair(other), "cannot compare prices for different pairs");
2102
+ return this.sqrtP < other.sqrtP;
2103
+ }
2104
+ lte(other) {
2105
+ assert(this.isSamePair(other), "cannot compare prices for different pairs");
2106
+ return this.sqrtP <= other.sqrtP;
2107
+ }
2108
+ gt(other) {
2109
+ assert(this.isSamePair(other), "cannot compare prices for different pairs");
2110
+ return this.sqrtP > other.sqrtP;
2111
+ }
2112
+ gte(other) {
2113
+ assert(this.isSamePair(other), "cannot compare prices for different pairs");
2114
+ return this.sqrtP >= other.sqrtP;
2115
+ }
2116
+ isSamePair(other) {
2117
+ return this.token0.address.equal(other.token0.address) && this.token1.address.equal(other.token1.address) && this.token0.decimals === other.token0.decimals && this.token1.decimals === other.token1.decimals;
2030
2118
  }
2031
2119
  /**
2032
- * Token with the larger address (token1 in pool convention; "Gt" in the math).
2120
+ * Raw price `P` with 1e18 fixed-point (`(sqrtP^2) / 1e18`), matching typical on-chain use.
2033
2121
  */
2034
- get token1() {
2035
- return this.tokenA.address.lt(this.tokenB.address) ? this.tokenB : this.tokenA;
2122
+ toRaw() {
2123
+ return this.sqrtP * this.sqrtP / ONE_E18$2;
2036
2124
  }
2037
- static new(data) {
2038
- return new ConcentrateLiquidityCalculator(data.tokenA, data.tokenB);
2125
+ toSqrt() {
2126
+ return this.sqrtP;
2039
2127
  }
2040
2128
  /**
2041
- * Compute reserves when one token amount is fixed: the position uses exactly
2042
- * `fixedReserve` of `fixedReserveForToken` and the other token amount is derived
2043
- * to keep the same liquidity L. Returns sqrt prices and token0/token1
2044
- * reserves (raw amounts).
2045
- * Due to integer math (floor division, sqrt), the fixed asset amount in the result
2046
- * may be less than requested by a few wei.
2129
+ * Decimal string for **quote per 1 base** at scale `10^(token0Decimals + token1Decimals)`.
2130
+ * Fractional digits after the dot are **rounded half-up** to {@link PriceToken.decimals} of
2131
+ * the quote token (then trailing zeros are removed).
2132
+ *
2133
+ * @param quoteToken Which token is the quote currency; base is the other token.
2047
2134
  */
2048
- computeFixedAllocation(scaledPrices, fixedReserveForToken, fixedReserve) {
2049
- const { minPriceRaw, spotPriceRaw, maxPriceRaw } = this.computeRawPrices(scaledPrices);
2050
- const sqrtPriceMin = bigintSqrt(minPriceRaw * ConcentrateLiquidityCalculator.ONE_E18);
2051
- const sqrtPriceSpot = bigintSqrt(spotPriceRaw * ConcentrateLiquidityCalculator.ONE_E18);
2052
- const sqrtPriceMax = bigintSqrt(maxPriceRaw * ConcentrateLiquidityCalculator.ONE_E18);
2053
- const isFixedLt = fixedReserveForToken.equal(this.token0.address);
2054
- const availableLt = isFixedLt ? fixedReserve : UINT_256_MAX;
2055
- const availableGt = isFixedLt ? UINT_256_MAX : fixedReserve;
2056
- const { actualLt, actualGt } = computeLiquidityFromAmounts(availableLt, availableGt, sqrtPriceSpot, sqrtPriceMin, sqrtPriceMax);
2135
+ toHuman(quoteToken) {
2136
+ assert(quoteToken.equal(this.token0.address) || quoteToken.equal(this.token1.address), "quote token should be one of pair price tokens");
2137
+ const d0 = this.token0.decimals;
2138
+ const d1 = this.token1.decimals;
2139
+ const scale = d0 + d1;
2140
+ const scaled = this.scaledRawAmountForQuote(quoteToken);
2141
+ const quoteDecimals = quoteToken.equal(this.token0.address) ? d0 : d1;
2142
+ const full = formatUnits(scaled, Number(scale));
2143
+ return truncateHumanDecimalString(full, Number(quoteDecimals));
2144
+ }
2145
+ toJSON() {
2057
2146
  return {
2058
- sqrtPriceMin,
2059
- sqrtPriceSpot,
2060
- sqrtPriceMax,
2061
- token0Reserve: actualLt,
2062
- token1Reserve: actualGt
2147
+ sqrtP: this.sqrtP.toString(),
2148
+ token0: {
2149
+ address: this.token0.address.toString(),
2150
+ decimals: this.token0.decimals.toString()
2151
+ },
2152
+ token1: {
2153
+ address: this.token1.address.toString(),
2154
+ decimals: this.token1.decimals.toString()
2155
+ }
2063
2156
  };
2064
2157
  }
2065
2158
  /**
2066
- * Compute reserves when both token amounts are taken from token info: uses
2067
- * token0.maxAvailableLiquidity and token1.maxAvailableLiquidity to maximize
2068
- * L. Returns sqrt prices and the token0/token1 reserves that achieve
2069
- * that maximum.
2159
+ * Quote per 1 base scaled by `10^(token0Decimals + token1Decimals)`.
2160
+ * Uses `sqrtP^2` in one step so we do not compound truncation from {@link toRaw}.
2070
2161
  */
2071
- computeMaxAllocation(scaledPrices) {
2072
- const { minPriceRaw, spotPriceRaw, maxPriceRaw } = this.computeRawPrices(scaledPrices);
2073
- const sqrtPriceMin = bigintSqrt(minPriceRaw * ConcentrateLiquidityCalculator.ONE_E18);
2074
- const sqrtPriceSpot = bigintSqrt(spotPriceRaw * ConcentrateLiquidityCalculator.ONE_E18);
2075
- const sqrtPriceMax = bigintSqrt(maxPriceRaw * ConcentrateLiquidityCalculator.ONE_E18);
2076
- const { actualLt, actualGt } = computeLiquidityFromAmounts(this.token0.maxAvailableLiquidity, this.token1.maxAvailableLiquidity, sqrtPriceSpot, sqrtPriceMin, sqrtPriceMax);
2162
+ scaledRawAmountForQuote(quoteToken) {
2163
+ const d0 = this.token0.decimals;
2164
+ const d1 = this.token1.decimals;
2165
+ const sqrtP2 = this.sqrtP * this.sqrtP;
2166
+ if (quoteToken.equal(this.token0.address)) {
2167
+ const numerator = 10n ** (d1 + d1) * ONE_E18$2;
2168
+ return numerator * ONE_E18$2 / sqrtP2;
2169
+ }
2170
+ if (quoteToken.equal(this.token1.address)) {
2171
+ const numerator = 10n ** (d0 + d0);
2172
+ return sqrtP2 * numerator / (ONE_E18$2 * ONE_E18$2);
2173
+ }
2174
+ throw new Error("quote token must be one of the pair tokens");
2175
+ }
2176
+ };
2177
+
2178
+ //#endregion
2179
+ //#region src/swap-vm/instructions/concentrate/token-reserve/token-reserve.ts
2180
+ var TokenReserve = class TokenReserve {
2181
+ constructor(token, reserve) {
2182
+ this.token = token;
2183
+ this.reserve = reserve;
2184
+ }
2185
+ static new(args) {
2186
+ return new TokenReserve(args.token, args.reserve);
2187
+ }
2188
+ static fromJSON(input) {
2189
+ return new TokenReserve(new Address$1(input.token), BigInt(input.reserve));
2190
+ }
2191
+ toJSON() {
2077
2192
  return {
2078
- sqrtPriceMin,
2079
- sqrtPriceSpot,
2080
- sqrtPriceMax,
2081
- token0Reserve: actualLt,
2082
- token1Reserve: actualGt
2193
+ token: this.token.toString(),
2194
+ reserve: this.reserve.toString()
2083
2195
  };
2084
2196
  }
2085
- /**
2086
- * Implied spot sqrt price from token0/token1 balances and a scaled price range
2087
- * (same convention as {@link computeMaxAllocation}). Inverse of the allocation math; wraps
2088
- * {@link computeLiquidityAndPrice} from concentrate-liquidity-math.
2089
- *
2090
- * @returns sqrt(P_spot) in 1e18 fixed-point (same as {@link ConcentratedLiquidityInfo.sqrtPriceSpot}).
2091
- */
2092
- computeSpotPrice(token0Balance, token1Balance, scaledPriceBounds) {
2093
- const { sqrtPriceMin, sqrtPriceMax } = this.computeSqrtPriceBounds(scaledPriceBounds);
2094
- const { sqrtPriceSpot } = computeLiquidityAndPrice(token0Balance, token1Balance, sqrtPriceMin, sqrtPriceMax);
2095
- return sqrtPriceSpot;
2197
+ };
2198
+
2199
+ //#endregion
2200
+ //#region src/swap-vm/instructions/concentrate/price-range/price-range.ts
2201
+ var PriceRange = class PriceRange {
2202
+ constructor(minPrice, spotPrice, maxPrice) {
2203
+ this.minPrice = minPrice;
2204
+ this.spotPrice = spotPrice;
2205
+ this.maxPrice = maxPrice;
2206
+ assert(maxPrice.gte(spotPrice), "maxPrice should be >= spotPrice");
2207
+ assert(spotPrice.gte(minPrice), "spotPrice should be >= minPrice");
2208
+ assert(minPrice.lt(maxPrice), "minPrice should be < maxPrice");
2209
+ assert(minPrice.isSamePair(spotPrice), "cannot create price range for different pairs");
2210
+ assert(maxPrice.isSamePair(spotPrice), "cannot create price range for different pairs");
2096
2211
  }
2097
- /**
2098
- * Convert user-facing ScaledPrices (scale 10^(token0Decimals+token1Decimals)) into internal
2099
- * raw prices P = token1/token0 (before sqrt), so that sqrt(P * 1e18) can be
2100
- * passed to the liquidity math. Handles both quote = token0 and quote = token1.
2101
- */
2102
- computeRawPrices(scaledPrices) {
2103
- const { minPriceRaw, maxPriceRaw } = this.computeRawPriceBounds(scaledPrices);
2104
- const token0 = this.token0;
2105
- const token1 = this.token1;
2106
- if (scaledPrices.quoteToken.equal(token0.address)) {
2107
- const numerator = 10n ** (token1.decimals + token1.decimals) * ConcentrateLiquidityCalculator.ONE_E18;
2108
- return {
2109
- minPriceRaw,
2110
- spotPriceRaw: numerator / scaledPrices.spotPriceRaw,
2111
- maxPriceRaw
2112
- };
2113
- }
2114
- if (scaledPrices.quoteToken.equal(token1.address)) {
2115
- const denominator = 10n ** (token0.decimals + token0.decimals);
2116
- return {
2117
- minPriceRaw,
2118
- spotPriceRaw: scaledPrices.spotPriceRaw * ConcentrateLiquidityCalculator.ONE_E18 / denominator,
2119
- maxPriceRaw
2120
- };
2121
- }
2122
- throw new Error("unknown quote token");
2212
+ get token0() {
2213
+ return this.minPrice.token0;
2214
+ }
2215
+ get token1() {
2216
+ return this.minPrice.token1;
2217
+ }
2218
+ static new(range) {
2219
+ const minPrice = range.minPrice.lte(range.spotPrice) ? range.minPrice : range.maxPrice;
2220
+ const maxPrice = range.maxPrice.gte(range.spotPrice) ? range.maxPrice : range.minPrice;
2221
+ return new PriceRange(minPrice, range.spotPrice, maxPrice);
2222
+ }
2223
+ static fromJSON(input) {
2224
+ return PriceRange.new({
2225
+ minPrice: Price.fromJSON(input.minPrice),
2226
+ spotPrice: Price.fromJSON(input.spotPrice),
2227
+ maxPrice: Price.fromJSON(input.maxPrice)
2228
+ });
2123
2229
  }
2124
- computeSqrtPriceBounds(scaledPriceBounds) {
2125
- const { minPriceRaw, maxPriceRaw } = this.computeRawPriceBounds(scaledPriceBounds);
2230
+ static fromPriceBounds(bounds, reserves) {
2231
+ const minPrice = bounds.minPrice.lt(bounds.maxPrice) ? bounds.minPrice : bounds.maxPrice;
2232
+ const maxPrice = bounds.minPrice.lt(bounds.maxPrice) ? bounds.maxPrice : bounds.minPrice;
2233
+ const zeroForOne = reserves.reserveA.token.equal(bounds.minPrice.token0.address);
2234
+ const reserve0 = zeroForOne ? reserves.reserveA : reserves.reserveB;
2235
+ const reserve1 = zeroForOne ? reserves.reserveB : reserves.reserveA;
2236
+ assert(reserve0.token.equal(bounds.minPrice.token0.address), "provided reserve for unknown token");
2237
+ assert(reserve1.token.equal(bounds.minPrice.token1.address), "provided reserve for unknown token");
2238
+ const { sqrtPriceSpot } = computeLiquidityAndPrice(reserve0.reserve, reserve1.reserve, minPrice.toSqrt(), maxPrice.toSqrt());
2239
+ const spotPrice = Price.fromSqrt(sqrtPriceSpot, {
2240
+ tokenA: bounds.minPrice.token0,
2241
+ tokenB: bounds.minPrice.token1
2242
+ });
2243
+ return PriceRange.new({
2244
+ minPrice,
2245
+ spotPrice,
2246
+ maxPrice
2247
+ });
2248
+ }
2249
+ computeFixedAllocation(fixedReserve) {
2250
+ assert(fixedReserve.token.equal(this.token0.address) || fixedReserve.token.equal(this.token1.address), "fixed reserve should be in some pair token");
2251
+ const isFixedLt = fixedReserve.token.equal(this.token0.address);
2252
+ const availableLt = isFixedLt ? fixedReserve.reserve : UINT_256_MAX;
2253
+ const availableGt = isFixedLt ? UINT_256_MAX : fixedReserve.reserve;
2254
+ const { actualLt, actualGt } = computeLiquidityFromAmounts(availableLt, availableGt, this.spotPrice.toSqrt(), this.minPrice.toSqrt(), this.maxPrice.toSqrt());
2126
2255
  return {
2127
- sqrtPriceMin: bigintSqrt(minPriceRaw * ConcentrateLiquidityCalculator.ONE_E18),
2128
- sqrtPriceMax: bigintSqrt(maxPriceRaw * ConcentrateLiquidityCalculator.ONE_E18)
2256
+ reserve0: TokenReserve.new({
2257
+ token: this.token0.address,
2258
+ reserve: actualLt
2259
+ }),
2260
+ reserve1: TokenReserve.new({
2261
+ token: this.token1.address,
2262
+ reserve: actualGt
2263
+ })
2129
2264
  };
2130
2265
  }
2131
- /**
2132
- * Internal P = token1/token0 (1e18) from scaled min/max only (same mapping as {@link computeRawPrices}).
2133
- */
2134
- computeRawPriceBounds(scaledPriceBounds) {
2135
- const token0 = this.token0;
2136
- const token1 = this.token1;
2137
- if (scaledPriceBounds.quoteToken.equal(token0.address)) {
2138
- const numerator = 10n ** (token1.decimals + token1.decimals) * ConcentrateLiquidityCalculator.ONE_E18;
2139
- return {
2140
- minPriceRaw: numerator / scaledPriceBounds.maxPriceRaw,
2141
- maxPriceRaw: numerator / scaledPriceBounds.minPriceRaw
2142
- };
2143
- }
2144
- if (scaledPriceBounds.quoteToken.equal(token1.address)) {
2145
- const denominator = 10n ** (token0.decimals + token0.decimals);
2146
- return {
2147
- minPriceRaw: scaledPriceBounds.minPriceRaw * ConcentrateLiquidityCalculator.ONE_E18 / denominator,
2148
- maxPriceRaw: scaledPriceBounds.maxPriceRaw * ConcentrateLiquidityCalculator.ONE_E18 / denominator
2149
- };
2150
- }
2151
- throw new Error("unknown quote token");
2266
+ computeMaxAllocation(maxAvailableLiquidity) {
2267
+ const zeroForOne = maxAvailableLiquidity.reserveA.token.equal(this.token0.address);
2268
+ const reserve0 = zeroForOne ? maxAvailableLiquidity.reserveA : maxAvailableLiquidity.reserveB;
2269
+ const reserve1 = zeroForOne ? maxAvailableLiquidity.reserveB : maxAvailableLiquidity.reserveA;
2270
+ assert(reserve0.token.equal(this.token0.address), "provided reserve for unknown token");
2271
+ assert(reserve1.token.equal(this.token1.address), "provided reserve for unknown token");
2272
+ const { actualLt, actualGt } = computeLiquidityFromAmounts(reserve0.reserve, reserve1.reserve, this.spotPrice.toSqrt(), this.minPrice.toSqrt(), this.maxPrice.toSqrt());
2273
+ return {
2274
+ reserve0: TokenReserve.new({
2275
+ token: this.token0.address,
2276
+ reserve: actualLt
2277
+ }),
2278
+ reserve1: TokenReserve.new({
2279
+ token: this.token1.address,
2280
+ reserve: actualGt
2281
+ })
2282
+ };
2283
+ }
2284
+ toJSON() {
2285
+ return {
2286
+ minPrice: this.minPrice.toJSON(),
2287
+ spotPrice: this.spotPrice.toJSON(),
2288
+ maxPrice: this.maxPrice.toJSON()
2289
+ };
2152
2290
  }
2153
2291
  };
2154
2292
 
@@ -2157,8 +2295,10 @@ var ConcentrateLiquidityCalculator = class ConcentrateLiquidityCalculator {
2157
2295
  var concentrate_exports = {};
2158
2296
  __export(concentrate_exports, {
2159
2297
  ConcentrateGrowLiquidity2DArgs: () => ConcentrateGrowLiquidity2DArgs,
2160
- ConcentrateLiquidityCalculator: () => ConcentrateLiquidityCalculator,
2161
- ONE_E18: () => ONE_E18,
2298
+ ONE_E18: () => ONE_E18$1,
2299
+ Price: () => Price,
2300
+ PriceRange: () => PriceRange,
2301
+ TokenReserve: () => TokenReserve,
2162
2302
  bigintSqrt: () => bigintSqrt,
2163
2303
  computeBalances: () => computeBalances,
2164
2304
  computeLiquidityAndPrice: () => computeLiquidityAndPrice,
@@ -3064,11 +3204,188 @@ var PeggedSwapArgs = class PeggedSwapArgs {
3064
3204
  **/
3065
3205
  const peggedSwapGrowPriceRange2D = new Opcode(Symbol("PeggedSwap.peggedSwapGrowPriceRange2D"), PeggedSwapArgs.CODER);
3066
3206
 
3207
+ //#endregion
3208
+ //#region src/swap-vm/instructions/pegged-swap/pegged-swap-calculator/pegged-swap-calculator.ts
3209
+ const MARGINAL_PRICE_ONE$1 = 10n ** 18n;
3210
+ var PeggedSwapCalculator = class PeggedSwapCalculator {
3211
+ constructor(tokenA, tokenB) {
3212
+ this.tokenA = tokenA;
3213
+ this.tokenB = tokenB;
3214
+ assert(!tokenA.address.equal(tokenB.address), "tokens must be different");
3215
+ }
3216
+ get tokenLt() {
3217
+ return this.tokenA.address.lt(this.tokenB.address) ? this.tokenA : this.tokenB;
3218
+ }
3219
+ get tokenGt() {
3220
+ return this.tokenA.address.lt(this.tokenB.address) ? this.tokenB : this.tokenA;
3221
+ }
3222
+ static new(args) {
3223
+ return new PeggedSwapCalculator(args.tokenA, args.tokenB);
3224
+ }
3225
+ /**
3226
+ * Initial balances before deployment (`currentReserve = initialReserve`, u = v = 1).
3227
+ * Given spot price and one raw initial reserve, returns the other.
3228
+ */
3229
+ computeFixedAllocation(spotPrice, fixedReserveForToken, fixedReserve) {
3230
+ assert(fixedReserve > 0n, "fixed reserve must be positive");
3231
+ assert(spotPrice.matchesTokens(this.tokenLt.address, this.tokenGt.address), "spot price must match calculator token pair");
3232
+ const marginalE18 = spotPrice.toGtPerLtE18();
3233
+ if (fixedReserveForToken.equal(this.tokenLt.address)) return {
3234
+ reserveLt: fixedReserve,
3235
+ reserveGt: fixedReserve * marginalE18 / MARGINAL_PRICE_ONE$1
3236
+ };
3237
+ if (fixedReserveForToken.equal(this.tokenGt.address)) return {
3238
+ reserveLt: fixedReserve * MARGINAL_PRICE_ONE$1 / marginalE18,
3239
+ reserveGt: fixedReserve
3240
+ };
3241
+ throw new Error("fixedReserveForToken token must be one of the two pair tokens");
3242
+ }
3243
+ };
3244
+
3245
+ //#endregion
3246
+ //#region src/swap-vm/instructions/pegged-swap/pegged-swap-math/pegged-swap-math.ts
3247
+ /** Matches `PeggedSwapMath.ONE` in swap-vm. */
3248
+ const PEGGED_SWAP_ONE = 10n ** 27n;
3249
+ const MARGINAL_PRICE_ONE = 10n ** 18n;
3250
+ /**
3251
+ * Spot price tokenGt per tokenLt (raw) in 1e18 fixed-point.
3252
+ *
3253
+ * P = (Y₀/X₀) · (1/(2√u) + A) / (1/(2√v) + A) · (rateLt/rateGt)
3254
+ *
3255
+ * where u = x·ONE/X₀, v = y·ONE/Y₀, x/y are rate-adjusted Lt/Gt balances, A = `linearWidth`.
3256
+ */
3257
+ function peggedSwapMarginalGtPerLtE18(balanceLtNorm, balanceGtNorm, x0, y0, linearWidth, rateLt, rateGt) {
3258
+ const u = normalizeReserve(balanceLtNorm, x0);
3259
+ const v = normalizeReserve(balanceGtNorm, y0);
3260
+ assert(u !== 0n && v !== 0n, "PeggedSwapMath: reserves cannot be zero");
3261
+ const slopeLt = peggedSwapMarginalWeight(bigintSqrt(u * PEGGED_SWAP_ONE), linearWidth);
3262
+ const slopeGt = peggedSwapMarginalWeight(bigintSqrt(v * PEGGED_SWAP_ONE), linearWidth);
3263
+ return y0 * slopeLt * rateLt * MARGINAL_PRICE_ONE / (x0 * slopeGt * rateGt);
3264
+ }
3265
+ /**
3266
+ * u = x·ONE/X₀, v = y·ONE/Y₀ (x, y are rate-adjusted reserves).
3267
+ */
3268
+ function normalizeReserve(currentReserve, initialReserve) {
3269
+ return mulDiv(currentReserve, PEGGED_SWAP_ONE, initialReserve);
3270
+ }
3271
+ /**
3272
+ * Marginal weight `1/(2√u) + A` (Lt side) or `1/(2√v) + A` (Gt side), A = `linearWidth`.
3273
+ */
3274
+ function peggedSwapMarginalWeight(sqrtCoord, linearWidth) {
3275
+ return mulDiv(PEGGED_SWAP_ONE, PEGGED_SWAP_ONE, 2n * sqrtCoord) + linearWidth;
3276
+ }
3277
+ function mulDiv(a, b, c) {
3278
+ if (c === 0n) throw new Error("mulDiv: division by zero");
3279
+ return a * b / c;
3280
+ }
3281
+
3282
+ //#endregion
3283
+ //#region src/swap-vm/instructions/pegged-swap/price/pegged-price.ts
3284
+ const ONE_E18 = 10n ** 18n;
3285
+ var PeggedPrice = class PeggedPrice {
3286
+ constructor(gtPerLtRaw, tokenLt, tokenGt) {
3287
+ this.gtPerLtRaw = gtPerLtRaw;
3288
+ this.tokenLt = tokenLt;
3289
+ this.tokenGt = tokenGt;
3290
+ assert(gtPerLtRaw > 0n, "price must be positive");
3291
+ assert(tokenLt.address.lt(tokenGt.address), "internal pair order violated");
3292
+ }
3293
+ /**
3294
+ * Spot price from per-token `initialReserve` / `currentReserve` (raw, not rate-scaled) and `linearWidth`.
3295
+ * Use currentReserve = initialReserve to calculate the spot price before the strategy was deployed
3296
+ */
3297
+ static fromReserves(input) {
3298
+ assert(input.reserveA.currentReserve > 0n && input.reserveB.currentReserve > 0n, "current reserves should be positive");
3299
+ assert(input.reserveA.initialReserve > 0n && input.reserveB.initialReserve > 0n, "initial reserves should be positive");
3300
+ const zeroForOne = input.reserveA.address.lt(input.reserveB.address);
3301
+ const reserveLt = zeroForOne ? input.reserveA : input.reserveB;
3302
+ const reserveGt = zeroForOne ? input.reserveB : input.reserveA;
3303
+ const rateLt = resolveRate(reserveLt.decimals, reserveGt.decimals);
3304
+ const rateGt = resolveRate(reserveGt.decimals, reserveLt.decimals);
3305
+ const initialLtNorm = reserveLt.initialReserve * rateLt;
3306
+ const initialGtNorm = reserveGt.initialReserve * rateGt;
3307
+ const marginalE18 = peggedSwapMarginalGtPerLtE18(reserveLt.currentReserve * rateLt, reserveGt.currentReserve * rateGt, initialLtNorm, initialGtNorm, input.linearWidth, rateLt, rateGt);
3308
+ return PeggedPrice.fromGtPerLtE18(marginalE18, reserveLt, reserveGt);
3309
+ }
3310
+ /**
3311
+ * Human decimal string for **quote per 1 base**.
3312
+ */
3313
+ static fromHuman(price, pair) {
3314
+ assert(!pair.quoteToken.address.equal(pair.baseToken.address), "quote and base must be different tokens");
3315
+ const quoteToBase = pair.quoteToken.address.lt(pair.baseToken.address);
3316
+ const tokenLt = quoteToBase ? pair.quoteToken : pair.baseToken;
3317
+ const tokenGt = quoteToBase ? pair.baseToken : pair.quoteToken;
3318
+ const parsed = parseUnits(price.trim(), Number(pair.quoteToken.decimals));
3319
+ const ltDecimals = BigInt(tokenLt.decimals);
3320
+ const gtDecimals = BigInt(tokenGt.decimals);
3321
+ const marginalE18 = quoteToBase ? 10n ** (gtDecimals + 18n + ltDecimals) / (parsed * 10n ** gtDecimals) : parsed * ONE_E18 / 10n ** ltDecimals;
3322
+ return PeggedPrice.fromGtPerLtE18(marginalE18, tokenLt, tokenGt);
3323
+ }
3324
+ static fromJSON(input) {
3325
+ const tokenLt = {
3326
+ address: new Address$1(input.tokenLt.address),
3327
+ decimals: Number(input.tokenLt.decimals)
3328
+ };
3329
+ const tokenGt = {
3330
+ address: new Address$1(input.tokenGt.address),
3331
+ decimals: Number(input.tokenGt.decimals)
3332
+ };
3333
+ assert(tokenLt.address.lt(tokenGt.address), "tokenLt address must be less than tokenGt (canonical order)");
3334
+ return new PeggedPrice(BigInt(input.gtPerLtRaw), tokenLt, tokenGt);
3335
+ }
3336
+ static fromGtPerLtE18(marginalGtPerLtE18, tokenLt, tokenGt) {
3337
+ assert(marginalGtPerLtE18 > 0n, "marginal rate must be positive");
3338
+ const scale = BigInt(tokenLt.decimals + tokenGt.decimals);
3339
+ const gtPerLtRaw = marginalGtPerLtE18 * 10n ** scale / ONE_E18;
3340
+ return new PeggedPrice(gtPerLtRaw, tokenLt, tokenGt);
3341
+ }
3342
+ matchesTokens(tokenA, tokenB) {
3343
+ return tokenA.equal(this.tokenLt.address) && tokenB.equal(this.tokenGt.address) || tokenA.equal(this.tokenGt.address) && tokenB.equal(this.tokenLt.address);
3344
+ }
3345
+ equals(other) {
3346
+ return this.gtPerLtRaw === other.gtPerLtRaw && this.tokenLt.address.equal(other.tokenLt.address) && this.tokenGt.address.equal(other.tokenGt.address) && BigInt(this.tokenLt.decimals) === BigInt(other.tokenLt.decimals) && BigInt(this.tokenGt.decimals) === BigInt(other.tokenGt.decimals);
3347
+ }
3348
+ /**
3349
+ * Decimal string for **quote per 1 base**; rounded half-up to quote token decimals.
3350
+ */
3351
+ toHuman(quoteToken) {
3352
+ assert(quoteToken.equal(this.tokenLt.address) || quoteToken.equal(this.tokenGt.address), "quote token must be one of the pair tokens");
3353
+ const isQuoteLt = quoteToken.equal(this.tokenLt.address);
3354
+ const quoteDecimals = isQuoteLt ? this.tokenLt.decimals : this.tokenGt.decimals;
3355
+ const ltDecimals = BigInt(this.tokenLt.decimals);
3356
+ const gtDecimals = BigInt(this.tokenGt.decimals);
3357
+ const marginalE18 = this.toGtPerLtE18();
3358
+ const scaled = quoteToken.equal(this.tokenGt.address) ? marginalE18 * 10n ** ltDecimals / ONE_E18 : 10n ** (gtDecimals + 18n + ltDecimals) / (marginalE18 * 10n ** gtDecimals);
3359
+ const full = formatUnits(scaled, Number(quoteDecimals));
3360
+ return truncateHumanDecimalString(full, Number(quoteDecimals));
3361
+ }
3362
+ /** Marginal gt-per-lt rate in 1e18 fixed-point. */
3363
+ toGtPerLtE18() {
3364
+ const scale = BigInt(this.tokenLt.decimals + this.tokenGt.decimals);
3365
+ return this.gtPerLtRaw * ONE_E18 / 10n ** scale;
3366
+ }
3367
+ toJSON() {
3368
+ return {
3369
+ gtPerLtRaw: this.gtPerLtRaw.toString(),
3370
+ tokenLt: {
3371
+ address: this.tokenLt.address.toString(),
3372
+ decimals: String(this.tokenLt.decimals)
3373
+ },
3374
+ tokenGt: {
3375
+ address: this.tokenGt.address.toString(),
3376
+ decimals: String(this.tokenGt.decimals)
3377
+ }
3378
+ };
3379
+ }
3380
+ };
3381
+
3067
3382
  //#endregion
3068
3383
  //#region src/swap-vm/instructions/pegged-swap/index.ts
3069
3384
  var pegged_swap_exports = {};
3070
3385
  __export(pegged_swap_exports, {
3386
+ PeggedPrice: () => PeggedPrice,
3071
3387
  PeggedSwapArgs: () => PeggedSwapArgs,
3388
+ PeggedSwapCalculator: () => PeggedSwapCalculator,
3072
3389
  peggedSwapGrowPriceRange2D: () => peggedSwapGrowPriceRange2D
3073
3390
  });
3074
3391
 
@@ -3174,6 +3491,7 @@ __export(instructions_exports, {
3174
3491
  aquaInstructions: () => aquaInstructions,
3175
3492
  balances: () => balances_exports,
3176
3493
  baseFeeAdjuster: () => base_fee_adjuster_exports,
3494
+ bigintSqrt: () => bigintSqrt,
3177
3495
  concentrate: () => concentrate_exports,
3178
3496
  controls: () => controls_exports,
3179
3497
  decay: () => decay_exports,
@@ -3186,6 +3504,7 @@ __export(instructions_exports, {
3186
3504
  oraclePriceAdjuster: () => oracle_price_adjuster_exports,
3187
3505
  peggedSwap: () => pegged_swap_exports,
3188
3506
  stableSwap: () => pegged_swap_exports,
3507
+ truncateHumanDecimalString: () => truncateHumanDecimalString,
3189
3508
  twapSwap: () => twap_swap_exports,
3190
3509
  xycSwap: () => xyc_swap_exports
3191
3510
  });