improved price tests

This commit is contained in:
tim
2025-11-25 16:06:15 -04:00
parent 64e73e5570
commit 2efcd4c0d3

View File

@@ -2,6 +2,7 @@
/* solhint-disable */
pragma solidity ^0.8.30;
import "forge-std/console2.sol";
import {ABDKMath64x64} from "../lib/abdk-libraries-solidity/ABDKMath64x64.sol";
import {CommonBase} from "../lib/forge-std/src/Base.sol";
import {StdAssertions} from "../lib/forge-std/src/StdAssertions.sol";
@@ -1145,5 +1146,55 @@ contract PartyPoolTest is Test {
assertEq(uint256(uint128(price)), uint256(uint128(expected)), "Price token1/token0 should be 3.0000000");
}
/// @notice Verify that PartyInfo.price() agrees (within tolerance) with the swapAmounts() quote
/// for a very small (de-minimis) exact-input swap from token1 -> token0.
function testPriceMatchesSwapForSmallInput() public {
// Build tokens array (reuse test tokens)
IERC20[] memory tokens = new IERC20[](3);
tokens[0] = IERC20(address(token0));
tokens[1] = IERC20(address(token1));
tokens[2] = IERC20(address(token2));
uint256 feePpm = 0;
// Use a large kappa to prevent slippage
int128 kappa = ABDKMath64x64.fromUInt(100);
// Prepare explicit per-token initial deposits so token0 starts at 3x token1
uint256[] memory deposits = new uint256[](3);
deposits[0] = INIT_BAL * 3; // token0 = 3 * INIT_BAL
deposits[1] = INIT_BAL; // token1 = INIT_BAL
deposits[2] = INIT_BAL; // token2 = INIT_BAL
// Deploy a fresh pool with the specified deposits
(IPartyPool poolCustom, ) = Deploy.newPartyPoolWithDeposits("LP3X_SWAP", "LP3X_SWAP", tokens, kappa, feePpm, feePpm, false, deposits, 0);
// Query the info viewer for the marginal price token1 (base) denominated in token0 (quote)
int128 infoPrice = info.price(poolCustom, 1, 0);
// Choose a small-but-sufficient input amount in external units to avoid underflow/rounding issues
uint256 inputAmount = INIT_BAL/100;
// Query the swapAmounts view to get grossIn (includes fee), amountOut, and fee
(uint256 grossIn, uint256 amountOut, uint256 inFee) = poolCustom.swapAmounts(1, 0, inputAmount, 0);
// Net input consumed by kernel excludes the fee
uint256 netIn = grossIn > inFee ? grossIn - inFee : 0;
require(netIn > 0, "net input must be positive for price comparison");
// Compute swap-implied price as Q64.64 (quote per base) = amountOut / netIn
int128 swapPrice = ABDKMath64x64.divu(amountOut, netIn);
console2.log('info price', infoPrice);
console2.log('swap price', swapPrice);
// Absolute difference between info.price and swap-implied price
int128 slippage = ABDKMath64x64.fromUInt(1) - swapPrice.div(infoPrice);
console2.log('slippage', slippage);
// Tolerance ~ 4e-5 in Q64.64
int128 tol = ABDKMath64x64.divu(4, 100_000);
assertTrue(slippage <= tol, "price from info and swapAmounts should be close");
}
}
/* solhint-enable */