per-asset fees
This commit is contained in:
@@ -131,8 +131,6 @@ library LMSRStabilized {
|
||||
int128 a,
|
||||
int128 limitPrice
|
||||
) internal pure returns (int128 amountIn, int128 amountOut) {
|
||||
require(i < nAssets && j < nAssets, "LMSR: idx");
|
||||
|
||||
// Initialize amountIn to full amount (will be adjusted if limit price is hit)
|
||||
amountIn = a;
|
||||
|
||||
@@ -140,48 +138,37 @@ library LMSRStabilized {
|
||||
int128 sizeMetric = _computeSizeMetric(qInternal);
|
||||
require(sizeMetric > int128(0), "LMSR: size metric zero");
|
||||
int128 b = kappa.mul(sizeMetric);
|
||||
require(b > int128(0), "LMSR: b<=0");
|
||||
|
||||
// Precompute reciprocal of b to avoid repeated divisions
|
||||
int128 invB = ABDKMath64x64.div(ONE, b);
|
||||
|
||||
// Guard: output asset must have non-zero effective weight to avoid degenerate/div-by-zero-like conditions
|
||||
require(qInternal[j] > int128(0), "LMSR: e_j==0");
|
||||
|
||||
// Compute r0 = exp((q_i - q_j) / b) directly using invB
|
||||
int128 r0 = _exp(qInternal[i].sub(qInternal[j]).mul(invB));
|
||||
require(r0 > int128(0), "LMSR: r0<=0"); // equivalent to e_j > 0 check
|
||||
|
||||
// If a positive limitPrice is given, determine whether the full `a` would
|
||||
// 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))
|
||||
if (limitPrice > int128(0)) {
|
||||
// r0 must be positive; if r0 == 0 then no risk of exceeding limit by increasing r.
|
||||
require(r0 >= int128(0), "LMSR: r0<0");
|
||||
if (r0 == int128(0)) {
|
||||
// console2.log("r0 == 0 (input asset has zero weight), no limit truncation needed");
|
||||
// If limitPrice <= current price, we revert (caller must choose a limit > current price to allow any fill)
|
||||
if (limitPrice <= r0) {
|
||||
revert("LMSR: limitPrice <= current price");
|
||||
}
|
||||
|
||||
// Compute a_limit directly from ln(limit / r0): a_limit = b * ln(limit / r0)
|
||||
int128 ratioLimitOverR0 = limitPrice.div(r0);
|
||||
require(ratioLimitOverR0 > int128(0), "LMSR: ratio<=0");
|
||||
|
||||
int128 aLimitOverB = _ln(ratioLimitOverR0); // > 0
|
||||
|
||||
// aLimit = b * aLimitOverB
|
||||
int128 aLimit64 = b.mul(aLimitOverB);
|
||||
|
||||
// If computed aLimit is less than the requested a, use the truncated value.
|
||||
if (aLimit64 < a) {
|
||||
amountIn = aLimit64; // Store the truncated input amount
|
||||
a = aLimit64; // Use truncated amount for calculations
|
||||
} else {
|
||||
// If limitPrice <= current price, we revert (caller must choose a limit > current price to allow any fill)
|
||||
if (limitPrice <= r0) {
|
||||
revert("LMSR: limitPrice <= current price");
|
||||
}
|
||||
|
||||
// Compute a_limit directly from ln(limit / r0): a_limit = b * ln(limit / r0)
|
||||
int128 ratioLimitOverR0 = limitPrice.div(r0);
|
||||
require(ratioLimitOverR0 > int128(0), "LMSR: ratio<=0");
|
||||
|
||||
int128 aLimitOverB = _ln(ratioLimitOverR0); // > 0
|
||||
|
||||
// aLimit = b * aLimitOverB
|
||||
int128 aLimit64 = b.mul(aLimitOverB);
|
||||
|
||||
// If computed aLimit is less than the requested a, use the truncated value.
|
||||
if (aLimit64 < a) {
|
||||
amountIn = aLimit64; // Store the truncated input amount
|
||||
a = aLimit64; // Use truncated amount for calculations
|
||||
} else {
|
||||
// console2.log("Not truncating: aLimit64 >= a");
|
||||
}
|
||||
// no truncation needed
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,28 +242,19 @@ library LMSRStabilized {
|
||||
uint256 j,
|
||||
int128 limitPrice
|
||||
) internal pure returns (int128 amountIn, int128 amountOut) {
|
||||
require(i < nAssets && j < nAssets, "LMSR: idx");
|
||||
require(limitPrice > int128(0), "LMSR: limitPrice <= 0");
|
||||
|
||||
// Compute b and ensure positivity before deriving invB
|
||||
int128 sizeMetric = _computeSizeMetric(qInternal);
|
||||
require(sizeMetric > int128(0), "LMSR: size metric zero");
|
||||
int128 b = kappa.mul(sizeMetric);
|
||||
require(b > int128(0), "LMSR: b<=0");
|
||||
|
||||
// Precompute reciprocal of b to avoid repeated divisions
|
||||
int128 invB = ABDKMath64x64.div(ONE, b);
|
||||
|
||||
// Guard: output asset must have non-zero effective weight to avoid degenerate/div-by-zero-like conditions
|
||||
require(qInternal[j] > int128(0), "LMSR: e_j==0");
|
||||
|
||||
// Compute r0 = exp((q_i - q_j) / b) directly using invB
|
||||
int128 r0 = _exp(qInternal[i].sub(qInternal[j]).mul(invB));
|
||||
|
||||
// Mirror swapAmountsForExactInput behavior: treat invalid r0 as an error condition.
|
||||
// Revert if r0 is non-positive (no finite trade under a price limit).
|
||||
require(r0 > int128(0), "LMSR: r0<=0");
|
||||
|
||||
// If current price already exceeds or equals limit, revert the same way swapAmountsForExactInput does.
|
||||
if (r0 >= limitPrice) {
|
||||
revert("LMSR: limitPrice <= current price");
|
||||
|
||||
Reference in New Issue
Block a user