Skip to content

Commit

Permalink
feat: allow migrator to be pausable (#35)
Browse files Browse the repository at this point in the history
* feat: allow migrator to be pausable

* feat: remove whenNotPaused for initializePool per feedback
  • Loading branch information
ChefMist authored Oct 15, 2024
1 parent a1463d7 commit 65e09a2
Show file tree
Hide file tree
Showing 32 changed files with 229 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1133418
1135806
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1020942
1023176
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1090293
1092527
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1205745
1208127
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1093364
1095592
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1156698
1158926
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1133430
1135818
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1020954
1023188
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1090290
1092524
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1203727
1206109
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1091346
1093574
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1154676
1156904
Original file line number Diff line number Diff line change
@@ -1 +1 @@
743226
745598
Original file line number Diff line number Diff line change
@@ -1 +1 @@
628769
631031
Original file line number Diff line number Diff line change
@@ -1 +1 @@
700382
702632
Original file line number Diff line number Diff line change
@@ -1 +1 @@
793085
795335
Original file line number Diff line number Diff line change
@@ -1 +1 @@
681183
683323
Original file line number Diff line number Diff line change
@@ -1 +1 @@
750284
752424
Original file line number Diff line number Diff line change
@@ -1 +1 @@
743238
745598
Original file line number Diff line number Diff line change
@@ -1 +1 @@
628781
631031
Original file line number Diff line number Diff line change
@@ -1 +1 @@
700382
702632
Original file line number Diff line number Diff line change
@@ -1 +1 @@
791067
793317
Original file line number Diff line number Diff line change
@@ -1 +1 @@
679165
681305
Original file line number Diff line number Diff line change
@@ -1 +1 @@
748266
750406
3 changes: 2 additions & 1 deletion src/base/BaseMigrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import {IV3NonfungiblePositionManager} from "../interfaces/external/IV3Nonfungib
import {IWETH9} from "../interfaces/external/IWETH9.sol";
import {Multicall_v4} from "./Multicall_v4.sol";
import {Currency, CurrencyLibrary} from "pancake-v4-core/src/types/Currency.sol";
import {Owner} from "pancake-v4-core/src/Owner.sol";
import {SelfPermitERC721} from "./SelfPermitERC721.sol";
import {IBaseMigrator} from "../interfaces/IBaseMigrator.sol";
import {IPositionManagerPermit2} from "../interfaces/IPositionManagerPermit2.sol";
import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol";
import {Permit2Forwarder} from "./Permit2Forwarder.sol";

contract BaseMigrator is IBaseMigrator, Permit2Forwarder, Multicall_v4, SelfPermitERC721 {
contract BaseMigrator is IBaseMigrator, Permit2Forwarder, Multicall_v4, SelfPermitERC721, Owner {
using SafeCast for uint256;
using SafeTransferLib for ERC20;

Expand Down
4 changes: 2 additions & 2 deletions src/pool-bin/BinMigrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ contract BinMigrator is IBinMigrator, BaseMigrator, ReentrancyLock {
V4BinPoolParams calldata v4PoolParams,
uint256 extraAmount0,
uint256 extraAmount1
) external payable override isNotLocked {
) external payable override isNotLocked whenNotPaused {
bool shouldReversePair = checkTokensOrderAndMatchFromV2(
v2PoolParams.pair, v4PoolParams.poolKey.currency0, v4PoolParams.poolKey.currency1
);
Expand Down Expand Up @@ -79,7 +79,7 @@ contract BinMigrator is IBinMigrator, BaseMigrator, ReentrancyLock {
V4BinPoolParams calldata v4PoolParams,
uint256 extraAmount0,
uint256 extraAmount1
) external payable override isNotLocked {
) external payable override isNotLocked whenNotPaused {
bool shouldReversePair = checkTokensOrderAndMatchFromV3(
v3PoolParams.nfp, v3PoolParams.tokenId, v4PoolParams.poolKey.currency0, v4PoolParams.poolKey.currency1
);
Expand Down
4 changes: 2 additions & 2 deletions src/pool-cl/CLMigrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ contract CLMigrator is ICLMigrator, BaseMigrator, ReentrancyLock {
V4CLPoolParams calldata v4PoolParams,
uint256 extraAmount0,
uint256 extraAmount1
) external payable override isNotLocked {
) external payable override isNotLocked whenNotPaused {
bool shouldReversePair = checkTokensOrderAndMatchFromV2(
v2PoolParams.pair, v4PoolParams.poolKey.currency0, v4PoolParams.poolKey.currency1
);
Expand Down Expand Up @@ -77,7 +77,7 @@ contract CLMigrator is ICLMigrator, BaseMigrator, ReentrancyLock {
V4CLPoolParams calldata v4PoolParams,
uint256 extraAmount0,
uint256 extraAmount1
) external payable override isNotLocked {
) external payable override isNotLocked whenNotPaused {
bool shouldReversePair = checkTokensOrderAndMatchFromV3(
v3PoolParams.nfp, v3PoolParams.tokenId, v4PoolParams.poolKey.currency0, v4PoolParams.poolKey.currency1
);
Expand Down
1 change: 0 additions & 1 deletion src/pool-cl/interfaces/ICLMigrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ pragma solidity ^0.8.24;
import {PoolKey} from "pancake-v4-core/src/types/PoolKey.sol";
import {IBaseMigrator} from "../../interfaces/IBaseMigrator.sol";
import {IV3NonfungiblePositionManager} from "../../interfaces/external/IV3NonfungiblePositionManager.sol";
// import {INonfungiblePositionManager} from "./INonfungiblePositionManager.sol";

interface ICLMigrator is IBaseMigrator {
error INSUFFICIENT_LIQUIDITY();
Expand Down
58 changes: 58 additions & 0 deletions test/pool-bin/migrator/BinMigratorFromV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {Permit2ApproveHelper} from "../../helpers/Permit2ApproveHelper.sol";
import {Permit2SignatureHelpers} from "../../shared/Permit2SignatureHelpers.sol";
import {Permit2Forwarder} from "../../../src/base/Permit2Forwarder.sol";
import {IPositionManager} from "../../../src/interfaces/IPositionManager.sol";
import {Pausable} from "pancake-v4-core/src/base/Pausable.sol";

interface IPancakeV2LikePairFactory {
function createPair(address tokenA, address tokenB) external returns (address pair);
Expand Down Expand Up @@ -119,6 +120,63 @@ abstract contract BinMigratorFromV2 is
v2PairWithoutNativeToken = IPancakePair(v2Factory.createPair(address(token0), address(token1)));
}

function testMigrateFromV2_Owner() public {
// casted as owner/transferOwnership not in IBinMigrator interface
BinMigrator _migrator = BinMigrator(payable(address(migrator)));
assertEq(_migrator.owner(), address(this));

address alice = makeAddr("alice");
_migrator.transferOwnership(alice);

assertEq(_migrator.owner(), alice);
}

function testMigrateFromV2_WhenPaused() public {
// 1. mint some liquidity to the v2 pair
_mintV2Liquidity(v2Pair);
uint256 lpTokenBefore = v2Pair.balanceOf(address(this));

// 2. make sure migrator can transfer user's v2 lp token
permit2ApproveWithSpecificAllowance(
address(this), permit2, address(v2Pair), address(migrator), lpTokenBefore, uint160(lpTokenBefore)
);

// 3. initialize the pool
migrator.initializePool(poolKey, ACTIVE_BIN_ID);

IBaseMigrator.V2PoolParams memory v2PoolParams = IBaseMigrator.V2PoolParams({
pair: address(v2Pair),
migrateAmount: lpTokenBefore,
// minor precision loss is acceptable
amount0Min: 9.999 ether,
amount1Min: 9.999 ether
});

IBinPositionManager.BinAddLiquidityParams memory params =
_getAddParams(poolKey, getBinIds(ACTIVE_BIN_ID, 3), 10 ether, 10 ether, ACTIVE_BIN_ID, address(this));

IBinMigrator.V4BinPoolParams memory v4BinPoolParams = IBinMigrator.V4BinPoolParams({
poolKey: params.poolKey,
amount0Max: params.amount0Max,
amount1Max: params.amount1Max,
activeIdDesired: params.activeIdDesired,
idSlippage: params.idSlippage,
deltaIds: params.deltaIds,
distributionX: params.distributionX,
distributionY: params.distributionY,
to: params.to,
deadline: block.timestamp + 1
});

// pre-req: pause
BinMigrator _migrator = BinMigrator(payable(address(migrator)));
_migrator.pause();

// 4. migrateFromV2
vm.expectRevert(Pausable.EnforcedPause.selector);
migrator.migrateFromV2(v2PoolParams, v4BinPoolParams, 0, 0);
}

function testMigrateFromV2ReentrancyLockRevert() public {
MockReentrantPositionManager reentrantPM = new MockReentrantPositionManager(permit2);
migrator = new BinMigrator(address(weth), address(reentrantPM), permit2);
Expand Down
47 changes: 47 additions & 0 deletions test/pool-bin/migrator/BinMigratorFromV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {MockReentrantPositionManager} from "../../mocks/MockReentrantPositionMan
import {ReentrancyLock} from "../../../src/base/ReentrancyLock.sol";
import {Permit2ApproveHelper} from "../../helpers/Permit2ApproveHelper.sol";
import {IPositionManager} from "../../../src/interfaces/IPositionManager.sol";
import {Pausable} from "pancake-v4-core/src/base/Pausable.sol";

interface IPancakeV3LikePairFactory {
function createPool(address tokenA, address tokenB, uint24 fee) external returns (address pool);
Expand Down Expand Up @@ -147,6 +148,52 @@ abstract contract BinMigratorFromV3 is
token1.approve(address(v3Nfpm), type(uint256).max);
}

function testMigrateFromV3_WhenPaused() public {
// 1. mint some liquidity to the v3 pool
_mintV3Liquidity(address(weth), address(token0));
(,,,,,,, uint128 liquidityFromV3Before,,,,) = v3Nfpm.positions(1);

// 2. make sure migrator can transfer user's v3 lp token
v3Nfpm.approve(address(migrator), 1);

// 3. initialize the pool
migrator.initializePool(poolKey, ACTIVE_BIN_ID);

IBaseMigrator.V3PoolParams memory v3PoolParams = IBaseMigrator.V3PoolParams({
nfp: address(v3Nfpm),
tokenId: 1,
liquidity: liquidityFromV3Before,
amount0Min: 9.9 ether,
amount1Min: 9.9 ether,
collectFee: false,
deadline: block.timestamp + 100
});

IBinPositionManager.BinAddLiquidityParams memory params =
_getAddParams(poolKey, getBinIds(ACTIVE_BIN_ID, 3), 10 ether, 10 ether, ACTIVE_BIN_ID, address(this));

IBinMigrator.V4BinPoolParams memory v4BinPoolParams = IBinMigrator.V4BinPoolParams({
poolKey: params.poolKey,
amount0Max: params.amount0Max,
amount1Max: params.amount1Max,
activeIdDesired: params.activeIdDesired,
idSlippage: params.idSlippage,
deltaIds: params.deltaIds,
distributionX: params.distributionX,
distributionY: params.distributionY,
to: params.to,
deadline: block.timestamp + 1
});

// pre-req: pause
BinMigrator _migrator = BinMigrator(payable(address(migrator)));
_migrator.pause();

// 4. migrateFromV3 directly given pool has been initialized
vm.expectRevert(Pausable.EnforcedPause.selector);
migrator.migrateFromV3(v3PoolParams, v4BinPoolParams, 0, 0);
}

function testMigrateFromV3ReentrancyLockRevert() public {
MockReentrantPositionManager reentrantPM = new MockReentrantPositionManager(permit2);
migrator = new BinMigrator(address(weth), address(reentrantPM), permit2);
Expand Down
52 changes: 52 additions & 0 deletions test/pool-cl/migrator/CLMigratorFromV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {Permit2ApproveHelper} from "../../helpers/Permit2ApproveHelper.sol";
import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol";
import {Permit2SignatureHelpers} from "../../shared/Permit2SignatureHelpers.sol";
import {Permit2Forwarder} from "../../../src/base/Permit2Forwarder.sol";
import {Pausable} from "pancake-v4-core/src/base/Pausable.sol";

interface IPancakeV2LikePairFactory {
function getPair(address tokenA, address tokenB) external view returns (address pair);
Expand Down Expand Up @@ -105,6 +106,57 @@ abstract contract CLMigratorFromV2 is
tickUpper = 100;
}

function test_Owner() public {
// casted as owner/transferOwnership not in ICLMigrator interface
CLMigrator _migrator = CLMigrator(payable(address(migrator)));
assertEq(_migrator.owner(), address(this));

address alice = makeAddr("alice");
_migrator.transferOwnership(alice);

assertEq(_migrator.owner(), alice);
}

function testCLMigrateFromV2_WhenPaused() public {
// 1. mint some liquidity to the v2 pair
_mintV2Liquidity(v2Pair);
uint256 lpTokenBefore = v2Pair.balanceOf(address(this));

// 2. make sure migrator can transfer user's v2 lp token
permit2ApproveWithSpecificAllowance(
address(this), permit2, address(v2Pair), address(migrator), lpTokenBefore, uint160(lpTokenBefore)
);

// 3. initialize the pool
uint160 initSqrtPrice = 79228162514264337593543950336;
migrator.initializePool(poolKey, initSqrtPrice);

IBaseMigrator.V2PoolParams memory v2PoolParams = IBaseMigrator.V2PoolParams({
pair: address(v2Pair),
migrateAmount: lpTokenBefore,
// minor precision loss is acceptable
amount0Min: 9.999 ether,
amount1Min: 9.999 ether
});

ICLMigrator.V4CLPoolParams memory v4MintParams = ICLMigrator.V4CLPoolParams({
poolKey: poolKey,
tickLower: -100,
tickUpper: 100,
liquidityMin: 0,
recipient: address(this),
deadline: block.timestamp + 100
});

// pre-req: pause
CLMigrator _migrator = CLMigrator(payable(address(migrator)));
_migrator.pause();

// 4. migrate from v2 to v4
vm.expectRevert(Pausable.EnforcedPause.selector);
migrator.migrateFromV2(v2PoolParams, v4MintParams, 0, 0);
}

function testCLMigrateFromV2ReentrancyLockRevert() public {
MockReentrantPositionManager reentrantPM = new MockReentrantPositionManager(permit2);
reentrantPM.setCLPoolMnager(poolManager);
Expand Down
Loading

0 comments on commit 65e09a2

Please sign in to comment.