removed console logs
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
// SPDX-License-Identifier: UNLICENSED
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
pragma solidity ^0.8.30;
|
pragma solidity ^0.8.30;
|
||||||
|
|
||||||
import "forge-std/console2.sol";
|
|
||||||
import "@abdk/ABDKMath64x64.sol";
|
import "@abdk/ABDKMath64x64.sol";
|
||||||
|
|
||||||
/// @notice Stabilized LMSR library with incremental exp(z) caching for gas efficiency.
|
/// @notice Stabilized LMSR library with incremental exp(z) caching for gas efficiency.
|
||||||
@@ -41,21 +40,11 @@ library LMSRStabilized {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int128 total = _computeSizeMetric(s.qInternal);
|
int128 total = _computeSizeMetric(s.qInternal);
|
||||||
console2.log("total (internal 64.64)");
|
|
||||||
console2.logInt(total);
|
|
||||||
require(total > int128(0), "LMSR: total zero");
|
require(total > int128(0), "LMSR: total zero");
|
||||||
|
|
||||||
console2.log("LMSR.init: start");
|
|
||||||
console2.log("nAssets", s.nAssets);
|
|
||||||
console2.log("qInternal.length", s.qInternal.length);
|
|
||||||
|
|
||||||
// Set kappa directly (caller provides kappa)
|
// Set kappa directly (caller provides kappa)
|
||||||
s.kappa = kappa;
|
s.kappa = kappa;
|
||||||
console2.log("kappa (64x64)");
|
|
||||||
console2.logInt(s.kappa);
|
|
||||||
require(s.kappa > int128(0), "LMSR: kappa>0");
|
require(s.kappa > int128(0), "LMSR: kappa>0");
|
||||||
|
|
||||||
console2.log("LMSR.init: done");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------
|
/* --------------------
|
||||||
@@ -125,49 +114,29 @@ library LMSRStabilized {
|
|||||||
// push the marginal price p_i/p_j beyond the limit; if so, truncate `a`.
|
// push the marginal price p_i/p_j beyond the limit; if so, truncate `a`.
|
||||||
// Marginal price ratio evolves as r(t) = r0 * exp(t/b) (since e_i multiplies by exp(t/b))
|
// Marginal price ratio evolves as r(t) = r0 * exp(t/b) (since e_i multiplies by exp(t/b))
|
||||||
if (limitPrice > int128(0)) {
|
if (limitPrice > int128(0)) {
|
||||||
console2.log("\n=== LimitPrice Logic Debug ===");
|
|
||||||
console2.log("Received limitPrice (64x64):");
|
|
||||||
console2.logInt(limitPrice);
|
|
||||||
|
|
||||||
console2.log("Current price ratio r0 (e_i/e_j, 64x64):");
|
|
||||||
console2.logInt(r0);
|
|
||||||
|
|
||||||
// r0 must be positive; if r0 == 0 then no risk of exceeding limit by increasing r.
|
// r0 must be positive; if r0 == 0 then no risk of exceeding limit by increasing r.
|
||||||
require(r0 >= int128(0), "LMSR: r0<0");
|
require(r0 >= int128(0), "LMSR: r0<0");
|
||||||
if (r0 == int128(0)) {
|
if (r0 == int128(0)) {
|
||||||
console2.log("r0 == 0 (input asset has zero weight), no limit truncation needed");
|
// console2.log("r0 == 0 (input asset has zero weight), no limit truncation needed");
|
||||||
} else {
|
} else {
|
||||||
// If limitPrice <= current price, we revert (caller must choose a limit > current price to allow any fill)
|
// If limitPrice <= current price, we revert (caller must choose a limit > current price to allow any fill)
|
||||||
if (limitPrice <= r0) {
|
require(limitPrice > r0, "LMSR: limitPrice <= current price");
|
||||||
console2.log("Limit price is <= current price: reverting");
|
|
||||||
revert("LMSR: limitPrice <= current price");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute a_limit directly from ln(limit / r0): a_limit = b * ln(limit / r0)
|
// Compute a_limit directly from ln(limit / r0): a_limit = b * ln(limit / r0)
|
||||||
int128 ratioLimitOverR0 = limitPrice.div(r0);
|
int128 ratioLimitOverR0 = limitPrice.div(r0);
|
||||||
console2.log("limitPrice/r0 (64x64):");
|
|
||||||
console2.logInt(ratioLimitOverR0);
|
|
||||||
require(ratioLimitOverR0 > int128(0), "LMSR: ratio<=0");
|
require(ratioLimitOverR0 > int128(0), "LMSR: ratio<=0");
|
||||||
|
|
||||||
int128 aLimitOverB = _ln(ratioLimitOverR0); // > 0
|
int128 aLimitOverB = _ln(ratioLimitOverR0); // > 0
|
||||||
console2.log("ln(limitPrice/r0) (64x64):");
|
|
||||||
console2.logInt(aLimitOverB);
|
|
||||||
|
|
||||||
// aLimit = b * aLimitOverB
|
// aLimit = b * aLimitOverB
|
||||||
int128 aLimit64 = b.mul(aLimitOverB);
|
int128 aLimit64 = b.mul(aLimitOverB);
|
||||||
console2.log("aLimit in 64x64 format:");
|
|
||||||
console2.logInt(aLimit64);
|
|
||||||
|
|
||||||
// If computed aLimit is less than the requested a, use the truncated value.
|
// If computed aLimit is less than the requested a, use the truncated value.
|
||||||
if (aLimit64 < a) {
|
if (aLimit64 < a) {
|
||||||
console2.log("TRUNCATING: a reduced from 64.64 value");
|
|
||||||
console2.logInt(a);
|
|
||||||
console2.log("to 64.64 value");
|
|
||||||
console2.logInt(aLimit64);
|
|
||||||
amountIn = aLimit64; // Store the truncated input amount
|
amountIn = aLimit64; // Store the truncated input amount
|
||||||
a = aLimit64; // Use truncated amount for calculations
|
a = aLimit64; // Use truncated amount for calculations
|
||||||
} else {
|
} else {
|
||||||
console2.log("Not truncating: aLimit64 >= a");
|
// console2.log("Not truncating: aLimit64 >= a");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,56 +146,24 @@ library LMSRStabilized {
|
|||||||
// Protect exp from enormous inputs (consistent with recenter thresholds)
|
// Protect exp from enormous inputs (consistent with recenter thresholds)
|
||||||
require(aOverB <= EXP_LIMIT, "LMSR: a/b too large (would overflow exp)");
|
require(aOverB <= EXP_LIMIT, "LMSR: a/b too large (would overflow exp)");
|
||||||
|
|
||||||
console2.log("\n=== AmountOut Calculation Debug ===");
|
|
||||||
console2.log("Input amount (64.64):");
|
|
||||||
console2.logInt(a);
|
|
||||||
console2.log("a/b (64x64):");
|
|
||||||
console2.logInt(aOverB);
|
|
||||||
|
|
||||||
// Use the closed-form fee-free formula:
|
// Use the closed-form fee-free formula:
|
||||||
// y = b * ln(1 + r0 * (1 - exp(-a/b)))
|
// y = b * ln(1 + r0 * (1 - exp(-a/b)))
|
||||||
console2.log("r0_for_calc (e_i/e_j):");
|
|
||||||
console2.logInt(r0);
|
|
||||||
|
|
||||||
int128 expNeg = _exp(aOverB.neg()); // exp(-a/b)
|
int128 expNeg = _exp(aOverB.neg()); // exp(-a/b)
|
||||||
console2.log("exp(-a/b):");
|
|
||||||
console2.logInt(expNeg);
|
|
||||||
|
|
||||||
int128 oneMinusExpNeg = ONE.sub(expNeg);
|
int128 oneMinusExpNeg = ONE.sub(expNeg);
|
||||||
console2.log("1 - exp(-a/b):");
|
|
||||||
console2.logInt(oneMinusExpNeg);
|
|
||||||
|
|
||||||
int128 inner = ONE.add(r0.mul(oneMinusExpNeg));
|
int128 inner = ONE.add(r0.mul(oneMinusExpNeg));
|
||||||
console2.log("inner = 1 + r0 * (1 - exp(-a/b)):");
|
|
||||||
console2.logInt(inner);
|
|
||||||
|
|
||||||
// If inner <= 0 then cap output to the current balance q_j (cannot withdraw more than q_j)
|
// If inner <= 0 then cap output to the current balance q_j (cannot withdraw more than q_j)
|
||||||
if (inner <= int128(0)) {
|
if (inner <= int128(0)) {
|
||||||
console2.log("WARNING: inner <= 0, capping output to balance q_j");
|
|
||||||
int128 qj64 = s.qInternal[j];
|
int128 qj64 = s.qInternal[j];
|
||||||
console2.log("Capped output (64.64):");
|
|
||||||
console2.logInt(qj64);
|
|
||||||
return (amountIn, qj64);
|
return (amountIn, qj64);
|
||||||
}
|
}
|
||||||
|
|
||||||
int128 lnInner = _ln(inner);
|
int128 lnInner = _ln(inner);
|
||||||
console2.log("ln(inner):");
|
|
||||||
console2.logInt(lnInner);
|
|
||||||
|
|
||||||
int128 b_lnInner = b.mul(lnInner);
|
int128 b_lnInner = b.mul(lnInner);
|
||||||
console2.log("b*ln(inner):");
|
|
||||||
console2.logInt(b_lnInner);
|
|
||||||
|
|
||||||
amountOut = b_lnInner;
|
amountOut = b_lnInner;
|
||||||
console2.log("amountOut = b*ln(inner):");
|
|
||||||
console2.logInt(amountOut);
|
|
||||||
|
|
||||||
console2.log("amountOut (final 64.64 amount):");
|
|
||||||
console2.logInt(amountOut);
|
|
||||||
|
|
||||||
// Safety check
|
// Safety check
|
||||||
if (amountOut <= 0) {
|
if (amountOut <= 0) {
|
||||||
console2.log("WARNING: x64 <= 0, returning 0");
|
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,60 +202,37 @@ library LMSRStabilized {
|
|||||||
// Compute r0 = exp((q_i - q_j) / b) directly using invB
|
// Compute r0 = exp((q_i - q_j) / b) directly using invB
|
||||||
int128 r0 = _exp(s.qInternal[i].sub(s.qInternal[j]).mul(invB));
|
int128 r0 = _exp(s.qInternal[i].sub(s.qInternal[j]).mul(invB));
|
||||||
|
|
||||||
console2.log("\n=== Max Input/Output Calculation ===");
|
|
||||||
console2.log("Limit price (64x64):");
|
|
||||||
console2.logInt(limitPrice);
|
|
||||||
console2.log("Current price ratio r0 (e_i/e_j, 64x64):");
|
|
||||||
console2.logInt(r0);
|
|
||||||
|
|
||||||
// Mirror swapAmountsForExactInput behavior: treat invalid r0 as an error condition.
|
// Mirror swapAmountsForExactInput behavior: treat invalid r0 as an error condition.
|
||||||
// Revert if r0 is non-positive (no finite trade under a price limit).
|
// Revert if r0 is non-positive (no finite trade under a price limit).
|
||||||
require(r0 > int128(0), "LMSR: r0<=0");
|
require(r0 > int128(0), "LMSR: r0<=0");
|
||||||
|
|
||||||
// If current price already exceeds or equals limit, revert the same way swapAmountsForExactInput does.
|
// If current price already exceeds or equals limit, revert the same way swapAmountsForExactInput does.
|
||||||
if (r0 >= limitPrice) {
|
if (r0 >= limitPrice) {
|
||||||
console2.log("Limit price is <= current price: reverting");
|
|
||||||
revert("LMSR: limitPrice <= current price");
|
revert("LMSR: limitPrice <= current price");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the price change factor: limitPrice/r0
|
// Calculate the price change factor: limitPrice/r0
|
||||||
int128 priceChangeFactor = limitPrice.div(r0);
|
int128 priceChangeFactor = limitPrice.div(r0);
|
||||||
console2.log("Price change factor (limitPrice/r0):");
|
|
||||||
console2.logInt(priceChangeFactor);
|
|
||||||
|
|
||||||
// ln(priceChangeFactor) gives us the maximum allowed delta in the exponent
|
// ln(priceChangeFactor) gives us the maximum allowed delta in the exponent
|
||||||
int128 maxDeltaExponent = _ln(priceChangeFactor);
|
int128 maxDeltaExponent = _ln(priceChangeFactor);
|
||||||
console2.log("Max delta exponent ln(priceChangeFactor):");
|
|
||||||
console2.logInt(maxDeltaExponent);
|
|
||||||
|
|
||||||
// Maximum input capable of reaching the price limit:
|
// Maximum input capable of reaching the price limit:
|
||||||
// x_max = b * ln(limitPrice / r0)
|
// x_max = b * ln(limitPrice / r0)
|
||||||
int128 amountInMax = b.mul(maxDeltaExponent);
|
int128 amountInMax = b.mul(maxDeltaExponent);
|
||||||
console2.log("Max input to reach limit (64.64):");
|
|
||||||
console2.logInt(amountInMax);
|
|
||||||
|
|
||||||
// The maximum output y corresponding to that input:
|
// The maximum output y corresponding to that input:
|
||||||
// y = b * ln(1 + (e_i/e_j) * (1 - exp(-x_max/b)))
|
// y = b * ln(1 + (e_i/e_j) * (1 - exp(-x_max/b)))
|
||||||
int128 expTerm = ONE.sub(_exp(maxDeltaExponent.neg()));
|
int128 expTerm = ONE.sub(_exp(maxDeltaExponent.neg()));
|
||||||
console2.log("1 - exp(-maxDeltaExponent):");
|
|
||||||
console2.logInt(expTerm);
|
|
||||||
|
|
||||||
int128 innerTerm = r0.mul(expTerm);
|
int128 innerTerm = r0.mul(expTerm);
|
||||||
console2.log("e_i/e_j * expTerm:");
|
|
||||||
console2.logInt(innerTerm);
|
|
||||||
|
|
||||||
int128 lnTerm = _ln(ONE.add(innerTerm));
|
int128 lnTerm = _ln(ONE.add(innerTerm));
|
||||||
console2.log("ln(1 + innerTerm):");
|
|
||||||
console2.logInt(lnTerm);
|
|
||||||
|
|
||||||
int128 maxOutput = b.mul(lnTerm);
|
int128 maxOutput = b.mul(lnTerm);
|
||||||
console2.log("Max output (b * lnTerm):");
|
|
||||||
console2.logInt(maxOutput);
|
|
||||||
|
|
||||||
// Current balance of asset j (in 64.64)
|
// Current balance of asset j (in 64.64)
|
||||||
int128 qj64 = s.qInternal[j];
|
int128 qj64 = s.qInternal[j];
|
||||||
console2.log("Current j balance (64.64):");
|
|
||||||
console2.logInt(qj64);
|
|
||||||
|
|
||||||
// Initialize outputs to the computed maxima
|
// Initialize outputs to the computed maxima
|
||||||
amountIn = amountInMax;
|
amountIn = amountInMax;
|
||||||
@@ -326,7 +240,6 @@ library LMSRStabilized {
|
|||||||
|
|
||||||
// If the calculated maximum output exceeds the balance, cap output and solve for input.
|
// If the calculated maximum output exceeds the balance, cap output and solve for input.
|
||||||
if (maxOutput > qj64) {
|
if (maxOutput > qj64) {
|
||||||
console2.log("Max output exceeds balance, capping to balance");
|
|
||||||
amountOut = qj64;
|
amountOut = qj64;
|
||||||
|
|
||||||
// Solve inverse relation for input given capped output:
|
// Solve inverse relation for input given capped output:
|
||||||
@@ -336,19 +249,12 @@ library LMSRStabilized {
|
|||||||
// a = -b * ln( (r0 + 1 - E) / r0 ) = b * ln( r0 / (r0 + 1 - E) )
|
// a = -b * ln( (r0 + 1 - E) / r0 ) = b * ln( r0 / (r0 + 1 - E) )
|
||||||
int128 E = _exp(amountOut.mul(invB)); // exp(y/b)
|
int128 E = _exp(amountOut.mul(invB)); // exp(y/b)
|
||||||
int128 rhs = r0.add(ONE).sub(E); // r0 + 1 - E
|
int128 rhs = r0.add(ONE).sub(E); // r0 + 1 - E
|
||||||
console2.log("E = exp(y/b):");
|
|
||||||
console2.logInt(E);
|
|
||||||
console2.log("rhs = r0 + 1 - E:");
|
|
||||||
console2.logInt(rhs);
|
|
||||||
|
|
||||||
// If rhs <= 0 due to numerical issues, fall back to amountInMax
|
// If rhs <= 0 due to numerical issues, fall back to amountInMax
|
||||||
if (rhs <= int128(0)) {
|
if (rhs <= int128(0)) {
|
||||||
console2.log("Numerical issue solving inverse; using amountInMax as fallback");
|
|
||||||
amountIn = amountInMax;
|
amountIn = amountInMax;
|
||||||
} else {
|
} else {
|
||||||
amountIn = b.mul(_ln(r0.div(rhs)));
|
amountIn = b.mul(_ln(r0.div(rhs)));
|
||||||
console2.log("Computed input required for capped output (64.64):");
|
|
||||||
console2.logInt(amountIn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,19 +580,9 @@ library LMSRStabilized {
|
|||||||
require(amountIn > int128(0), "LMSR: amountIn <= 0");
|
require(amountIn > int128(0), "LMSR: amountIn <= 0");
|
||||||
require(amountOut > int128(0), "LMSR: amountOut <= 0");
|
require(amountOut > int128(0), "LMSR: amountOut <= 0");
|
||||||
|
|
||||||
console2.log("\n=== Applying Swap ===");
|
|
||||||
console2.log("Input asset:", i);
|
|
||||||
console2.log("Output asset:", j);
|
|
||||||
console2.log("Amount in (64.64):");
|
|
||||||
console2.logInt(amountIn);
|
|
||||||
console2.log("Amount out (64.64):");
|
|
||||||
console2.logInt(amountOut);
|
|
||||||
|
|
||||||
// Update internal balances
|
// Update internal balances
|
||||||
s.qInternal[i] = s.qInternal[i].add(amountIn);
|
s.qInternal[i] = s.qInternal[i].add(amountIn);
|
||||||
s.qInternal[j] = s.qInternal[j].sub(amountOut);
|
s.qInternal[j] = s.qInternal[j].sub(amountOut);
|
||||||
|
|
||||||
console2.log("=== Swap Applied (qInternal updated) ===\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -697,19 +593,12 @@ library LMSRStabilized {
|
|||||||
function updateForProportionalChange(State storage s, int128[] memory newQInternal) internal {
|
function updateForProportionalChange(State storage s, int128[] memory newQInternal) internal {
|
||||||
require(newQInternal.length == s.nAssets, "LMSR: length mismatch");
|
require(newQInternal.length == s.nAssets, "LMSR: length mismatch");
|
||||||
|
|
||||||
console2.log("LMSR.updateForProportionalChange: start");
|
|
||||||
|
|
||||||
// Compute new total for validation
|
// Compute new total for validation
|
||||||
int128 newTotal = _computeSizeMetric(newQInternal);
|
int128 newTotal = _computeSizeMetric(newQInternal);
|
||||||
console2.log("new total");
|
|
||||||
console2.logInt(newTotal);
|
|
||||||
|
|
||||||
require(newTotal > int128(0), "LMSR: new total zero");
|
require(newTotal > int128(0), "LMSR: new total zero");
|
||||||
|
|
||||||
// With kappa formulation, b automatically scales with pool size
|
// With kappa formulation, b automatically scales with pool size
|
||||||
int128 newB = s.kappa.mul(newTotal);
|
int128 newB = s.kappa.mul(newTotal);
|
||||||
console2.log("new effective b");
|
|
||||||
console2.logInt(newB);
|
|
||||||
|
|
||||||
// Update the cached qInternal with new values
|
// Update the cached qInternal with new values
|
||||||
for (uint i = 0; i < s.nAssets; ) {
|
for (uint i = 0; i < s.nAssets; ) {
|
||||||
@@ -717,7 +606,6 @@ library LMSRStabilized {
|
|||||||
unchecked { i++; }
|
unchecked { i++; }
|
||||||
}
|
}
|
||||||
|
|
||||||
console2.log("LMSR.updateForProportionalChange: end");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @notice Price-share of asset i: exp(z_i) / Z (64.64)
|
/// @notice Price-share of asset i: exp(z_i) / Z (64.64)
|
||||||
@@ -904,8 +792,6 @@ library LMSRStabilized {
|
|||||||
/// @notice De-initialize the LMSR state when the entire pool is drained.
|
/// @notice De-initialize the LMSR state when the entire pool is drained.
|
||||||
/// This resets the state so the pool can be re-initialized by init(...) on next mint.
|
/// This resets the state so the pool can be re-initialized by init(...) on next mint.
|
||||||
function deinit(State storage s) internal {
|
function deinit(State storage s) internal {
|
||||||
console2.log("LMSR.deinit: resetting state");
|
|
||||||
|
|
||||||
// Reset core state
|
// Reset core state
|
||||||
s.nAssets = 0;
|
s.nAssets = 0;
|
||||||
s.kappa = int128(0);
|
s.kappa = int128(0);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// SPDX-License-Identifier: UNLICENSED
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
pragma solidity ^0.8.30;
|
pragma solidity ^0.8.30;
|
||||||
|
|
||||||
import "forge-std/console2.sol";
|
|
||||||
import "@abdk/ABDKMath64x64.sol";
|
import "@abdk/ABDKMath64x64.sol";
|
||||||
import "./LMSRStabilized.sol";
|
import "./LMSRStabilized.sol";
|
||||||
|
|
||||||
@@ -40,7 +39,6 @@ library LMSRStabilizedBalancedPair {
|
|||||||
|
|
||||||
// If not exactly a two-asset pool, fall back to the general routine.
|
// If not exactly a two-asset pool, fall back to the general routine.
|
||||||
if (s.nAssets != 2) {
|
if (s.nAssets != 2) {
|
||||||
console2.log('balanced2: fallback nAssets!=n2');
|
|
||||||
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +46,6 @@ library LMSRStabilizedBalancedPair {
|
|||||||
int128 b = LMSRStabilized._computeB(s);
|
int128 b = LMSRStabilized._computeB(s);
|
||||||
// Guard: if b not positive, fallback to exact implementation (will revert there if necessary)
|
// Guard: if b not positive, fallback to exact implementation (will revert there if necessary)
|
||||||
if (!(b > int128(0))) {
|
if (!(b > int128(0))) {
|
||||||
console2.log("balanced2: fallback b<=0");
|
|
||||||
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
||||||
}
|
}
|
||||||
int128 invB = ABDKMath64x64.div(ONE, b);
|
int128 invB = ABDKMath64x64.div(ONE, b);
|
||||||
@@ -58,8 +55,6 @@ library LMSRStabilizedBalancedPair {
|
|||||||
|
|
||||||
// If a positive limitPrice is given, attempt a 2-asset near-parity polynomial solution
|
// If a positive limitPrice is given, attempt a 2-asset near-parity polynomial solution
|
||||||
if (limitPrice > int128(0)) {
|
if (limitPrice > int128(0)) {
|
||||||
console2.log("balanced2: handling limitPrice via small-delta approx");
|
|
||||||
|
|
||||||
// Approximate r0 = exp(delta) using Taylor: 1 + δ + δ^2/2 + δ^3/6
|
// Approximate r0 = exp(delta) using Taylor: 1 + δ + δ^2/2 + δ^3/6
|
||||||
int128 delta_sq = delta.mul(delta);
|
int128 delta_sq = delta.mul(delta);
|
||||||
int128 delta_cu = delta_sq.mul(delta);
|
int128 delta_cu = delta_sq.mul(delta);
|
||||||
@@ -68,19 +63,13 @@ library LMSRStabilizedBalancedPair {
|
|||||||
.add(delta_sq.div(ABDKMath64x64.fromUInt(2)))
|
.add(delta_sq.div(ABDKMath64x64.fromUInt(2)))
|
||||||
.add(delta_cu.div(ABDKMath64x64.fromUInt(6)));
|
.add(delta_cu.div(ABDKMath64x64.fromUInt(6)));
|
||||||
|
|
||||||
console2.log("r0_approx:");
|
|
||||||
console2.logInt(r0_approx);
|
|
||||||
|
|
||||||
// If limitPrice <= r0 (current price) we must revert (same semantic as original)
|
// If limitPrice <= r0 (current price) we must revert (same semantic as original)
|
||||||
if (limitPrice <= r0_approx) {
|
if (limitPrice <= r0_approx) {
|
||||||
console2.log("balanced2: limitPrice <= r0_approx -> revert");
|
|
||||||
revert("LMSR: limitPrice <= current price");
|
revert("LMSR: limitPrice <= current price");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ratio = limitPrice / r0_approx
|
// Ratio = limitPrice / r0_approx
|
||||||
int128 ratio = limitPrice.div(r0_approx);
|
int128 ratio = limitPrice.div(r0_approx);
|
||||||
console2.log("limitPrice/r0_approx:");
|
|
||||||
console2.logInt(ratio);
|
|
||||||
|
|
||||||
// x = ratio - 1; use Taylor for ln(1+x) when |x| is small
|
// x = ratio - 1; use Taylor for ln(1+x) when |x| is small
|
||||||
int128 x = ratio.sub(ONE);
|
int128 x = ratio.sub(ONE);
|
||||||
@@ -90,7 +79,6 @@ library LMSRStabilizedBalancedPair {
|
|||||||
int128 X_MAX = ABDKMath64x64.divu(1, 10); // 0.1
|
int128 X_MAX = ABDKMath64x64.divu(1, 10); // 0.1
|
||||||
if (absX > X_MAX) {
|
if (absX > X_MAX) {
|
||||||
// Too large to safely approximate; fall back to exact computation
|
// Too large to safely approximate; fall back to exact computation
|
||||||
console2.log("balanced2: fallback limitPrice ratio too far from 1");
|
|
||||||
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,63 +89,34 @@ library LMSRStabilizedBalancedPair {
|
|||||||
.sub(x_sq.div(ABDKMath64x64.fromUInt(2)))
|
.sub(x_sq.div(ABDKMath64x64.fromUInt(2)))
|
||||||
.add(x_cu.div(ABDKMath64x64.fromUInt(3)));
|
.add(x_cu.div(ABDKMath64x64.fromUInt(3)));
|
||||||
|
|
||||||
console2.log("lnRatioApprox (64x64):");
|
|
||||||
console2.logInt(lnRatioApprox);
|
|
||||||
|
|
||||||
// aLimitOverB = ln(limitPrice / r0) approximated
|
// aLimitOverB = ln(limitPrice / r0) approximated
|
||||||
int128 aLimitOverB = lnRatioApprox;
|
int128 aLimitOverB = lnRatioApprox;
|
||||||
|
|
||||||
// Must be > 0; otherwise fall back
|
// Must be > 0; otherwise fall back
|
||||||
if (!(aLimitOverB > int128(0))) {
|
if (!(aLimitOverB > int128(0))) {
|
||||||
console2.log("balanced2: fallback non-positive aLimitOverB");
|
|
||||||
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
// aLimit = b * aLimitOverB (in Q64.64)
|
// aLimit = b * aLimitOverB (in Q64.64)
|
||||||
int128 aLimit64 = b.mul(aLimitOverB);
|
int128 aLimit64 = b.mul(aLimitOverB);
|
||||||
console2.log("aLimit64 (64x64):");
|
|
||||||
console2.logInt(aLimit64);
|
|
||||||
|
|
||||||
// If computed aLimit is less than requested a, use the truncated value.
|
// If computed aLimit is less than requested a, use the truncated value.
|
||||||
if (aLimit64 < a) {
|
if (aLimit64 < a) {
|
||||||
console2.log("balanced2: truncating input a to aLimit64 due to limitPrice");
|
|
||||||
console2.log("original a:");
|
|
||||||
console2.logInt(a);
|
|
||||||
console2.log("truncated aLimit64:");
|
|
||||||
console2.logInt(aLimit64);
|
|
||||||
a = aLimit64;
|
a = aLimit64;
|
||||||
} else {
|
} else {
|
||||||
console2.log("balanced2: limitPrice does not truncate input");
|
// console2.log("balanced2: limitPrice does not truncate input");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: after potential truncation we continue with the polynomial approximation below
|
// Note: after potential truncation we continue with the polynomial approximation below
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug: entry trace
|
|
||||||
console2.log("balanced2: enter");
|
|
||||||
console2.log("i", i);
|
|
||||||
console2.log("j", j);
|
|
||||||
console2.log("nAssets", s.nAssets);
|
|
||||||
console2.log("a (64x64):");
|
|
||||||
console2.logInt(a);
|
|
||||||
console2.log("b (64x64):");
|
|
||||||
console2.logInt(b);
|
|
||||||
console2.log("invB (64x64):");
|
|
||||||
console2.logInt(invB);
|
|
||||||
|
|
||||||
// Small-signal delta already computed above; reuse it
|
// Small-signal delta already computed above; reuse it
|
||||||
int128 absDelta = delta >= int128(0) ? delta : delta.neg();
|
int128 absDelta = delta >= int128(0) ? delta : delta.neg();
|
||||||
|
|
||||||
console2.log("delta (q_i - q_j)/b:");
|
|
||||||
console2.logInt(delta);
|
|
||||||
console2.log("absDelta:");
|
|
||||||
console2.logInt(absDelta);
|
|
||||||
|
|
||||||
// Allow balanced pools only: require |delta| <= 1% (approx ln(1.01) ~ 0.00995; we use conservative 0.01)
|
// Allow balanced pools only: require |delta| <= 1% (approx ln(1.01) ~ 0.00995; we use conservative 0.01)
|
||||||
int128 DELTA_MAX = ABDKMath64x64.divu(1, 100); // 0.01
|
int128 DELTA_MAX = ABDKMath64x64.divu(1, 100); // 0.01
|
||||||
if (absDelta > DELTA_MAX) {
|
if (absDelta > DELTA_MAX) {
|
||||||
// Not balanced within 1% -> use exact routine
|
// Not balanced within 1% -> use exact routine
|
||||||
console2.log("balanced2: fallback delta too large");
|
|
||||||
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,18 +124,13 @@ library LMSRStabilizedBalancedPair {
|
|||||||
int128 u = a.mul(invB);
|
int128 u = a.mul(invB);
|
||||||
if (u <= int128(0)) {
|
if (u <= int128(0)) {
|
||||||
// Non-positive input -> behave like exact implementation (will revert if invalid)
|
// Non-positive input -> behave like exact implementation (will revert if invalid)
|
||||||
console2.log("balanced2: fallback u<=0");
|
|
||||||
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
console2.log("u = a/b (64x64):");
|
|
||||||
console2.logInt(u);
|
|
||||||
|
|
||||||
// Restrict to a conservative polynomial radius for accuracy; fallback otherwise.
|
// Restrict to a conservative polynomial radius for accuracy; fallback otherwise.
|
||||||
// We choose u <= 0.5 (0.5 in Q64.64) as safe for cubic approximation in typical parameters.
|
// We choose u <= 0.5 (0.5 in Q64.64) as safe for cubic approximation in typical parameters.
|
||||||
int128 U_MAX = ABDKMath64x64.divu(1, 2); // 0.5
|
int128 U_MAX = ABDKMath64x64.divu(1, 2); // 0.5
|
||||||
if (u > U_MAX) {
|
if (u > U_MAX) {
|
||||||
console2.log("balanced2: fallback u too large");
|
|
||||||
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,39 +154,26 @@ library LMSRStabilizedBalancedPair {
|
|||||||
if (u <= U_TIER1) {
|
if (u <= U_TIER1) {
|
||||||
// Cheap quadratic ln(1+X) ≈ X - X^2/2
|
// Cheap quadratic ln(1+X) ≈ X - X^2/2
|
||||||
lnApprox = X.sub(X2.div(ABDKMath64x64.fromUInt(2)));
|
lnApprox = X.sub(X2.div(ABDKMath64x64.fromUInt(2)));
|
||||||
console2.log("balanced2: using tier1 quadratic approx");
|
|
||||||
} else if (u <= U_MAX_LOCAL) {
|
} else if (u <= U_MAX_LOCAL) {
|
||||||
// Secondary cubic correction: ln(1+X) ≈ X - X^2/2 + X^3/3
|
// Secondary cubic correction: ln(1+X) ≈ X - X^2/2 + X^3/3
|
||||||
int128 X3 = X2.mul(X);
|
int128 X3 = X2.mul(X);
|
||||||
lnApprox = X.sub(X2.div(ABDKMath64x64.fromUInt(2))).add(X3.div(ABDKMath64x64.fromUInt(3)));
|
lnApprox = X.sub(X2.div(ABDKMath64x64.fromUInt(2))).add(X3.div(ABDKMath64x64.fromUInt(3)));
|
||||||
console2.log("balanced2: using tier2 cubic approx");
|
|
||||||
} else {
|
} else {
|
||||||
// u beyond allowed range - fallback
|
// u beyond allowed range - fallback
|
||||||
console2.log("balanced2: fallback u too large for approximation");
|
|
||||||
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
console2.log("lnApprox (64x64):");
|
|
||||||
console2.logInt(lnApprox);
|
|
||||||
|
|
||||||
int128 approxOut = b.mul(lnApprox);
|
int128 approxOut = b.mul(lnApprox);
|
||||||
|
|
||||||
console2.log("approxOut (64x64):");
|
|
||||||
console2.logInt(approxOut);
|
|
||||||
|
|
||||||
// Safety sanity: approximation must be > 0
|
// Safety sanity: approximation must be > 0
|
||||||
if (approxOut <= int128(0)) {
|
if (approxOut <= int128(0)) {
|
||||||
console2.log("balanced2: fallback approxOut <= 0");
|
|
||||||
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cap to available j balance: if approximated output exceeds q_j, it's likely approximation break;
|
// Cap to available j balance: if approximated output exceeds q_j, it's likely approximation break;
|
||||||
// fall back to the exact solver to handle capping/edge cases.
|
// fall back to the exact solver to handle capping/edge cases.
|
||||||
int128 qj64 = s.qInternal[j];
|
int128 qj64 = s.qInternal[j];
|
||||||
console2.log("qj64 (64x64):");
|
|
||||||
console2.logInt(qj64);
|
|
||||||
if (approxOut >= qj64) {
|
if (approxOut >= qj64) {
|
||||||
console2.log("balanced2: fallback approxOut >= qj");
|
|
||||||
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,15 +181,8 @@ library LMSRStabilizedBalancedPair {
|
|||||||
amountIn = a;
|
amountIn = a;
|
||||||
amountOut = approxOut;
|
amountOut = approxOut;
|
||||||
|
|
||||||
console2.log("balanced2: returning approx results");
|
|
||||||
console2.log("amountIn (64x64):");
|
|
||||||
console2.logInt(amountIn);
|
|
||||||
console2.log("amountOut (64x64):");
|
|
||||||
console2.logInt(amountOut);
|
|
||||||
|
|
||||||
// Final guard: ensure output is sensible and not NaN-like (rely on positivity checks above)
|
// Final guard: ensure output is sensible and not NaN-like (rely on positivity checks above)
|
||||||
if (amountOut < int128(0)) {
|
if (amountOut < int128(0)) {
|
||||||
console2.log("balanced2: fallback final guard amountOut<0");
|
|
||||||
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
return LMSRStabilized.swapAmountsForExactInput(s, i, j, a, limitPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
// SPDX-License-Identifier: UNLICENSED
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
pragma solidity ^0.8.30;
|
pragma solidity ^0.8.30;
|
||||||
|
|
||||||
import "forge-std/console2.sol";
|
|
||||||
import "@abdk/ABDKMath64x64.sol";
|
import "@abdk/ABDKMath64x64.sol";
|
||||||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||||
@@ -31,44 +30,12 @@ contract PartyPool is IPartyPool, ERC20, ReentrancyGuard {
|
|||||||
using SafeERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Immutable pool configuration
|
|
||||||
//
|
|
||||||
|
|
||||||
/// @notice Token addresses comprising the pool. Effectively immutable after construction.
|
/// @notice Token addresses comprising the pool. Effectively immutable after construction.
|
||||||
/// @dev tokens[i] corresponds to the i-th asset and maps to index i in the internal LMSR arrays.
|
/// @dev tokens[i] corresponds to the i-th asset and maps to index i in the internal LMSR arrays.
|
||||||
IERC20[] public tokens; // effectively immutable since there is no interface to change the tokens
|
IERC20[] public tokens; // effectively immutable since there is no interface to change the tokens
|
||||||
|
|
||||||
/// @inheritdoc IPartyPool
|
|
||||||
function numTokens() external view returns (uint256) { return tokens.length; }
|
|
||||||
|
|
||||||
/// @inheritdoc IPartyPool
|
|
||||||
function allTokens() external view returns (IERC20[] memory) { return tokens; }
|
|
||||||
|
|
||||||
// NOTE that the slippage target is only exactly achieved in completely balanced pools where all assets are
|
|
||||||
// priced the same. This target is actually a minimum slippage that the pool imposes on traders, and the actual
|
|
||||||
// slippage cost can be multiples bigger in practice due to pool inventory imbalances.
|
|
||||||
|
|
||||||
/// @notice Liquidity parameter κ (Q64.64) used by the LMSR kernel: b = κ * S(q)
|
|
||||||
/// @dev Pool is constructed with a fixed κ. Clients that previously passed tradeFrac/targetSlippage
|
|
||||||
/// should use LMSRStabilized.computeKappaFromSlippage(...) to derive κ and pass it here.
|
|
||||||
int128 public immutable kappa; // kappa in Q64.64
|
|
||||||
|
|
||||||
/// @notice Per-swap fee in parts-per-million (ppm). Fee is taken from input amounts before LMSR computations.
|
|
||||||
uint256 public immutable swapFeePpm;
|
|
||||||
|
|
||||||
/// @notice Flash-loan fee in parts-per-million (ppm) applied to flash borrow amounts.
|
|
||||||
uint256 public immutable flashFeePpm;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Internal state
|
|
||||||
//
|
|
||||||
|
|
||||||
LMSRStabilized.State internal lmsr;
|
LMSRStabilized.State internal lmsr;
|
||||||
|
|
||||||
/// @notice If true and there are exactly two assets, an optimized 2-asset stable-pair path is used for some computations.
|
|
||||||
bool immutable private _stablePair; // if true, the optimized LMSRStabilizedBalancedPair optimization path is enabled
|
|
||||||
|
|
||||||
// Cached on-chain balances (uint) and internal 64.64 representation
|
// Cached on-chain balances (uint) and internal 64.64 representation
|
||||||
// balance / base = internal
|
// balance / base = internal
|
||||||
uint256[] internal cachedUintBalances;
|
uint256[] internal cachedUintBalances;
|
||||||
@@ -77,6 +44,28 @@ contract PartyPool is IPartyPool, ERC20, ReentrancyGuard {
|
|||||||
/// @dev denominators()[i] is the base for tokens[i]. These bases are chosen by deployer and must match token decimals.
|
/// @dev denominators()[i] is the base for tokens[i]. These bases are chosen by deployer and must match token decimals.
|
||||||
uint256[] internal bases; // per-token uint base used to scale token amounts <-> internal
|
uint256[] internal bases; // per-token uint base used to scale token amounts <-> internal
|
||||||
|
|
||||||
|
|
||||||
|
/// @inheritdoc IPartyPool
|
||||||
|
function numTokens() external view returns (uint256) { return tokens.length; }
|
||||||
|
|
||||||
|
/// @inheritdoc IPartyPool
|
||||||
|
function allTokens() external view returns (IERC20[] memory) { return tokens; }
|
||||||
|
|
||||||
|
/// @notice Liquidity parameter κ (Q64.64) used by the LMSR kernel: b = κ * S(q)
|
||||||
|
/// @dev Pool is constructed with a fixed κ. Clients may use LMSRStabilized.computeKappaFromSlippage(...) to
|
||||||
|
/// derive κ and pass it here.
|
||||||
|
int128 public immutable kappa; // kappa in Q64.64
|
||||||
|
|
||||||
|
/// @notice Per-swap fee in parts-per-million (ppm). Fee is taken from input amounts before LMSR computations.
|
||||||
|
uint256 public immutable swapFeePpm;
|
||||||
|
|
||||||
|
/// @notice Flash-loan fee in parts-per-million (ppm) applied to flash borrow amounts.
|
||||||
|
uint256 public immutable flashFeePpm;
|
||||||
|
|
||||||
|
/// @notice If true and there are exactly two assets, an optimized 2-asset stable-pair path is used for some computations.
|
||||||
|
bool private immutable _stablePair; // if true, the optimized LMSRStabilizedBalancedPair optimization path is enabled
|
||||||
|
|
||||||
|
|
||||||
/// @inheritdoc IPartyPool
|
/// @inheritdoc IPartyPool
|
||||||
function denominators() external view returns (uint256[] memory) { return bases; }
|
function denominators() external view returns (uint256[] memory) { return bases; }
|
||||||
|
|
||||||
@@ -90,41 +79,41 @@ contract PartyPool is IPartyPool, ERC20, ReentrancyGuard {
|
|||||||
|
|
||||||
/// @param name_ LP token name
|
/// @param name_ LP token name
|
||||||
/// @param symbol_ LP token symbol
|
/// @param symbol_ LP token symbol
|
||||||
/// @param _tokens token addresses (n)
|
/// @param tokens_ token addresses (n)
|
||||||
/// @param _bases scaling bases for each token (n) - used when converting to/from internal 64.64 amounts
|
/// @param bases_ scaling bases for each token (n) - used when converting to/from internal 64.64 amounts
|
||||||
/// @param _kappa liquidity parameter κ (Q64.64) used to derive b = κ * S(q)
|
/// @param kappa_ liquidity parameter κ (Q64.64) used to derive b = κ * S(q)
|
||||||
/// @param _swapFeePpm fee in parts-per-million, taken from swap input amounts before LMSR calculations
|
/// @param swapFeePpm_ fee in parts-per-million, taken from swap input amounts before LMSR calculations
|
||||||
/// @param _flashFeePpm fee in parts-per-million, taken for flash loans
|
/// @param flashFeePpm_ fee in parts-per-million, taken for flash loans
|
||||||
/// @param _stable if true and assets.length==2, then the optimization for 2-asset stablecoin pools is activated.
|
/// @param stable_ if true and assets.length==2, then the optimization for 2-asset stablecoin pools is activated.
|
||||||
constructor(
|
constructor(
|
||||||
string memory name_,
|
string memory name_,
|
||||||
string memory symbol_,
|
string memory symbol_,
|
||||||
IERC20[] memory _tokens,
|
IERC20[] memory tokens_,
|
||||||
uint256[] memory _bases,
|
uint256[] memory bases_,
|
||||||
int128 _kappa,
|
int128 kappa_,
|
||||||
uint256 _swapFeePpm,
|
uint256 swapFeePpm_,
|
||||||
uint256 _flashFeePpm,
|
uint256 flashFeePpm_,
|
||||||
bool _stable
|
bool stable_
|
||||||
) ERC20(name_, symbol_) {
|
) ERC20(name_, symbol_) {
|
||||||
require(_tokens.length > 1, "Pool: need >1 asset");
|
require(tokens_.length > 1, "Pool: need >1 asset");
|
||||||
require(_tokens.length == _bases.length, "Pool: lengths mismatch");
|
require(tokens_.length == bases_.length, "Pool: lengths mismatch");
|
||||||
tokens = _tokens;
|
tokens = tokens_;
|
||||||
bases = _bases;
|
bases = bases_;
|
||||||
kappa = _kappa;
|
kappa = kappa_;
|
||||||
require(_swapFeePpm < 1_000_000, "Pool: fee >= ppm");
|
require(swapFeePpm_ < 1_000_000, "Pool: fee >= ppm");
|
||||||
swapFeePpm = _swapFeePpm;
|
swapFeePpm = swapFeePpm_;
|
||||||
require(_flashFeePpm < 1_000_000, "Pool: flash fee >= ppm");
|
require(flashFeePpm_ < 1_000_000, "Pool: flash fee >= ppm");
|
||||||
flashFeePpm = _flashFeePpm;
|
flashFeePpm = flashFeePpm_;
|
||||||
_stablePair = _stable && _tokens.length == 2;
|
_stablePair = stable_ && tokens_.length == 2;
|
||||||
|
|
||||||
uint256 n = _tokens.length;
|
uint256 n = tokens_.length;
|
||||||
|
|
||||||
// Initialize LMSR state nAssets; full init occurs on first mint when quantities are known.
|
// Initialize LMSR state nAssets; full init occurs on first mint when quantities are known.
|
||||||
lmsr.nAssets = n;
|
lmsr.nAssets = n;
|
||||||
|
|
||||||
// Initialize token address to index mapping
|
// Initialize token address to index mapping
|
||||||
for (uint i = 0; i < n;) {
|
for (uint i = 0; i < n;) {
|
||||||
tokenAddressToIndexPlusOne[_tokens[i]] = i + 1;
|
tokenAddressToIndexPlusOne[tokens_[i]] = i + 1;
|
||||||
unchecked {i++;}
|
unchecked {i++;}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,7 +536,6 @@ contract PartyPool is IPartyPool, ERC20, ReentrancyGuard {
|
|||||||
|
|
||||||
// Compute internal amounts using LMSR (exact-input with price limit)
|
// Compute internal amounts using LMSR (exact-input with price limit)
|
||||||
// if _stablePair is true, use the optimized path
|
// if _stablePair is true, use the optimized path
|
||||||
console2.log('stablepair optimization?', _stablePair);
|
|
||||||
(amountInInternalUsed, amountOutInternal) =
|
(amountInInternalUsed, amountOutInternal) =
|
||||||
_stablePair ? LMSRStabilizedBalancedPair.swapAmountsForExactInput(lmsr, inputTokenIndex, outputTokenIndex, deltaInternalI, limitPrice)
|
_stablePair ? LMSRStabilizedBalancedPair.swapAmountsForExactInput(lmsr, inputTokenIndex, outputTokenIndex, deltaInternalI, limitPrice)
|
||||||
: lmsr.swapAmountsForExactInput(inputTokenIndex, outputTokenIndex, deltaInternalI, limitPrice);
|
: lmsr.swapAmountsForExactInput(inputTokenIndex, outputTokenIndex, deltaInternalI, limitPrice);
|
||||||
|
|||||||
Reference in New Issue
Block a user