@@ -28,28 +28,24 @@ pragma experimental "ABIEncoderV2";
2828
2929contract ZeroExApiAdapter {
3030
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 ;
4242 }
4343
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;
5349 }
5450
5551 /* ============ State Variables ============ */
@@ -149,23 +145,31 @@ contract ZeroExApiAdapter {
149145 require (path.length > 1 , "Uniswap token path too short " );
150146 inputToken = path[0 ];
151147 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+ }
169173 } else if (selector == 0x6af479b2 ) {
170174 // sellTokenForTokenToUniswapV3()
171175 bytes memory encodedPath;
@@ -208,6 +212,17 @@ contract ZeroExApiAdapter {
208212 );
209213 }
210214
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+
211226 // Decode input and output tokens from an arbitrary length encoded Uniswap V3 path
212227 function _decodeTokensFromUniswapV3EncodedPath (bytes memory encodedPath )
213228 private
0 commit comments