1
+ /*
2
+ Copyright 2022 Index Cooperative
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+ Unless required by applicable law or agreed to in writing, software
9
+ distributed under the License is distributed on an "AS IS" BASIS,
10
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ See the License for the specific language governing permissions and
12
+ limitations under the License.
13
+
14
+ SPDX-License-Identifier: Apache License, Version 2.0
15
+ */
16
+
17
+ pragma solidity 0.6.10 ;
18
+ pragma experimental ABIEncoderV2;
19
+
20
+ import { Address } from "@openzeppelin/contracts/utils/Address.sol " ;
21
+ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol " ;
22
+ import { Math } from "@openzeppelin/contracts/math/Math.sol " ;
23
+ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol " ;
24
+ import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol " ;
25
+ import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol " ;
26
+
27
+ import { IController } from "../interfaces/IController.sol " ;
28
+ import { IDebtIssuanceModule } from "../interfaces/IDebtIssuanceModule.sol " ;
29
+ import { ISetToken } from "../interfaces/ISetToken.sol " ;
30
+ import { IWETH } from "../interfaces/IWETH.sol " ;
31
+ import { PreciseUnitMath } from "../lib/PreciseUnitMath.sol " ;
32
+
33
+ /**
34
+ * @title FlashMintWrapped
35
+ *
36
+ * Flash issues SetTokens whose components are purely made up of wrapped tokens.
37
+ * In particular, for issuance, the contract needs to:
38
+ * 1. For all components in a SetToken, swap input token into matching unwrapped component
39
+ * 2. For each unwrapped component, execute the wrapping function
40
+ * 3. Call on issuanceModule to issue tokens
41
+ */
42
+ contract FlashMintWrapped is ReentrancyGuard {
43
+
44
+ using Address for address payable ;
45
+ using SafeMath for uint256 ;
46
+ using PreciseUnitMath for uint256 ;
47
+ using SafeERC20 for IERC20 ;
48
+ using SafeERC20 for ISetToken;
49
+
50
+ struct WrappedCalldata {
51
+ address target;
52
+ uint256 quantity;
53
+ bytes callData;
54
+ }
55
+
56
+ /* ============ Enums ============ */
57
+
58
+ /* ============ Constants ============= */
59
+
60
+ uint256 constant private MAX_UINT96 = 2 ** 96 - 1 ;
61
+ address constant public ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE ;
62
+
63
+ /* ============ State Variables ============ */
64
+
65
+ IController public immutable controller;
66
+
67
+ /* ============ Events ============ */
68
+
69
+ event ExchangeIssue (
70
+ address indexed _recipient , // The recipient address of the issued SetTokens
71
+ ISetToken indexed _setToken , // The issued SetToken
72
+ IERC20 indexed _inputToken , // The address of the input asset(ERC20/ETH) used to issue the SetTokens
73
+ uint256 _amountInputToken , // The amount of input tokens used for issuance
74
+ uint256 _amountSetIssued // The amount of SetTokens received by the recipient
75
+ );
76
+
77
+ event ExchangeRedeem (
78
+ address indexed _recipient , // The recipient address which redeemed the SetTokens
79
+ ISetToken indexed _setToken , // The redeemed SetToken
80
+ IERC20 indexed _outputToken , // The address of output asset(ERC20/ETH) received by the recipient
81
+ uint256 _amountSetRedeemed , // The amount of SetTokens redeemed for output tokens
82
+ uint256 _amountOutputToken // The amount of output tokens received by the recipient
83
+ );
84
+
85
+ /* ============ Modifiers ============ */
86
+
87
+ modifier isSetToken (ISetToken _setToken ) {
88
+ require (controller.isSet (address (_setToken)), "ExchangeIssuance: INVALID SET " );
89
+ _;
90
+ }
91
+
92
+ modifier isValidModule (address _issuanceModule ) {
93
+ require (controller.isModule (_issuanceModule), "ExchangeIssuance: INVALID ISSUANCE MODULE " );
94
+ _;
95
+ }
96
+
97
+ /* ========== Constructor ========== */
98
+
99
+ constructor (address _controller ) {
100
+ controller = IController (_controller);
101
+ }
102
+
103
+ /* ============ External Functions ============ */
104
+
105
+ /**
106
+ * Runs all the necessary approval functions required for a given ERC20 token.
107
+ * This function can be called when a new token is added to a SetToken during a
108
+ * rebalance.
109
+ *
110
+ * @param _token Address of the token which needs approval
111
+ * @param _spender Address of the spender which will be approved to spend token. (Must be a whitlisted issuance module)
112
+ */
113
+ function approveToken (IERC20 _token , address _spender ) external isValidModule (_spender) {
114
+ }
115
+
116
+ /**
117
+ * Runs all the necessary approval functions required for a list of ERC20 tokens.
118
+ *
119
+ * @param _tokens Addresses of the tokens which need approval
120
+ * @param _spender Address of the spender which will be approved to spend token. (Must be a whitlisted issuance module)
121
+ */
122
+ function approveTokens (IERC20 [] calldata _tokens , address _spender ) external {
123
+ }
124
+
125
+ /**
126
+ * Runs all the necessary approval functions required before issuing
127
+ * or redeeming a SetToken. This function need to be called only once before the first time
128
+ * this smart contract is used on any particular SetToken.
129
+ *
130
+ * @param _setToken Address of the SetToken being initialized
131
+ * @param _issuanceModule Address of the issuance module which will be approved to spend component tokens.
132
+ */
133
+ function approveSetToken (ISetToken _setToken , address _issuanceModule ) external {
134
+ }
135
+
136
+ /**
137
+ * Issues an exact amount of SetTokens for given amount of input ERC20 tokens.
138
+ * The excess amount of tokens is returned in an equivalent amount of ether.
139
+ *
140
+ * @param _setToken Address of the SetToken to be issued
141
+ * @param _inputToken Address of the input token
142
+ * @param _amountSetToken Amount of SetTokens to issue
143
+ * @param _calldata The calldata needed to execute all the wrapping of tokens
144
+ *
145
+ * @return totalInputTokenSold Amount of input token spent for issuance
146
+ */
147
+ function issueExactSetFromToken (
148
+ ISetToken _setToken ,
149
+ IERC20 _inputToken ,
150
+ uint256 _amountSetToken ,
151
+ WrappedCalldata[] memory _calldata
152
+ )
153
+ external
154
+ nonReentrant
155
+ returns (uint256 )
156
+ {
157
+ return 0 ;
158
+ }
159
+
160
+
161
+ /**
162
+ * Issues an exact amount of SetTokens for given amount of ETH.
163
+ * The excess amount of tokens is returned in an equivalent amount of ether.
164
+ *
165
+ * @param _setToken Address of the SetToken to be issued
166
+ * @param _amountSetToken Amount of SetTokens to issue
167
+ * @param _componentQuotes The encoded 0x transactions to execute
168
+ *
169
+ * @return amountEthReturn Amount of ether returned to the caller
170
+ */
171
+ function issueExactSetFromETH (
172
+ ISetToken _setToken ,
173
+ uint256 _amountSetToken
174
+ )
175
+ external
176
+ nonReentrant
177
+ payable
178
+ returns (uint256 )
179
+ {
180
+ return 0 ;
181
+ }
182
+
183
+ /**
184
+ * Redeems an exact amount of SetTokens for an ERC20 token.
185
+ * The SetToken must be approved by the sender to this contract.
186
+ *
187
+ * @param _setToken Address of the SetToken being redeemed
188
+ * @param _outputToken Address of output token
189
+ * @param _amountSetToken Amount SetTokens to redeem
190
+ * @param _minOutputReceive Minimum amount of output token to receive
191
+ * @param _componentQuotes The encoded 0x transactions execute (components -> WETH).
192
+ * @param _issuanceModule Address of issuance Module to use
193
+ * @param _isDebtIssuance Flag indicating wether given issuance module is a debt issuance module
194
+ *
195
+ * @return outputAmount Amount of output tokens sent to the caller
196
+ */
197
+ function redeemExactSetForToken (
198
+ ISetToken _setToken ,
199
+ IERC20 _outputToken ,
200
+ uint256 _amountSetToken ,
201
+ uint256 _minOutputReceive ,
202
+ address _issuanceModule
203
+ )
204
+ external
205
+ nonReentrant
206
+ returns (uint256 )
207
+ {
208
+ return 0 ;
209
+ }
210
+
211
+ /**
212
+ * Redeems an exact amount of SetTokens for ETH.
213
+ * The SetToken must be approved by the sender to this contract.
214
+ *
215
+ * @param _setToken Address of the SetToken being redeemed
216
+ * @param _amountSetToken Amount SetTokens to redeem
217
+ * @param _minEthReceive Minimum amount of Eth to receive
218
+ * @param _componentQuotes The encoded 0x transactions execute
219
+ * @param _issuanceModule Address of issuance Module to use
220
+ * @param _isDebtIssuance Flag indicating wether given issuance module is a debt issuance module
221
+ *
222
+ * @return outputAmount Amount of output tokens sent to the caller
223
+ */
224
+ function redeemExactSetForETH (
225
+ ISetToken _setToken ,
226
+ uint256 _amountSetToken ,
227
+ uint256 _minEthReceive ,
228
+ address _issuanceModule
229
+ )
230
+ external
231
+ nonReentrant
232
+ returns (uint256 )
233
+ {
234
+ return 0 ;
235
+ }
236
+ }
0 commit comments