@@ -28,28 +28,24 @@ pragma experimental "ABIEncoderV2";
28
28
29
29
contract ZeroExApiAdapter {
30
30
31
- struct BatchFillData {
32
- address inputToken ;
33
- address outputToken ;
34
- uint256 sellAmount ;
35
- WrappedBatchCall[] calls ;
36
- }
37
-
38
- struct WrappedBatchCall {
39
- bytes4 selector ;
40
- uint256 sellAmount ;
41
- bytes data ;
31
+ struct RfqOrder {
32
+ address makerToken ;
33
+ address takerToken ;
34
+ uint128 makerAmount ;
35
+ uint128 takerAmount ;
36
+ address maker;
37
+ address taker;
38
+ address txOrigin;
39
+ bytes32 pool ;
40
+ uint64 expiry ;
41
+ uint256 salt ;
42
42
}
43
43
44
- struct MultiHopFillData {
45
- address [] tokens;
46
- uint256 sellAmount;
47
- WrappedMultiHopCall[] calls;
48
- }
49
-
50
- struct WrappedMultiHopCall {
51
- bytes4 selector;
52
- bytes data;
44
+ struct Signature {
45
+ uint8 signatureType;
46
+ uint8 v;
47
+ bytes32 r;
48
+ bytes32 s;
53
49
}
54
50
55
51
/* ============ State Variables ============ */
@@ -149,23 +145,31 @@ contract ZeroExApiAdapter {
149
145
require (path.length > 1 , "Uniswap token path too short " );
150
146
inputToken = path[0 ];
151
147
outputToken = path[path.length - 1 ];
152
- } else if (selector == 0xafc6728e ) {
153
- // batchFill()
154
- BatchFillData memory fillData;
155
- (fillData, minOutputTokenAmount) =
156
- abi.decode (_data[4 :], (BatchFillData, uint256 ));
157
- inputToken = fillData.inputToken;
158
- outputToken = fillData.outputToken;
159
- inputTokenAmount = fillData.sellAmount;
160
- } else if (selector == 0x21c184b6 ) {
161
- // multiHopFill()
162
- MultiHopFillData memory fillData;
163
- (fillData, minOutputTokenAmount) =
164
- abi.decode (_data[4 :], (MultiHopFillData, uint256 ));
165
- require (fillData.tokens.length > 1 , "Multihop token path too short " );
166
- inputToken = fillData.tokens[0 ];
167
- outputToken = fillData.tokens[fillData.tokens.length - 1 ];
168
- inputTokenAmount = fillData.sellAmount;
148
+ } else if (selector == 0xaa77476c ) {
149
+ // fillRfqOrder()
150
+ RfqOrder memory order;
151
+ uint128 takerTokenFillAmount;
152
+ (order, , takerTokenFillAmount) =
153
+ abi.decode (_data[4 :], (RfqOrder, Signature, uint128 ));
154
+ inputTokenAmount = uint256 (takerTokenFillAmount);
155
+ inputToken = order.takerToken;
156
+ outputToken = order.makerToken;
157
+ minOutputTokenAmount = getRfqOrderMakerFillAmount (order, inputTokenAmount);
158
+ } else if (selector == 0x75103cb9 ) {
159
+ // batchFillRfqOrders()
160
+ RfqOrder[] memory orders;
161
+ uint128 [] memory takerTokenFillAmounts;
162
+ bool revertIfIncomplete;
163
+ (orders, , takerTokenFillAmounts, revertIfIncomplete) =
164
+ abi.decode (_data[4 :], (RfqOrder[], uint256 , uint128 [], bool ));
165
+ require (orders.length > 0 , "Empty RFQ orders " );
166
+ require (revertIfIncomplete, "batchFillRfqOrder must be all or nothing " );
167
+ inputToken = orders[0 ].takerToken;
168
+ outputToken = orders[0 ].makerToken;
169
+ for (uint256 i = 0 ; i < orders.length ; ++ i) {
170
+ inputTokenAmount += uint256 (takerTokenFillAmounts[i]);
171
+ minOutputTokenAmount += getRfqOrderMakerFillAmount (orders[i], takerTokenFillAmounts[i]);
172
+ }
169
173
} else if (selector == 0x6af479b2 ) {
170
174
// sellTokenForTokenToUniswapV3()
171
175
bytes memory encodedPath;
@@ -208,6 +212,17 @@ contract ZeroExApiAdapter {
208
212
);
209
213
}
210
214
215
+ function getRfqOrderMakerFillAmount (RfqOrder memory order , uint256 takerTokenFillAmount )
216
+ private
217
+ pure
218
+ returns (uint256 makerTokenFillAmount )
219
+ {
220
+ if (order.takerAmount == 0 || order.makerAmount == 0 || takerTokenFillAmount == 0 ) {
221
+ return 0 ;
222
+ }
223
+ return uint256 (order.makerAmount * takerTokenFillAmount / order.takerAmount);
224
+ }
225
+
211
226
// Decode input and output tokens from an arbitrary length encoded Uniswap V3 path
212
227
function _decodeTokensFromUniswapV3EncodedPath (bytes memory encodedPath )
213
228
private
0 commit comments