Skip to content

Commit

Permalink
some initial tests to drive TDD
Browse files Browse the repository at this point in the history
  • Loading branch information
saucepoint committed Jun 26, 2024
1 parent 1e52f82 commit 97080cb
Show file tree
Hide file tree
Showing 24 changed files with 192 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeAddInitialLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
354477
311181
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeAddLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
161786
122990
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeFirstSwap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
146400
80220
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeInitialize.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1039616
1016976
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeRemoveLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
146394
110566
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeRemoveLiquidityAndRebalance.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
281672
240044
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeSecondSwap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
116110
45930
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeSwap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
145819
79351
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleGrow10Slots.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
254164
232960
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleGrow10SlotsCardinalityGreater.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
249653
223649
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleGrow1Slot.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
54049
32845
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleGrow1SlotCardinalityGreater.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
49549
23545
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleInitialize.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
72794
51310
2 changes: 1 addition & 1 deletion .forge-snapshots/TWAMMSubmitOrder.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
156828
122336
2 changes: 1 addition & 1 deletion .forge-snapshots/autocompound_exactUnclaimedFees.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
261455
177143
Original file line number Diff line number Diff line change
@@ -1 +1 @@
193828
94292
2 changes: 1 addition & 1 deletion .forge-snapshots/autocompound_excessFeesCredit.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
281994
197658
2 changes: 1 addition & 1 deletion .forge-snapshots/decreaseLiquidity_erc20.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
191784
121605
2 changes: 1 addition & 1 deletion .forge-snapshots/decreaseLiquidity_erc6909.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
170651
119377
2 changes: 1 addition & 1 deletion .forge-snapshots/increaseLiquidity_erc20.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
174219
61707
2 changes: 1 addition & 1 deletion .forge-snapshots/increaseLiquidity_erc6909.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
149801
65477
2 changes: 1 addition & 1 deletion .forge-snapshots/mintWithLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
469640
445756
2 changes: 1 addition & 1 deletion contracts/NonfungiblePositionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ contract NonfungiblePositionManager is INonfungiblePositionManager, BaseLiquidit
}

modifier isAuthorizedForToken(uint256 tokenId) {
require(_isApprovedOrOwner(msg.sender, tokenId), "Not approved");
require(msg.sender == address(this) || _isApprovedOrOwner(msg.sender, tokenId), "Not approved");
_;
}
}
169 changes: 169 additions & 0 deletions test/position-managers/Execute.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "forge-std/Test.sol";
import {GasSnapshot} from "forge-gas-snapshot/GasSnapshot.sol";
import {PoolManager} from "@uniswap/v4-core/src/PoolManager.sol";
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
import {Deployers} from "@uniswap/v4-core/test/utils/Deployers.sol";
import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol";
import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol";
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
import {PoolSwapTest} from "@uniswap/v4-core/src/test/PoolSwapTest.sol";
import {LiquidityAmounts} from "../../contracts/libraries/LiquidityAmounts.sol";
import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol";
import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol";
import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol";
import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol";

import {IERC20} from "forge-std/interfaces/IERC20.sol";
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";

import {INonfungiblePositionManager} from "../../contracts/interfaces/INonfungiblePositionManager.sol";
import {NonfungiblePositionManager} from "../../contracts/NonfungiblePositionManager.sol";
import {LiquidityRange, LiquidityRangeId, LiquidityRangeIdLibrary} from "../../contracts/types/LiquidityRange.sol";

import {LiquidityFuzzers} from "../shared/fuzz/LiquidityFuzzers.sol";

contract ExecuteTest is Test, Deployers, GasSnapshot, LiquidityFuzzers {
using FixedPointMathLib for uint256;
using CurrencyLibrary for Currency;
using LiquidityRangeIdLibrary for LiquidityRange;
using PoolIdLibrary for PoolKey;
using SafeCast for uint256;

NonfungiblePositionManager lpm;

PoolId poolId;
address alice = makeAddr("ALICE");
address bob = makeAddr("BOB");

uint256 constant STARTING_USER_BALANCE = 10_000_000 ether;

// expresses the fee as a wad (i.e. 3000 = 0.003e18 = 0.30%)
uint256 FEE_WAD;

LiquidityRange range;

function setUp() public {
Deployers.deployFreshManagerAndRouters();
Deployers.deployMintAndApprove2Currencies();

(key, poolId) = initPool(currency0, currency1, IHooks(address(0)), 3000, SQRT_PRICE_1_1, ZERO_BYTES);
FEE_WAD = uint256(key.fee).mulDivDown(FixedPointMathLib.WAD, 1_000_000);

lpm = new NonfungiblePositionManager(manager);
IERC20(Currency.unwrap(currency0)).approve(address(lpm), type(uint256).max);
IERC20(Currency.unwrap(currency1)).approve(address(lpm), type(uint256).max);

// Give tokens to Alice and Bob, with approvals
IERC20(Currency.unwrap(currency0)).transfer(alice, STARTING_USER_BALANCE);
IERC20(Currency.unwrap(currency1)).transfer(alice, STARTING_USER_BALANCE);
IERC20(Currency.unwrap(currency0)).transfer(bob, STARTING_USER_BALANCE);
IERC20(Currency.unwrap(currency1)).transfer(bob, STARTING_USER_BALANCE);
vm.startPrank(alice);
IERC20(Currency.unwrap(currency0)).approve(address(lpm), type(uint256).max);
IERC20(Currency.unwrap(currency1)).approve(address(lpm), type(uint256).max);
vm.stopPrank();
vm.startPrank(bob);
IERC20(Currency.unwrap(currency0)).approve(address(lpm), type(uint256).max);
IERC20(Currency.unwrap(currency1)).approve(address(lpm), type(uint256).max);
vm.stopPrank();

// define a reusable range
range = LiquidityRange({poolKey: key, tickLower: -300, tickUpper: 300});
}

function test_execute_increaseLiquidity_once(uint256 initialLiquidity, uint256 liquidityToAdd) public {
initialLiquidity = bound(initialLiquidity, 1e18, 1000e18);
liquidityToAdd = bound(liquidityToAdd, 1e18, 1000e18);
(uint256 tokenId,) = lpm.mint(range, initialLiquidity, 0, address(this), ZERO_BYTES);

bytes[] memory data = new bytes[](1);
data[0] = abi.encodeWithSelector(
INonfungiblePositionManager.increaseLiquidity.selector, tokenId, liquidityToAdd, ZERO_BYTES, false
);

lpm.unlockAndExecute(data);

(,, uint256 liquidity,,,,) = lpm.positions(address(this), range.toId());
assertEq(liquidity, initialLiquidity + liquidityToAdd);
}

function test_execute_increaseLiquidity_twice(
uint256 initialiLiquidity,
uint256 liquidityToAdd,
uint256 liquidityToAdd2
) public {
initialiLiquidity = bound(initialiLiquidity, 1e18, 1000e18);
liquidityToAdd = bound(liquidityToAdd, 1e18, 1000e18);
liquidityToAdd2 = bound(liquidityToAdd2, 1e18, 1000e18);
(uint256 tokenId,) = lpm.mint(range, initialiLiquidity, 0, address(this), ZERO_BYTES);

bytes[] memory data = new bytes[](2);
data[0] = abi.encodeWithSelector(
INonfungiblePositionManager.increaseLiquidity.selector, tokenId, liquidityToAdd, ZERO_BYTES, false
);
data[1] = abi.encodeWithSelector(
INonfungiblePositionManager.increaseLiquidity.selector, tokenId, liquidityToAdd2, ZERO_BYTES, false
);

lpm.unlockAndExecute(data);

(,, uint256 liquidity,,,,) = lpm.positions(address(this), range.toId());
assertEq(liquidity, initialiLiquidity + liquidityToAdd + liquidityToAdd2);
}

// this case doesnt make sense in real world usage, so it doesnt have a cool name. but its a good test case
function test_execute_mintAndIncrease(uint256 intialLiquidity, uint256 liquidityToAdd) public {
intialLiquidity = bound(intialLiquidity, 1e18, 1000e18);
liquidityToAdd = bound(liquidityToAdd, 1e18, 1000e18);

uint256 tokenId = 1; // assume that the .mint() produces tokenId=1, to be used in increaseLiquidity
bytes[] memory data = new bytes[](2);
data[0] = abi.encodeWithSelector(
INonfungiblePositionManager.mint.selector,
range,
intialLiquidity,
block.timestamp + 1,
address(this),
ZERO_BYTES
);
data[1] = abi.encodeWithSelector(
INonfungiblePositionManager.increaseLiquidity.selector, tokenId, liquidityToAdd, ZERO_BYTES, false
);

lpm.unlockAndExecute(data);

(,, uint256 liquidity,,,,) = lpm.positions(address(this), range.toId());
assertEq(liquidity, intialLiquidity + liquidityToAdd);
}

// rebalance: burn and mint
function test_execute_rebalance() public {}
// coalesce: burn and increase
function test_execute_coalesce() public {}
// split: decrease and mint
function test_execute_split() public {}
// shift: decrease and increase
function test_execute_shift() public {}
// shard: collect and mint
function test_execute_shard() public {}
// feed: collect and increase
function test_execute_feed() public {}

// transplant: burn and mint on different keys
function test_execute_transplant() public {}
// cross-coalesce: burn and increase on different keys
function test_execute_crossCoalesce() public {}
// cross-split: decrease and mint on different keys
function test_execute_crossSplit() public {}
// cross-shift: decrease and increase on different keys
function test_execute_crossShift() public {}
// cross-shard: collect and mint on different keys
function test_execute_crossShard() public {}
// cross-feed: collect and increase on different keys
function test_execute_crossFeed() public {}
}

0 comments on commit 97080cb

Please sign in to comment.