Skip to content

Commit

Permalink
add minimum liquidity
Browse files Browse the repository at this point in the history
  • Loading branch information
emmaguo13 committed Aug 11, 2023
1 parent da2b0e6 commit 79f5064
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 32 deletions.
2 changes: 1 addition & 1 deletion .forge-snapshots/add liquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
440321
466859
13 changes: 11 additions & 2 deletions contracts/hooks/examples/FullRange.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {FixedPoint128} from "@uniswap/v4-core/contracts/libraries/FixedPoint128.
import {FixedPoint96} from "@uniswap/v4-core/contracts/libraries/FixedPoint96.sol";
import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol";
import {ILockCallback} from "@uniswap/v4-core/contracts/interfaces/callback/ILockCallback.sol";
import {IERC20Metadata} from "../../interfaces/IERC20Metadata.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/interfaces/IERC20Metadata.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";

import "../../libraries/LiquidityAmounts.sol";
Expand All @@ -42,6 +42,7 @@ contract FullRange is BaseHook, ILockCallback {
int24 internal constant MAX_TICK = -MIN_TICK;

int256 internal constant MAX_INT = type(int256).max;
uint16 internal constant MINIMUM_LIQUIDITY = 10 ** 3;

struct CallbackData {
address sender;
Expand Down Expand Up @@ -99,6 +100,10 @@ contract FullRange is BaseHook, ILockCallback {

if (sqrtPriceX96 == 0) revert PoolNotInitialized();

PoolInfo storage pool = poolInfo[poolId];

uint128 poolLiquidity = poolManager.getLiquidity(poolId);

liquidity = LiquidityAmounts.getLiquidityForAmounts(
sqrtPriceX96,
TickMath.getSqrtRatioAtTick(MIN_TICK),
Expand All @@ -115,7 +120,11 @@ contract FullRange is BaseHook, ILockCallback {
liquidityDelta: int256(int128(liquidity))
})
);
PoolInfo storage pool = poolInfo[poolId];

if (poolLiquidity == 0) {
liquidity -= MINIMUM_LIQUIDITY;
UniswapV4ERC20(pool.liquidityToken).mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
}

UniswapV4ERC20(pool.liquidityToken).mint(to, liquidity);
}
Expand Down
17 changes: 0 additions & 17 deletions contracts/interfaces/IERC20Metadata.sol

This file was deleted.

24 changes: 12 additions & 12 deletions test/FullRange.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {

(, address liquidityToken) = fullRange.poolInfo(id);

assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 10 ether);
assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 10 ether - 1000);

(bool owed,) = fullRange.poolInfo(id);
assertEq(owed, false);
Expand All @@ -171,7 +171,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {

(, address liquidityToken) = fullRange.poolInfo(id);

assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 25 ether + 1);
assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 25 ether + 1 - 1000);

(bool owed,) = fullRange.poolInfo(id);
assertEq(owed, false);
Expand All @@ -187,7 +187,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {

(, address liquidityToken) = fullRange.poolInfo(id);

assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 10 ether);
assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 10 ether - 1000);
assertEq(MockERC20(token0).balanceOf(address(this)), prevBalance0 - 10 ether);
assertEq(MockERC20(token0).balanceOf(address(this)), prevBalance1 - 10 ether);

Expand All @@ -212,7 +212,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {

fullRange.addLiquidity(address(token0), address(token1), 3000, 5 ether, 5 ether, address(this), MAX_DEADLINE);

assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 14546694553059925434);
assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 14546694553059925434 - 1000);

(owed,) = fullRange.poolInfo(id);
assertEq(owed, true);
Expand Down Expand Up @@ -279,7 +279,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {

(, address liquidityToken) = fullRange.poolInfo(id);

assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 10 ether);
assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 10 ether - 1000);

assertEq(MockERC20(token0).balanceOf(address(this)), prevBalance0 - 10 ether);
assertEq(MockERC20(token1).balanceOf(address(this)), prevBalance1 - 10 ether);
Expand All @@ -290,7 +290,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {
fullRange.removeLiquidity(address(token0), address(token1), 3000, 1 ether, MAX_DEADLINE);
snapEnd();

assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 9 ether);
assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 9 ether - 1000);
assertEq(MockERC20(token0).balanceOf(address(this)), prevBalance0 - 9 ether - 1);
assertEq(MockERC20(token1).balanceOf(address(this)), prevBalance1 - 9 ether - 1);

Expand Down Expand Up @@ -323,7 +323,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {

(, address liquidityToken) = fullRange.poolInfo(id);

assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 10 ether);
assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 10 ether - 1000);

assertEq(MockERC20(token0).balanceOf(address(this)), prevBalance0 - 10 ether);
assertEq(MockERC20(token1).balanceOf(address(this)), prevBalance1 - 10 ether);
Expand All @@ -332,7 +332,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {

fullRange.removeLiquidity(address(token0), address(token1), 3000, 5 ether, MAX_DEADLINE);

assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 5 ether);
assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 5 ether - 1000);
assertEq(MockERC20(token0).balanceOf(address(this)), prevBalance0 - 5 ether - 1);
assertEq(MockERC20(token1).balanceOf(address(this)), prevBalance1 - 5 ether - 1);

Expand All @@ -353,14 +353,14 @@ contract TestFullRange is Test, Deployers, GasSnapshot {

(, address liquidityToken) = fullRange.poolInfo(id);

assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 10 ether);
assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 10 ether - 1000);

fullRange.addLiquidity(address(token0), address(token1), 3000, 5 ether, 2.5 ether, address(this), MAX_DEADLINE);

assertEq(MockERC20(token0).balanceOf(address(this)), prevBalance0 - 12.5 ether);
assertEq(MockERC20(token1).balanceOf(address(this)), prevBalance1 - 12.5 ether);

assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 12.5 ether);
assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 12.5 ether - 1000);

UniswapV4ERC20(liquidityToken).approve(address(fullRange), type(uint256).max);

Expand All @@ -369,7 +369,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {
assertEq(MockERC20(token0).balanceOf(address(this)), prevBalance0 - 7.5 ether - 1);
assertEq(MockERC20(token1).balanceOf(address(this)), prevBalance1 - 7.5 ether - 1);

assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 7.5 ether);
assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 7.5 ether - 1000);
}

function testSwapRemoveLiquiditySucceedsWithRebalance() public {
Expand All @@ -379,7 +379,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot {

(, address liquidityToken) = fullRange.poolInfo(id);

assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 10 ether);
assertEq(UniswapV4ERC20(liquidityToken).balanceOf(address(this)), 10 ether - 1000);

IPoolManager.SwapParams memory params =
IPoolManager.SwapParams({zeroForOne: true, amountSpecified: 1 ether, sqrtPriceLimitX96: SQRT_RATIO_1_2});
Expand Down

0 comments on commit 79f5064

Please sign in to comment.