-
Notifications
You must be signed in to change notification settings - Fork 28
/
UniswapV2FlashSwap.sol
84 lines (72 loc) · 2.7 KB
/
UniswapV2FlashSwap.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
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import {IUniswapV2Pair} from
"../../../src/interfaces/uniswap-v2/IUniswapV2Pair.sol";
import {IERC20} from "../../../src/interfaces/IERC20.sol";
error InvalidToken();
error NotPair();
error NotSender();
contract UniswapV2FlashSwap {
IUniswapV2Pair private immutable pair;
address private immutable token0;
address private immutable token1;
constructor(address _pair) {
pair = IUniswapV2Pair(_pair);
token0 = pair.token0();
token1 = pair.token1();
}
function flashSwap(address token, uint256 amount) external {
if (token != token0 && token != token1) {
revert InvalidToken();
}
// Write your code here
// Don’t change any other code
// 1. Determine amount0Out and amount1Out
(uint256 amount0Out, uint256 amount1Out) =
token == token0 ? (amount, uint256(0)) : (uint256(0), amount);
// 2. Encode token and msg.sender as bytes
bytes memory data = abi.encode(token, msg.sender);
// 3. Call pair.swap
pair.swap({
amount0Out: amount0Out,
amount1Out: amount1Out,
to: address(this),
data: data
});
}
// Uniswap V2 callback
function uniswapV2Call(
address sender,
uint256 amount0,
uint256 amount1,
bytes calldata data
) external {
// Write your code here
// Don’t change any other code
// 1. Require msg.sender is pair contract
// 2. Require sender is this contract
// Alice -> FlashSwap ---- to = FlashSwap ----> UniswapV2Pair
// <-- sender = FlashSwap --
// Eve ------------ to = FlashSwap -----------> UniswapV2Pair
// FlashSwap <-- sender = Eve --------
if (msg.sender != address(pair)) {
revert NotPair();
}
// 2. Check sender is this contract
if (sender != address(this)) {
revert NotSender();
}
// 3. Decode token and caller from data
(address token, address caller) = abi.decode(data, (address, address));
// 4. Determine amount borrowed (only one of them is > 0)
uint256 amount = token == token0 ? amount0 : amount1;
// 5. Calculate flash swap fee and amount to repay
// fee = borrowed amount * 3 / 997 + 1 to round up
uint256 fee = ((amount * 3) / 997) + 1;
uint256 amountToRepay = amount + fee;
// 6. Get flash swap fee from caller
IERC20(token).transferFrom(caller, address(this), fee);
// 7. Repay Uniswap V2 pair
IERC20(token).transfer(address(pair), amountToRepay);
}
}