@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.
- package/dist/index.js +454 -135
- package/dist/index.mjs +455 -136
- package/dist/swap-vm/instructions/concentrate/concentrate-liquidity-calculator/types.d.mts +9 -21
- package/dist/swap-vm/instructions/concentrate/concentrate-liquidity-calculator/types.d.ts +9 -21
- package/dist/swap-vm/instructions/concentrate/index.d.mts +8 -3
- package/dist/swap-vm/instructions/concentrate/index.d.ts +8 -3
- package/dist/swap-vm/instructions/concentrate/price/index.d.mts +3 -0
- package/dist/swap-vm/instructions/concentrate/price/index.d.ts +3 -0
- package/dist/swap-vm/instructions/concentrate/price/price.d.mts +45 -0
- package/dist/swap-vm/instructions/concentrate/price/price.d.ts +45 -0
- package/dist/swap-vm/instructions/concentrate/price/types.d.mts +21 -0
- package/dist/swap-vm/instructions/concentrate/price/types.d.ts +21 -0
- package/dist/swap-vm/instructions/concentrate/price-range/index.d.mts +2 -0
- package/dist/swap-vm/instructions/concentrate/price-range/index.d.ts +2 -0
- package/dist/swap-vm/instructions/concentrate/price-range/price-range.d.mts +18 -0
- package/dist/swap-vm/instructions/concentrate/price-range/price-range.d.ts +18 -0
- package/dist/swap-vm/instructions/concentrate/price-range/types.d.mts +26 -0
- package/dist/swap-vm/instructions/concentrate/price-range/types.d.ts +26 -0
- package/dist/swap-vm/instructions/concentrate/token-reserve/index.d.mts +2 -0
- package/dist/swap-vm/instructions/concentrate/token-reserve/index.d.ts +2 -0
- package/dist/swap-vm/instructions/concentrate/token-reserve/token-reserve.d.mts +10 -0
- package/dist/swap-vm/instructions/concentrate/token-reserve/token-reserve.d.ts +10 -0
- package/dist/swap-vm/instructions/concentrate/token-reserve/types.d.mts +10 -0
- package/dist/swap-vm/instructions/concentrate/token-reserve/types.d.ts +10 -0
- package/dist/swap-vm/instructions/index.d.mts +1 -0
- package/dist/swap-vm/instructions/index.d.ts +1 -0
- package/dist/swap-vm/instructions/pegged-swap/index.d.mts +4 -0
- package/dist/swap-vm/instructions/pegged-swap/index.d.ts +4 -0
- package/dist/swap-vm/instructions/pegged-swap/pegged-swap-calculator/index.d.mts +2 -0
- package/dist/swap-vm/instructions/pegged-swap/pegged-swap-calculator/index.d.ts +2 -0
- package/dist/swap-vm/instructions/pegged-swap/pegged-swap-calculator/pegged-swap-calculator.d.mts +16 -0
- package/dist/swap-vm/instructions/pegged-swap/pegged-swap-calculator/pegged-swap-calculator.d.ts +16 -0
- package/dist/swap-vm/instructions/pegged-swap/pegged-swap-calculator/types.d.mts +9 -0
- package/dist/swap-vm/instructions/pegged-swap/pegged-swap-calculator/types.d.ts +9 -0
- package/dist/swap-vm/instructions/pegged-swap/pegged-swap-math/pegged-swap-math.d.mts +18 -0
- package/dist/swap-vm/instructions/pegged-swap/pegged-swap-math/pegged-swap-math.d.ts +18 -0
- package/dist/swap-vm/instructions/pegged-swap/price/index.d.mts +2 -0
- package/dist/swap-vm/instructions/pegged-swap/price/index.d.ts +2 -0
- package/dist/swap-vm/instructions/pegged-swap/price/pegged-price.d.mts +28 -0
- package/dist/swap-vm/instructions/pegged-swap/price/pegged-price.d.ts +28 -0
- package/dist/swap-vm/instructions/pegged-swap/price/types.d.mts +30 -0
- package/dist/swap-vm/instructions/pegged-swap/price/types.d.ts +30 -0
- package/dist/swap-vm/instructions/utils/index.d.mts +2 -0
- package/dist/swap-vm/instructions/utils/index.d.ts +2 -0
- package/dist/swap-vm/instructions/utils/truncate-human-decimal-string.d.mts +9 -0
- package/dist/swap-vm/instructions/utils/truncate-human-decimal-string.d.ts +9 -0
- package/package.json +4 -4
- package/dist/swap-vm/instructions/concentrate/concentrate-liquidity-calculator/concentrate-liquidity-calculator.d.mts +0 -61
- package/dist/swap-vm/instructions/concentrate/concentrate-liquidity-calculator/concentrate-liquidity-calculator.d.ts +0 -61
- /package/dist/swap-vm/instructions/{concentrate → utils}/bigint-sqrt.d.mts +0 -0
- /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/
|
|
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/
|
|
2009
|
+
//#region src/swap-vm/instructions/utils/truncate-human-decimal-string.ts
|
|
2010
2010
|
/**
|
|
2011
|
-
*
|
|
2012
|
-
*
|
|
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
|
-
*
|
|
2016
|
-
*
|
|
2017
|
-
*
|
|
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
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
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
|
-
*
|
|
2063
|
+
* Human decimal string for **quote per 1 base**`.
|
|
2027
2064
|
*/
|
|
2028
|
-
|
|
2029
|
-
|
|
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
|
-
*
|
|
2120
|
+
* Raw price `P` with 1e18 fixed-point (`(sqrtP^2) / 1e18`), matching typical on-chain use.
|
|
2033
2121
|
*/
|
|
2034
|
-
|
|
2035
|
-
return this.
|
|
2122
|
+
toRaw() {
|
|
2123
|
+
return this.sqrtP * this.sqrtP / ONE_E18$2;
|
|
2036
2124
|
}
|
|
2037
|
-
|
|
2038
|
-
return
|
|
2125
|
+
toSqrt() {
|
|
2126
|
+
return this.sqrtP;
|
|
2039
2127
|
}
|
|
2040
2128
|
/**
|
|
2041
|
-
*
|
|
2042
|
-
*
|
|
2043
|
-
*
|
|
2044
|
-
*
|
|
2045
|
-
*
|
|
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
|
-
|
|
2049
|
-
|
|
2050
|
-
const
|
|
2051
|
-
const
|
|
2052
|
-
const
|
|
2053
|
-
const
|
|
2054
|
-
const
|
|
2055
|
-
const
|
|
2056
|
-
|
|
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
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
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
|
-
*
|
|
2067
|
-
*
|
|
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
|
-
|
|
2072
|
-
const
|
|
2073
|
-
const
|
|
2074
|
-
const
|
|
2075
|
-
|
|
2076
|
-
|
|
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
|
-
|
|
2079
|
-
|
|
2080
|
-
sqrtPriceMax,
|
|
2081
|
-
token0Reserve: actualLt,
|
|
2082
|
-
token1Reserve: actualGt
|
|
2193
|
+
token: this.token.toString(),
|
|
2194
|
+
reserve: this.reserve.toString()
|
|
2083
2195
|
};
|
|
2084
2196
|
}
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
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
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
const
|
|
2105
|
-
const
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
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
|
-
|
|
2125
|
-
const
|
|
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
|
-
|
|
2128
|
-
|
|
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
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
}
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
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
|
-
|
|
2161
|
-
|
|
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
|
});
|