diff --git a/contracts/OrderRFQMixin.sol b/contracts/OrderRFQMixin.sol index 45352f72..9779b764 100644 --- a/contracts/OrderRFQMixin.sol +++ b/contracts/OrderRFQMixin.sol @@ -56,18 +56,6 @@ abstract contract OrderRFQMixin is IOrderRFQMixin, EIP712, OnlyWethReceiver { _invalidateOrder(msg.sender, orderInfo, additionalMask); } - /** - * @notice See {IOrderRFQMixin-fillRFQ}. - */ - function fillRFQ( - OrderRFQLib.OrderRFQ calldata order, - bytes32 r, - bytes32 vs, - uint256 flagsAndAmount - ) external payable returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash) { - return fillOrderRFQTo(order, r, vs, flagsAndAmount, msg.data[:0], msg.sender); - } - /** * @notice See {IOrderRFQMixin-fillOrderRFQ}. */ @@ -75,10 +63,9 @@ abstract contract OrderRFQMixin is IOrderRFQMixin, EIP712, OnlyWethReceiver { OrderRFQLib.OrderRFQ calldata order, bytes32 r, bytes32 vs, - uint256 flagsAndAmount, - bytes calldata interaction + uint256 flagsAndAmount ) external payable returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash) { - return fillOrderRFQTo(order, r, vs, flagsAndAmount, interaction, msg.sender); + return fillOrderRFQTo(order, r, vs, flagsAndAmount, msg.sender, msg.data[:0]); } /** @@ -89,8 +76,8 @@ abstract contract OrderRFQMixin is IOrderRFQMixin, EIP712, OnlyWethReceiver { bytes32 r, bytes32 vs, uint256 flagsAndAmount, - bytes calldata interaction, - address target + address target, + bytes calldata interaction ) public payable returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash) { orderHash = order.hash(_domainSeparatorV4()); address maker = ECDSA.recover(orderHash, r, vs); @@ -107,12 +94,12 @@ abstract contract OrderRFQMixin is IOrderRFQMixin, EIP712, OnlyWethReceiver { bytes32 r, bytes32 vs, uint256 flagsAndAmount, - bytes calldata interaction, address target, + bytes calldata interaction, bytes calldata permit ) external returns(uint256 /* filledMakingAmount */, uint256 /* filledTakingAmount */, bytes32 /* orderHash */) { IERC20(order.takerAsset.get()).safePermit(permit); - return fillOrderRFQTo(order, r, vs, flagsAndAmount, interaction, target); + return fillOrderRFQTo(order, r, vs, flagsAndAmount, target, interaction); } /** @@ -123,8 +110,8 @@ abstract contract OrderRFQMixin is IOrderRFQMixin, EIP712, OnlyWethReceiver { bytes calldata signature, Address maker, uint256 flagsAndAmount, - bytes calldata interaction, address target, + bytes calldata interaction, bytes calldata permit ) external returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash) { if (permit.length > 0) { diff --git a/contracts/interfaces/IOrderRFQMixin.sol b/contracts/interfaces/IOrderRFQMixin.sol index 83f14f8d..cf6408e6 100644 --- a/contracts/interfaces/IOrderRFQMixin.sol +++ b/contracts/interfaces/IOrderRFQMixin.sol @@ -53,33 +53,11 @@ interface IOrderRFQMixin { * @return filledTakingAmount Actual amount transferred from taker to maker * @return orderHash Hash of the filled order */ - function fillRFQ( - OrderRFQLib.OrderRFQ calldata order, - bytes32 r, - bytes32 vs, - uint256 flagsAndAmount - ) external payable returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash); - - /** - * @notice Fills order's quote, fully or partially (whichever is possible) - * @param order Order quote to fill - * @param r R component of signature - * @param vs VS component of signature - * @param flagsAndAmount Fill configuration flags with amount packed in one slot - * - Bits 0-253 contain the amount to fill - * - Bit 254 is used to indicate whether weth should be unwrapped to eth - * - Bit 255 is used to indicate whether maker (1) or taker amount (0) is given in the amount parameter - * @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets. - * @return filledMakingAmount Actual amount transferred from maker to taker - * @return filledTakingAmount Actual amount transferred from taker to maker - * @return orderHash Hash of the filled order - */ function fillOrderRFQ( OrderRFQLib.OrderRFQ calldata order, bytes32 r, bytes32 vs, - uint256 flagsAndAmount, - bytes calldata interaction + uint256 flagsAndAmount ) external payable returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash); /** @@ -88,8 +66,8 @@ interface IOrderRFQMixin { * @param r R component of signature * @param vs VS component of signature * @param flagsAndAmount Fill configuration flags with amount packed in one slot - * @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets. * @param target Address that will receive swap funds + * @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets. * @return filledMakingAmount Actual amount transferred from maker to taker * @return filledTakingAmount Actual amount transferred from taker to maker * @return orderHash Hash of the filled order @@ -99,8 +77,8 @@ interface IOrderRFQMixin { bytes32 r, bytes32 vs, uint256 flagsAndAmount, - bytes calldata interaction, - address target + address target, + bytes calldata interaction ) external payable returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash); /** @@ -111,8 +89,8 @@ interface IOrderRFQMixin { * @param r R component of signature * @param vs VS component of signature * @param flagsAndAmount Fill configuration flags with amount packed in one slot - * @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets. * @param target Address that will receive swap funds + * @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets. * @param permit Should contain abi-encoded calldata for `IERC20Permit.permit` call * @return filledMakingAmount Actual amount transferred from maker to taker * @return filledTakingAmount Actual amount transferred from taker to maker @@ -124,8 +102,8 @@ interface IOrderRFQMixin { bytes32 r, bytes32 vs, uint256 flagsAndAmount, - bytes calldata interaction, address target, + bytes calldata interaction, bytes calldata permit ) external returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash); @@ -137,8 +115,8 @@ interface IOrderRFQMixin { * @param signature Signature to confirm quote ownership * @param maker Smart contract that signed the order * @param flagsAndAmount Fill configuration flags with amount packed in one slot - * @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets. * @param target Address that will receive swap funds + * @param interaction A call data for InteractiveNotificationReceiver. Taker may execute interaction after getting maker assets and before sending taker assets. * @param permit Should contain abi-encoded calldata for `IERC20Permit.permit` call * @return filledMakingAmount Actual amount transferred from maker to taker * @return filledTakingAmount Actual amount transferred from taker to maker @@ -150,8 +128,8 @@ interface IOrderRFQMixin { bytes calldata signature, Address maker, uint256 flagsAndAmount, - bytes calldata interaction, address target, + bytes calldata interaction, bytes calldata permit ) external returns(uint256 filledMakingAmount, uint256 filledTakingAmount, bytes32 orderHash); } diff --git a/contracts/mocks/RecursiveMatcher.sol b/contracts/mocks/RecursiveMatcher.sol index f3cfef45..e2cb1860 100644 --- a/contracts/mocks/RecursiveMatcher.sol +++ b/contracts/mocks/RecursiveMatcher.sol @@ -41,11 +41,12 @@ contract RecursiveMatcher is IInteractionNotificationReceiver { uint256 flagsAndAmount, bytes calldata interaction ) external { - orderRFQMixin.fillOrderRFQ( + orderRFQMixin.fillOrderRFQTo( order, r, vs, flagsAndAmount, + address(this), interaction ); } @@ -70,6 +71,8 @@ contract RecursiveMatcher is IInteractionNotificationReceiver { } } else { if(interactiveData[0] & _RFQ_FLAG != 0x0) { + // msg.sender.call(abi.encodePacked(IOrderRFQMixin.fillOrderRFQTo.selector, interactiveData[1:])); + ( OrderRFQLib.OrderRFQ memory order, bytes32 r, @@ -78,31 +81,36 @@ contract RecursiveMatcher is IInteractionNotificationReceiver { bytes memory interaction ) = abi.decode(interactiveData[1:], (OrderRFQLib.OrderRFQ, bytes32, bytes32, uint256, bytes)); - IOrderRFQMixin(msg.sender).fillOrderRFQ( + IOrderRFQMixin(msg.sender).fillOrderRFQTo( order, r, vs, flagsAndAmount, + address(this), interaction ); } else { - ( - OrderLib.Order memory order, - bytes memory signature, - bytes memory interaction, - uint256 makingOrderAmount, - uint256 takingOrderAmount, - uint256 thresholdAmount - ) = abi.decode(interactiveData[1:], (OrderLib.Order, bytes, bytes, uint256, uint256, uint256)); + // Not necessary to encode and decode calldata, because it is already encoded + // solhint-disable-next-line avoid-low-level-calls + msg.sender.call(abi.encodePacked(IOrderMixin.fillOrder.selector, interactiveData[1:])); - IOrderMixin(msg.sender).fillOrder( - order, - signature, - interaction, - makingOrderAmount, - takingOrderAmount, - thresholdAmount - ); + // ( + // OrderLib.Order memory order, + // bytes memory signature, + // bytes memory interaction, + // uint256 makingOrderAmount, + // uint256 takingOrderAmount, + // uint256 thresholdAmount + // ) = abi.decode(interactiveData[1:], (OrderLib.Order, bytes, bytes, uint256, uint256, uint256)); + + // IOrderMixin(msg.sender).fillOrder( + // order, + // signature, + // interaction, + // makingOrderAmount, + // takingOrderAmount, + // thresholdAmount + // ); } } return 0; diff --git a/test/ContractRFQ.js b/test/ContractRFQ.js index 774acdfd..7649d268 100644 --- a/test/ContractRFQ.js +++ b/test/ContractRFQ.js @@ -46,7 +46,7 @@ describe('ContractRFQ', function () { const order = buildOrderRFQ('1', usdc.address, usdt.address, 1000000000, 1000700000); const signature = abiCoder.encode([ABIOrderRFQ], [order]); - await swap.fillContractOrderRFQToWithPermit(order, signature, rfq.address, makingAmount(1000000), emptyInteraction, constants.AddressZero, '0x'); + await swap.fillContractOrderRFQToWithPermit(order, signature, rfq.address, makingAmount(1000000), constants.AddressZero, emptyInteraction, '0x'); expect(await usdc.balanceOf(rfq.address)).to.equal(makerUsdc.sub(1000000)); expect(await usdc.balanceOf(addr.address)).to.equal(takerUsdc.add(1000000)); @@ -55,6 +55,6 @@ describe('ContractRFQ', function () { const order2 = buildOrderRFQ('2', usdc.address, usdt.address, 1000000000, 1000700000); const signature2 = abiCoder.encode([ABIOrderRFQ], [order2]); - await swap.fillContractOrderRFQToWithPermit(order2, signature2, rfq.address, makingAmount(1000000), emptyInteraction, constants.AddressZero, '0x'); + await swap.fillContractOrderRFQToWithPermit(order2, signature2, rfq.address, makingAmount(1000000), constants.AddressZero, emptyInteraction, '0x'); }); }); diff --git a/test/RfqOrders.js b/test/RfqOrders.js index 09957af2..6bf966f8 100644 --- a/test/RfqOrders.js +++ b/test/RfqOrders.js @@ -48,7 +48,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const takerWeth = await weth.balanceOf(addr.address); const { r, vs } = compactSignature(signature); - const receipt = await swap.fillRFQ(order, r, vs, makingAmount(1)); + const receipt = await swap.fillOrderRFQ(order, r, vs, makingAmount(1)); expect( await profileEVM(ethers.provider, receipt.hash, ['CALL', 'STATICCALL', 'SSTORE', 'SLOAD', 'EXTCODESIZE']), @@ -79,7 +79,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const takerWeth = await weth.balanceOf(addr.address); const { r, vs } = compactSignature(signature); - await swap.fillOrderRFQToWithPermit(order, r, vs, makingAmount(1), emptyInteraction, addr.address, permit); + await swap.fillOrderRFQToWithPermit(order, r, vs, makingAmount(1), addr.address, emptyInteraction, permit); expect(await dai.balanceOf(addr1.address)).to.equal(makerDai.sub(1)); expect(await dai.balanceOf(addr.address)).to.equal(takerDai.add(1)); @@ -94,7 +94,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const permit = await getPermit(addr.address, addr, weth, '1', chainId, swap.address, '1'); const { r, vs } = compactSignature(signature); - const requestFunc = () => swap.fillOrderRFQToWithPermit(order, r, vs, takingAmount(1), emptyInteraction, addr.address, permit); + const requestFunc = () => swap.fillOrderRFQToWithPermit(order, r, vs, takingAmount(1), addr.address, emptyInteraction, permit); await requestFunc(); await expect(requestFunc()).to.be.revertedWith('ERC20Permit: invalid signature'); }); @@ -106,7 +106,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const permit = await getPermit(addr.address, addr2, weth, '1', chainId, swap.address, '1'); const { r, vs } = compactSignature(signature); - const requestFunc = () => swap.fillOrderRFQToWithPermit(order, r, vs, takingAmount(1), emptyInteraction, addr.address, permit); + const requestFunc = () => swap.fillOrderRFQToWithPermit(order, r, vs, takingAmount(1), addr.address, emptyInteraction, permit); await expect(requestFunc()).to.be.revertedWith('ERC20Permit: invalid signature'); }); @@ -118,7 +118,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const permit = await getPermit(addr.address, addr1, weth, '1', chainId, swap.address, '1', deadline); const { r, vs } = compactSignature(signature); - const requestFunc = () => swap.fillOrderRFQToWithPermit(order, r, vs, takingAmount(1), emptyInteraction, addr.address, permit); + const requestFunc = () => swap.fillOrderRFQToWithPermit(order, r, vs, takingAmount(1), addr.address, emptyInteraction, permit); await expect(requestFunc()).to.be.revertedWith('ERC20Permit: expired deadline'); }); }); @@ -148,7 +148,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const { r, vs } = compactSignature(signature); await expect( - swap.fillRFQ(order, r, vs, makingAmount(1)), + swap.fillOrderRFQ(order, r, vs, makingAmount(1)), ).to.be.revertedWithCustomError(swap, 'InvalidatedOrder'); }); }); @@ -165,7 +165,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const takerWeth = await weth.balanceOf(addr.address); const { r, vs } = compactSignature(signature); - await swap.fillRFQ(order, r, vs, makingAmount(1)); + await swap.fillOrderRFQ(order, r, vs, makingAmount(1)); expect(await dai.balanceOf(addr1.address)).to.equal(makerDai.sub(1)); expect(await dai.balanceOf(addr.address)).to.equal(takerDai.add(1)); @@ -184,7 +184,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const takerWeth = await weth.balanceOf(addr.address); const { r, vs } = compactSignature(signature); - await swap.fillRFQ(order, r, vs, takingAmount(1)); + await swap.fillOrderRFQ(order, r, vs, takingAmount(1)); expect(await dai.balanceOf(addr1.address)).to.equal(makerDai.sub(1)); expect(await dai.balanceOf(addr.address)).to.equal(takerDai.add(1)); @@ -203,7 +203,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const takerWeth = await weth.balanceOf(addr.address); const { r, vs } = compactSignature(signature); - await swap.fillRFQ(order, r, vs, makingAmount(1)); + await swap.fillOrderRFQ(order, r, vs, makingAmount(1)); expect(await dai.balanceOf(addr1.address)).to.equal(makerDai.sub(1)); expect(await dai.balanceOf(addr.address)).to.equal(takerDai.add(1)); @@ -222,7 +222,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const takerWeth = await weth.balanceOf(addr.address); const { r, vs } = compactSignature(signature); - await swap.fillRFQ(order, r, vs, takingAmount(1)); + await swap.fillOrderRFQ(order, r, vs, takingAmount(1)); expect(await dai.balanceOf(addr1.address)).to.equal(makerDai.sub(1)); expect(await dai.balanceOf(addr.address)).to.equal(takerDai.add(1)); @@ -241,7 +241,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const takerWeth = await weth.balanceOf(addr.address); const { r, vs } = compactSignature(signature); - await swap.fillRFQ(order, r, vs, 0); + await swap.fillOrderRFQ(order, r, vs, 0); expect(await dai.balanceOf(addr1.address)).to.equal(makerDai.sub(1)); expect(await dai.balanceOf(addr.address)).to.equal(takerDai.add(1)); @@ -260,7 +260,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const takerWeth = await weth.balanceOf(addr.address); const { r, vs } = compactSignature(signature); - await swap.fillRFQ(order, r, vs, 0); + await swap.fillOrderRFQ(order, r, vs, 0); expect(await dai.balanceOf(addr1.address)).to.equal(makerDai.sub(1)); expect(await dai.balanceOf(addr.address)).to.equal(takerDai.add(1)); @@ -275,7 +275,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const { r, vs } = compactSignature(signature); await expect( - swap.fillRFQ(order, r, vs, takingAmount(1)), + swap.fillOrderRFQ(order, r, vs, takingAmount(1)), ).to.be.revertedWithCustomError(swap, 'RFQSwapWithZeroAmount'); }); @@ -286,7 +286,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const { r, vs } = compactSignature(signature); await expect( - swap.fillRFQ(order, r, vs, takingAmount(1)), + swap.fillOrderRFQ(order, r, vs, takingAmount(1)), ).to.be.revertedWithCustomError(swap, 'RFQSwapWithZeroAmount'); }); @@ -297,7 +297,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const { r, vs } = compactSignature(signature); await expect( - swap.fillRFQ(order, r, vs, makingAmount(1)), + swap.fillOrderRFQ(order, r, vs, makingAmount(1)), ).to.be.revertedWithCustomError(swap, 'OrderExpired'); }); @@ -308,7 +308,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const { r, vs } = compactSignature(signature); await expect( - swap.fillRFQ(order, r, vs, takingAmount(1)), + swap.fillOrderRFQ(order, r, vs, takingAmount(1)), ).to.be.revertedWithCustomError(swap, 'OrderExpired'); }); }); @@ -325,7 +325,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const takerWeth = await weth.balanceOf(addr.address); const { r, vs } = compactSignature(signature); - await swap.fillRFQ(order, r, vs, takingAmount(3), { value: 3 }); + await swap.fillOrderRFQ(order, r, vs, takingAmount(3), { value: 3 }); expect(await dai.balanceOf(addr1.address)).to.equal(makerDai.sub(900)); expect(await dai.balanceOf(addr.address)).to.equal(takerDai.add(900)); @@ -344,7 +344,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const takerWeth = await weth.balanceOf(addr.address); const { r, vs } = compactSignature(signature); - await swap.fillRFQ(order, r, vs, unwrapWeth(makingAmount(3))); + await swap.fillOrderRFQ(order, r, vs, unwrapWeth(makingAmount(3))); expect(await dai.balanceOf(addr1.address)).to.equal(makerDai.add(900)); expect(await dai.balanceOf(addr.address)).to.equal(takerDai.sub(900)); @@ -359,10 +359,10 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const { r, vs } = compactSignature(signature); await expect( - swap.fillRFQ(order, r, vs, makingAmount(900), { value: 2 }), + swap.fillOrderRFQ(order, r, vs, makingAmount(900), { value: 2 }), ).to.be.revertedWithCustomError(swap, 'InvalidMsgValue'); await expect( - swap.fillRFQ(order, r, vs, makingAmount(900), { value: 4 }), + swap.fillOrderRFQ(order, r, vs, makingAmount(900), { value: 4 }), ).to.be.revertedWithCustomError(swap, 'InvalidMsgValue'); }); @@ -374,7 +374,7 @@ describe('RFQ Orders in LimitOrderProtocol', function () { const { r, vs } = compactSignature(signature); await expect( - swap.fillRFQ(order, r, vs, makingAmount(900), { value: 1 }), + swap.fillOrderRFQ(order, r, vs, makingAmount(900), { value: 1 }), ).to.be.revertedWithCustomError(swap, 'InvalidMsgValue'); }); });