Skip to content

Commit 1d6faef

Browse files
initial migration to [email protected] (Uniswap#10)
* initial migration to [email protected] * make syntax consistent * switch back to using published build artifacts
1 parent 0b08acb commit 1d6faef

23 files changed

+133
-137
lines changed

contracts/ExampleFlashSwap.sol

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pragma solidity =0.5.16;
1+
pragma solidity =0.6.6;
22

33
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Callee.sol';
44

@@ -10,21 +10,20 @@ import './interfaces/IERC20.sol';
1010
import './interfaces/IWETH.sol';
1111

1212
contract ExampleFlashSwap is IUniswapV2Callee, UniswapV2Library {
13-
IUniswapV1Factory public factoryV1;
14-
IWETH public WETH;
13+
IUniswapV1Factory immutable factoryV1;
14+
IWETH immutable WETH;
1515

16-
constructor(address _factoryV1) public {
16+
constructor(address _factory, address _factoryV1, address router) UniswapV2Library(_factory) public {
1717
factoryV1 = IUniswapV1Factory(_factoryV1);
18-
// router address is identical across mainnet and testnets but differs between testing and deployed environments
19-
WETH = IWETH(IUniswapV2Router01(0x84e924C5E04438D2c1Df1A981f7E7104952e6de1).WETH());
18+
WETH = IWETH(IUniswapV2Router01(router).WETH());
2019
}
2120

2221
// needs to accept ETH from any V1 exchange and WETH. ideally this could be enforced, as in the router,
2322
// but it's not possible because it requires a call to the v1 factory, which takes too much gas
24-
function() external payable {}
23+
receive() external payable {}
2524

2625
// gets tokens/WETH via a V2 flash swap, swaps for the ETH/tokens on V1, repays V2, and keeps the rest!
27-
function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external {
26+
function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external override {
2827
address[] memory path = new address[](2);
2928
uint amountToken;
3029
uint amountETH;
@@ -49,14 +48,14 @@ contract ExampleFlashSwap is IUniswapV2Callee, UniswapV2Library {
4948
uint amountReceived = exchangeV1.tokenToEthSwapInput(amountToken, minETH, uint(-1));
5049
uint amountRequired = getAmountsIn(amountToken, path)[0];
5150
assert(amountReceived > amountRequired); // fail if we didn't get enough ETH back to repay our flash loan
52-
WETH.deposit.value(amountRequired)();
51+
WETH.deposit{value: amountRequired}();
5352
assert(WETH.transfer(msg.sender, amountRequired)); // return WETH to V2 pair
54-
(bool success,) = sender.call.value(amountReceived - amountRequired)(new bytes(0)); // keep the rest! (ETH)
53+
(bool success,) = sender.call{value: amountReceived - amountRequired}(new bytes(0)); // keep the rest! (ETH)
5554
assert(success);
5655
} else {
5756
(uint minTokens) = abi.decode(data, (uint)); // slippage parameter for V1, passed in by caller
5857
WETH.withdraw(amountETH);
59-
uint amountReceived = exchangeV1.ethToTokenSwapInput.value(amountETH)(minTokens, uint(-1));
58+
uint amountReceived = exchangeV1.ethToTokenSwapInput{value: amountETH}(minTokens, uint(-1));
6059
uint amountRequired = getAmountsIn(amountETH, path)[0];
6160
assert(amountReceived > amountRequired); // fail if we didn't get enough tokens back to repay our flash loan
6261
assert(token.transfer(msg.sender, amountRequired)); // return tokens to V2 pair

contracts/ExampleOracleSimple.sol

+17-12
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,35 @@
1-
pragma solidity =0.5.16;
1+
pragma solidity =0.6.6;
2+
3+
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol';
4+
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';
25

3-
import './UniswapV2Library.sol';
46
import './libraries/UQ112x112.sol';
57

6-
contract ExampleOracleSimple is UniswapV2Library {
8+
contract ExampleOracleSimple {
79
using UQ112x112 for uint224;
810

911
uint public constant PERIOD = 24 hours;
10-
address public token0;
11-
address public token1;
12-
IUniswapV2Pair public pair;
12+
13+
IUniswapV2Pair immutable pair;
14+
address public immutable token0;
15+
address public immutable token1;
1316

1417
uint public price0CumulativeLast;
1518
uint public price1CumulativeLast;
1619
uint32 public blockTimestampLast;
1720
uint224 public price0Average;
1821
uint224 public price1Average;
1922

20-
constructor(address tokenA, address tokenB) public {
21-
(token0, token1) = sortTokens(tokenA, tokenB);
22-
pair = IUniswapV2Pair(pairFor(token0, token1));
23-
price0CumulativeLast = pair.price0CumulativeLast(); // fetch the current accumulated price value (1 / 0)
24-
price1CumulativeLast = pair.price1CumulativeLast(); // fetch the current accumulated price value (0 / 1)
23+
constructor(address factory, address tokenA, address tokenB) public {
24+
IUniswapV2Pair _pair = IUniswapV2Pair(IUniswapV2Factory(factory).getPair(tokenA, tokenB));
25+
pair = _pair;
26+
token0 = _pair.token0();
27+
token1 = _pair.token1();
28+
price0CumulativeLast = _pair.price0CumulativeLast(); // fetch the current accumulated price value (1 / 0)
29+
price1CumulativeLast = _pair.price1CumulativeLast(); // fetch the current accumulated price value (0 / 1)
2530
uint112 reserve0;
2631
uint112 reserve1;
27-
(reserve0, reserve1, blockTimestampLast) = pair.getReserves();
32+
(reserve0, reserve1, blockTimestampLast) = _pair.getReserves();
2833
assert(reserve0 != 0 && reserve1 != 0); // ensure that there's liquidity in the pair
2934
assert(blockTimestampLast != 0); // ensure there's a price history
3035
}

contracts/UniswapV2Library.sol

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
pragma solidity =0.5.16;
1+
pragma solidity =0.6.6;
22

3-
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol';
43
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';
54

65
import './interfaces/IUniswapV2Library.sol';
@@ -9,8 +8,11 @@ import './libraries/SafeMath.sol';
98
contract UniswapV2Library is IUniswapV2Library {
109
using SafeMath for uint;
1110

12-
// factory address is identical across mainnet and testnets but differs between testing and deployed environments
13-
IUniswapV2Factory public constant factory = IUniswapV2Factory(0xdCCc660F92826649754E357b11bd41C31C0609B9);
11+
address public immutable override factory;
12+
13+
constructor(address _factory) public {
14+
factory = _factory;
15+
}
1416

1517
// returns sorted token addresses, used to handle return values from pairs sorted in this order
1618
function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
@@ -20,13 +22,13 @@ contract UniswapV2Library is IUniswapV2Library {
2022
}
2123

2224
// calculates the CREATE2 address for a pair without making any external calls
23-
function pairFor(address tokenA, address tokenB) internal pure returns (address pair) {
25+
function pairFor(address tokenA, address tokenB) internal view returns (address pair) {
2426
(address token0, address token1) = sortTokens(tokenA, tokenB);
2527
pair = address(uint(keccak256(abi.encodePacked(
2628
hex'ff',
2729
factory,
2830
keccak256(abi.encodePacked(token0, token1)),
29-
hex'0b77fb54a078d9399fa29cac94f5b35b9f11611b456ab507c7f46754712b642b' // init code hash
31+
hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash
3032
))));
3133
}
3234

@@ -38,14 +40,14 @@ contract UniswapV2Library is IUniswapV2Library {
3840
}
3941

4042
// given some amount of an asset and pair reserves, returns an equivalent amount of the other asset
41-
function quote(uint amountA, uint reserveA, uint reserveB) public pure returns (uint amountB) {
43+
function quote(uint amountA, uint reserveA, uint reserveB) public pure override returns (uint amountB) {
4244
require(amountA > 0, 'UniswapV2Helper: INSUFFICIENT_AMOUNT');
4345
require(reserveA > 0 && reserveB > 0, 'UniswapV2Helper: INSUFFICIENT_LIQUIDITY');
4446
amountB = amountA.mul(reserveB) / reserveA;
4547
}
4648

4749
// given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
48-
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) public pure returns (uint amountOut) {
50+
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) public pure override returns (uint amountOut) {
4951
require(amountIn > 0, 'UniswapV2Helper: INSUFFICIENT_INPUT_AMOUNT');
5052
require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Helper: INSUFFICIENT_LIQUIDITY');
5153
uint amountInWithFee = amountIn.mul(997);
@@ -55,7 +57,7 @@ contract UniswapV2Library is IUniswapV2Library {
5557
}
5658

5759
// given an output amount of an asset and pair reserves, returns a required input amount of the other asset
58-
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) public pure returns (uint amountIn) {
60+
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) public pure override returns (uint amountIn) {
5961
require(amountOut > 0, 'UniswapV2Helper: INSUFFICIENT_OUTPUT_AMOUNT');
6062
require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Helper: INSUFFICIENT_LIQUIDITY');
6163
uint numerator = reserveIn.mul(amountOut).mul(1000);
@@ -64,7 +66,7 @@ contract UniswapV2Library is IUniswapV2Library {
6466
}
6567

6668
// performs chained getAmountOut calculations on any number of pairs
67-
function getAmountsOut(uint amountIn, address[] memory path) public view returns (uint[] memory amounts) {
69+
function getAmountsOut(uint amountIn, address[] memory path) public view override returns (uint[] memory amounts) {
6870
require(path.length >= 2, 'UniswapV2Helper: INVALID_PATH');
6971
amounts = new uint[](path.length);
7072
amounts[0] = amountIn;
@@ -75,7 +77,7 @@ contract UniswapV2Library is IUniswapV2Library {
7577
}
7678

7779
// performs chained getAmountIn calculations on any number of pairs
78-
function getAmountsIn(uint amountOut, address[] memory path) public view returns (uint[] memory amounts) {
80+
function getAmountsIn(uint amountOut, address[] memory path) public view override returns (uint[] memory amounts) {
7981
require(path.length >= 2, 'UniswapV2Helper: INVALID_PATH');
8082
amounts = new uint[](path.length);
8183
amounts[amounts.length - 1] = amountOut;

contracts/UniswapV2Migrator.sol

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pragma solidity =0.5.16;
1+
pragma solidity =0.6.6;
22

33
import './interfaces/IUniswapV2Migrator.sol';
44
import './interfaces/V1/IUniswapV1Factory.sol';
@@ -7,9 +7,8 @@ import './interfaces/IUniswapV2Router01.sol';
77
import './interfaces/IERC20.sol';
88

99
contract UniswapV2Migrator is IUniswapV2Migrator {
10-
IUniswapV1Factory public factoryV1;
11-
// router address is identical across mainnet and testnets but differs between testing and deployed environments
12-
IUniswapV2Router01 public constant router = IUniswapV2Router01(0x84e924C5E04438D2c1Df1A981f7E7104952e6de1);
10+
IUniswapV1Factory immutable factoryV1;
11+
IUniswapV2Router01 immutable router;
1312

1413
function _safeApprove(address token, address to, uint value) private {
1514
// bytes4(keccak256(bytes('approve(address,uint256)')));
@@ -24,25 +23,29 @@ contract UniswapV2Migrator is IUniswapV2Migrator {
2423
}
2524

2625
function _safeTransferETH(address to, uint value) private {
27-
(bool success,) = to.call.value(value)(new bytes(0));
26+
(bool success,) = to.call{value: value}(new bytes(0));
2827
require(success, 'ETH_TRANSFER_FAILED');
2928
}
3029

31-
constructor(address _factoryV1) public {
30+
constructor(address _factoryV1, address _router) public {
3231
factoryV1 = IUniswapV1Factory(_factoryV1);
32+
router = IUniswapV2Router01(_router);
3333
}
3434

3535
// needs to accept ETH from any v1 exchange and the router. ideally this could be enforced, as in the router,
3636
// but it's not possible because it requires a call to the v1 factory, which takes too much gas
37-
function() external payable {}
37+
receive() external payable {}
3838

39-
function migrate(address token, uint amountTokenMin, uint amountETHMin, address to, uint deadline) external {
39+
function migrate(address token, uint amountTokenMin, uint amountETHMin, address to, uint deadline)
40+
external
41+
override
42+
{
4043
IUniswapV1Exchange exchangeV1 = IUniswapV1Exchange(factoryV1.getExchange(token));
4144
uint liquidityV1 = exchangeV1.balanceOf(msg.sender);
4245
require(exchangeV1.transferFrom(msg.sender, address(this), liquidityV1), 'TRANSFER_FROM_FAILED');
4346
(uint amountETHV1, uint amountTokenV1) = exchangeV1.removeLiquidity(liquidityV1, 1, 1, uint(-1));
4447
_safeApprove(token, address(router), amountTokenV1);
45-
(uint amountTokenV2, uint amountETHV2,) = router.addLiquidityETH.value(amountETHV1)(
48+
(uint amountTokenV2, uint amountETHV2,) = router.addLiquidityETH{value: amountETHV1}(
4649
token,
4750
amountTokenV1,
4851
amountTokenMin,

0 commit comments

Comments
 (0)