price() fixes; sepolia redeploy
This commit is contained in:
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user