상세 컨텐츠

본문 제목

UniswapV2-periphery UniswapV2Migrator.sol 코드 분석

Blockchain/DeFi

by Yongari 2023. 3. 15. 23:01

본문

UniswapV2Migrator.sol

 

UniswapV2Migrator.sol은 Uniswap V1에서 Uniswap V2로의 마이그레이션을 용이하게 하기 위한 스마트 컨트랙트입니다. Uniswap V1에서 유동성을 제공하는 유저들은 Uniswap V2로 마이그레이션하면서 새로운 유동성을 공급할 수 있게 됩니다.

이 스마트 컨트랙트는 UniswapV2Router02.sol과 함께 작동하며, 유동성 마이그레이션을 위한 인터페이스를 제공합니다. 마이그레이션을 위해서는 Uniswap V1에서 Liquidity Provider(LP) 토큰을 받아온 뒤, 해당 토큰을 UniswapV2Router02.sol에 전송하여 V2의 LP 토큰을 받아옵니다.

이 스마트 컨트랙트는 마이그레이션 중에 LP 토큰을 전송하고, 이전 버전의 유동성 공급자에게 새로운 LP 토큰을 발행합니다. 마이그레이션을 완료하면, 유동성 공급자는 새로운 Uniswap V2 플랫폼에서 LP 토큰을 사용할 수 있습니다.

따라서 UniswapV2Migrator.sol은 Uniswap V1에서 Uniswap V2로의 유동성 마이그레이션을 돕는 중요한 스마트 컨트랙트입니다.

 

다음은 UniswapV2Migrator Solidity코드를 분석한 내용입니다.

 

pragma solidity =0.6.6;

import '@uniswap/lib/contracts/libraries/TransferHelper.sol';

import './interfaces/IUniswapV2Migrator.sol';
import './interfaces/V1/IUniswapV1Factory.sol';
import './interfaces/V1/IUniswapV1Exchange.sol';
import './interfaces/IUniswapV2Router01.sol';
import './interfaces/IERC20.sol';

//이 코드는 Uniswap v1에서 v2로 토큰 및 유동성을 이전하기 위한 UniswapV2Migrator 컨트랙트입니다.
contract UniswapV2Migrator is IUniswapV2Migrator {

    //uniswapV1의 factory를 가져옴 
    IUniswapV1Factory immutable factoryV1;
    //uniswapV1의 router를 가져옴 
    IUniswapV2Router01 immutable router;

    //스마트 컨트랙트가 빌드될 때 실행됨
    //IUniswapV1Factory에 팩토리 변수 설정 
    //IUniswapV2Router01에 라우터 변수를 설정 
    constructor(address _factoryV1, address _router) public {
        factoryV1 = IUniswapV1Factory(_factoryV1);
        router = IUniswapV2Router01(_router);
    }

    // needs to accept ETH from any v1 exchange and the router. ideally this could be enforced, as in the router,
    // but it's not possible because it requires a call to the v1 factory, which takes too much gas
    // 모든 v1 교환 및 라우터에서 ETH를 수락해야 합니다. 이상적으로 이것은 라우터에서와 같이 시행될 수 있다,
    // 하지만 가스가 너무 많이 들어가는 v1 공장으로 호출이 필요하기 때문에 불가능합니다
    receive() external payable {}


    function migrate(address token, uint amountTokenMin, uint amountETHMin, address to, uint deadline)
        external
        override
    {
        //, Uniswap v1에서 주어진 토큰을 현재 계정에서 컨트랙트 계정으로 이전한 다음, 
        //  v2로 해당 토큰의 유동성을 추가하는 것입니다. 이를 위해 IUniswapV1Exchange 인터페이스를 사용하여 v1의 exchange를 가져옵니다. 
        IUniswapV1Exchange exchangeV1 = IUniswapV1Exchange(factoryV1.getExchange(token));
        
        // 유동성 v1변수 설정 
        uint liquidityV1 = exchangeV1.balanceOf(msg.sender);

        //트랜스퍼 프롬함수 실행, 이 컨트랙트가 자산을 받는 것으로 함수 호출(컨트랙트 호출자, 현재 컨트랙트 주소, 유동성 토큰 ) 
        require(exchangeV1.transferFrom(msg.sender, address(this), liquidityV1), 'TRANSFER_FROM_FAILED');

        //그런 다음 removeLiquidity 함수를 사용하여 v1에서 유동성을 제거하고 해당 토큰과 ETH의 수량을 반환합니다.
        (uint amountETHV1, uint amountTokenV1) = exchangeV1.removeLiquidity(liquidityV1, 1, 1, uint(-1));

        
        TransferHelper.safeApprove(token, address(router), amountTokenV1);

        //addLiquidityETH 함수를 사용하여 v2에서 해당 토큰의 유동성을 추가합니다.
        (uint amountTokenV2, uint amountETHV2,) = router.addLiquidityETH{value: amountETHV1}(
            token,
            amountTokenV1,
            amountTokenMin,
            amountETHMin,
            to,
            deadline
        );
        //amountTokenV1이 amountTokenV2보다 어마운트가 많으면 다음 함수 실행
        if (amountTokenV1 > amountTokenV2) {

            TransferHelper.safeApprove(token, address(router), 0); // 선량한 블록체인 시민이 되어 allowance을 0으로 초기화하세요.

            TransferHelper.safeTransfer(token, msg.sender, amountTokenV1 - amountTokenV2);
        // amountETHV1이 amountETHV2보다 어마운트가 많으면 다음 함수 실행
        } else if (amountETHV1 > amountETHV2) {

            // addLiquidityETH는 amountETHV1 또는 amountTokenV1이 모두 사용되도록 보장하므로 다른 것은 안전합니다.
            TransferHelper.safeTransferETH(msg.sender, amountETHV1 - amountETHV2);
        }
    }
}

관련글 더보기