-
Notifications
You must be signed in to change notification settings - Fork 1
/
UniswapV2Migrator.sol
49 lines (43 loc) · 2.16 KB
/
UniswapV2Migrator.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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';
contract UniswapV2Migrator is IUniswapV2Migrator {
IUniswapV1Factory immutable factoryV1;
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
receive() external payable {}
function migrate(address token, uint amountTokenMin, uint amountETHMin, address to, uint deadline)
external
override
{
IUniswapV1Exchange exchangeV1 = IUniswapV1Exchange(factoryV1.getExchange(token));
uint liquidityV1 = exchangeV1.balanceOf(msg.sender);
require(exchangeV1.transferFrom(msg.sender, address(this), liquidityV1), 'TRANSFER_FROM_FAILED');
(uint amountETHV1, uint amountTokenV1) = exchangeV1.removeLiquidity(liquidityV1, 1, 1, uint(-1));
TransferHelper.safeApprove(token, address(router), amountTokenV1);
(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);
}
}
}