1
+ /*
2
+ Copyright 2021 Set Labs Inc.
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
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+
16
+ SPDX-License-Identifier: Apache License, Version 2.0
17
+ */
18
+
19
+ pragma solidity 0.6.10 ;
20
+ pragma experimental "ABIEncoderV2 " ;
21
+
22
+ import { ISwapRouter } from "contracts/interfaces/external/ISwapRouter.sol " ;
23
+ import { BytesLib } from "external/contracts/uniswap/v3/lib/BytesLib.sol " ;
24
+
25
+ import { IIndexExchangeAdapter } from "../../../interfaces/IIndexExchangeAdapter.sol " ;
26
+
27
+ /**
28
+ * @title UniswapV3IndexExchangeAdapter
29
+ * @author Set Protocol
30
+ *
31
+ * A Uniswap V3 exchange adapter that returns calldata for trading with GeneralIndexModule, allows encoding a trade with a fixed input quantity or
32
+ * a fixed output quantity.
33
+ */
34
+ contract UniswapV3IndexExchangeAdapter is IIndexExchangeAdapter {
35
+
36
+ using BytesLib for bytes ;
37
+
38
+ /* ============ Constants ============ */
39
+
40
+ // Uniswap router function string for swapping exact amount of input tokens for a minimum of output tokens
41
+ string internal constant SWAP_EXACT_INPUT = "exactInputSingle((address,address,uint24,address,uint256,uint256,uint256,uint160)) " ;
42
+ // Uniswap router function string for swapping max amoutn of input tokens for an exact amount of output tokens
43
+ string internal constant SWAP_EXACT_OUTPUT = "exactOutputSingle((address,address,uint24,address,uint256,uint256,uint256,uint160)) " ;
44
+
45
+ /* ============ State Variables ============ */
46
+
47
+ // Address of Uniswap V3 SwapRouter contract
48
+ address public immutable router;
49
+
50
+ /* ============ Constructor ============ */
51
+
52
+ /**
53
+ * Set state variables
54
+ *
55
+ * @param _router Address of Uniswap V3 SwapRouter contract
56
+ */
57
+ constructor (address _router ) public {
58
+ router = _router;
59
+ }
60
+
61
+ /* ============ External Getter Functions ============ */
62
+
63
+ /**
64
+ * Return calldata for trading with Uniswap V3 SwapRouter. Trade paths are created from _sourceToken,
65
+ * _destinationToken and pool fees (which is encoded in _data).
66
+ *
67
+ * ---------------------------------------------------------------------------------------------------------------
68
+ * _isSendTokenFixed | Parameter | Amount |
69
+ * ---------------------------------------------------------------------------------------------------------------
70
+ * True | _sourceQuantity | Fixed amount of _sourceToken to trade |
71
+ * | _destinationQuantity | Minimum amount of _destinationToken willing to receive |
72
+ * ---------------------------------------------------------------------------------------------------------------
73
+ * False | _sourceQuantity | Maximum amount of _sourceToken to trade |
74
+ * | _destinationQuantity | Fixed amount of _destinationToken want to receive |
75
+ * ---------------------------------------------------------------------------------------------------------------
76
+ *
77
+ * @param _sourceToken Address of source token to be sold
78
+ * @param _destinationToken Address of destination token to buy
79
+ * @param _destinationAddress Address that assets should be transferred to
80
+ * @param _isSendTokenFixed Boolean indicating if the send quantity is fixed, used to determine correct trade interface
81
+ * @param _sourceQuantity Fixed/Max amount of source token to sell
82
+ * @param _destinationQuantity Min/Fixed amount of destination token to buy
83
+ * @param _data Arbitrary bytes containing fees value, expressed in hundredths of a bip,
84
+ * used to determine the pool to trade among similar asset pools on Uniswap V3.
85
+ * Note: SetToken manager must set the appropriate pool fees via `setExchangeData` in GeneralIndexModule
86
+ * for each component that needs to be traded on UniswapV3. This is different from UniswapV3ExchangeAdapter,
87
+ * where `_data` represents UniswapV3 trade path vs just the pool fees percentage.
88
+ *
89
+ * @return address Target contract address
90
+ * @return uint256 Call value
91
+ * @return bytes Trade calldata
92
+ */
93
+ function getTradeCalldata (
94
+ address _sourceToken ,
95
+ address _destinationToken ,
96
+ address _destinationAddress ,
97
+ bool _isSendTokenFixed ,
98
+ uint256 _sourceQuantity ,
99
+ uint256 _destinationQuantity ,
100
+ bytes memory _data
101
+ )
102
+ external
103
+ view
104
+ override
105
+ returns (address , uint256 , bytes memory )
106
+ {
107
+ uint24 fee = _data.toUint24 (0 );
108
+
109
+ bytes memory callData = _isSendTokenFixed
110
+ ? abi.encodeWithSignature (
111
+ SWAP_EXACT_INPUT,
112
+ ISwapRouter.ExactInputSingleParams (
113
+ _sourceToken,
114
+ _destinationToken,
115
+ fee,
116
+ _destinationAddress,
117
+ block .timestamp ,
118
+ _sourceQuantity,
119
+ _destinationQuantity,
120
+ 0
121
+ )
122
+ ) : abi.encodeWithSignature (
123
+ SWAP_EXACT_OUTPUT,
124
+ ISwapRouter.ExactOutputSingleParams (
125
+ _sourceToken,
126
+ _destinationToken,
127
+ fee,
128
+ _destinationAddress,
129
+ block .timestamp ,
130
+ _destinationQuantity,
131
+ _sourceQuantity,
132
+ 0
133
+ )
134
+ );
135
+
136
+ return (router, 0 , callData);
137
+ }
138
+
139
+ /**
140
+ * Returns the address to approve source tokens to for trading. This is the Uniswap V3 router address.
141
+ *
142
+ * @return address Address of the contract to approve tokens to
143
+ */
144
+ function getSpender () external view override returns (address ) {
145
+ return router;
146
+ }
147
+
148
+ /**
149
+ * Helper that returns encoded fee value.
150
+ *
151
+ * @param fee UniswapV3 pool fee percentage, expressed in hundredths of a bip
152
+ *
153
+ * @return bytes Encoded fee value
154
+ */
155
+ function getEncodedFeeData (uint24 fee ) external view returns (bytes memory ) {
156
+ return abi.encodePacked (fee);
157
+ }
158
+ }
0 commit comments