price() fixes; sepolia redeploy

This commit is contained in:
tim
2025-11-25 23:11:38 -04:00
parent 2efcd4c0d3
commit cce229b99c
29 changed files with 140 additions and 57 deletions

View File

@@ -1196,5 +1196,88 @@ contract PartyPoolTest is Test {
assertTrue(slippage <= tol, "price from info and swapAmounts should be close");
}
/// @notice Ensure sequence is monotonically non-increasing:
/// marginal (highest), then avg price for a de-minimis swap, then larger inputs.
function testPricesMonotoneDecreasingWithLargerInputs() public {
// Build tokens array
IERC20[] memory tokens = new IERC20[](3);
tokens[0] = IERC20(address(token0));
tokens[1] = IERC20(address(token1));
tokens[2] = IERC20(address(token2));
// Zero fees to avoid fee effects in avg price
uint256 feePpm = 0;
// Use moderate kappa to see price movement while avoiding numerical instability
int128 kappa = ABDKMath64x64.divu(1, 10);
// Use imbalanced deposits (3:1:1) so initial price is not 1.0 and price decay is observable
uint256[] memory deposits = new uint256[](3);
deposits[0] = INIT_BAL * 3;
deposits[1] = INIT_BAL;
deposits[2] = INIT_BAL;
// Fresh pool
(IPartyPool poolCustom, ) = Deploy.newPartyPoolWithDeposits(
"LP_MONO", "LP_MONO", tokens, kappa, feePpm, feePpm, false, deposits, 0
);
// Base = token1 (input), Quote = token0 (output)
uint256 base = 1;
uint256 quote = 0;
// Marginal out-per-in price (Q64.64)
int128 p0 = info.price(poolCustom, base, quote);
// Define de-minimis and larger inputs (in external units)
uint256 eps = INIT_BAL / 1000; // de-minimis relative to deposits
if (eps == 0) eps = 1;
uint256 a1 = eps * 5;
uint256 a2 = eps * 10;
uint256 a3 = eps * 50;
// Compute average prices p = amountOut / netIn (fee-free here; still compute netIn robustly)
int128 p_eps;
{
(uint256 grossIn, uint256 amountOut, uint256 inFee) = poolCustom.swapAmounts(base, quote, eps, 0);
uint256 netIn = grossIn > inFee ? grossIn - inFee : 0;
require(netIn > 0 && amountOut > 0, "nonzero quote");
p_eps = ABDKMath64x64.divu(amountOut, netIn);
}
int128 p_a1;
{
(uint256 grossIn, uint256 amountOut, uint256 inFee) = poolCustom.swapAmounts(base, quote, a1, 0);
uint256 netIn = grossIn > inFee ? grossIn - inFee : 0;
require(netIn > 0 && amountOut > 0, "nonzero quote");
p_a1 = ABDKMath64x64.divu(amountOut, netIn);
}
int128 p_a2;
{
(uint256 grossIn, uint256 amountOut, uint256 inFee) = poolCustom.swapAmounts(base, quote, a2, 0);
uint256 netIn = grossIn > inFee ? grossIn - inFee : 0;
require(netIn > 0 && amountOut > 0, "nonzero quote");
p_a2 = ABDKMath64x64.divu(amountOut, netIn);
}
int128 p_a3;
{
(uint256 grossIn, uint256 amountOut, uint256 inFee) = poolCustom.swapAmounts(base, quote, a3, 0);
uint256 netIn = grossIn > inFee ? grossIn - inFee : 0;
require(netIn > 0 && amountOut > 0, "nonzero quote");
p_a3 = ABDKMath64x64.divu(amountOut, netIn);
}
// Tolerance for fixed-point/rounding (~4e-5)
int128 tol = ABDKMath64x64.divu(4, 100_000);
// Assert monotone non-increasing: next <= prev + tol
assertTrue(p_eps <= p0.add(tol), "p(eps) must be <= marginal");
assertTrue(p_a1 <= p_eps.add(tol), "p(a1) must be <= p(eps)");
assertTrue(p_a2 <= p_a1.add(tol), "p(a2) must be <= p(a1)");
assertTrue(p_a3 <= p_a2.add(tol), "p(a3) must be <= p(a2)");
}
}
/* solhint-enable */