-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathFlashForwardLoan.sol
160 lines (135 loc) · 4.6 KB
/
FlashForwardLoan.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.7.0;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/utils/SafeCast.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "./interfaces/IZkSync.sol";
import "./interfaces/IUSDC.sol";
import "./BasicMetaTransaction.sol";
import { FlashLoanReceiverBase } from "FlashLoanReceiverBase.sol";
import { ILendingPool, ILendingPoolAddressesProvider, IERC20 } from "Interfaces.sol";
import { SafeMath } from "Libraries.sol";
/**
!!!
Never keep funds permanently on your FlashLoanReceiverBase contract as they could be
exposed to a 'griefing' attack, where the stored funds are used by an attacker.
!!!
*/
contract FlashForwardLoan is FlashLoanReceiverBase, BasicMetaTransaction {
using SafeMath for uint256;
constructor(ILendingPoolAddressesProvider _addressProvider) FlashLoanReceiverBase(_addressProvider) public {}
using SafeERC20 for IERC20;
using SafeERC20 for IUSDC;
IZkSync internal _zkSync;
IUSDC private _usdc;
constructor(
IZkSync zkSync,
IUSDC usdc,
uint256 chainId
) public BasicMetaTransaction(chainId) {
_zkSync = zkSync;
_usdc = usdc;
_usdc.safeApprove(address(_zkSync), uint256(-1));
}
receive() external payable {}
function deposit(
address from,
address to,
uint256 value,
uint256 validAfter,
uint256 validBefore,
bytes32 nonce,
uint8 v,
bytes32 r,
bytes32 s
) external {
require(value < 2**104, "Amount doesn't fit in 104 bits");
require(to == address(this), "Recipient is not this contract");
_usdc.transferWithAuthorization(
from,
to,
value,
validAfter,
validBefore,
nonce,
v,
r,
s
);
_zkSync.depositERC20(address(_usdc), uint104(value), from);
}
function claim() external {
address user = _msgSender();
_usdc.safeTransfer(user, 100 * (10**6));
}
}
/**
This function is called after your contract has received the flash loaned amount
*/
function executeOperation(
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata premiums,
address initiator,
bytes calldata params
)
external
override
returns (bool)
{
//
// This contract now has the funds requested.
// Your logic goes here.
//
// At the end of your logic above, this contract owes
// the flashloaned amounts + premiums.
// Therefore ensure your contract has enough to repay
// these amounts.
// Approve the LendingPool contract allowance to *pull* the owed amount
for (uint i = 0; i < assets.length; i++) {
uint amountOwing = amounts[i].add(premiums[i]);
IERC20(assets[i]).approve(address(LENDING_POOL), amountOwing);
}
return true;
}
function myFlashLoanCall() public {
address receiverAddress = address(this);
address[] memory assets = new address[](7);
assets[0] = address(0xB597cd8D3217ea6477232F9217fa70837ff667Af); // Kovan AAVE
assets[1] = address(0x2d12186Fbb9f9a8C28B3FfdD4c42920f8539D738); // Kovan BAT
assets[2] = address(0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD); // Kovan DAI
assets[3] = address(0x075A36BA8846C6B6F53644fDd3bf17E5151789DC); // Kovan UNI
assets[4] = address(0xb7c325266ec274fEb1354021D27FA3E3379D840d); // Kovan YFI
assets[5] = address(0xAD5ce863aE3E4E9394Ab43d4ba0D80f419F61789); // Kovan LINK
assets[6] = address(0x7FDb81B0b8a010dd4FFc57C3fecbf145BA8Bd947); // Kovan SNX
uint256[] memory amounts = new uint256[](7);
amounts[0] = 1 ether;
amounts[1] = 1 ether;
amounts[2] = 1 ether;
amounts[3] = 1 ether;
amounts[4] = 1 ether;
amounts[5] = 1 ether;
amounts[6] = 1 ether;
// 0 = no debt, 1 = stable, 2 = variable
uint256[] memory modes = new uint256[](7);
modes[0] = 0;
modes[1] = 0;
modes[2] = 0;
modes[3] = 0;
modes[4] = 0;
modes[5] = 0;
modes[6] = 0;
address onBehalfOf = address(this);
bytes memory params = "";
uint16 referralCode = 0;
LENDING_POOL.flashLoan(
receiverAddress,
assets,
amounts,
modes,
onBehalfOf,
params,
referralCode
);
}
}