forked from Uniswap/v3-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TestUniswapV3Router.sol
91 lines (81 loc) · 2.93 KB
/
TestUniswapV3Router.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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// SPDX-License-Identifier: UNLICENSED
pragma solidity =0.7.6;
import '../libraries/SafeCast.sol';
import '../libraries/TickMath.sol';
import '../interfaces/IERC20Minimal.sol';
import '../interfaces/callback/IUniswapV3SwapCallback.sol';
import '../interfaces/IUniswapV3Pool.sol';
contract TestUniswapV3Router is IUniswapV3SwapCallback {
using SafeCast for uint256;
// flash swaps for an exact amount of token0 in the output pool
function swapForExact0Multi(
address recipient,
address poolInput,
address poolOutput,
uint256 amount0Out
) external {
address[] memory pools = new address[](1);
pools[0] = poolInput;
IUniswapV3Pool(poolOutput).swap(
recipient,
false,
-amount0Out.toInt256(),
TickMath.MAX_SQRT_RATIO - 1,
abi.encode(pools, msg.sender)
);
}
// flash swaps for an exact amount of token1 in the output pool
function swapForExact1Multi(
address recipient,
address poolInput,
address poolOutput,
uint256 amount1Out
) external {
address[] memory pools = new address[](1);
pools[0] = poolInput;
IUniswapV3Pool(poolOutput).swap(
recipient,
true,
-amount1Out.toInt256(),
TickMath.MIN_SQRT_RATIO + 1,
abi.encode(pools, msg.sender)
);
}
event SwapCallback(int256 amount0Delta, int256 amount1Delta);
function uniswapV3SwapCallback(
int256 amount0Delta,
int256 amount1Delta,
bytes calldata data
) public override {
emit SwapCallback(amount0Delta, amount1Delta);
(address[] memory pools, address payer) = abi.decode(data, (address[], address));
if (pools.length == 1) {
// get the address and amount of the token that we need to pay
address tokenToBePaid =
amount0Delta > 0 ? IUniswapV3Pool(msg.sender).token0() : IUniswapV3Pool(msg.sender).token1();
int256 amountToBePaid = amount0Delta > 0 ? amount0Delta : amount1Delta;
bool zeroForOne = tokenToBePaid == IUniswapV3Pool(pools[0]).token1();
IUniswapV3Pool(pools[0]).swap(
msg.sender,
zeroForOne,
-amountToBePaid,
zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1,
abi.encode(new address[](0), payer)
);
} else {
if (amount0Delta > 0) {
IERC20Minimal(IUniswapV3Pool(msg.sender).token0()).transferFrom(
payer,
msg.sender,
uint256(amount0Delta)
);
} else {
IERC20Minimal(IUniswapV3Pool(msg.sender).token1()).transferFrom(
payer,
msg.sender,
uint256(amount1Delta)
);
}
}
}
}