From 38371614fc74022a01df8af56fd1aa925cb92a05 Mon Sep 17 00:00:00 2001 From: tim Date: Wed, 15 Oct 2025 14:55:15 -0400 Subject: [PATCH] mock sets up three pools including a stablecoin pair pool and a pool with native wrapper token --- script/DeployMock.sol | 149 ++++++++++++++++++++++++++++++++++-------- src/PartyPlanner.sol | 2 + src/PartyPool.sol | 2 - test/NativeTest.t.sol | 15 ++--- 4 files changed, 128 insertions(+), 40 deletions(-) diff --git a/script/DeployMock.sol b/script/DeployMock.sol index 318cdb5..a3996ba 100644 --- a/script/DeployMock.sol +++ b/script/DeployMock.sol @@ -23,58 +23,143 @@ contract DeployMock is Script { usxd = new MockERC20('Joke Currency', 'USXD', 6); fusd = new MockERC20('Fake USD', 'FUSD', 6); dive = new MockERC20('DAI Virtually Equal', 'DIVE', 18); - - string memory name = 'Mock Pool'; - string memory symbol = 'MP'; - IERC20[] memory tokens = new IERC20[](3); - tokens[0] = IERC20(usxd); - tokens[1] = IERC20(fusd); - tokens[2] = IERC20(dive); - uint256[] memory _bases = new uint256[](3); - _bases[0] = 10**6; - _bases[1] = 10**6; - _bases[2] = 10**18; - int128 _tradeFrac = ABDKMath64x64.divu(1, 10); - int128 _targetSlippage = ABDKMath64x64.divu(1,10000); - uint256 _feePpm = 100; + butc = new MockERC20('Buttcoin', 'BUTC', 8); + wteth = new MockERC20('Wrapped TETH', 'WTETH', 18); // deploy a PartyPlanner factory and create the pool via factory PartyPlanner planner = Deploy.newPartyPlanner(); + // + // Deploy 3-asset pool + // + + uint256 _feePpm = 200; + IERC20[] memory tokens = new IERC20[](3); + tokens[0] = IERC20(usxd); + tokens[1] = IERC20(butc); + tokens[2] = IERC20(wteth); + uint256[] memory _bases = new uint256[](3); + _bases[0] = 10**6; + _bases[1] = 10**8; + _bases[2] = 10**18; + + // mint _tokens to the deployer so it can fund the initial deposits and approve the factory + mintAll(msg.sender, 10_000); // prepare initial deposits (10_000 units of each token, scaled by _bases) uint256[] memory initialDeposits = new uint256[](3); initialDeposits[0] = _bases[0] * 10_000; initialDeposits[1] = _bases[1] * 10_000; initialDeposits[2] = _bases[2] * 10_000; - uint256 initialLpAmount = 0; - uint256 deadline = 0; - - // mint _tokens to the deployer so it can fund the initial deposits and approve the factory - mintAll(msg.sender, 10_000); - // approve factory to move initial deposits for (uint i = 0; i < tokens.length; i++) { IERC20(tokens[i]).approve(address(planner), initialDeposits[i]); } // call full newPool signature on factory which will take the deposits and mint initial LP - (IPartyPool pool, ) = planner.newPool( - name, - symbol, + planner.newPool( + 'Token Pool', + 'TP', tokens, _bases, - _tradeFrac, - _targetSlippage, + ABDKMath64x64.divu(1, 10), + ABDKMath64x64.divu(1,10000), _feePpm, _feePpm, false, msg.sender, // payer: this script DEV_ACCOUNT_7, // receiver of initial LP initialDeposits, - initialLpAmount, - deadline + 10000, + 0 ); + + // + // Deploy 3-asset stablecoin pool + // + + _feePpm = 100; + tokens = new IERC20[](3); + tokens[0] = IERC20(usxd); + tokens[1] = IERC20(fusd); + tokens[2] = IERC20(dive); + _bases = new uint256[](3); + _bases[0] = 10**6; + _bases[1] = 10**6; + _bases[2] = 10**18; + + // mint _tokens to the deployer so it can fund the initial deposits and approve the factory + mintAll(msg.sender, 10_000); + // prepare initial deposits (10_000 units of each token, scaled by _bases) + initialDeposits = new uint256[](3); + initialDeposits[0] = _bases[0] * 10_000; + initialDeposits[1] = _bases[1] * 10_000; + initialDeposits[2] = _bases[2] * 10_000; + // approve factory to move initial deposits + for (uint i = 0; i < tokens.length; i++) { + IERC20(tokens[i]).approve(address(planner), initialDeposits[i]); + } + + // call full newPool signature on factory which will take the deposits and mint initial LP + planner.newPool( + 'Stablecoin Pool', + 'STAP', + tokens, + _bases, + ABDKMath64x64.divu(1, 10), + ABDKMath64x64.divu(1,10000), + _feePpm, + _feePpm, + false, + msg.sender, // payer: this script + DEV_ACCOUNT_7, // receiver of initial LP + initialDeposits, + 10000, + 0 + ); + + + // + // Deploy 2-asset balanced pair pool + // + + _feePpm = 80; + tokens = new IERC20[](2); + tokens[0] = IERC20(usxd); + tokens[1] = IERC20(dive); + _bases = new uint256[](2); + _bases[0] = 10**6; + _bases[1] = 10**18; + + // mint _tokens to the deployer so it can fund the initial deposits and approve the factory + mintAll(msg.sender, 10_000); + // prepare initial deposits (10_000 units of each token, scaled by _bases) + initialDeposits = new uint256[](2); + initialDeposits[0] = _bases[0] * 10_000; + initialDeposits[1] = _bases[1] * 10_000; + // approve factory to move initial deposits + for (uint i = 0; i < tokens.length; i++) { + IERC20(tokens[i]).approve(address(planner), initialDeposits[i]); + } + + // call full newPool signature on factory which will take the deposits and mint initial LP + planner.newPool( + 'Stable Pair', + 'SPAIR', + tokens, + _bases, + ABDKMath64x64.divu(8,10), // kappa = 0.8 + _feePpm, + _feePpm, + true, // STABLE + msg.sender, // payer: this script + DEV_ACCOUNT_7, // receiver of initial LP + initialDeposits, + 10000, + 0 + ); + + // give _tokens to dev7 for later use mintAll(DEV_ACCOUNT_7, 1_000_000); @@ -83,10 +168,11 @@ contract DeployMock is Script { // Set ENV vars string memory plannerStr = vm.toString(address(planner)); vm.setEnv('PLANNER', plannerStr); - vm.setEnv('POOL', vm.toString(address(pool))); vm.setEnv('USXD', vm.toString(address(usxd))); vm.setEnv('FUSD', vm.toString(address(fusd))); vm.setEnv('DIVE', vm.toString(address(dive))); + vm.setEnv('BUTC', vm.toString(address(butc))); + vm.setEnv('WTETH', vm.toString(address(wteth))); // Write JSON config file string memory config = 'config'; @@ -99,21 +185,26 @@ contract DeployMock is Script { console2.log(); console2.log(' PartyPlanner', address(planner)); - console2.log(' PartyPool', address(pool)); 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)); } MockERC20 private usxd; MockERC20 private fusd; MockERC20 private dive; + MockERC20 private butc; + MockERC20 private wteth; function mintAll(address who, uint256 amount) internal { usxd.mint(who, amount * 1e6); fusd.mint(who, amount * 1e6); dive.mint(who, amount * 1e18); + butc.mint(who, amount * 1e8); + wteth.mint(who, amount * 1e18); } } diff --git a/src/PartyPlanner.sol b/src/PartyPlanner.sol index 424b0e1..8b60123 100644 --- a/src/PartyPlanner.sol +++ b/src/PartyPlanner.sol @@ -34,6 +34,8 @@ contract PartyPlanner is IPartyPlanner { function protocolFeeAddress() external view returns (address) { return PROTOCOL_FEE_ADDRESS; } IWETH9 private immutable WRAPPER; + function wrapper() external view returns (IWETH9) { return WRAPPER; } + IPartyPoolDeployer private immutable NORMAL_POOL_DEPLOYER; IPartyPoolDeployer private immutable BALANCED_PAIR_DEPLOYER; diff --git a/src/PartyPool.sol b/src/PartyPool.sol index a5b07ba..14e3a86 100644 --- a/src/PartyPool.sol +++ b/src/PartyPool.sol @@ -291,8 +291,6 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool { uint256 feeUint ) { - uint256 n = _tokens.length; - // Estimate max net input (fee on gross rounded up, then subtract) (, uint256 netUintForSwap) = _computeFee(maxAmountIn, SWAP_FEE_PPM); diff --git a/test/NativeTest.t.sol b/test/NativeTest.t.sol index 36a1345..b077444 100644 --- a/test/NativeTest.t.sol +++ b/test/NativeTest.t.sol @@ -140,7 +140,7 @@ contract NativeTest is Test { // Execute swap: WETH (index 2) -> token0 (index 0) // Send native currency with {value: maxIn} - (uint256 amountIn, uint256 amountOut, uint256 fee) = pool.swap{value: maxIn}( + (uint256 amountIn, uint256 amountOut, ) = pool.swap{value: maxIn}( alice, // payer alice, // receiver 2, // inputTokenIndex (WETH) @@ -177,7 +177,7 @@ contract NativeTest is Test { uint256 aliceEthBefore = alice.balance; // Execute swap: token0 (index 0) -> WETH (index 2) with unwrap=true - (uint256 amountIn, uint256 amountOut, uint256 fee) = pool.swap( + (uint256 amountIn, uint256 amountOut, ) = pool.swap( alice, // payer alice, // receiver 0, // inputTokenIndex (token0) @@ -212,7 +212,7 @@ contract NativeTest is Test { uint256 aliceEthBefore = alice.balance; // Execute swap with excess native currency - (uint256 amountIn, uint256 amountOut, uint256 fee) = pool.swap{value: totalSent}( + (uint256 amountIn, , ) = pool.swap{value: totalSent}( alice, // payer alice, // receiver 2, // inputTokenIndex (WETH) @@ -225,7 +225,6 @@ contract NativeTest is Test { // Verify that only amountIn was used, and excess was refunded assertTrue(amountIn <= maxIn, "used input must not exceed max"); - uint256 expectedRefund = totalSent - amountIn; assertEq(alice.balance, aliceEthBefore - amountIn, "Alice should be refunded excess ETH"); vm.stopPrank(); @@ -537,21 +536,19 @@ contract NativeTest is Test { token0.approve(address(pool), type(uint256).max); token1.approve(address(pool), type(uint256).max); - uint256 aliceEthStart = alice.balance; - uint256 lpMinted = pool.mint{value: deposits[2]}(alice, alice, lpRequest, 0); assertTrue(lpMinted > 0, "Should mint LP"); // 2. Swap native currency for token0 uint256 swapAmount = 5_000; - (uint256 amountIn, uint256 amountOut, ) = pool.swap{value: swapAmount}( + (, uint256 amountOut, ) = pool.swap{value: swapAmount}( alice, alice, 2, 0, swapAmount, 0, 0, false ); assertTrue(amountOut > 0, "Should receive token0"); // 3. Swap token0 back to native currency uint256 token0Balance = token0.balanceOf(alice); - (uint256 swapIn2, uint256 swapOut2, ) = pool.swap( + (, uint256 swapOut2, ) = pool.swap( alice, alice, 0, 2, token0Balance / 2, 0, 0, true ); assertTrue(swapOut2 > 0, "Should receive native currency"); @@ -578,7 +575,7 @@ contract NativeTest is Test { uint256 aliceEthBefore = alice.balance; // Swap token0 -> WETH without unwrap - (uint256 amountIn, uint256 amountOut, ) = pool.swap( + (, uint256 amountOut, ) = pool.swap( alice, alice, 0, 2, maxIn, 0, 0, false // unwrap=false );