Robinhood MainnetChain ID: 4663
Contract detail

V3Migrator

Live Robinhood Chain account facts for 0xbc203d7f…f4ecc5c2 with at least 3 observed transactions. The history total is updating as indexing continues.

Address type
Smart contract
Transactions
3+ observed
First indexed block
#536534
Latest indexed block
#536534
History coverage
Recent activity available; total is catching up
Native balance
0 ETH
Balance observed at
Block #35706461
Verification
Verified
Compiler
v0.7.6+commit.7338295f
Verification match
partial
Creation transaction
0x3630d4f4…28689eaa
Created at block
#536534
Language
solidity
EVM version
istanbul
License
none
Compiler optimization
Enabled · 1000000 runs
Related activity

Transactions

Verified contract

Contract source code

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma abicoder v2;

import "@pancakeswap/v3-core/contracts/libraries/LowGasSafeMath.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol";

import "./interfaces/INonfungiblePositionManager.sol";

import "./libraries/TransferHelper.sol";

import "./interfaces/IV3Migrator.sol";
import "./base/PeripheryImmutableState.sol";
import "./base/Multicall.sol";
import "./base/SelfPermit.sol";
import "./interfaces/external/IWETH9.sol";
import "./base/PoolInitializer.sol";

/// @title Pancakeswap Migrator
contract V3Migrator is IV3Migrator, PeripheryImmutableState, PoolInitializer, Multicall, SelfPermit {
    using LowGasSafeMath for uint256;

    address public immutable nonfungiblePositionManager;

    constructor(address _deployer, address _factory, address _WETH9, address _nonfungiblePositionManager)
        PeripheryImmutableState(_deployer, _factory, _WETH9)
    {
        nonfungiblePositionManager = _nonfungiblePositionManager;
    }

    receive() external payable {
        require(msg.sender == WETH9, "Not WETH9");
    }

    function migrate(MigrateParams calldata params) external override {
        require(params.percentageToMigrate > 0, "Percentage too small");
        require(params.percentageToMigrate <= 100, "Percentage too large");

        // burn v2 liquidity to this address
        IUniswapV2Pair(params.pair).transferFrom(msg.sender, params.pair, params.liquidityToMigrate);
        (uint256 amount0V2, uint256 amount1V2) = IUniswapV2Pair(params.pair).burn(address(this));

        // calculate the amounts to migrate to v3
        uint256 amount0V2ToMigrate = amount0V2.mul(params.percentageToMigrate) / 100;
        uint256 amount1V2ToMigrate = amount1V2.mul(params.percentageToMigrate) / 100;

        // approve the position manager up to the maximum token amounts
        TransferHelper.safeApprove(params.token0, nonfungiblePositionManager, amount0V2ToMigrate);
        TransferHelper.safeApprove(params.token1, nonfungiblePositionManager, amount1V2ToMigrate);

        // mint v3 position
        (,, uint256 amount0V3, uint256 amount1V3) = INonfungiblePositionManager(nonfungiblePositionManager).mint(
            INonfungiblePositionManager.MintParams({
                token0: params.token0,
                token1: params.token1,
                fee: params.fee,
                tickLower: params.tickLower,
                tickUpper: params.tickUpper,
                amount0Desired: amount0V2ToMigrate,
                amount1Desired: amount1V2ToMigrate,
                amount0Min: params.amount0Min,
                amount1Min: params.amount1Min,
                recipient: params.recipient,
                deadline: params.deadline
            })
        );

        // if necessary, clear allowance and refund dust
        if (amount0V3 < amount0V2) {
            if (amount0V3 < amount0V2ToMigrate) {
                TransferHelper.safeApprove(params.token0, nonfungiblePositionManager, 0);
            }

            uint256 refund0 = amount0V2 - amount0V3;
            if (params.refundAsETH && params.token0 == WETH9) {
                IWETH9(WETH9).withdraw(refund0);
                TransferHelper.safeTransferETH(msg.sender, refund0);
            } else {
                TransferHelper.safeTransfer(params.token0, msg.sender, refund0);
            }
        }
        if (amount1V3 < amount1V2) {
            if (amount1V3 < amount1V2ToMigrate) {
                TransferHelper.safeApprove(params.token1, nonfungiblePositionManager, 0);
            }

            uint256 refund1 = amount1V2 - amount1V3;
            if (params.refundAsETH && params.token1 == WETH9) {
                IWETH9(WETH9).withdraw(refund1);
                TransferHelper.safeTransferETH(msg.sender, refund1);
            } else {
                TransferHelper.safeTransfer(params.token1, msg.sender, refund1);
            }
        }
    }
}