mock sets up three pools including a stablecoin pair pool and a pool with native wrapper token
This commit is contained in:
@@ -23,58 +23,143 @@ contract DeployMock is Script {
|
|||||||
usxd = new MockERC20('Joke Currency', 'USXD', 6);
|
usxd = new MockERC20('Joke Currency', 'USXD', 6);
|
||||||
fusd = new MockERC20('Fake USD', 'FUSD', 6);
|
fusd = new MockERC20('Fake USD', 'FUSD', 6);
|
||||||
dive = new MockERC20('DAI Virtually Equal', 'DIVE', 18);
|
dive = new MockERC20('DAI Virtually Equal', 'DIVE', 18);
|
||||||
|
butc = new MockERC20('Buttcoin', 'BUTC', 8);
|
||||||
string memory name = 'Mock Pool';
|
wteth = new MockERC20('Wrapped TETH', 'WTETH', 18);
|
||||||
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;
|
|
||||||
|
|
||||||
// deploy a PartyPlanner factory and create the pool via factory
|
// deploy a PartyPlanner factory and create the pool via factory
|
||||||
PartyPlanner planner = Deploy.newPartyPlanner();
|
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)
|
// prepare initial deposits (10_000 units of each token, scaled by _bases)
|
||||||
uint256[] memory initialDeposits = new uint256[](3);
|
uint256[] memory initialDeposits = new uint256[](3);
|
||||||
initialDeposits[0] = _bases[0] * 10_000;
|
initialDeposits[0] = _bases[0] * 10_000;
|
||||||
initialDeposits[1] = _bases[1] * 10_000;
|
initialDeposits[1] = _bases[1] * 10_000;
|
||||||
initialDeposits[2] = _bases[2] * 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
|
// approve factory to move initial deposits
|
||||||
for (uint i = 0; i < tokens.length; i++) {
|
for (uint i = 0; i < tokens.length; i++) {
|
||||||
IERC20(tokens[i]).approve(address(planner), initialDeposits[i]);
|
IERC20(tokens[i]).approve(address(planner), initialDeposits[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// call full newPool signature on factory which will take the deposits and mint initial LP
|
// call full newPool signature on factory which will take the deposits and mint initial LP
|
||||||
(IPartyPool pool, ) = planner.newPool(
|
planner.newPool(
|
||||||
name,
|
'Token Pool',
|
||||||
symbol,
|
'TP',
|
||||||
tokens,
|
tokens,
|
||||||
_bases,
|
_bases,
|
||||||
_tradeFrac,
|
ABDKMath64x64.divu(1, 10),
|
||||||
_targetSlippage,
|
ABDKMath64x64.divu(1,10000),
|
||||||
_feePpm,
|
_feePpm,
|
||||||
_feePpm,
|
_feePpm,
|
||||||
false,
|
false,
|
||||||
msg.sender, // payer: this script
|
msg.sender, // payer: this script
|
||||||
DEV_ACCOUNT_7, // receiver of initial LP
|
DEV_ACCOUNT_7, // receiver of initial LP
|
||||||
initialDeposits,
|
initialDeposits,
|
||||||
initialLpAmount,
|
10000,
|
||||||
deadline
|
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
|
// give _tokens to dev7 for later use
|
||||||
mintAll(DEV_ACCOUNT_7, 1_000_000);
|
mintAll(DEV_ACCOUNT_7, 1_000_000);
|
||||||
|
|
||||||
@@ -83,10 +168,11 @@ contract DeployMock is Script {
|
|||||||
// Set ENV vars
|
// Set ENV vars
|
||||||
string memory plannerStr = vm.toString(address(planner));
|
string memory plannerStr = vm.toString(address(planner));
|
||||||
vm.setEnv('PLANNER', plannerStr);
|
vm.setEnv('PLANNER', plannerStr);
|
||||||
vm.setEnv('POOL', vm.toString(address(pool)));
|
|
||||||
vm.setEnv('USXD', vm.toString(address(usxd)));
|
vm.setEnv('USXD', vm.toString(address(usxd)));
|
||||||
vm.setEnv('FUSD', vm.toString(address(fusd)));
|
vm.setEnv('FUSD', vm.toString(address(fusd)));
|
||||||
vm.setEnv('DIVE', vm.toString(address(dive)));
|
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
|
// Write JSON config file
|
||||||
string memory config = 'config';
|
string memory config = 'config';
|
||||||
@@ -99,21 +185,26 @@ contract DeployMock is Script {
|
|||||||
|
|
||||||
console2.log();
|
console2.log();
|
||||||
console2.log(' PartyPlanner', address(planner));
|
console2.log(' PartyPlanner', address(planner));
|
||||||
console2.log(' PartyPool', address(pool));
|
|
||||||
console2.log('PartyPoolViewer', address(viewer));
|
console2.log('PartyPoolViewer', address(viewer));
|
||||||
console2.log(' USXD', address(usxd));
|
console2.log(' USXD', address(usxd));
|
||||||
console2.log(' FUSD', address(fusd));
|
console2.log(' FUSD', address(fusd));
|
||||||
console2.log(' DIVE', address(dive));
|
console2.log(' DIVE', address(dive));
|
||||||
|
console2.log(' BUTC', address(butc));
|
||||||
|
console2.log(' WTETH', address(wteth));
|
||||||
}
|
}
|
||||||
|
|
||||||
MockERC20 private usxd;
|
MockERC20 private usxd;
|
||||||
MockERC20 private fusd;
|
MockERC20 private fusd;
|
||||||
MockERC20 private dive;
|
MockERC20 private dive;
|
||||||
|
MockERC20 private butc;
|
||||||
|
MockERC20 private wteth;
|
||||||
|
|
||||||
function mintAll(address who, uint256 amount) internal {
|
function mintAll(address who, uint256 amount) internal {
|
||||||
usxd.mint(who, amount * 1e6);
|
usxd.mint(who, amount * 1e6);
|
||||||
fusd.mint(who, amount * 1e6);
|
fusd.mint(who, amount * 1e6);
|
||||||
dive.mint(who, amount * 1e18);
|
dive.mint(who, amount * 1e18);
|
||||||
|
butc.mint(who, amount * 1e8);
|
||||||
|
wteth.mint(who, amount * 1e18);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ contract PartyPlanner is IPartyPlanner {
|
|||||||
function protocolFeeAddress() external view returns (address) { return PROTOCOL_FEE_ADDRESS; }
|
function protocolFeeAddress() external view returns (address) { return PROTOCOL_FEE_ADDRESS; }
|
||||||
|
|
||||||
IWETH9 private immutable WRAPPER;
|
IWETH9 private immutable WRAPPER;
|
||||||
|
function wrapper() external view returns (IWETH9) { return WRAPPER; }
|
||||||
|
|
||||||
IPartyPoolDeployer private immutable NORMAL_POOL_DEPLOYER;
|
IPartyPoolDeployer private immutable NORMAL_POOL_DEPLOYER;
|
||||||
IPartyPoolDeployer private immutable BALANCED_PAIR_DEPLOYER;
|
IPartyPoolDeployer private immutable BALANCED_PAIR_DEPLOYER;
|
||||||
|
|
||||||
|
|||||||
@@ -291,8 +291,6 @@ contract PartyPool is PartyPoolBase, ERC20External, IPartyPool {
|
|||||||
uint256 feeUint
|
uint256 feeUint
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint256 n = _tokens.length;
|
|
||||||
|
|
||||||
// Estimate max net input (fee on gross rounded up, then subtract)
|
// Estimate max net input (fee on gross rounded up, then subtract)
|
||||||
(, uint256 netUintForSwap) = _computeFee(maxAmountIn, SWAP_FEE_PPM);
|
(, uint256 netUintForSwap) = _computeFee(maxAmountIn, SWAP_FEE_PPM);
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ contract NativeTest is Test {
|
|||||||
|
|
||||||
// Execute swap: WETH (index 2) -> token0 (index 0)
|
// Execute swap: WETH (index 2) -> token0 (index 0)
|
||||||
// Send native currency with {value: maxIn}
|
// 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, // payer
|
||||||
alice, // receiver
|
alice, // receiver
|
||||||
2, // inputTokenIndex (WETH)
|
2, // inputTokenIndex (WETH)
|
||||||
@@ -177,7 +177,7 @@ contract NativeTest is Test {
|
|||||||
uint256 aliceEthBefore = alice.balance;
|
uint256 aliceEthBefore = alice.balance;
|
||||||
|
|
||||||
// Execute swap: token0 (index 0) -> WETH (index 2) with unwrap=true
|
// 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, // payer
|
||||||
alice, // receiver
|
alice, // receiver
|
||||||
0, // inputTokenIndex (token0)
|
0, // inputTokenIndex (token0)
|
||||||
@@ -212,7 +212,7 @@ contract NativeTest is Test {
|
|||||||
uint256 aliceEthBefore = alice.balance;
|
uint256 aliceEthBefore = alice.balance;
|
||||||
|
|
||||||
// Execute swap with excess native currency
|
// 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, // payer
|
||||||
alice, // receiver
|
alice, // receiver
|
||||||
2, // inputTokenIndex (WETH)
|
2, // inputTokenIndex (WETH)
|
||||||
@@ -225,7 +225,6 @@ contract NativeTest is Test {
|
|||||||
|
|
||||||
// Verify that only amountIn was used, and excess was refunded
|
// Verify that only amountIn was used, and excess was refunded
|
||||||
assertTrue(amountIn <= maxIn, "used input must not exceed max");
|
assertTrue(amountIn <= maxIn, "used input must not exceed max");
|
||||||
uint256 expectedRefund = totalSent - amountIn;
|
|
||||||
assertEq(alice.balance, aliceEthBefore - amountIn, "Alice should be refunded excess ETH");
|
assertEq(alice.balance, aliceEthBefore - amountIn, "Alice should be refunded excess ETH");
|
||||||
|
|
||||||
vm.stopPrank();
|
vm.stopPrank();
|
||||||
@@ -537,21 +536,19 @@ contract NativeTest is Test {
|
|||||||
token0.approve(address(pool), type(uint256).max);
|
token0.approve(address(pool), type(uint256).max);
|
||||||
token1.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);
|
uint256 lpMinted = pool.mint{value: deposits[2]}(alice, alice, lpRequest, 0);
|
||||||
assertTrue(lpMinted > 0, "Should mint LP");
|
assertTrue(lpMinted > 0, "Should mint LP");
|
||||||
|
|
||||||
// 2. Swap native currency for token0
|
// 2. Swap native currency for token0
|
||||||
uint256 swapAmount = 5_000;
|
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
|
alice, alice, 2, 0, swapAmount, 0, 0, false
|
||||||
);
|
);
|
||||||
assertTrue(amountOut > 0, "Should receive token0");
|
assertTrue(amountOut > 0, "Should receive token0");
|
||||||
|
|
||||||
// 3. Swap token0 back to native currency
|
// 3. Swap token0 back to native currency
|
||||||
uint256 token0Balance = token0.balanceOf(alice);
|
uint256 token0Balance = token0.balanceOf(alice);
|
||||||
(uint256 swapIn2, uint256 swapOut2, ) = pool.swap(
|
(, uint256 swapOut2, ) = pool.swap(
|
||||||
alice, alice, 0, 2, token0Balance / 2, 0, 0, true
|
alice, alice, 0, 2, token0Balance / 2, 0, 0, true
|
||||||
);
|
);
|
||||||
assertTrue(swapOut2 > 0, "Should receive native currency");
|
assertTrue(swapOut2 > 0, "Should receive native currency");
|
||||||
@@ -578,7 +575,7 @@ contract NativeTest is Test {
|
|||||||
uint256 aliceEthBefore = alice.balance;
|
uint256 aliceEthBefore = alice.balance;
|
||||||
|
|
||||||
// Swap token0 -> WETH without unwrap
|
// 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
|
alice, alice, 0, 2, maxIn, 0, 0, false // unwrap=false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user