Skip to content

Commit 00c676c

Browse files
0xSachinKbweick
andauthored
Add GeneralIndexModule contract (#59)
Add GeneralIndexModule contract, UniswapV2ExchangeAdapterV2 updates, and BalancerV1ExchangeAdapter Co-authored-by: bweick <[email protected]>
1 parent 71fcef7 commit 00c676c

File tree

9 files changed

+3150
-31
lines changed

9 files changed

+3150
-31
lines changed

contracts/interfaces/IExchangeAdapter.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,9 @@ interface IExchangeAdapter {
3030
external
3131
view
3232
returns (address, uint256, bytes memory);
33+
function generateDataParam(
34+
address _sellComponent,
35+
address _buyComponent,
36+
bool _fixIn
37+
) external view returns (bytes memory);
3338
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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+
/**
23+
* @title BalancerV1ExchangeAdapter
24+
* @author Set Protocol
25+
*
26+
* A Balancer exchange adapter that returns calldata for trading.
27+
*/
28+
contract BalancerV1ExchangeAdapter {
29+
30+
/* ============ Constants ============ */
31+
32+
// Amount of pools examined when fetching quote
33+
uint256 private constant BALANCER_POOL_LIMIT = 3;
34+
35+
/* ============ State Variables ============ */
36+
37+
// Address of Uniswap V2 Router02 contract
38+
address public immutable balancerProxy;
39+
// Balancer proxy function string for swapping exact tokens for a minimum of receive tokens
40+
string internal constant EXACT_IN = "smartSwapExactIn(address,address,uint256,uint256,uint256)";
41+
// Balancer proxy function string for swapping tokens for an exact amount of receive tokens
42+
string internal constant EXACT_OUT = "smartSwapExactOut(address,address,uint256,uint256,uint256)";
43+
44+
/* ============ Constructor ============ */
45+
46+
/**
47+
* Set state variables
48+
*
49+
* @param _balancerProxy Balancer exchange proxy address
50+
*/
51+
constructor(address _balancerProxy) public {
52+
balancerProxy = _balancerProxy;
53+
}
54+
55+
/* ============ External Getter Functions ============ */
56+
57+
/**
58+
* Return calldata for Balancer Proxy. Bool to select trade function is encoded in the arbitrary data parameter.
59+
*
60+
* @param _sourceToken Address of source token to be sold
61+
* @param _destinationToken Address of destination token to buy
62+
* @param _destinationAddress Address that assets should be transferred to
63+
* @param _sourceQuantity Fixed/Max amount of source token to sell
64+
* @param _destinationQuantity Min/Fixed amount of destination tokens to receive
65+
* @param _data Arbitrary bytes containing bool to determine function string
66+
*
67+
* @return address Target contract address
68+
* @return uint256 Call value
69+
* @return bytes Trade calldata
70+
*/
71+
function getTradeCalldata(
72+
address _sourceToken,
73+
address _destinationToken,
74+
address _destinationAddress,
75+
uint256 _sourceQuantity,
76+
uint256 _destinationQuantity,
77+
bytes memory _data
78+
)
79+
external
80+
view
81+
returns (address, uint256, bytes memory)
82+
{
83+
(
84+
bool shouldSwapFixedInputAmount
85+
) = abi.decode(_data, (bool));
86+
87+
bytes memory callData = abi.encodeWithSignature(
88+
shouldSwapFixedInputAmount ? EXACT_IN : EXACT_OUT,
89+
_sourceToken,
90+
_destinationToken,
91+
shouldSwapFixedInputAmount ? _sourceQuantity : _destinationQuantity,
92+
shouldSwapFixedInputAmount ? _destinationQuantity : _sourceQuantity,
93+
BALANCER_POOL_LIMIT
94+
);
95+
96+
return (balancerProxy, 0, callData);
97+
}
98+
99+
/**
100+
* Generate data parameter to be passed to `getTradeCallData`. Returns encoded bool to select trade function.
101+
*
102+
* @param _sellComponent Address of the token to be sold
103+
* @param _buyComponent Address of the token to be bought
104+
* @param _fixIn Boolean representing if input tokens amount is fixed
105+
*
106+
* @return bytes Data parameter to be passed to `getTradeCallData`
107+
*/
108+
function generateDataParam(address _sellComponent, address _buyComponent, bool _fixIn)
109+
external
110+
view
111+
returns (bytes memory)
112+
{
113+
return abi.encode(_fixIn);
114+
}
115+
116+
/**
117+
* Returns the address to approve source tokens to for trading. This is the Balancer proxy address
118+
*
119+
* @return address Address of the contract to approve tokens to
120+
*/
121+
function getSpender() external view returns (address) {
122+
return balancerProxy;
123+
}
124+
}

contracts/protocol/integration/UniswapV2ExchangeAdapterV2.sol

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ pragma experimental "ABIEncoderV2";
2323
* @title UniswapV2ExchangeAdapterV2
2424
* @author Set Protocol
2525
*
26-
* A Uniswap Router02 exchange adapter that returns calldata for trading. Includes option for 2 different trade types on Uniswap
26+
* A Uniswap Router02 exchange adapter that returns calldata for trading. Includes option for 2 different trade types on Uniswap.
2727
*
2828
* CHANGE LOG:
2929
* - Add helper that encodes path and boolean into bytes
3030
* - Generalized ability to choose whether to swap an exact amount of source token for a min amount of receive token or swap a max amount of source token for
3131
* an exact amount of receive token
32+
* - Add helper to generate data parameter for `getTradeCallData`
3233
*
3334
*/
3435
contract UniswapV2ExchangeAdapterV2 {
@@ -64,8 +65,8 @@ contract UniswapV2ExchangeAdapterV2 {
6465
* @param _sourceToken Address of source token to be sold
6566
* @param _destinationToken Address of destination token to buy
6667
* @param _destinationAddress Address that assets should be transferred to
67-
* @param _sourceQuantity Amount of source token to sell
68-
* @param _minDestinationQuantity Min amount of destination token to buy
68+
* @param _sourceQuantity Fixed/Max amount of source token to sell
69+
* @param _destinationQuantity Min/Fixed amount of destination token to buy
6970
* @param _data Arbitrary bytes containing trade path and bool to determine function string
7071
*
7172
* @return address Target contract address
@@ -77,7 +78,7 @@ contract UniswapV2ExchangeAdapterV2 {
7778
address _destinationToken,
7879
address _destinationAddress,
7980
uint256 _sourceQuantity,
80-
uint256 _minDestinationQuantity,
81+
uint256 _destinationQuantity,
8182
bytes memory _data
8283
)
8384
external
@@ -86,22 +87,40 @@ contract UniswapV2ExchangeAdapterV2 {
8687
{
8788
(
8889
address[] memory path,
89-
bool shouldSwapTokensForExactTokens
90+
bool shouldSwapExactTokensForTokens
9091
) = abi.decode(_data, (address[],bool));
9192

92-
// If shouldSwapTokensForExactTokens, use appropriate function string and flip source and destination quantities to conform with Uniswap interface
9393
bytes memory callData = abi.encodeWithSignature(
94-
shouldSwapTokensForExactTokens ? SWAP_TOKENS_FOR_EXACT_TOKENS : SWAP_EXACT_TOKENS_FOR_TOKENS,
95-
shouldSwapTokensForExactTokens ? _minDestinationQuantity : _sourceQuantity,
96-
shouldSwapTokensForExactTokens ? _sourceQuantity : _minDestinationQuantity,
94+
shouldSwapExactTokensForTokens ? SWAP_EXACT_TOKENS_FOR_TOKENS : SWAP_TOKENS_FOR_EXACT_TOKENS,
95+
shouldSwapExactTokensForTokens ? _sourceQuantity : _destinationQuantity,
96+
shouldSwapExactTokensForTokens ? _destinationQuantity : _sourceQuantity,
9797
path,
9898
_destinationAddress,
9999
block.timestamp
100100
);
101-
102101
return (router, 0, callData);
103102
}
104103

104+
/**
105+
* Generate data parameter to be passed to `getTradeCallData`. Returns encoded trade paths and bool to select trade function.
106+
*
107+
* @param _sellComponent Address of the token to be sold
108+
* @param _buyComponent Address of the token to be bought
109+
* @param _fixIn Boolean representing if input tokens amount is fixed
110+
*
111+
* @return bytes Data parameter to be passed to `getTradeCallData`
112+
*/
113+
function generateDataParam(address _sellComponent, address _buyComponent, bool _fixIn)
114+
external
115+
view
116+
returns (bytes memory)
117+
{
118+
address[] memory path = new address[](2);
119+
path[0] = _sellComponent;
120+
path[1] = _buyComponent;
121+
return abi.encode(path, _fixIn);
122+
}
123+
105124
/**
106125
* Returns the address to approve source tokens to for trading. This is the Uniswap router address
107126
*
@@ -116,7 +135,7 @@ contract UniswapV2ExchangeAdapterV2 {
116135
*
117136
* @return bytes Encoded data used for trading on Uniswap
118137
*/
119-
function getUniswapExchangeData(address[] memory _path, bool _shouldSwapTokensForExactTokens) external view returns (bytes memory) {
120-
return abi.encode(_path, _shouldSwapTokensForExactTokens);
138+
function getUniswapExchangeData(address[] memory _path, bool _shouldSwapExactTokensForTokens) external view returns (bytes memory) {
139+
return abi.encode(_path, _shouldSwapExactTokensForTokens);
121140
}
122141
}

0 commit comments

Comments
 (0)