From ba08da2fca63bb07478953b490d86aa12cef22cb Mon Sep 17 00:00:00 2001 From: tim Date: Sat, 25 Oct 2025 18:18:18 -0400 Subject: [PATCH] computed bases --- research/pool_design.py | 70 ++++++++++++++++++++++++++--------- script/DeployMock.sol | 3 -- script/DeploySepolia.sol | 3 -- src/IPartyPlanner.sol | 4 -- src/PartyPlanner.sol | 4 -- src/PartyPool.sol | 7 ++-- src/PartyPoolBalancedPair.sol | 3 +- src/PartyPoolDeployer.sol | 5 --- src/PartyPoolMintImpl.sol | 32 ++++++++++------ test/Deploy.sol | 6 +-- test/GasTest.sol | 4 +- test/NativeTest.t.sol | 2 +- test/PartyPlanner.t.sol | 15 ++++---- test/PartyPool.t.sol | 33 +++-------------- 14 files changed, 93 insertions(+), 98 deletions(-) diff --git a/research/pool_design.py b/research/pool_design.py index 0c40ef6..3bcdf56 100644 --- a/research/pool_design.py +++ b/research/pool_design.py @@ -7,7 +7,6 @@ import numpy as np log = logging.getLogger(__name__) -LMSR_FEE = 0.0025 # UNISWAP_GAS=0 # LMSR_GAS=0 UNISWAP_GAS=115_000 @@ -180,31 +179,66 @@ def lmsr_marginal_price(balances, base_index, quote_index, kappa): -def compare(file, tvl, kappa): +def compare(file, tvl, fee, kappa): d = pd.read_csv(file) d.columns = ['block', 'price0', 'price1', 'in0', 'out0', 'rate'] - # Calibrate LMSR balances so that exp((q1 - q0)/b) equals the initial price + # New approach: derive bases from initial external balances (assuming equal-valued deposits) + # This matches the Solidity implementation and eliminates the κ·ln(price) constraint p0 = float(d.iloc[0].price0) - S = float(tvl) # choose the LMSR size metric - b = kappa * S - delta = b * math.log(p0) # q1 - q0 - q0 = 0.5 * (S - delta) - q1 = 0.5 * (S + delta) - if q0 <= 0.0 or q1 <= 0.0: - raise ValueError("Invalid LMSR calibration: choose kappa such that kappa * ln(price0) < 1.") + + # Set external balances assuming equal values: if token0 = B0 and token1 = B1, + # and they have equal value, then B0 * price0 = B1 * price1 = V (value per asset) + # For simplicity, choose B0 such that the total value is tvl, then B1 = B0 * price0 + total_value = float(tvl) + # Since B0 * price0 + B1 = total_value and B1 = B0 * price0, we get: + # B0 * price0 + B0 * price0 = total_value, so B0 = total_value / (2 * price0) + B0 = total_value / (2.0 * p0) # external balance of token 0 + B1 = B0 * p0 # external balance of token 1 (equal value) + + external_balances = [B0, B1] + + # Derive bases: set base_i = B_i so that q_i = B_i / base_i = 1.0 internally + bases = [B0, B1] + + # Internal balances: q_i = external_balance_i / base_i ≈ 1.0 + q0 = B0 / bases[0] # ≈ 1.0 + q1 = B1 / bases[1] # ≈ 1.0 + balances = [q0, q1] - print(balances) + print(f"External balances: {external_balances}") + print(f"Bases: {bases}") + print(f"Internal balances: {balances}") + # Convert external input amounts to internal for LMSR calculations, then convert results back X = np.geomspace(1, 1_000_000, 100) orig_price = lmsr_marginal_price(balances, 0, 1, kappa) - in_out = [(float(amount_in), lmsr_swap_amount_out(balances, float(amount_in), 0, 1, LMSR_FEE, kappa)) for amount_in in X] - print(in_out) + + # Convert X to internal amounts, compute swap, then convert back to external + in_out = [] + for amount_in_external in X: + # Convert external input to internal units + amount_in_internal = amount_in_external / bases[0] # input token 0 + + # Compute swap in internal units + amount_out_internal = lmsr_swap_amount_out(balances, amount_in_internal, 0, 1, fee, kappa) + + # Convert output back to external units + amount_out_external = amount_out_internal * bases[1] # output token 1 + + in_out.append((float(amount_in_external), float(amount_out_external))) + + print(f"Sample internal/external conversions: {in_out[:3]}") + + # Compute initial marginal price in external units + # Internal price is exp((q1 - q0)/b), external price needs conversion by bases[1]/bases[0] + orig_price_external = orig_price * (bases[1] / bases[0]) + # Relative execution price deviation from the initial marginal price: - # slippage = |(amount_out/amount_in)/orig_price - 1| + # slippage = |(amount_out/amount_in)/orig_price_external - 1| eps = 1e-12 - Y = [max(eps, abs((amount_out / amount_in) / orig_price - 1.0)) + Y = [max(eps, abs((amount_out / amount_in) / orig_price_external - 1.0)) for amount_in, amount_out in in_out] - plt.plot(X, Y, label=f'LMSR {LMSR_FEE:.2%} κ={kappa:.2f}', color='cornflowerblue') + plt.plot(X, Y, label=f'LMSR {fee:.2%} κ={kappa:.2g}', color='cornflowerblue') # Uniswap execution price deviation from its initial quoted price: # slippage = |(out/in)/initial_price - 1| @@ -257,6 +291,6 @@ def plot_kappa(): if __name__ == '__main__': # compare('uni4_quotes/swap_results_block_23640998.csv') - # compare('uni4_quotes/ETH-USDC-30.csv', 53_000_000, 0.1) - compare('uni4_quotes/ETH-USDC-30.csv', 1_00_000, .1) + compare('uni4_quotes/ETH-USDC-30.csv', 53_000_000, 0.0025, 0.00025) + # compare('uni4_quotes/ETH-USDC-30.csv', 100_000, 0.0025, 0.00025) # plot_kappa() diff --git a/script/DeployMock.sol b/script/DeployMock.sol index cf412dc..897ea4e 100644 --- a/script/DeployMock.sol +++ b/script/DeployMock.sol @@ -67,7 +67,6 @@ contract DeployMock is Script { 'Token Pool', 'TP', tokens, - _bases, ABDKMath64x64.divu(1, 10), ABDKMath64x64.divu(1,10000), _feePpm, @@ -112,7 +111,6 @@ contract DeployMock is Script { 'Stablecoin Pool', 'STAP', IERC20[](tokens), - _bases, ABDKMath64x64.divu(1, 10), ABDKMath64x64.divu(1,10000), _feePpm, @@ -154,7 +152,6 @@ contract DeployMock is Script { 'Stable Pair', 'SPAIR', IERC20[](tokens), - _bases, ABDKMath64x64.divu(8,10), // kappa = 0.8 _feePpm, _feePpm, diff --git a/script/DeploySepolia.sol b/script/DeploySepolia.sol index 50569b0..fc70ce5 100644 --- a/script/DeploySepolia.sol +++ b/script/DeploySepolia.sol @@ -76,7 +76,6 @@ contract DeploySepolia is Script { 'Token Pool', 'TP', tokens, - _bases, ABDKMath64x64.divu(1, 10), ABDKMath64x64.divu(1,10000), _feePpm, @@ -121,7 +120,6 @@ contract DeploySepolia is Script { 'Stablecoin Pool', 'STAP', tokens, - _bases, ABDKMath64x64.divu(1, 10), ABDKMath64x64.divu(1,10000), _feePpm, @@ -163,7 +161,6 @@ contract DeploySepolia is Script { 'Stable Pair', 'SPAIR', tokens, - _bases, ABDKMath64x64.divu(8,10), // kappa = 0.8 _feePpm, _feePpm, diff --git a/src/IPartyPlanner.sol b/src/IPartyPlanner.sol index 22d9dcf..57c55eb 100644 --- a/src/IPartyPlanner.sol +++ b/src/IPartyPlanner.sol @@ -18,7 +18,6 @@ interface IPartyPlanner is IOwnable { /// @param name LP token name /// @param symbol LP token symbol /// @param tokens token addresses (n) - /// @param bases scaling bases for each token (n) - used when converting to/from internal 64.64 amounts /// @param tradeFrac trade fraction in 64.64 fixed-point (as used by LMSR) /// @param targetSlippage target slippage in 64.64 fixed-point (as used by LMSR) /// @param swapFeePpm fee in parts-per-million, taken from swap input amounts before LMSR calculations @@ -35,7 +34,6 @@ interface IPartyPlanner is IOwnable { string memory name, string memory symbol, IERC20[] memory tokens, - uint256[] memory bases, int128 tradeFrac, int128 targetSlippage, uint256 swapFeePpm, @@ -53,7 +51,6 @@ interface IPartyPlanner is IOwnable { /// @param name LP token name /// @param symbol LP token symbol /// @param tokens token addresses (n) - /// @param bases scaling bases for each token (n) - used when converting to/from internal 64.64 amounts /// @param kappa liquidity parameter κ in 64.64 fixed-point used to derive b = κ * S(q) /// @param swapFeePpm fee in parts-per-million, taken from swap input amounts before LMSR calculations /// @param flashFeePpm fee in parts-per-million, taken for flash loans @@ -69,7 +66,6 @@ interface IPartyPlanner is IOwnable { string memory name, string memory symbol, IERC20[] memory tokens, - uint256[] memory bases, int128 kappa, uint256 swapFeePpm, uint256 flashFeePpm, diff --git a/src/PartyPlanner.sol b/src/PartyPlanner.sol index 0849606..e323157 100644 --- a/src/PartyPlanner.sol +++ b/src/PartyPlanner.sol @@ -87,7 +87,6 @@ contract PartyPlanner is OwnableExternal, IPartyPlanner { string memory name_, string memory symbol_, IERC20[] memory tokens_, - uint256[] memory bases_, int128 kappa_, uint256 swapFeePpm_, uint256 flashFeePpm_, @@ -115,7 +114,6 @@ contract PartyPlanner is OwnableExternal, IPartyPlanner { name_, symbol_, tokens_, - bases_, kappa_, swapFeePpm_, flashFeePpm_, @@ -165,7 +163,6 @@ contract PartyPlanner is OwnableExternal, IPartyPlanner { string memory name_, string memory symbol_, IERC20[] memory tokens_, - uint256[] memory bases_, int128 tradeFrac_, int128 targetSlippage_, uint256 swapFeePpm_, @@ -190,7 +187,6 @@ contract PartyPlanner is OwnableExternal, IPartyPlanner { name_, symbol_, tokens_, - bases_, computedKappa, swapFeePpm_, flashFeePpm_, diff --git a/src/PartyPool.sol b/src/PartyPool.sol index 0fdd2fa..2e09214 100644 --- a/src/PartyPool.sol +++ b/src/PartyPool.sol @@ -99,7 +99,6 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool /// @param name_ LP token name /// @param symbol_ LP token symbol /// @param tokens_ token addresses (n) - /// @param bases_ scaling _bases for each token (n) - used when converting to/from internal 64.64 amounts /// @param kappa_ liquidity parameter κ (Q64.64) used to derive b = κ * S(q) /// @param swapFeePpm_ fee in parts-per-million, taken from swap input amounts before LMSR calculations /// @param flashFeePpm_ fee in parts-per-million, taken for flash loans @@ -110,7 +109,6 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool string memory name_, string memory symbol_, IERC20[] memory tokens_, - uint256[] memory bases_, int128 kappa_, uint256 swapFeePpm_, uint256 flashFeePpm_, @@ -126,9 +124,7 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool { require(owner_ != address(0)); require(tokens_.length > 1, "Pool: need >1 asset"); - require(tokens_.length == bases_.length, "Pool: lengths mismatch"); _tokens = tokens_; - _bases = bases_; KAPPA = kappa_; require(swapFeePpm_ < 1_000_000, "Pool: fee >= ppm"); SWAP_FEE_PPM = swapFeePpm_; @@ -153,6 +149,9 @@ contract PartyPool is PartyPoolBase, OwnableExternal, ERC20External, IPartyPool unchecked {i++;} } + // Allocate denominators (bases) to be computed during initialMint from initial deposits + _bases = new uint256[](n); + // Initialize caches to zero and protocol ledger _cachedUintBalances = new uint256[](n); _protocolFeesOwed = new uint256[](n); diff --git a/src/PartyPoolBalancedPair.sol b/src/PartyPoolBalancedPair.sol index 80f04ce..f7f3399 100644 --- a/src/PartyPoolBalancedPair.sol +++ b/src/PartyPoolBalancedPair.sol @@ -15,7 +15,6 @@ contract PartyPoolBalancedPair is PartyPool { string memory name_, string memory symbol_, IERC20[] memory tokens_, - uint256[] memory bases_, int128 kappa_, uint256 swapFeePpm_, uint256 flashFeePpm_, @@ -25,7 +24,7 @@ contract PartyPoolBalancedPair is PartyPool { PartyPoolSwapImpl swapMintImpl_, PartyPoolMintImpl mintImpl_ ) - PartyPool(owner_, name_, symbol_, tokens_, bases_, kappa_, swapFeePpm_, flashFeePpm_, protocolFeePpm_, protocolFeeAddress_, wrapperToken_, swapMintImpl_, mintImpl_) + PartyPool(owner_, name_, symbol_, tokens_, kappa_, swapFeePpm_, flashFeePpm_, protocolFeePpm_, protocolFeeAddress_, wrapperToken_, swapMintImpl_, mintImpl_) {} function _swapAmountsForExactInput(uint256 i, uint256 j, int128 a, int128 limitPrice) internal virtual override view diff --git a/src/PartyPoolDeployer.sol b/src/PartyPoolDeployer.sol index ac297e1..aabaf60 100644 --- a/src/PartyPoolDeployer.sol +++ b/src/PartyPoolDeployer.sol @@ -15,7 +15,6 @@ interface IPartyPoolDeployer { string memory name_, string memory symbol_, IERC20[] memory tokens_, - uint256[] memory bases_, int128 kappa_, uint256 swapFeePpm_, uint256 flashFeePpm_, @@ -33,7 +32,6 @@ contract PartyPoolDeployer is IPartyPoolDeployer { string memory name_, string memory symbol_, IERC20[] memory tokens_, - uint256[] memory bases_, int128 kappa_, uint256 swapFeePpm_, uint256 flashFeePpm_, @@ -48,7 +46,6 @@ contract PartyPoolDeployer is IPartyPoolDeployer { name_, symbol_, tokens_, - bases_, kappa_, swapFeePpm_, flashFeePpm_, @@ -67,7 +64,6 @@ contract PartyPoolBalancedPairDeployer is IPartyPoolDeployer { string memory name_, string memory symbol_, IERC20[] memory tokens_, - uint256[] memory bases_, int128 kappa_, uint256 swapFeePpm_, uint256 flashFeePpm_, @@ -82,7 +78,6 @@ contract PartyPoolBalancedPairDeployer is IPartyPoolDeployer { name_, symbol_, tokens_, - bases_, kappa_, swapFeePpm_, flashFeePpm_, diff --git a/src/PartyPoolMintImpl.sol b/src/PartyPoolMintImpl.sol index 121432e..50f6e40 100644 --- a/src/PartyPoolMintImpl.sol +++ b/src/PartyPoolMintImpl.sol @@ -33,30 +33,38 @@ contract PartyPoolMintImpl is PartyPoolBase { bool isInitialDeposit = _totalSupply == 0 || _lmsr.nAssets == 0; require(isInitialDeposit, "initialMint: pool already initialized"); - // Update cached balances for all assets + // Read initial on-chain balances, require all > 0, and compute denominators (bases) from deposits. + // We assume equal-valued deposits; set base[i] = depositAmount so internal q_i starts at 1.0. int128[] memory newQInternal = new int128[](n); uint256[] memory depositAmounts = new uint256[](n); + for (uint i = 0; i < n; ) { uint256 bal = IERC20(_tokens[i]).balanceOf(address(this)); - _cachedUintBalances[i] = bal; - newQInternal[i] = _uintToInternalFloor(bal, _bases[i]); + require(bal > 0, "initialMint: zero initial balance"); depositAmounts[i] = bal; + + // Cache external balances + _cachedUintBalances[i] = bal; + + // Set per-asset denominator to the observed deposit amount (at least 1) + _bases[i] = bal; + + // Compute internal q_i = bal / base_i => ~1.0 in 64.64 + newQInternal[i] = _uintToInternalFloor(bal, _bases[i]); + require(newQInternal[i] > int128(0), "initialMint: zero internal q"); + unchecked { i++; } } // Initialize the stabilized LMSR state with provided kappa _lmsr.init(newQInternal, KAPPA); - // Compute actual LP _tokens to mint based on size metric (scaled) - if( lpTokens != 0 ) - lpMinted = lpTokens; - else { - int128 newTotal = _computeSizeMetric(newQInternal); - lpMinted = ABDKMath64x64.mulu(newTotal, LP_SCALE); - } + // Obey the passed-in initial LP amount. If 0, default to 1e18 + lpMinted = lpTokens == 0 ? 1e18 : lpTokens; - require(lpMinted > 0, "initialMint: zero LP amount"); - _mint(receiver, lpMinted); + if (lpMinted > 0) { + _mint(receiver, lpMinted); + } emit IPartyPool.Mint(address(0), receiver, depositAmounts, lpMinted); } diff --git a/test/Deploy.sol b/test/Deploy.sol index 4ceece1..870327e 100644 --- a/test/Deploy.sol +++ b/test/Deploy.sol @@ -44,14 +44,13 @@ library Deploy { string memory name_, string memory symbol_, IERC20[] memory tokens_, - uint256[] memory bases_, int128 _kappa, uint256 _swapFeePpm, uint256 _flashFeePpm, bool _stable ) internal returns (PartyPool) { NativeWrapper wrapper = new WETH9(); - return newPartyPool(owner_, name_, symbol_, tokens_, bases_, _kappa, _swapFeePpm, _flashFeePpm, wrapper, _stable); + return newPartyPool(owner_, name_, symbol_, tokens_, _kappa, _swapFeePpm, _flashFeePpm, wrapper, _stable); } function newPartyPool( @@ -59,7 +58,6 @@ library Deploy { string memory name_, string memory symbol_, IERC20[] memory tokens_, - uint256[] memory bases_, int128 _kappa, uint256 _swapFeePpm, uint256 _flashFeePpm, @@ -72,7 +70,6 @@ library Deploy { name_, symbol_, tokens_, - bases_, _kappa, _swapFeePpm, _flashFeePpm, @@ -87,7 +84,6 @@ library Deploy { name_, symbol_, tokens_, - bases_, _kappa, _swapFeePpm, _flashFeePpm, diff --git a/test/GasTest.sol b/test/GasTest.sol index a21bfef..623b884 100644 --- a/test/GasTest.sol +++ b/test/GasTest.sol @@ -141,7 +141,7 @@ contract GasTest is Test { } // Compute kappa from slippage params and number of _tokens, then construct pool with kappa int128 computedKappa = LMSRStabilized.computeKappaFromSlippage(ierc20Tokens.length, tradeFrac, targetSlippage); - PartyPool newPool = Deploy.newPartyPool(address(this), poolName, poolName, ierc20Tokens, bases, computedKappa, feePpm, feePpm, false); + PartyPool newPool = Deploy.newPartyPool(address(this), poolName, poolName, ierc20Tokens, computedKappa, feePpm, feePpm, false); // Transfer initial deposit amounts into pool before initial mint for (uint256 i = 0; i < numTokens; i++) { @@ -181,7 +181,7 @@ contract GasTest is Test { ierc20Tokens[i] = IERC20(tokens[i]); } int128 computedKappa = LMSRStabilized.computeKappaFromSlippage(ierc20Tokens.length, tradeFrac, targetSlippage); - PartyPool newPool = Deploy.newPartyPool(address(this), poolName, poolName, ierc20Tokens, bases, computedKappa, feePpm, feePpm, true); + PartyPool newPool = Deploy.newPartyPool(address(this), poolName, poolName, ierc20Tokens, computedKappa, feePpm, feePpm, true); // Transfer initial deposit amounts into pool before initial mint for (uint256 i = 0; i < numTokens; i++) { diff --git a/test/NativeTest.t.sol b/test/NativeTest.t.sol index 5d691e9..e6948a9 100644 --- a/test/NativeTest.t.sol +++ b/test/NativeTest.t.sol @@ -94,7 +94,7 @@ contract NativeTest is Test { uint256 feePpm = 1000; int128 kappa = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage); - pool = Deploy.newPartyPool(address(this), "LP", "LP", tokens, bases, kappa, feePpm, feePpm, weth, false); + pool = Deploy.newPartyPool(address(this), "LP", "LP", tokens, kappa, feePpm, feePpm, weth, false); // Transfer initial deposit amounts into pool token0.transfer(address(pool), INIT_BAL); diff --git a/test/PartyPlanner.t.sol b/test/PartyPlanner.t.sol index d901450..50f8cd7 100644 --- a/test/PartyPlanner.t.sol +++ b/test/PartyPlanner.t.sol @@ -100,7 +100,6 @@ contract PartyPlannerTest is Test { name, symbol, tokens, - bases, computedKappa, swapFeePpm, flashFeePpm, @@ -176,7 +175,7 @@ contract PartyPlannerTest is Test { int128 kappa1 = LMSRStabilized.computeKappaFromSlippage(tokens1.length, int128((1 << 64) - 1), int128(1 << 62)); (IPartyPool pool1,) = planner.newPool( - "Pool 1", "LP1", tokens1, bases1, + "Pool 1", "LP1", tokens1, kappa1, 3000, 5000, false, payer, receiver, deposits1, 1000e18, 0 ); @@ -196,7 +195,7 @@ contract PartyPlannerTest is Test { int128 kappa2 = LMSRStabilized.computeKappaFromSlippage(tokens2.length, int128((1 << 64) - 1), int128(1 << 62)); (IPartyPool pool2,) = planner.newPool( - "Pool 2", "LP2", tokens2, bases2, + "Pool 2", "LP2", tokens2, kappa2, 3000, 5000, false, payer, receiver, deposits2, 1000e18, 0 ); @@ -240,7 +239,7 @@ contract PartyPlannerTest is Test { vm.expectRevert("Planner: tokens and deposits length mismatch"); // call old-signature convenience (it will still exist) for the mismatched-length revert check planner.newPool( - "Test Pool", "TESTLP", tokens, bases, + "Test Pool", "TESTLP", tokens, int128((1 << 64) - 1), int128(1 << 62), 3000, 5000, false, payer, receiver, deposits, 1000e18, 0 ); @@ -254,7 +253,7 @@ contract PartyPlannerTest is Test { vm.expectRevert("Planner: payer cannot be zero address"); planner.newPool( - "Test Pool", "TESTLP", tokens, bases, + "Test Pool", "TESTLP", tokens, kappaErr, 3000, 5000, false, address(0), receiver, validDeposits, 1000e18, 0 ); @@ -262,7 +261,7 @@ contract PartyPlannerTest is Test { // Test zero receiver address vm.expectRevert("Planner: receiver cannot be zero address"); planner.newPool( - "Test Pool", "TESTLP", tokens, bases, + "Test Pool", "TESTLP", tokens, kappaErr, 3000, 5000, false, payer, address(0), validDeposits, 1000e18, 0 ); @@ -273,7 +272,7 @@ contract PartyPlannerTest is Test { vm.warp(1000); vm.expectRevert("Planner: deadline exceeded"); planner.newPool( - "Test Pool", "TESTLP", tokens, bases, + "Test Pool", "TESTLP", tokens, kappaDeadline, 3000, 5000, false, payer, receiver, validDeposits, 1000e18, block.timestamp - 1 ); @@ -301,7 +300,7 @@ contract PartyPlannerTest is Test { (IPartyPool pool,) = planner.newPool( string(abi.encodePacked("Pool ", vm.toString(i))), string(abi.encodePacked("LP", vm.toString(i))), - tokens, bases, + tokens, kappaLoop, 3000, 5000, false, payer, receiver, deposits, 1000e18, 0 ); diff --git a/test/PartyPool.t.sol b/test/PartyPool.t.sol index 628928a..b0873ee 100644 --- a/test/PartyPool.t.sol +++ b/test/PartyPool.t.sol @@ -123,7 +123,6 @@ contract PartyPoolTest is Test { int128 targetSlippage; uint256 constant INIT_BAL = 1_000_000; // initial token units for each token (internal==amount when base==1) - uint256 constant BASE = 1; // use base=1 so internal amounts correspond to raw integers (Q64.64 units) function setUp() public { planner = Deploy.newPartyPlanner(); @@ -164,16 +163,11 @@ contract PartyPoolTest is Test { tokens[1] = IERC20(address(token1)); tokens[2] = IERC20(address(token2)); - uint256[] memory bases = new uint256[](3); - bases[0] = BASE; - bases[1] = BASE; - bases[2] = BASE; - // Deploy pool with a small fee to test fee-handling paths (use 1000 ppm = 0.1%) uint256 feePpm = 1000; int128 kappa3 = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage); - pool = Deploy.newPartyPool(address(this), "LP", "LP", tokens, bases, kappa3, feePpm, feePpm, false); + pool = Deploy.newPartyPool(address(this), "LP", "LP", tokens, kappa3, feePpm, feePpm, false); // Transfer initial deposit amounts into pool before initial mint (pool expects _tokens already in contract) // We deposit equal amounts INIT_BAL for each token @@ -197,13 +191,8 @@ contract PartyPoolTest is Test { tokens10[8] = IERC20(address(token8)); tokens10[9] = IERC20(address(token9)); - uint256[] memory bases10 = new uint256[](10); - for (uint i = 0; i < 10; i++) { - bases10[i] = BASE; - } - int128 kappa10 = LMSRStabilized.computeKappaFromSlippage(tokens10.length, tradeFrac, targetSlippage); - pool10 = Deploy.newPartyPool(address(this), "LP10", "LP10", tokens10, bases10, kappa10, feePpm, feePpm, false); + pool10 = Deploy.newPartyPool(address(this), "LP10", "LP10", tokens10, kappa10, feePpm, feePpm, false); // Mint additional _tokens for pool10 initial deposit token0.mint(address(this), INIT_BAL); @@ -983,20 +972,15 @@ contract PartyPoolTest is Test { tokens[1] = IERC20(address(token1)); tokens[2] = IERC20(address(token2)); - uint256[] memory bases = new uint256[](3); - bases[0] = BASE; - bases[1] = BASE; - bases[2] = BASE; - uint256 feePpm = 1000; // Pool with default initialization (lpTokens = 0) int128 kappaDefault = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage); - PartyPool poolDefault = Deploy.newPartyPool(address(this), "LP_DEFAULT", "LP_DEFAULT", tokens, bases, kappaDefault, feePpm, feePpm, false); + PartyPool poolDefault = Deploy.newPartyPool(address(this), "LP_DEFAULT", "LP_DEFAULT", tokens, kappaDefault, feePpm, feePpm, false); // Pool with custom initialization (lpTokens = custom amount) int128 kappaCustom = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage); - PartyPool poolCustom = Deploy.newPartyPool(address(this), "LP_CUSTOM", "LP_CUSTOM", tokens, bases, kappaCustom, feePpm, feePpm, false); + PartyPool poolCustom = Deploy.newPartyPool(address(this), "LP_CUSTOM", "LP_CUSTOM", tokens, kappaCustom, feePpm, feePpm, false); // Mint additional _tokens for both pools token0.mint(address(this), INIT_BAL * 2); @@ -1060,17 +1044,12 @@ contract PartyPoolTest is Test { tokens[1] = IERC20(address(token1)); tokens[2] = IERC20(address(token2)); - uint256[] memory bases = new uint256[](3); - bases[0] = BASE; - bases[1] = BASE; - bases[2] = BASE; - uint256 feePpm = 1000; int128 kappaDefault2 = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage); - PartyPool poolDefault = Deploy.newPartyPool(address(this), "LP_DEFAULT", "LP_DEFAULT", tokens, bases, kappaDefault2, feePpm, feePpm, false); + PartyPool poolDefault = Deploy.newPartyPool(address(this), "LP_DEFAULT", "LP_DEFAULT", tokens, kappaDefault2, feePpm, feePpm, false); int128 kappaCustom2 = LMSRStabilized.computeKappaFromSlippage(tokens.length, tradeFrac, targetSlippage); - PartyPool poolCustom = Deploy.newPartyPool(address(this), "LP_CUSTOM", "LP_CUSTOM", tokens, bases, kappaCustom2, feePpm, feePpm, false); + PartyPool poolCustom = Deploy.newPartyPool(address(this), "LP_CUSTOM", "LP_CUSTOM", tokens, kappaCustom2, feePpm, feePpm, false); // Mint additional _tokens token0.mint(address(this), INIT_BAL * 4);