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';
//该合约负责将V1迁移到V2
contract UniswapV2Migrator is IUniswapV2Migrator{
IUniswapV1Factory immutable factoryV1;//immutable相当于常量,可以在构造函数中设置,之后不能修改访问他们相对来说更节省gas
IUniswapV2Router01 immutable router;
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
//该函数旨在表明本合约可以接受其他地址的ETH转账
receive()external payable{}
function migrate(address token,uint amountTokenMin,uint amountETHMin,address to,uint deadline)//应该是V1主动调用本函数进行迁移
external
override
{
//V1是token/ETH交易对因此输入token即可查询对应地址
IUniswapV1Exchange exchangeV1=IUniswapV1Exchange(factoryV1.getExchange(token));
uint liquidityV1=exchangeV1.balanceOf(msg.sender);
//将流动性代币UNI1转移到本合约中
require(exchangeV1.transferFrom(msg.sender,address(this),liquidityV1),'TRANSFER_FROM_FAILED');
//在本合约移除流动性销毁UNI1返回token/ETH到本合约中
(uint amountETHV1,uint amountTokenV1)=exchangeV1.removeLiquidity(liquidityV1,1,1,uint(-1));
//授权给router合约进行路径查找后的token转账
TransferHelper.safeApprove(token,address(router),amountTokenV1);
//通过router为该token/ETH池子添加流动性
(uint amountTokenV2,uint amountETHV2,)=router.addLiquidityETH{value:amountETHV1}(
token,
amountTokenV1,
amountTokenMin,
amountETHMin,
to,
deadline
);
if(amountTokenV1>amountTokenV2){
TransferHelper.safeApprove(token,address(router),0);//be a good blockchain citizen,reset allowance to 0
TransferHelper.safeTransfer(token,msg.sender,amountTokenV1-amountTokenV2);
}else if(amountETHV1>amountETHV2){
//addLiquidityETH guarantees that all of amountETHV1 or amountTokenV1 will be used,hence this else is safe
TransferHelper.safeTransferETH(msg.sender,amountETHV1-amountETHV2);
}
}
}