rename to PartyInfo; README fees

This commit is contained in:
tim
2025-11-07 16:18:00 -04:00
parent ff9ed674f9
commit a08a928f7f
10 changed files with 84 additions and 73 deletions

View File

@@ -70,16 +70,27 @@ quotes on all pairs in the pool.
Deployment addresses for each chain may be found in `deployment/liqp-deployments.json`, and the `solc` output including ABI information is stored under `deployment/{chain_id}/v1/...`
The primary entrypoint for all Liquidity Party actions is the [PartyPlanner](src/IPartyPlanner.sol) contract, which is a singleton per chain. The `PartyPlanner` contract not only deploys new pools but also indexes the pools and their tokens for easy metadata discovery. After a pool is created or discovered using the `PartyPlanner`, it can be used to perform swaps, minting, and other actions according to the [IPartyPool](src/IPartyPlanner.sol) interface. Due to contract size limitations, most view methods for prices and swaps are available from a separate singleton contract, the [PartyPoolViewer](src/IPartyPoolViewer.sol).
The primary entrypoint for all Liquidity Party actions is the [PartyPlanner](src/IPartyPlanner.sol) contract, which is a singleton per chain. The `PartyPlanner` contract not only deploys new pools but also indexes the pools and their tokens for easy metadata discovery. After a pool is created or discovered using the `PartyPlanner`, it can be used to perform swaps, minting, and other actions according to the [IPartyPool](src/IPartyPlanner.sol) interface. Due to contract size limitations, most view methods for prices and swaps are available from a separate singleton contract, [PartyInfo](src/IPartyInfo.sol).
# Implementation Notes
## Non-upgradable Proxy
Due to contract size constraints, the `PartyPool` contract uses `DELEGATECALL` to invoke implementations on the singleton [PartyPoolSwapImpl](src/PartyPoolSwapImpl.sol) and [PartyPoolMintImpl](src/PartyPoolMintImpl.sol) contracts. This proxy pattern is NOT upgradable and the implementation contract addresses used by the pool are immutable. Views implemented in `PartyPoolViewer` have no delegation but simply accept the target pool as an argument, calculating prices etc. from public getters.
Due to contract size constraints, the `PartyPool` contract uses `DELEGATECALL` to invoke implementations on the singleton [PartyPoolSwapImpl](src/PartyPoolSwapImpl.sol) and [PartyPoolMintImpl](src/PartyPoolMintImpl.sol) contracts. This proxy pattern is NOT upgradable and the implementation contract addresses used by the pool are immutable. Views implemented in `PartyInfo` have no delegation but simply accept the target pool as an argument, calculating prices etc. from public getters.
## Admin-Only Deployment
`PartyPlanner` allows only the admin to deploy new pools. This decision was made because Liquidity Party is a new protocol that does not support non-standard tokens such as fee-on-transfer tokens or rebasing tokens, and the selection of the `kappa` liquidity parameter is not straightforward for an average user. We hope to offer a version of Liquidity Party in the future that allows regular users to create their pools.
## Killable Contracts
PartyPools may be "killed" by their admin, in which case all swaps and mints are disabled, and the only modifying function allowed to be called is `burn()` to allow LP's to safely withdraw their funds. Killing is irreversible and intended to be used as a last-ditch safety measure in case a critical vulnerablility is discovered.
## Fee Mechanisms
Each asset in the pool has a fee associated with it, which is paid when that asset is involved in a swap.
The fee for a swap is the input asset fee plus the output asset fee, but this total fee percentage is taken only from the input amount, prior to the LMSR calculation. This results in more of the input asset being collected by the pool compared to the value of the output asset removed. In this way, the LP holders accumulate fee value implicitly in their prorata share of the pool's total assets.
For a swap-mint operation, only the input asset fee is charged on the input token. For a burn-swap, only the output asset fee is charged on the output token.
Flash loans are charged a single fee, the flash fee, no matter what asset is loaned.
Protocol fees are taken as a fraction of any LP fees earned, rounding down in favor of the LP stakers. Protocol fees accumulate in a separate account in the pool until the admin sends a collection transaction to sweep the fees. While protocol fees are waiting to be collected, those funds do not participate in liquidity operations or earn fees.

View File

@@ -65,7 +65,7 @@ token() {
}
PARTY_PLANNER=$(contract PartyPlanner)
PARTY_POOL_VIEWER=$(contract PartyPoolViewer)
PARTY_INFO=$(contract PartyInfo)
PARTY_POOL_MINT_IMPL=$(contract PartyPoolMintImpl)
PARTY_POOL_SWAP_IMPL=$(contract PartyPoolSwapImpl)
PARTY_POOL_DEPLOYER=$(contract PartyPoolDeployer)
@@ -85,7 +85,7 @@ cp -r out $OUT/
jq -n \
--arg chainId "$CHAINID" \
--arg partyPlanner "$PARTY_PLANNER" \
--arg partyPoolViewer "$PARTY_POOL_VIEWER" \
--arg partyInfo "$PARTY_INFO" \
--arg partyPoolMintImpl "$PARTY_POOL_MINT_IMPL" \
--arg partyPoolSwapImpl "$PARTY_POOL_SWAP_IMPL" \
--arg partyPoolDeployer "$PARTY_POOL_DEPLOYER" \
@@ -99,7 +99,7 @@ jq -n \
{
v1: {
PartyPlanner: $partyPlanner,
PartyPoolViewer: $partyPoolViewer,
PartyInfo: $partyInfo,
PartyPoolMintImpl: $partyPoolMintImpl,
PartyPoolSwapImpl: $partyPoolSwapImpl,
PartyPoolDeployer: $partyPoolDeployer,
@@ -116,7 +116,7 @@ jq -n \
jq -n \
--arg chainId "$CHAINID" \
--arg partyPlanner "$PARTY_PLANNER" \
--arg partyPoolViewer "$PARTY_POOL_VIEWER" \
--arg partyInfo "$PARTY_INFO" \
--arg partyPoolMintImpl "$PARTY_POOL_MINT_IMPL" \
--arg partyPoolSwapImpl "$PARTY_POOL_SWAP_IMPL" \
--arg partyPoolDeployer "$PARTY_POOL_DEPLOYER" \
@@ -129,7 +129,7 @@ jq -n \
'{($chainId): {
v1: {
PartyPlanner: $partyPlanner,
PartyPoolViewer: $partyPoolViewer,
PartyInfo.sol: $partyInfo,
PartyPoolMintImpl: $partyPoolMintImpl,
PartyPoolSwapImpl: $partyPoolSwapImpl,
PartyPoolDeployer: $partyPoolDeployer,

View File

@@ -11,7 +11,7 @@ import {StdUtils} from "../lib/forge-std/src/StdUtils.sol";
import {IERC20} from "../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import {IERC20Metadata} from "../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {PartyPlanner} from "../src/PartyPlanner.sol";
import {PartyPoolViewer} from "../src/PartyPoolViewer.sol";
import {PartyInfo} from "../src/PartyInfo.sol";
import {Deploy} from "../test/Deploy.sol";
import {MockERC20} from "../test/MockERC20.sol";
@@ -163,7 +163,7 @@ contract DeployMock is Script {
0
);
PartyPoolViewer viewer = Deploy.newViewer();
PartyInfo info = Deploy.newInfo();
// give _tokens to dev7 for later use
mintAll(DEV_ACCOUNT_7, 1_000_000);
@@ -172,9 +172,9 @@ contract DeployMock is Script {
// Set ENV vars
string memory plannerStr = vm.toString(address(planner));
string memory viewerStr = vm.toString(address(viewer));
string memory infoStr = vm.toString(address(info));
vm.setEnv('PLANNER', plannerStr);
vm.setEnv('VIEWER', viewerStr);
vm.setEnv('INFO', infoStr);
vm.setEnv('USXD', vm.toString(address(usxd)));
vm.setEnv('FUSD', vm.toString(address(fusd)));
vm.setEnv('DIVE', vm.toString(address(dive)));
@@ -183,19 +183,19 @@ contract DeployMock is Script {
// Write JSON config file
string memory chainConfigStr = vm.serializeString('config', 'PartyPlanner', plannerStr);
chainConfigStr = vm.serializeString('config', 'PartyPoolViewer', viewerStr);
chainConfigStr = vm.serializeString('config', 'PartyInfo', infoStr);
string memory v1ConfigStr = vm.serializeString('v1', 'v1', chainConfigStr);
string memory configStr = vm.serializeString('chain config', vm.toString(block.chainid), v1ConfigStr);
vm.writeJson(configStr, 'liqp-deployments.json');
console2.log();
console2.log(' PartyPlanner', address(planner));
console2.log('PartyPoolViewer', address(viewer));
console2.log(' USXD', address(usxd));
console2.log(' FUSD', address(fusd));
console2.log(' DIVE', address(dive));
console2.log(' BUTC', address(butc));
console2.log(' WTETH', address(wteth));
console2.log('PartyPlanner', address(planner));
console2.log(' PartyInfo', address(info));
console2.log(' USXD', address(usxd));
console2.log(' FUSD', address(fusd));
console2.log(' DIVE', address(dive));
console2.log(' BUTC', address(butc));
console2.log(' WTETH', address(wteth));
}
MockERC20 private usxd;

View File

@@ -11,14 +11,14 @@ import {StdUtils} from "../lib/forge-std/src/StdUtils.sol";
import {IERC3156FlashBorrower} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol";
import {IERC20} from "../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import {IPartyPool} from "../src/IPartyPool.sol";
import {IPartyPoolViewer} from "../src/IPartyPoolViewer.sol";
import {IPartyInfo} from "../src/IPartyInfo.sol";
import {LMSRStabilized} from "../src/LMSRStabilized.sol";
import {NativeWrapper} from "../src/NativeWrapper.sol";
import {PartyPlanner} from "../src/PartyPlanner.sol";
import {PartyPoolDeployer, PartyPoolBalancedPairDeployer} from "../src/PartyPoolDeployer.sol";
import {PartyPoolMintImpl} from "../src/PartyPoolMintImpl.sol";
import {PartyPoolSwapImpl} from "../src/PartyPoolSwapImpl.sol";
import {PartyPoolViewer} from "../src/PartyPoolViewer.sol";
import {PartyInfo} from "../src/PartyInfo.sol";
import {MockERC20} from "../test/MockERC20.sol";
import {MockFlashBorrower} from "../test/MockFlashBorrower.sol";
@@ -189,17 +189,17 @@ contract DeploySepolia is Script {
0
);
PartyPoolViewer viewer = new PartyPoolViewer(swapImpl, mintImpl);
PartyInfo info = new PartyInfo(swapImpl, mintImpl);
exercise(exercisePool, viewer);
exercise(exercisePool, info);
vm.stopBroadcast();
// Set ENV vars
string memory plannerStr = vm.toString(address(planner));
string memory viewerStr = vm.toString(address(viewer));
string memory infoStr = vm.toString(address(info));
vm.setEnv('PLANNER', plannerStr);
vm.setEnv('VIEWER', viewerStr);
vm.setEnv('INFO', infoStr);
vm.setEnv('USXD', vm.toString(address(usxd)));
vm.setEnv('FUSD', vm.toString(address(fusd)));
vm.setEnv('DIVE', vm.toString(address(dive)));
@@ -207,18 +207,18 @@ contract DeploySepolia is Script {
vm.setEnv('WTETH', vm.toString(address(wteth)));
console2.log();
console2.log(' PartyPlanner', address(planner));
console2.log('PartyPoolViewer', address(viewer));
console2.log(' SwapImpl', address(swapImpl));
console2.log(' MintImpl', address(mintImpl));
console2.log(' Deployer', address(deployer));
console2.log(' BPair Deployer', address(balancedPairDeployer));
console2.log(' PartyPlanner', address(planner));
console2.log(' PartyInfo', address(info));
console2.log(' SwapImpl', address(swapImpl));
console2.log(' MintImpl', address(mintImpl));
console2.log(' Deployer', address(deployer));
console2.log('BPair Deployer', address(balancedPairDeployer));
console2.log();
console2.log(' USXD', address(usxd));
console2.log(' FUSD', address(fusd));
console2.log(' DIVE', address(dive));
console2.log(' BUTC', address(butc));
console2.log(' WTETH', address(wteth));
console2.log(' USXD', address(usxd));
console2.log(' FUSD', address(fusd));
console2.log(' DIVE', address(dive));
console2.log(' BUTC', address(butc));
console2.log(' WTETH', address(wteth));
}
MockERC20 private usxd;
@@ -243,7 +243,7 @@ contract DeploySepolia is Script {
wteth.approve(spender, type(uint256).max);
}
function exercise( IPartyPool pool, IPartyPoolViewer viewer ) internal {
function exercise( IPartyPool pool, IPartyInfo info) internal {
// gather tokens and denominators
IERC20[] memory tokens = pool.allTokens();
uint256 n = tokens.length;
@@ -263,7 +263,7 @@ contract DeploySepolia is Script {
// deploy a temporary borrower that repays amount + fee back to the pool
MockFlashBorrower borrower = new MockFlashBorrower();
uint256 flashAmt = 53 * 10**6; // arbitrary non-even amount
uint256 flashFee = viewer.flashFee(pool, address(tokens[0]), flashAmt);
uint256 flashFee = info.flashFee(pool, address(tokens[0]), flashAmt);
// Mint enough to cover the flash fee
MockERC20(address(tokens[0])).mint(address(borrower), flashFee);
// pass the pool address in data so borrower can repay back to this pool

View File

@@ -3,7 +3,7 @@ pragma solidity ^0.8.30;
import {IPartyPool} from "./IPartyPool.sol";
interface IPartyPoolViewer {
interface IPartyInfo {
/// @notice Marginal price of `base` denominated in `quote` as Q64.64.
/// @dev Returns the LMSR marginal price p_quote / p_base in ABDK 64.64 fixed-point format.
/// Useful for off-chain quoting; raw 64.64 value is returned (no scaling to token units).

View File

@@ -5,13 +5,13 @@ import "forge-std/console2.sol";
import {ABDKMath64x64} from "../lib/abdk-libraries-solidity/ABDKMath64x64.sol";
import {IERC20} from "../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import {IPartyPool} from "./IPartyPool.sol";
import {IPartyPoolViewer} from "./IPartyPoolViewer.sol";
import {IPartyInfo} from "./IPartyInfo.sol";
import {LMSRStabilized} from "./LMSRStabilized.sol";
import {PartyPoolHelpers} from "./PartyPoolHelpers.sol";
import {PartyPoolMintImpl} from "./PartyPoolMintImpl.sol";
import {PartyPoolSwapImpl} from "./PartyPoolSwapImpl.sol";
contract PartyPoolViewer is PartyPoolHelpers, IPartyPoolViewer {
contract PartyInfo is PartyPoolHelpers, IPartyInfo {
using ABDKMath64x64 for int128;
PartyPoolSwapImpl immutable internal SWAP_IMPL;

View File

@@ -19,7 +19,7 @@ import {SafeERC20} from "../lib/openzeppelin-contracts/contracts/token/ERC20/uti
import {IERC3156FlashLender} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashLender.sol";
import {NativeWrapper} from "./NativeWrapper.sol";
import {OwnableExternal} from "./OwnableExternal.sol";
import {IPartyPoolViewer} from "./IPartyPoolViewer.sol";
import {IPartyInfo} from "./IPartyInfo.sol";
/// @title PartyPool - LMSR-backed multi-asset pool with LP ERC20 token
/// @notice A multi-asset liquidity pool backed by the LMSRStabilized pricing model.

View File

@@ -9,7 +9,7 @@ import {PartyPoolBalancedPair} from "../src/PartyPoolBalancedPair.sol";
import {PartyPoolDeployer, PartyPoolBalancedPairDeployer} from "../src/PartyPoolDeployer.sol";
import {PartyPoolMintImpl} from "../src/PartyPoolMintImpl.sol";
import {PartyPoolSwapImpl} from "../src/PartyPoolSwapImpl.sol";
import {PartyPoolViewer} from "../src/PartyPoolViewer.sol";
import {PartyInfo} from "../src/PartyInfo.sol";
import {WETH9} from "./WETH9.sol";
library Deploy {
@@ -99,8 +99,8 @@ library Deploy {
}
function newViewer() internal returns (PartyPoolViewer) {
function newInfo() internal returns (PartyInfo) {
NativeWrapper wrapper = new WETH9();
return new PartyPoolViewer(new PartyPoolSwapImpl(wrapper), new PartyPoolMintImpl(wrapper));
return new PartyInfo(new PartyPoolSwapImpl(wrapper), new PartyPoolMintImpl(wrapper));
}
}

View File

@@ -10,7 +10,7 @@ import "../src/PartyPool.sol";
import {NativeWrapper} from "../src/NativeWrapper.sol";
import {PartyPlanner} from "../src/PartyPlanner.sol";
import {Deploy} from "./Deploy.sol";
import {PartyPoolViewer} from "../src/PartyPoolViewer.sol";
import {PartyInfo} from "../src/PartyInfo.sol";
import {WETH9} from "./WETH9.sol";
/// @notice Minimal ERC20 token for tests with an external mint function.
@@ -41,7 +41,7 @@ contract NativeTest is Test {
TestERC20Native token1;
WETH9 weth; // WETH is our third token
PartyPool pool;
PartyPoolViewer viewer;
PartyInfo info;
address alice;
address bob;
@@ -111,7 +111,7 @@ contract NativeTest is Test {
token0.mint(bob, INIT_BAL);
token1.mint(bob, INIT_BAL);
viewer = Deploy.newViewer();
info = Deploy.newInfo();
}
/// @notice Helper to verify refunds work correctly
@@ -300,7 +300,7 @@ contract NativeTest is Test {
uint256 lpRequest = pool.totalSupply() / 10; // Request 10% of pool
// Get required deposit amounts
uint256[] memory deposits = viewer.mintAmounts(pool, lpRequest);
uint256[] memory deposits = info.mintAmounts(pool, lpRequest);
vm.startPrank(alice);
token0.approve(address(pool), type(uint256).max);
@@ -329,7 +329,7 @@ contract NativeTest is Test {
/// @notice Test mint with excess native currency - verify refund
function testMintWithExcessNativeRefunded() public {
uint256 lpRequest = pool.totalSupply() / 10;
uint256[] memory deposits = viewer.mintAmounts(pool, lpRequest);
uint256[] memory deposits = info.mintAmounts(pool, lpRequest);
vm.startPrank(alice);
token0.approve(address(pool), type(uint256).max);
@@ -365,7 +365,7 @@ contract NativeTest is Test {
uint256 lpToBurn = pool.totalSupply() / 10;
// Get expected withdraw amounts
uint256[] memory withdraws = viewer.burnAmounts(pool, lpToBurn);
uint256[] memory withdraws = info.burnAmounts(pool, lpToBurn);
uint256 thisEthBefore = address(this).balance;
uint256 expectedWethWithdraw = withdraws[2]; // WETH is index 2
@@ -391,7 +391,7 @@ contract NativeTest is Test {
/// @notice Test burn to a different receiver with native output
function testBurnToReceiverWithNativeOutput() public {
uint256 lpToBurn = pool.totalSupply() / 10;
uint256[] memory withdraws = viewer.burnAmounts(pool, lpToBurn);
uint256[] memory withdraws = info.burnAmounts(pool, lpToBurn);
uint256 bobEthBefore = bob.balance;
uint256 bobToken0Before = token0.balanceOf(bob);
@@ -531,7 +531,7 @@ contract NativeTest is Test {
// 1. Mint with native currency
uint256 lpRequest = pool.totalSupply() / 20; // 5% of pool
uint256[] memory deposits = viewer.mintAmounts(pool, lpRequest);
uint256[] memory deposits = info.mintAmounts(pool, lpRequest);
token0.approve(address(pool), type(uint256).max);
token1.approve(address(pool), type(uint256).max);

View File

@@ -12,7 +12,7 @@ import "../src/PartyPool.sol";
import "../lib/openzeppelin-contracts/contracts/interfaces/IERC3156FlashBorrower.sol";
import {PartyPlanner} from "../src/PartyPlanner.sol";
import {Deploy} from "./Deploy.sol";
import {PartyPoolViewer} from "../src/PartyPoolViewer.sol";
import {PartyInfo} from "../src/PartyInfo.sol";
/// @notice Test contract that implements the flash callback for testing flash loans
contract FlashBorrower is IERC3156FlashBorrower {
@@ -113,7 +113,7 @@ contract PartyPoolTest is Test {
PartyPlanner planner;
PartyPool pool;
PartyPool pool10;
PartyPoolViewer viewer;
PartyInfo info;
address alice;
address bob;
@@ -244,7 +244,7 @@ contract PartyPoolTest is Test {
token8.mint(bob, INIT_BAL);
token9.mint(bob, INIT_BAL);
viewer = Deploy.newViewer();
info = Deploy.newInfo();
}
/// @notice Basic sanity: initial mint should have produced LP _tokens for this contract and the pool holds _tokens.
@@ -286,7 +286,7 @@ contract PartyPoolTest is Test {
token2.approve(address(pool), type(uint256).max);
// Inspect the deposit amounts that the pool will require (these are rounded up)
uint256[] memory deposits = viewer.mintAmounts(pool, 1);
uint256[] memory deposits = info.mintAmounts(pool, 1);
// Basic sanity: deposits array length must match token count and not all zero necessarily
assertEq(deposits.length, 3);
@@ -328,7 +328,7 @@ contract PartyPoolTest is Test {
uint256 totalLpBefore = pool.totalSupply();
// Compute required deposits and perform mint for 1 wei
uint256[] memory deposits = viewer.mintAmounts(pool, 1);
uint256[] memory deposits = info.mintAmounts(pool, 1);
// Sum deposits as deposited_value
uint256 depositedValue = 0;
@@ -369,7 +369,7 @@ contract PartyPoolTest is Test {
// Request half of LP supply
uint256 want = totalLp / 2;
uint256[] memory deposits = viewer.mintAmounts(pool, want);
uint256[] memory deposits = info.mintAmounts(pool, want);
// We expect each deposit to be roughly half the pool balance, but due to rounding up it should satisfy:
// deposits[i] * 2 >= cached balance (i.e., rounding up)
@@ -386,7 +386,7 @@ contract PartyPoolTest is Test {
assertTrue(totalLp > 0, "precondition: LP > 0");
// Compute amounts required to redeem entire supply (should be current balances)
uint256[] memory withdrawAmounts = viewer.burnAmounts(pool, totalLp);
uint256[] memory withdrawAmounts = info.burnAmounts(pool, totalLp);
// Sanity: withdrawAmounts should equal pool balances (or very close due to rounding)
for (uint i = 0; i < withdrawAmounts.length; i++) {
@@ -490,7 +490,7 @@ contract PartyPoolTest is Test {
if (req == 0) req = 1;
// Compute expected deposit amounts via view
uint256[] memory expected = viewer.mintAmounts(pool, req);
uint256[] memory expected = info.mintAmounts(pool, req);
// Ensure alice has _tokens and approve pool
vm.startPrank(alice);
@@ -535,7 +535,7 @@ contract PartyPoolTest is Test {
uint256 req = requests[k];
if (req == 0) req = 1;
uint256[] memory expected = viewer.mintAmounts(pool10, req);
uint256[] memory expected = info.mintAmounts(pool10, req);
// Approve all _tokens from alice
vm.startPrank(alice);
@@ -613,7 +613,7 @@ contract PartyPoolTest is Test {
}
// Recompute withdraw amounts via view after any top-up
uint256[] memory expected = viewer.burnAmounts(pool, req);
uint256[] memory expected = info.burnAmounts(pool, req);
// If expected withdraws are all zero (rounding edge), skip this iteration
if (expected[0] == 0 && expected[1] == 0 && expected[2] == 0) {
@@ -670,7 +670,7 @@ contract PartyPoolTest is Test {
vm.stopPrank();
}
uint256[] memory expected = viewer.burnAmounts(pool10, req);
uint256[] memory expected = info.burnAmounts(pool10, req);
// If expected withdraws are all zero (rounding edge), skip this iteration
bool allZero = true;
@@ -949,7 +949,7 @@ contract PartyPoolTest is Test {
for (uint256 i = 0; i < testAmounts.length; i++) {
uint256 amount = testAmounts[i];
uint256 fee = viewer.flashFee(pool, address(token0), amount);
uint256 fee = info.flashFee(pool, address(token0), amount);
// Calculate expected fee
uint256 expectedFee = (amount * pool.flashFeePpm() + 1_000_000 - 1) / 1_000_000; // ceiling
@@ -1096,8 +1096,8 @@ contract PartyPoolTest is Test {
token2.approve(address(poolCustom), type(uint256).max);
// Get required deposit amounts for both pools
uint256[] memory depositsDefault = viewer.mintAmounts(poolDefault, lpRequestDefault);
uint256[] memory depositsCustom = viewer.mintAmounts(poolCustom, lpRequestCustom);
uint256[] memory depositsDefault = info.mintAmounts(poolDefault, lpRequestDefault);
uint256[] memory depositsCustom = info.mintAmounts(poolCustom, lpRequestCustom);
// Deposits should be identical (same proportion of identical balances)
assertEq(depositsDefault[0], depositsCustom[0], "Token0 deposits should be identical");
@@ -1126,8 +1126,8 @@ contract PartyPoolTest is Test {
/// @notice Verify that the initial relative price between token0 and token1 is 1.0000000
function testInitialPriceIsOne() public view {
// Query the viewer for the relative price between token index 0 and 1
int128 price = viewer.price(pool, 0, 1);
// Query the info viewer for the relative price between token index 0 and 1
int128 price = info.price(pool, 0, 1);
// Expected price is 1.0 in ABDK 64.64 fixed point
int128 expected = ABDKMath64x64.fromInt(1);
@@ -1137,8 +1137,8 @@ contract PartyPoolTest is Test {
/// @notice Verify that the initial LP price in terms of token0 is 1.0000000
function testInitialPoolPriceIsOne() public {
// Query the viewer for the pool price for token0
int128 price = viewer.poolPrice(pool, 0);
// Query the info viewer for the pool price for token0
int128 price = info.poolPrice(pool, 0);
// Expected price is 1.0 in ABDK 64.64 fixed point
int128 expected = ABDKMath64x64.fromInt(1);
@@ -1157,7 +1157,7 @@ contract PartyPoolTest is Test {
if (lpRequest == 0) lpRequest = 1;
// Compute required deposits and perform mint if not trivial
uint256[] memory deposits = viewer.mintAmounts(pool, lpRequest);
uint256[] memory deposits = info.mintAmounts(pool, lpRequest);
bool allZero = true;
for (uint i = 0; i < deposits.length; i++) { if (deposits[i] != 0) { allZero = false; break; } }
@@ -1167,7 +1167,7 @@ contract PartyPoolTest is Test {
vm.stopPrank();
// Re-query the pool price and ensure it remains 1.0 (within exact fixed-point equality)
int128 priceAfter = viewer.poolPrice(pool, 0);
int128 priceAfter = info.poolPrice(pool, 0);
assertEq(uint256(uint128(priceAfter)), uint256(uint128(expected)), "Pool price should remain 1.0000000 after mint");
}