diff --git a/contracts/zero-ex/CHANGELOG.json b/contracts/zero-ex/CHANGELOG.json index bc71ce44e2..d491bbd3ec 100644 --- a/contracts/zero-ex/CHANGELOG.json +++ b/contracts/zero-ex/CHANGELOG.json @@ -25,6 +25,10 @@ { "note": "Convert metatransactions to use `LibSignature`", "pr": 31 + }, + { + "note": "Add metatransaction support for limit orders", + "pr": 44 } ] }, diff --git a/contracts/zero-ex/contracts/src/features/MetaTransactionsFeature.sol b/contracts/zero-ex/contracts/src/features/MetaTransactionsFeature.sol index c51e8fdb43..4298352cb4 100644 --- a/contracts/zero-ex/contracts/src/features/MetaTransactionsFeature.sol +++ b/contracts/zero-ex/contracts/src/features/MetaTransactionsFeature.sol @@ -35,6 +35,7 @@ import "./ITransformERC20Feature.sol"; import "./libs/LibSignature.sol"; import "./ISignatureValidatorFeature.sol"; import "./IFeature.sol"; +import "./INativeOrdersFeature.sol"; /// @dev MetaTransactions feature. contract MetaTransactionsFeature is @@ -48,7 +49,6 @@ contract MetaTransactionsFeature is using LibBytesV06 for bytes; using LibRichErrorsV06 for bytes; - /// @dev Describes the state of a meta transaction. struct ExecuteState { // Sender of the meta-transaction. @@ -292,6 +292,10 @@ contract MetaTransactionsFeature is state.selector = state.mtx.callData.readBytes4(0); if (state.selector == ITransformERC20Feature.transformERC20.selector) { returnResult = _executeTransformERC20Call(state); + } else if (state.selector == INativeOrdersFeature.fillLimitOrder.selector) { + returnResult = _executeFillLimitOrderCall(state); + } else if (state.selector == INativeOrdersFeature.fillRfqOrder.selector) { + returnResult = _executeFillRfqOrderCall(state); } else { LibMetaTransactionsRichErrors .MetaTransactionUnsupportedFunctionError(state.hash, state.selector) @@ -453,6 +457,88 @@ contract MetaTransactionsFeature is ); } + /// @dev Extract arguments from call data by copying everything after the + /// 4-byte selector into a new byte array. + /// @param callData The call data from which arguments are to be extracted. + /// @return args The extracted arguments as a byte array. + function _extractArgumentsFromCallData( + bytes memory callData + ) + private + pure + returns (bytes memory args) + { + args = new bytes(callData.length - 4); + uint256 fromMem; + uint256 toMem; + + assembly { + fromMem := add(callData, 36) // skip length and 4-byte selector + toMem := add(args, 32) // write after length prefix + } + + LibBytesV06.memCopy(toMem, fromMem, args.length); + + return args; + } + + /// @dev Execute a `INativeOrdersFeature.fillLimitOrder()` meta-transaction call + /// by decoding the call args and translating the call to the internal + /// `INativeOrdersFeature._fillLimitOrder()` variant, where we can override + /// the taker address. + function _executeFillLimitOrderCall(ExecuteState memory state) + private + returns (bytes memory returnResult) + { + LibNativeOrder.LimitOrder memory order; + LibSignature.Signature memory signature; + uint128 takerTokenFillAmount; + + bytes memory args = _extractArgumentsFromCallData(state.mtx.callData); + (order, signature, takerTokenFillAmount) = abi.decode(args, (LibNativeOrder.LimitOrder, LibSignature.Signature, uint128)); + + return _callSelf( + state.hash, + abi.encodeWithSelector( + INativeOrdersFeature._fillLimitOrder.selector, + order, + signature, + takerTokenFillAmount, + state.mtx.signer, // taker is mtx signer + msg.sender + ), + state.mtx.value + ); + } + + /// @dev Execute a `INativeOrdersFeature.fillRfqOrder()` meta-transaction call + /// by decoding the call args and translating the call to the internal + /// `INativeOrdersFeature._fillRfqOrder()` variant, where we can overrideunimpleme + /// the taker address. + function _executeFillRfqOrderCall(ExecuteState memory state) + private + returns (bytes memory returnResult) + { + LibNativeOrder.RfqOrder memory order; + LibSignature.Signature memory signature; + uint128 takerTokenFillAmount; + + bytes memory args = _extractArgumentsFromCallData(state.mtx.callData); + (order, signature, takerTokenFillAmount) = abi.decode(args, (LibNativeOrder.RfqOrder, LibSignature.Signature, uint128)); + + return _callSelf( + state.hash, + abi.encodeWithSelector( + INativeOrdersFeature._fillRfqOrder.selector, + order, + signature, + takerTokenFillAmount, + state.mtx.signer // taker is mtx signer + ), + state.mtx.value + ); + } + /// @dev Make an arbitrary internal, meta-transaction call. /// Warning: Do not let unadulterated `callData` into this function. function _callSelf(bytes32 hash, bytes memory callData, uint256 value) diff --git a/contracts/zero-ex/contracts/src/features/NativeOrdersFeature.sol b/contracts/zero-ex/contracts/src/features/NativeOrdersFeature.sol index ae40077af9..ca75d3ef0e 100644 --- a/contracts/zero-ex/contracts/src/features/NativeOrdersFeature.sol +++ b/contracts/zero-ex/contracts/src/features/NativeOrdersFeature.sol @@ -319,6 +319,7 @@ contract NativeOrdersFeature is address sender ) public + virtual override payable onlySelf @@ -355,6 +356,7 @@ contract NativeOrdersFeature is address taker ) public + virtual override payable onlySelf diff --git a/contracts/zero-ex/contracts/src/features/libs/LibSignature.sol b/contracts/zero-ex/contracts/src/features/libs/LibSignature.sol index 0f9b765714..990b595c7c 100644 --- a/contracts/zero-ex/contracts/src/features/libs/LibSignature.sol +++ b/contracts/zero-ex/contracts/src/features/libs/LibSignature.sol @@ -38,7 +38,7 @@ library LibSignature { /// The valid range is given by fig (283) of the yellow paper. uint256 private constant ECDSA_SIGNATURE_S_LIMIT = ECDSA_SIGNATURE_R_LIMIT / 2 + 1; - /// @dev Allowed signature types. + /// @dev Allowed signature types. enum SignatureType { ILLEGAL, INVALID, diff --git a/contracts/zero-ex/contracts/test/TestMetaTransactionsNativeOrdersFeature.sol b/contracts/zero-ex/contracts/test/TestMetaTransactionsNativeOrdersFeature.sol new file mode 100644 index 0000000000..f60ff429c4 --- /dev/null +++ b/contracts/zero-ex/contracts/test/TestMetaTransactionsNativeOrdersFeature.sol @@ -0,0 +1,104 @@ +/* + + Copyright 2020 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity ^0.6.5; +pragma experimental ABIEncoderV2; + +import "../src/features/NativeOrdersFeature.sol"; +import "../src/features/IMetaTransactionsFeature.sol"; + + +contract TestMetaTransactionsNativeOrdersFeature is + NativeOrdersFeature +{ + constructor( + ) + public + NativeOrdersFeature(address(0), IEtherTokenV06(0), IStaking(0), 0, bytes32(0)) + { + } + + event FillLimitOrderCalled( + LibNativeOrder.LimitOrder order, + LibSignature.SignatureType signatureType, + uint8 v, + bytes32 r, + bytes32 s, + uint128 takerTokenFillAmount, + address taker, + address sender + ); + + function _fillLimitOrder( + LibNativeOrder.LimitOrder memory order, + LibSignature.Signature memory signature, + uint128 takerTokenFillAmount, + address taker, + address sender + ) + public + override + payable + returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount) + { + emit FillLimitOrderCalled( + order, + signature.signatureType, + signature.v, + signature.r, + signature.s, + takerTokenFillAmount, + taker, + sender + ); + return (0, 1337); + } + + event FillRfqOrderCalled( + LibNativeOrder.RfqOrder order, + LibSignature.SignatureType signatureType, + uint8 v, + bytes32 r, + bytes32 s, + uint128 takerTokenFillAmount, + address taker + ); + + function _fillRfqOrder( + LibNativeOrder.RfqOrder memory order, + LibSignature.Signature memory signature, + uint128 takerTokenFillAmount, + address taker + ) + public + override + payable + returns (uint128 takerTokenFilledAmount, uint128 makerTokenFilledAmount) + { + emit FillRfqOrderCalled( + order, + signature.signatureType, + signature.v, + signature.r, + signature.s, + takerTokenFillAmount, + taker + ); + return (0, 1337); + } +} diff --git a/contracts/zero-ex/package.json b/contracts/zero-ex/package.json index 5fac3d3ac5..134392de3f 100644 --- a/contracts/zero-ex/package.json +++ b/contracts/zero-ex/package.json @@ -42,7 +42,7 @@ "config": { "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IAllowanceTarget,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITokenSpenderFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,TokenSpenderFeature,AffiliateFeeTransformer,SignatureValidatorFeature,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature", "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.", - "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|AllowanceTarget|BootstrapFeature|BridgeAdapter|FeeCollector|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|IAllowanceTarget|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IExchange|IFeature|IFlashWallet|IGasToken|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|INativeOrdersFeature|IOwnableFeature|ISignatureValidatorFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOrderHash|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSignedCallData|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibSpenderRichErrors|LibStorage|LibTokenSpenderStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAdapterAddresses|MixinBalancer|MixinCurve|MixinDodo|MixinKyber|MixinMStable|MixinMooniswap|MixinOasis|MixinShell|MixinSushiswap|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|NativeOrdersFeature|OwnableFeature|PayTakerTransformer|SignatureValidatorFeature|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestDelegateCaller|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestNativeOrdersFeature|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpender|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TokenSpenderFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx|ZeroExOptimized).json" + "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|AllowanceTarget|BootstrapFeature|BridgeAdapter|FeeCollector|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|IAllowanceTarget|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IExchange|IFeature|IFlashWallet|IGasToken|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|INativeOrdersFeature|IOwnableFeature|ISignatureValidatorFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOrderHash|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSignedCallData|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibSpenderRichErrors|LibStorage|LibTokenSpenderStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAdapterAddresses|MixinBalancer|MixinCurve|MixinDodo|MixinKyber|MixinMStable|MixinMooniswap|MixinOasis|MixinShell|MixinSushiswap|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|NativeOrdersFeature|OwnableFeature|PayTakerTransformer|SignatureValidatorFeature|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestDelegateCaller|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestNativeOrdersFeature|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpender|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TokenSpenderFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx|ZeroExOptimized).json" }, "repository": { "type": "git", diff --git a/contracts/zero-ex/test/artifacts.ts b/contracts/zero-ex/test/artifacts.ts index 7949e132f8..1ddfded855 100644 --- a/contracts/zero-ex/test/artifacts.ts +++ b/contracts/zero-ex/test/artifacts.ts @@ -104,6 +104,7 @@ import * as TestInitialMigration from '../test/generated-artifacts/TestInitialMi import * as TestLibNativeOrder from '../test/generated-artifacts/TestLibNativeOrder.json'; import * as TestLibSignature from '../test/generated-artifacts/TestLibSignature.json'; import * as TestLiquidityProvider from '../test/generated-artifacts/TestLiquidityProvider.json'; +import * as TestMetaTransactionsNativeOrdersFeature from '../test/generated-artifacts/TestMetaTransactionsNativeOrdersFeature.json'; import * as TestMetaTransactionsTransformERC20Feature from '../test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json'; import * as TestMigrator from '../test/generated-artifacts/TestMigrator.json'; import * as TestMintableERC20Token from '../test/generated-artifacts/TestMintableERC20Token.json'; @@ -237,6 +238,7 @@ export const artifacts = { TestLibNativeOrder: TestLibNativeOrder as ContractArtifact, TestLibSignature: TestLibSignature as ContractArtifact, TestLiquidityProvider: TestLiquidityProvider as ContractArtifact, + TestMetaTransactionsNativeOrdersFeature: TestMetaTransactionsNativeOrdersFeature as ContractArtifact, TestMetaTransactionsTransformERC20Feature: TestMetaTransactionsTransformERC20Feature as ContractArtifact, TestMigrator: TestMigrator as ContractArtifact, TestMintTokenERC20Transformer: TestMintTokenERC20Transformer as ContractArtifact, diff --git a/contracts/zero-ex/test/features/meta_transactions_test.ts b/contracts/zero-ex/test/features/meta_transactions_test.ts index 8a0e138a37..da1bd5488f 100644 --- a/contracts/zero-ex/test/features/meta_transactions_test.ts +++ b/contracts/zero-ex/test/features/meta_transactions_test.ts @@ -17,7 +17,10 @@ import { IZeroExContract, MetaTransactionsFeatureContract } from '../../src/wrap import { artifacts } from '../artifacts'; import { abis } from '../utils/abis'; import { fullMigrateAsync } from '../utils/migration'; +import { getRandomLimitOrder, getRandomRfqOrder } from '../utils/orders'; import { + TestMetaTransactionsNativeOrdersFeatureContract, + TestMetaTransactionsNativeOrdersFeatureEvents, TestMetaTransactionsTransformERC20FeatureContract, TestMetaTransactionsTransformERC20FeatureEvents, TestMintableERC20TokenContract, @@ -27,12 +30,14 @@ const { NULL_ADDRESS, NULL_BYTES, ZERO_AMOUNT } = constants; blockchainTests.resets('MetaTransactions feature', env => { let owner: string; + let maker: string; let sender: string; let signers: string[]; let zeroEx: IZeroExContract; let feature: MetaTransactionsFeatureContract; let feeToken: TestMintableERC20TokenContract; let transformERC20Feature: TestMetaTransactionsTransformERC20FeatureContract; + let nativeOrdersFeature: TestMetaTransactionsNativeOrdersFeatureContract; const MAX_FEE_AMOUNT = new BigNumber('1e18'); const TRANSFORM_ERC20_FAILING_VALUE = new BigNumber(666); @@ -41,15 +46,22 @@ blockchainTests.resets('MetaTransactions feature', env => { const REENTRANCY_FLAG_MTX = 0x1; before(async () => { - [owner, sender, ...signers] = await env.getAccountAddressesAsync(); + [owner, maker, sender, ...signers] = await env.getAccountAddressesAsync(); transformERC20Feature = await TestMetaTransactionsTransformERC20FeatureContract.deployFrom0xArtifactAsync( artifacts.TestMetaTransactionsTransformERC20Feature, env.provider, env.txDefaults, {}, ); + nativeOrdersFeature = await TestMetaTransactionsNativeOrdersFeatureContract.deployFrom0xArtifactAsync( + artifacts.TestMetaTransactionsNativeOrdersFeature, + env.provider, + env.txDefaults, + {}, + ); zeroEx = await fullMigrateAsync(owner, env.provider, env.txDefaults, { transformERC20: transformERC20Feature.address, + nativeOrders: nativeOrdersFeature.address, }); feature = new MetaTransactionsFeatureContract( zeroEx.address, @@ -141,9 +153,77 @@ blockchainTests.resets('MetaTransactions feature', env => { }; } - const RAW_SUCCESS_RESULT = hexUtils.leftPad(1337); + const RAW_TRANSFORM_SUCCESS_RESULT = hexUtils.leftPad(1337); + const RAW_ORDER_SUCCESS_RESULT = hexUtils.leftPad(1337, 64); describe('executeMetaTransaction()', () => { + it('can call NativeOrders.fillLimitOrder()', async () => { + const order = getRandomLimitOrder({ maker }); + const fillAmount = new BigNumber(23456); + const sig = await order.getSignatureWithProviderAsync(env.provider); + const mtx = getRandomMetaTransaction({ + callData: nativeOrdersFeature.fillLimitOrder(order, sig, fillAmount).getABIEncodedTransactionData(), + }); + const signature = await signMetaTransactionAsync(mtx); + const callOpts = { + gasPrice: mtx.minGasPrice, + value: mtx.value, + }; + const rawResult = await feature.executeMetaTransaction(mtx, signature).callAsync(callOpts); + expect(rawResult).to.eq(RAW_ORDER_SUCCESS_RESULT); + const receipt = await feature.executeMetaTransaction(mtx, signature).awaitTransactionSuccessAsync(callOpts); + + verifyEventsFromLogs( + receipt.logs, + [ + { + order: _.omit(order, ['verifyingContract', 'chainId']), + sender: mtx.sender, + taker: mtx.signer, + takerTokenFillAmount: fillAmount, + signatureType: sig.signatureType, + v: sig.v, + r: sig.r, + s: sig.s, + }, + ], + TestMetaTransactionsNativeOrdersFeatureEvents.FillLimitOrderCalled, + ); + }); + + it('can call NativeOrders.fillRfqOrder()', async () => { + const order = getRandomRfqOrder({ maker }); + const sig = await order.getSignatureWithProviderAsync(env.provider); + const fillAmount = new BigNumber(23456); + const mtx = getRandomMetaTransaction({ + callData: nativeOrdersFeature.fillRfqOrder(order, sig, fillAmount).getABIEncodedTransactionData(), + }); + const signature = await signMetaTransactionAsync(mtx); + const callOpts = { + gasPrice: mtx.minGasPrice, + value: mtx.value, + }; + const rawResult = await feature.executeMetaTransaction(mtx, signature).callAsync(callOpts); + expect(rawResult).to.eq(RAW_ORDER_SUCCESS_RESULT); + const receipt = await feature.executeMetaTransaction(mtx, signature).awaitTransactionSuccessAsync(callOpts); + + verifyEventsFromLogs( + receipt.logs, + [ + { + order: _.omit(order, ['verifyingContract', 'chainId']), + taker: mtx.signer, + takerTokenFillAmount: fillAmount, + signatureType: sig.signatureType, + v: sig.v, + r: sig.r, + s: sig.s, + }, + ], + TestMetaTransactionsNativeOrdersFeatureEvents.FillRfqOrderCalled, + ); + }); + it('can call `TransformERC20.transformERC20()`', async () => { const args = getRandomTransformERC20Args(); const mtx = getRandomMetaTransaction({ @@ -163,7 +243,7 @@ blockchainTests.resets('MetaTransactions feature', env => { value: mtx.value, }; const rawResult = await feature.executeMetaTransaction(mtx, signature).callAsync(callOpts); - expect(rawResult).to.eq(RAW_SUCCESS_RESULT); + expect(rawResult).to.eq(RAW_TRANSFORM_SUCCESS_RESULT); const receipt = await feature.executeMetaTransaction(mtx, signature).awaitTransactionSuccessAsync(callOpts); verifyEventsFromLogs( receipt.logs, @@ -206,7 +286,7 @@ blockchainTests.resets('MetaTransactions feature', env => { value: mtx.value, }; const rawResult = await feature.executeMetaTransaction(mtx, signature).callAsync(callOpts); - expect(rawResult).to.eq(RAW_SUCCESS_RESULT); + expect(rawResult).to.eq(RAW_TRANSFORM_SUCCESS_RESULT); const receipt = await feature.executeMetaTransaction(mtx, signature).awaitTransactionSuccessAsync(callOpts); verifyEventsFromLogs( receipt.logs, @@ -249,7 +329,7 @@ blockchainTests.resets('MetaTransactions feature', env => { from: randomAddress(), }; const rawResult = await feature.executeMetaTransaction(mtx, signature).callAsync(callOpts); - expect(rawResult).to.eq(RAW_SUCCESS_RESULT); + expect(rawResult).to.eq(RAW_TRANSFORM_SUCCESS_RESULT); }); it('works without fee', async () => { @@ -273,7 +353,7 @@ blockchainTests.resets('MetaTransactions feature', env => { value: mtx.value, }; const rawResult = await feature.executeMetaTransaction(mtx, signature).callAsync(callOpts); - expect(rawResult).to.eq(RAW_SUCCESS_RESULT); + expect(rawResult).to.eq(RAW_TRANSFORM_SUCCESS_RESULT); }); it('fails if the translated call fails', async () => { @@ -638,7 +718,7 @@ blockchainTests.resets('MetaTransactions feature', env => { value: BigNumber.sum(...mtxs.map(mtx => mtx.value)), }; const rawResults = await feature.batchExecuteMetaTransactions(mtxs, signatures).callAsync(callOpts); - expect(rawResults).to.eql(mtxs.map(() => RAW_SUCCESS_RESULT)); + expect(rawResults).to.eql(mtxs.map(() => RAW_TRANSFORM_SUCCESS_RESULT)); }); it('cannot execute the same transaction twice', async () => { diff --git a/contracts/zero-ex/test/wrappers.ts b/contracts/zero-ex/test/wrappers.ts index c645125d83..47966fb4cc 100644 --- a/contracts/zero-ex/test/wrappers.ts +++ b/contracts/zero-ex/test/wrappers.ts @@ -102,6 +102,7 @@ export * from '../test/generated-wrappers/test_initial_migration'; export * from '../test/generated-wrappers/test_lib_native_order'; export * from '../test/generated-wrappers/test_lib_signature'; export * from '../test/generated-wrappers/test_liquidity_provider'; +export * from '../test/generated-wrappers/test_meta_transactions_native_orders_feature'; export * from '../test/generated-wrappers/test_meta_transactions_transform_erc20_feature'; export * from '../test/generated-wrappers/test_migrator'; export * from '../test/generated-wrappers/test_mint_token_erc20_transformer'; diff --git a/contracts/zero-ex/tsconfig.json b/contracts/zero-ex/tsconfig.json index 2a66e650c7..862124b2d1 100644 --- a/contracts/zero-ex/tsconfig.json +++ b/contracts/zero-ex/tsconfig.json @@ -129,6 +129,7 @@ "test/generated-artifacts/TestLibNativeOrder.json", "test/generated-artifacts/TestLibSignature.json", "test/generated-artifacts/TestLiquidityProvider.json", + "test/generated-artifacts/TestMetaTransactionsNativeOrdersFeature.json", "test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json", "test/generated-artifacts/TestMigrator.json", "test/generated-artifacts/TestMintTokenERC20Transformer.json",