Skip to content

Commit fc6df5c

Browse files
feat: Flash Mint Compound
Flash mint contract for cTokens.
1 parent 905e8b8 commit fc6df5c

File tree

1 file changed

+236
-0
lines changed

1 file changed

+236
-0
lines changed
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
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

Comments
 (0)